Compruebe si el bit solo se establece una vez en un vector de int -- ++ campo con c++11 campo con bitwise camp codereview Relacionados El problema

Check if bit is only set once in a vector of int


8
vote

problema

Español

Tengo un vector de public class GraphValidation { public string Target { get; set; } = ""; public bool Result = false; } 9 y quiero verificar si hay un bit, que solo se establece en un solo vector. Luego obtengo su posición dentro del vector, así como del bit.

Digamos que tenemos:

  public class GraphRow {      //clone the columns down to show parent child relationships rather then just a single endpoint on each line.      public GraphRow(string[] clone)     {         int i = 0;         var values = clone.Where(x => x != "" & x != null);         foreach (var value in values)         {             Columns[i] = value ?? "";             i = i + 1;         }     }     //Strings.     public string[] Columns = new string[25];      //indexing the strings.     public virtual string this[int i]     {         get { if (i >= 0 && i < Columns.Length) { return this.Columns[i].ToString(); } else { return null; } }         set { if (i >= 0 && i < Columns.Length) { this.Columns[i] = value; } else { return; } }     }      #region IDisposable Support      private static bool disposedValue = false; // To detect redundant calls       protected virtual void Dispose(bool disposing)     {         if (!disposedValue)         {             if (disposing)             {                 // TODO: dispose managed state (managed objects).             }              // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.             // TODO: set large fields to null.              disposedValue = true;         }     }     // This code added to correctly implement the disposable pattern.     public void Dispose()     {         // Do not change this code. Put cleanup code in Dispose(bool disposing) above.         Dispose(true);         // TODO: uncomment the following line if the finalizer is overridden above.         // GC.SuppressFinalize(this);     }      #endregion IDisposable Support } public static class Grapher {     public static Dictionary<string, object> roots { get; set; }     //Row store     public static List<GraphRow> Rows = new List<GraphRow>();      //Current row initialization     private static GraphRow CurrentRow = new GraphRow(new string[25]);      public static List<GraphValidation> Validations = new List<GraphValidation>();      public static List<GraphValidation> AddValidation(this List<GraphValidation> validations, string Attribute)     {         var Obj = new GraphValidation();          Obj.Target = Attribute;          Validations.Add(Obj);          return Validations;     }     public static List<GraphValidation> Validate(this List<GraphValidation> validations)     {         if (roots != null)         {             var AttributeGraph = Graph(roots);             //AttributeGraph.ViewThis();             if (Validations.Count > 0)             {                 foreach(var validation in validations)                 {                     validation.Result = AttributeGraph.Select(x => x.ToString()).Any(x => x.Contains(validation.Target));                 }             }         }         return validations;     }     private static IQueryable<object> Graph(object roots, int Level = 0)     {         if (roots is IDictionary<string, object>)         {             foreach (var root in roots as IDictionary<string, object>)             {                 //set key                 CurrentRow[Level] = root.Key;                 //loop around increasing the level as I dig down                 if (root.Value is IDictionary<string, object>)                 {                     Graph(root.Value as IDictionary<string, object>, Level + 1);                 }                 else if (root.Value is IList<object>)                 {                     Graph(root.Value as IList<object>, Level);                 }                 else                 {                     var ol = Level;                     while(ol <= CurrentRow.Columns.Length -1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null)                     {                         CurrentRow.Columns[ol + 1] = "";                         ol += 1;                     }                     //add the current row                     Rows.Add(CurrentRow);                     //Clone the Current row;                     CurrentRow = new GraphRow(CurrentRow.Columns);                 }             }         }         else if (roots is List<object>)         {             foreach (var value in roots as List<object>)             {                 if (value is IDictionary<string, object>)                 {                     Graph(value as IDictionary<string, object>, Level + 1);                 }                 else                 {                     if (value is IList<object>)                     {                         Graph(value as IList<object>, Level);                     }                 }             }         }         else         {              //set end of path             CurrentRow[Level] = roots.ToString();             var ol = Level;             while (ol <= CurrentRow.Columns.Length - 1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null)             {                 CurrentRow.Columns[ol + 1] = "";                 ol += 1;             }             //add the current row             Rows.Add(CurrentRow);             //Clone the Current row;             CurrentRow = new GraphRow(CurrentRow.Columns);         }          return (from row in Rows                 select new { Column0 = row.Columns[0], Column1 = row.Columns[1], Column2 = row.Columns[2], Column3 = row.Columns[3], Column4 = row.Columns[4], Column5 = row.Columns[5], Column6 = row.Columns[6], Column7 = row.Columns[7], Column8 = row.Columns[8], Column9 = row.Columns[9], Column10 = row.Columns[10], Column11 = row.Columns[11], Column12 = row.Columns[12], Column13 = row.Columns[13], Column14 = row.Columns[14], Column15 = row.Columns[15], Column16 = row.Columns[16], Column17 = row.Columns[17], Column18 = row.Columns[18], Column19 = row.Columns[19], Column20 = row.Columns[20], Column21 = row.Columns[21], Column22 = row.Columns[22], Column23 = row.Columns[23], Column24 = row.Columns[24] }).AsQueryable();       } } 0  

Me gustaría saber que public class GraphRow { //clone the columns down to show parent child relationships rather then just a single endpoint on each line. public GraphRow(string[] clone) { int i = 0; var values = clone.Where(x => x != "" & x != null); foreach (var value in values) { Columns[i] = value ?? ""; i = i + 1; } } //Strings. public string[] Columns = new string[25]; //indexing the strings. public virtual string this[int i] { get { if (i >= 0 && i < Columns.Length) { return this.Columns[i].ToString(); } else { return null; } } set { if (i >= 0 && i < Columns.Length) { this.Columns[i] = value; } else { return; } } } #region IDisposable Support private static bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } } // This code added to correctly implement the disposable pattern. public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); // TODO: uncomment the following line if the finalizer is overridden above. // GC.SuppressFinalize(this); } #endregion IDisposable Support } public static class Grapher { public static Dictionary<string, object> roots { get; set; } //Row store public static List<GraphRow> Rows = new List<GraphRow>(); //Current row initialization private static GraphRow CurrentRow = new GraphRow(new string[25]); public static List<GraphValidation> Validations = new List<GraphValidation>(); public static List<GraphValidation> AddValidation(this List<GraphValidation> validations, string Attribute) { var Obj = new GraphValidation(); Obj.Target = Attribute; Validations.Add(Obj); return Validations; } public static List<GraphValidation> Validate(this List<GraphValidation> validations) { if (roots != null) { var AttributeGraph = Graph(roots); //AttributeGraph.ViewThis(); if (Validations.Count > 0) { foreach(var validation in validations) { validation.Result = AttributeGraph.Select(x => x.ToString()).Any(x => x.Contains(validation.Target)); } } } return validations; } private static IQueryable<object> Graph(object roots, int Level = 0) { if (roots is IDictionary<string, object>) { foreach (var root in roots as IDictionary<string, object>) { //set key CurrentRow[Level] = root.Key; //loop around increasing the level as I dig down if (root.Value is IDictionary<string, object>) { Graph(root.Value as IDictionary<string, object>, Level + 1); } else if (root.Value is IList<object>) { Graph(root.Value as IList<object>, Level); } else { var ol = Level; while(ol <= CurrentRow.Columns.Length -1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null) { CurrentRow.Columns[ol + 1] = ""; ol += 1; } //add the current row Rows.Add(CurrentRow); //Clone the Current row; CurrentRow = new GraphRow(CurrentRow.Columns); } } } else if (roots is List<object>) { foreach (var value in roots as List<object>) { if (value is IDictionary<string, object>) { Graph(value as IDictionary<string, object>, Level + 1); } else { if (value is IList<object>) { Graph(value as IList<object>, Level); } } } } else { //set end of path CurrentRow[Level] = roots.ToString(); var ol = Level; while (ol <= CurrentRow.Columns.Length - 1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null) { CurrentRow.Columns[ol + 1] = ""; ol += 1; } //add the current row Rows.Add(CurrentRow); //Clone the Current row; CurrentRow = new GraphRow(CurrentRow.Columns); } return (from row in Rows select new { Column0 = row.Columns[0], Column1 = row.Columns[1], Column2 = row.Columns[2], Column3 = row.Columns[3], Column4 = row.Columns[4], Column5 = row.Columns[5], Column6 = row.Columns[6], Column7 = row.Columns[7], Column8 = row.Columns[8], Column9 = row.Columns[9], Column10 = row.Columns[10], Column11 = row.Columns[11], Column12 = row.Columns[12], Column13 = row.Columns[13], Column14 = row.Columns[14], Column15 = row.Columns[15], Column16 = row.Columns[16], Column17 = row.Columns[17], Column18 = row.Columns[18], Column19 = row.Columns[19], Column20 = row.Columns[20], Column21 = row.Columns[21], Column22 = row.Columns[22], Column23 = row.Columns[23], Column24 = row.Columns[24] }).AsQueryable(); } } 1 y public class GraphRow { //clone the columns down to show parent child relationships rather then just a single endpoint on each line. public GraphRow(string[] clone) { int i = 0; var values = clone.Where(x => x != "" & x != null); foreach (var value in values) { Columns[i] = value ?? ""; i = i + 1; } } //Strings. public string[] Columns = new string[25]; //indexing the strings. public virtual string this[int i] { get { if (i >= 0 && i < Columns.Length) { return this.Columns[i].ToString(); } else { return null; } } set { if (i >= 0 && i < Columns.Length) { this.Columns[i] = value; } else { return; } } } #region IDisposable Support private static bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } } // This code added to correctly implement the disposable pattern. public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); // TODO: uncomment the following line if the finalizer is overridden above. // GC.SuppressFinalize(this); } #endregion IDisposable Support } public static class Grapher { public static Dictionary<string, object> roots { get; set; } //Row store public static List<GraphRow> Rows = new List<GraphRow>(); //Current row initialization private static GraphRow CurrentRow = new GraphRow(new string[25]); public static List<GraphValidation> Validations = new List<GraphValidation>(); public static List<GraphValidation> AddValidation(this List<GraphValidation> validations, string Attribute) { var Obj = new GraphValidation(); Obj.Target = Attribute; Validations.Add(Obj); return Validations; } public static List<GraphValidation> Validate(this List<GraphValidation> validations) { if (roots != null) { var AttributeGraph = Graph(roots); //AttributeGraph.ViewThis(); if (Validations.Count > 0) { foreach(var validation in validations) { validation.Result = AttributeGraph.Select(x => x.ToString()).Any(x => x.Contains(validation.Target)); } } } return validations; } private static IQueryable<object> Graph(object roots, int Level = 0) { if (roots is IDictionary<string, object>) { foreach (var root in roots as IDictionary<string, object>) { //set key CurrentRow[Level] = root.Key; //loop around increasing the level as I dig down if (root.Value is IDictionary<string, object>) { Graph(root.Value as IDictionary<string, object>, Level + 1); } else if (root.Value is IList<object>) { Graph(root.Value as IList<object>, Level); } else { var ol = Level; while(ol <= CurrentRow.Columns.Length -1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null) { CurrentRow.Columns[ol + 1] = ""; ol += 1; } //add the current row Rows.Add(CurrentRow); //Clone the Current row; CurrentRow = new GraphRow(CurrentRow.Columns); } } } else if (roots is List<object>) { foreach (var value in roots as List<object>) { if (value is IDictionary<string, object>) { Graph(value as IDictionary<string, object>, Level + 1); } else { if (value is IList<object>) { Graph(value as IList<object>, Level); } } } } else { //set end of path CurrentRow[Level] = roots.ToString(); var ol = Level; while (ol <= CurrentRow.Columns.Length - 1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null) { CurrentRow.Columns[ol + 1] = ""; ol += 1; } //add the current row Rows.Add(CurrentRow); //Clone the Current row; CurrentRow = new GraphRow(CurrentRow.Columns); } return (from row in Rows select new { Column0 = row.Columns[0], Column1 = row.Columns[1], Column2 = row.Columns[2], Column3 = row.Columns[3], Column4 = row.Columns[4], Column5 = row.Columns[5], Column6 = row.Columns[6], Column7 = row.Columns[7], Column8 = row.Columns[8], Column9 = row.Columns[9], Column10 = row.Columns[10], Column11 = row.Columns[11], Column12 = row.Columns[12], Column13 = row.Columns[13], Column14 = row.Columns[14], Column15 = row.Columns[15], Column16 = row.Columns[16], Column17 = row.Columns[17], Column18 = row.Columns[18], Column19 = row.Columns[19], Column20 = row.Columns[20], Column21 = row.Columns[21], Column22 = row.Columns[22], Column23 = row.Columns[23], Column24 = row.Columns[24] }).AsQueryable(); } } 2 .

En el código torpe, esto sería así:

  public class GraphRow {      //clone the columns down to show parent child relationships rather then just a single endpoint on each line.      public GraphRow(string[] clone)     {         int i = 0;         var values = clone.Where(x => x != "" & x != null);         foreach (var value in values)         {             Columns[i] = value ?? "";             i = i + 1;         }     }     //Strings.     public string[] Columns = new string[25];      //indexing the strings.     public virtual string this[int i]     {         get { if (i >= 0 && i < Columns.Length) { return this.Columns[i].ToString(); } else { return null; } }         set { if (i >= 0 && i < Columns.Length) { this.Columns[i] = value; } else { return; } }     }      #region IDisposable Support      private static bool disposedValue = false; // To detect redundant calls       protected virtual void Dispose(bool disposing)     {         if (!disposedValue)         {             if (disposing)             {                 // TODO: dispose managed state (managed objects).             }              // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.             // TODO: set large fields to null.              disposedValue = true;         }     }     // This code added to correctly implement the disposable pattern.     public void Dispose()     {         // Do not change this code. Put cleanup code in Dispose(bool disposing) above.         Dispose(true);         // TODO: uncomment the following line if the finalizer is overridden above.         // GC.SuppressFinalize(this);     }      #endregion IDisposable Support } public static class Grapher {     public static Dictionary<string, object> roots { get; set; }     //Row store     public static List<GraphRow> Rows = new List<GraphRow>();      //Current row initialization     private static GraphRow CurrentRow = new GraphRow(new string[25]);      public static List<GraphValidation> Validations = new List<GraphValidation>();      public static List<GraphValidation> AddValidation(this List<GraphValidation> validations, string Attribute)     {         var Obj = new GraphValidation();          Obj.Target = Attribute;          Validations.Add(Obj);          return Validations;     }     public static List<GraphValidation> Validate(this List<GraphValidation> validations)     {         if (roots != null)         {             var AttributeGraph = Graph(roots);             //AttributeGraph.ViewThis();             if (Validations.Count > 0)             {                 foreach(var validation in validations)                 {                     validation.Result = AttributeGraph.Select(x => x.ToString()).Any(x => x.Contains(validation.Target));                 }             }         }         return validations;     }     private static IQueryable<object> Graph(object roots, int Level = 0)     {         if (roots is IDictionary<string, object>)         {             foreach (var root in roots as IDictionary<string, object>)             {                 //set key                 CurrentRow[Level] = root.Key;                 //loop around increasing the level as I dig down                 if (root.Value is IDictionary<string, object>)                 {                     Graph(root.Value as IDictionary<string, object>, Level + 1);                 }                 else if (root.Value is IList<object>)                 {                     Graph(root.Value as IList<object>, Level);                 }                 else                 {                     var ol = Level;                     while(ol <= CurrentRow.Columns.Length -1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null)                     {                         CurrentRow.Columns[ol + 1] = "";                         ol += 1;                     }                     //add the current row                     Rows.Add(CurrentRow);                     //Clone the Current row;                     CurrentRow = new GraphRow(CurrentRow.Columns);                 }             }         }         else if (roots is List<object>)         {             foreach (var value in roots as List<object>)             {                 if (value is IDictionary<string, object>)                 {                     Graph(value as IDictionary<string, object>, Level + 1);                 }                 else                 {                     if (value is IList<object>)                     {                         Graph(value as IList<object>, Level);                     }                 }             }         }         else         {              //set end of path             CurrentRow[Level] = roots.ToString();             var ol = Level;             while (ol <= CurrentRow.Columns.Length - 1 && CurrentRow.Columns[ol + 1] != "" && CurrentRow.Columns[ol + 1] != null)             {                 CurrentRow.Columns[ol + 1] = "";                 ol += 1;             }             //add the current row             Rows.Add(CurrentRow);             //Clone the Current row;             CurrentRow = new GraphRow(CurrentRow.Columns);         }          return (from row in Rows                 select new { Column0 = row.Columns[0], Column1 = row.Columns[1], Column2 = row.Columns[2], Column3 = row.Columns[3], Column4 = row.Columns[4], Column5 = row.Columns[5], Column6 = row.Columns[6], Column7 = row.Columns[7], Column8 = row.Columns[8], Column9 = row.Columns[9], Column10 = row.Columns[10], Column11 = row.Columns[11], Column12 = row.Columns[12], Column13 = row.Columns[13], Column14 = row.Columns[14], Column15 = row.Columns[15], Column16 = row.Columns[16], Column17 = row.Columns[17], Column18 = row.Columns[18], Column19 = row.Columns[19], Column20 = row.Columns[20], Column21 = row.Columns[21], Column22 = row.Columns[22], Column23 = row.Columns[23], Column24 = row.Columns[24] }).AsQueryable();       } } 3  

¿Hay una mejor manera de hacer esto? En caso de que importa usando G ++ con Ubuntu.

Original en ingles

I have a vector of uint16_t and I want to check if there is a bit which is only set in one vector. I then get its position within the vector as well as from the bit.

Let's say we have:

v[0] = 0100 v[1] = 0110 v[2] = 1001 

I would like to know that ind = 1 and val = 2.

In clumsy code this would be like that:

#include <cstdint> #include <vector> #include <fstream>  const uint16_t N = 10;  int main() {     // Create a dataset     std::vector<uint16_t> vec(N, (1 << 2) + (1 << 3));     vec[3] = (1 << 5);     vec[6] = (1 << 7);      // loop over the values     for (auto i = 0; i < 16; i++) {          uint16_t counter = 0,ind;          // loop over the vector         for (auto ii = 0; ii < N; ii++) {              if (vec[ii] & (1 << i)) {                 if (counter++ == 1) { break; }                 ind = ii;             }         } // vector loop          // Do we only have a single value?         if (counter == 1) {             printf("%i @ %i\n",i,ind);         }     } // value loop } // main 

Is there a better way to do this? In case it matters using g++ with Ubuntu.

        

Lista de respuestas

8
 
vote
vote
La mejor respuesta
 

Permítanme comenzar señalando problemas en su código:

Tipo incorrecto

El tipo de su constante global :as5 es :as6 . Hay varios problemas con esto:

  • Como está utilizando :as7 El tipo debe ser :as8 (porque el encabezado de C ++ los proporciona en el espacio de nombres :as9 , esta nota debe ser Aplicado a todas las instancias de let0 en su código)
  • Está usando let1 Para indicar el tamaño del let2 , pero se especifican los tamaños usando let3
  • Usted está utilizando let4 Para las variables let5 y let6 , que no están relacionados con el tipo. let7 Simplemente cuenta, por lo que estaría bien con let8 99887766555443329 es un índice a un vector, por lo que puede ser un 99887776655443330 < / Código> Tan Bien

Número mágico

El límite de bucle 16 en su código está relacionado con el tamaño del tipo que se almacena en el vector y ofrece posibilidades para las inconsistencias entre los dos. No debe confiar en eso, en su lugar calcularlo desde el tipo:

    ([string stack]     (let [[first-char & other] string] 1  

y use que como límite de bucle.

Nombres de variables

Mientras ([string stack] (let [[first-char & other] string] 22 es Borderline (Tan pronto como haya más contenedores, se vuelva ambiguo), los otros nombres de las variables no son:

  • ([string stack] (let [[first-char & other] string] 33 es tan genérico que puede obtener para una variable de contador de bucle. Lo que realmente hace es significar el índice de la broca que está mirando actualmente, por lo que en qué se trata: ([string stack] (let [[first-char & other] string] 4
  • ([string stack] (let [[first-char & other] string] 5 Solo me dice que ([string stack] (let [[first-char & other] string] 6 ya estaba y usted olvidó temporalmente cuál fue la siguiente letra en el alfabeto. Este índice realmente camina a través de los elementos ([string stack] (let [[first-char & other] string] 77 , por lo que puede llamarlo ([string stack] (let [[first-char & other] string] 88 (que sigue siendo demasiado genérico, pero no sé qué se almacena exactamente en el vector )
  • ([string stack] (let [[first-char & other] string] 9 tiene alguna información, pero aún no le informa lo que se cuenta, ¿qué tal 99887776655443340 o si toma la noción de organizar sus elementos por encima de la otra manera que los bits con el mismo índice forman una columna: ([[first-char & other :as string] stack] 1 (en esa luz 99887776655443342 puede ser nombrado ([[first-char & other :as string] stack] 3 )
  • ([[first-char & other :as string] stack] 4 (probablemente corto para el índice) es solo otro nombre genérico. Significa el índice del elemento que es el único que tiene un momento en esta columna. ([[first-char & other :as string] stack] 5 podría ser un poco verboso, pero la idea general debe ser clara
  • ([[first-char & other :as string] stack] 6 no dice mucho sobre los contenidos. Al permanecer en la metáfora de la mesa, podríamos elegir ([[first-char & other :as string] stack] 7 como el nuevo nombre

Esto es C ++

Usted está utilizando ([[first-char & other :as string] stack] 8 en C ++ Donde hay mejores alternativas (al menos tipsionalSafety WISE). También no ha incluido ([[first-char & other :as string] stack] 9 o 99887766555443350 donde proviene de.

Como es C ++, prometería (def braces #{( ) [ ] { }}) (def pairs { ) (, ] [, } { }) 2 en su lugar:

  (def braces #{( ) [ ] { }})  (def pairs { ) (,              ] [,              } { }) 3  

Algoritmo

ahora al algoritmo en sí. Debe caminar por cada columna y mirar cada fila, por lo que no hay mucho que cambiar en los bucles. (Además del hecho de que el automóvil podría ser excesivo para (def braces #{( ) [ ] { }}) (def pairs { ) (, ] [, } { }) 4 variables)

Sin embargo, encuentro la interrupción del bucle innecesaria (evite cambiar el flujo de bucles dentro del cuerpo) y el 99887776655443355 demasiado pesado.

Básicamente hay 3 estados para una columna: - 0 un bits - 1 un bit - demasiados bits

Esto encajaría muy bien en un Enum:

  (def braces #{( ) [ ] { }})  (def pairs { ) (,              ] [,              } { }) 6  

Su contador se reemplaza con esto:

  (def braces #{( ) [ ] { }})  (def pairs { ) (,              ] [,              } { }) 7  

En el segundo pensamiento, el (def braces #{( ) [ ] { }}) (def pairs { ) (, ] [, } { }) 8 se ve demasiado verboso y el problema principal que tuve con el descanso fue el (def braces #{( ) [ ] { }}) (def pairs { ) (, ] [, } { }) 9 que es un poco de flexión de la mente. Volviendo a un contador podría ser más legible:

  (def braces (set (concat (keys pairs) (vals pairs)))) 0 

Encapsulación

Es posible que desee separar la lógica de encontrar los ganadores de la columna del código de salida y la entrada. La firma de una función que permite que esto pueda ser

  (def braces (set (concat (keys pairs) (vals pairs)))) 1 

Donde el vector de resultados le da la fila ganadora para cada columna o (def braces (set (concat (keys pairs) (vals pairs)))) 2 Si no hay ganador en esta columna.

 

Let me start by pointing out problems in your code:

Wrong type

The type of your global constant N is uint16_t. There are several problems with this:

  • as you are using cstdint the type should be std::uint16_t (because the C++ header provides them in the namespace std, this note should be applied to all instances of uint16_t in your code)
  • you are using N to indicate the size of the std::vector but sizes are specified using std::size_t
  • you are using uint16_t for the variables counter and ind, which are not related to the type. counter just counts, so you would be fine with std::size_t and ind is an index to a vector so it might be an std::size_t as well

Magic number

The loop boundary 16 in your code is related to the size of the type that is stored in the vector and offers possibilities for inconsistencies between the two. You should not rely on that, instead calculate it from the type:

int numberOfBitsPerEntry = sizeof(vec[0]) * CHAR_BIT; 

And use that as loop boundary.

Variable names

While N is borderline (as soon as there are more then one containers it becomes ambiguous) the other variable names are not:

  • i is about as generic as it can get for a loop counter variable. What it actually does is signify the index of the bit you are currently looking at, so how about: bitIndex
  • ii just tells me that i was already taken and you temporarily forgot what was the next letter in the alphabet. This index actually walks through the std::vector's elements, so you might call it elementIndex (which is still too generic but I don't know what exactly is stored in the vector)
  • counter has already some information but it still does not inform you what is counted, how about enabledBitsCounter or if you take the notion of arranging your elements above each other so that the bits with the same index form a column: columnBitsCounter (in that light elementIndex might be named rowIndex)
  • ind (probably short for index) is just another generic name. It signifies the index of the element that is the only one that has a one bit in this column. columnWinnerRowIndex might be a bit too verbose but the general idea should be clear
  • vec does not say much about the contents. By staying in the table metaphor we might choose rows as the new name

This is C++

You are using printf in C++ where there are better alternatives (at least typesafety wise). Also you haven't included cstdio or stdio.h where printf comes from.

As it is C++ I would pledge for std::cout instead:

std::cout << bitIndex << " @ " << columnWinnerRowIndex << "\n"; 

Algorithm

Now to the algorithm itself. You need to walk through every column and look at each row so there is not much to change on the loops. (Besides the fact that auto might be overkill for int variables)

However, I find the loop break unnecessary (avoid changing the flow of loops from within the body) and the counter too heavyweight.

Basically there are 3 states for a column: - 0 one bits - 1 one bit - too many one bits

This would fit nicely into an enum:

enum ColumnState {     NO_ONE_BITS,     ONE_ONE_BIT,     TOO_MANY_ONE_BITS }; 

Your counter is replaced with this:

    ColumnState columnState = NO_ONE_BITS;     for(int rowIndex = 0; rowIndex < (int)rows.size() &&                           columnState != TOO_MANY_ONE_BITS; ++rowIndex) {         if(rows[rowIndex] & (1 << columnIndex)) {             switch(columnState) {             case NO_ONE_BITS:                 columnState = ONE_ONE_BIT;                 columnWinnerRowIndex = rowIndex;                 break;             case ONE_ONE_BIT:                 columnState = TOO_MANY_ONE_BITS;                 break;             default:                 assert(!"Invalid state");             }         }     } 

On second thought the enum looks too verbose and the main problem I had with the break was the counter++ == 1 part that is a bit mind bending. Reverting to a counter might be more readable:

    int columnBitsCounter = 0;     for(int rowIndex = 0; rowIndex < (int)rows.size(); ++rowIndex) {         if(rows[rowIndex] & (1 << columnIndex)) {             ++columnBitsCounter;             if(columnBitsCounter > 1) {                 break;             }              columnWinnerRowIndex = rowIndex;         }     } 

Encapsulation

You might want to separate the logic of finding the column winners from the output code and the input. The signature of a function that allows this could be

std::vector<std::size_t> findRowWinners(const std::vector<std::uint16_t> &rows); 

Where the result vector gives the winning row for each column or rows.size() if there is no winner in this column.

 
 
 
 
3
 
vote

(def braces (set (concat (keys pairs) (vals pairs)))) 3 Organización

Es una buena idea mantener su biblioteca estándar (def braces (set (concat (keys pairs) (vals pairs)))) 4 Directivas ordenadas alfabéticamente. Esto hace que sea fácil detectar duplicados, o para agregar nuevas dependencias en la posición correcta.

(def braces (set (concat (keys pairs) (vals pairs)))) 5 es para constantes

C ++ 11 introduce (def braces (set (concat (keys pairs) (vals pairs)))) 6 , que debe usar para declarar (def braces (set (concat (keys pairs) (vals pairs)))) 7 Una constante verdadera:

  (def braces (set (concat (keys pairs) (vals pairs)))) 8  

Los comentarios de Fin-Brace son innecesarios

En general, no necesita agregar un comentario al final de un bloque que indique lo que acabamos de terminar, como este:

  (def braces (set (concat (keys pairs) (vals pairs)))) 9  

Esto clava el código. Debe ser obvio lo que está haciendo cada bloque. Si no es obvio, probablemente tengas demasiados bloques anidados. Lo que significa ...

Crear un método para el bucle interno

Su bucle interno sobre el vector se puede extraer sucintamente a una función propia. Crear una función le permite dar un nombre descriptivo a lo que está haciendo, y limitar el alcance de las variables. También hace que el bucle externo sea más fácil de leer y entender.

He reescrito el bucle interno en su propia función que hace uso de algoritmos estándar. Es ligeramente menos eficiente que su método original, pero mejora la inmutabilidad, la legibilidad y la simplicidad del bucle externo.

  clojure.test0  

Esta es la versión más sucinta en la que puedo pensar. Si desea obtener más garantías en el resultado y aumentar la eficiencia, podría mover el 99887766655443371 Llamar dentro de un bloqueo clojure.test2 Bloquear y devolver un valor de Sentinel (como clojure.test3 < / Código> en la respuesta de nadie) de lo contrario.

Escritura de la función de esta manera y que devuelve un clojure.test4 permite que el bucle sobre el índice de bits se simplifique en gran medida:

  clojure.test5  

Tendrá a clojure.test6 clojure.test7 Para clojure.test8 y clojure.test9 para test-strings0 .

 

#include organization

It is a good idea to keep your standard library #include directives sorted alphabetically. This makes it easy to spot duplicates, or to add new dependencies in the right position.

constexpr is for constants

C++11 introduces constexpr, which you should use to declare N a true constant:

constexpr uint16_t N = 16; 

End-brace comments are unnecessary

In general, you don't need to add a comment at the end of a block indicating what just ended, like this:

for (/* ... */) {         // code...     } // vector loop 

This clutters the code. It should be obvious what each block is doing. If it isn't obvious, you probably have too many nested blocks. Which means...

Create a method for the inner loop

Your inner loop over the vector can be succinctly extracted to a function of its own. Creating a function allows you to give a descriptive name to what you're doing, and limit the scope of variables. It also makes the outer loop easier to read and understand.

I have rewritten the inner loop into its own function that makes use of standard algorithms. It is slightly less efficient than your original method, but improves immutability, readability, and simplicity of the outer loop.

// Returns std::pair containing (count, index) // If count is not 1, index is undefined std::pair<std::size_t, std::size_t> uniqueVectorIndex(const std::size_t bit,                                                       const std::vector<uint16_t>& vec) {     const auto isBitSet = [&] (uint16_t num) {return num & (1 << bit);};     const auto count = std::count_if(vec.begin(), vec.end(), isBitSet);     const auto indexPos = std::find_if(vec.begin(), vec.end(), isBitSet);     return std::make_pair(count, std::distance(vec.begin(), indexPos)); } 

This is the most succinct version I can think of. If you want to make more guarantees on the result and increase efficiency, you could move the find_if() call inside an if(count == 1) block and return a sentinel value (like vec.size() in Nobody's answer) otherwise.

Writing the function this way and returning a std::pair allows the loop over the bit index to be greatly simplified:

for (auto bitIdx = 0; bitIdx < 16; ++bitIdx) {     std::size_t counter, ind;     std::tie(counter, ind) = uniqueVectorIndex(bitIdx, vec);      // Do we only have a single value?     if (counter == 1) {         printf("%i @ %lu\n", bitIdx, ind);     } } 

You will have to #include <utility> to get std::pair, and <tuple> for std::tie.

 
 
   
   
2
 
vote

@nobody cubre casi todo.

Una alternativa a usar numberOfBitsPerEntry sería hacer el campo de bits la variable de bucle.

   // loop over the values for (uint16_t bitField = 1; bitField > 0; bitField = bitField << 1) {     // etc. } // value loop   

Esto usa el hecho de que una vez que nos murmuramos más allá de la bit alta, 32768 en este caso, obtengamos cero.

 

@Nobody covers almost everything.

One alternative to using numberOfBitsPerEntry would be to make the bit field the loop variable.

 // loop over the values for (uint16_t bitField = 1; bitField > 0; bitField = bitField << 1) {     // etc. } // value loop 

This uses the fact that once we bit shift past the high bit, 32768 in this case, we get zero.

 
 
 
 

Relacionados problema

4  Decodificación de datos binarios (AIS) del zócalo  ( Decoding of binary data ais from socket ) 
Actualmente estoy trabajando en una Mensaje AIS Decoder escrito en python puro. Es solo un pequeño proyecto para enseñarme algunas cosas sobre los datos bin...

2  Función de desvanecimiento de color [cerrado]  ( Color fading function ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

2  Simplifique el código de verificación de banderas de bits  ( Simplify bit flags checking code ) 
Por favor, ayuda a hacer que este código sea más limpio. Es parte del procedimiento de la ventana que notifica a mi renderizado antes de Área de cliente de ...

4  Calculadora binaria de Python  ( Python binary calculator ) 
Mi tarea fue construir una calculadora en la adición binaria de soporte de Python, etc. Para comenzar Definir un par de excepciones personalizadas: paper...

0  Escritor BMP en C  ( Bmp writer in c ) 
Recientemente escribí un escritor BMP en C: bmpwriter.h #ifndef BMPWRITER_ #define BMPWRITER_ #include <stdint.h> int write24BitBMP(const char *outpu...

10  Suma más rápida de valores absolutos de 32 diferencias  ( Fastest sum of absolute values of 32 differences ) 
A long1 debe tratarse como una lista de 32 números sin firmar, cada uno de ellos a solo dos bits. Por lo que 0x1234F... representa {0, 1, 0, 2, 0, 3, 1...

7  Cálculo del permiso de archivo octal basado en Linux  ( Calculating linux based octal file permission ) 
Estoy solicitando una posición de devloper de nivel medio. Para avanzar a la 2ª entrevista, debe pasar una prueba técnica. Una de las preguntas fue escribir...

3  Pruebas de divisibilidad de números - Seguimiento  ( Testing for divisibility of numbers follow up ) 
( aquí es la pregunta de seguimiento) Tuve otra oportunidad de intentar acelerar mi programa descrito en mi Pregunta previa . La respuesta de JS1 fue...

11  CODILIDAD SOLUCIÓN DE GAPO BINARIO CON REGEX  ( Codility binary gap solution using regex ) 
A continuación se muestra el código que implementé para resolver el problema de brecha binario : Encuentra la secuencia más larga de ceros, limitada por l...

5  Cálculo de suma de comprobación de 16 bits [cerrado]  ( 16 bit checksum calculation ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos