2011-01-02 30 views
11

tuve que dividir un int "123456" cada valor de la misma a un int [] y ya tienen una solución pero no sé ¿hay alguna forma mejor: Mi solución fue:entero a matriz de enteros de C#

public static int[] intToArray(int num){ 
    String holder = num.ToString(); 
    int[] numbers = new int[Holder.ToString().Length]; 
    for(int i=0;i<numbers.length;i++){ 
     numbers[i] = Convert.toInt32(holder.CharAt(i)); 
    } 
    return numbers; 
} 
+0

comprobar mi amigo respuesta, que es la forma más fácil si usted oído hablar de 'LINQ' –

+0

@Hans Passant, estoy bastante seguro de la longitud de la matriz porque el número más largo que tendré puede ser 999996, por lo que 6 es la longitud más alta de una matriz, y también el rendimiento no es un problema debido a esa limitación de número. – Burimi

Respuesta

10

Creo que esto será mejor que convertir de ida y vuelta. A diferencia de la respuesta de JBSnorro, invierto después de convertir a una matriz y por lo tanto evito IEnumerable que creo que contribuirá a un código un poco más rápido. Este método funciona para números no negativos, por lo que 0 devolverá new int[1] { 0 }.

Si funcionara con números negativos, podría hacer un n = Math.Abs(n) pero no creo que tenga sentido.

Además, si fuera más eficaz, podría crear la matriz final para empezar haciendo una búsqueda binaria como combinación de sentencias if para determinar la cantidad de dígitos.

public static int[] digitArr(int n) 
{ 
    if (n == 0) return new int[1] { 0 }; 

    var digits = new List<int>(); 

    for (; n != 0; n /= 10) 
     digits.Add(n % 10); 

    var arr = digits.ToArray(); 
    Array.Reverse(arr); 
    return arr; 
} 
+0

Pensé si primero quería crear una matriz o invertir la lista primero. Pero pensé, ¿por qué no hacerlos al mismo tiempo (utilizando los métodos de extensión IEnumerable). Me doy cuenta de que esto es solo una micro-optimización, ya que la lista no será larga. El otro argumento (más importante) que se me ocurrió fue la elegancia. – JBSnorro

+0

Creo que tus puntos son perfectamente válidos :) Solo quería que Burim Shala supiera por qué hice lo que hice y por qué creo que es mejor. Veo que ha actualizado su respuesta, que es agradable :) –

+0

Un mejor enfoque para esto es realmente encontrar la cantidad de dígitos primero (se puede hacer rápidamente) y luego construir la matriz. Esto evitaría 'List' y' Reverse'. –

5

El uso de la conversión de int a cadena y viceversa probablemente no sea tan rápido. Utilizaría el siguiente

public static int[] ToDigitArray(int i) 
{ 
    List<int> result = new List<int>(); 
    while (i != 0) 
    { 
     result.Add(i % 10); 
     i /= 10; 
    } 
    return result.Reverse().ToArray(); 
} 

Tengo que tener en cuenta que esto solo funciona para enteros estrictamente positivos.

EDIT:

me ocurrió una alternativa. Si el rendimiento realmente es un problema, probablemente sea más rápido, aunque solo puede estar seguro si lo comprueba usted mismo para su uso y aplicación específicos.

public static int[] ToDigitArray(int n) 
{ 
    int[] result = new int[GetDigitArrayLength(n)]; 
    for (int i = 0; i < result.Length; i++) 
    { 
     result[result.Length - i - 1] = n % 10; 
     n /= 10; 
    } 
    return result; 
} 
private static int GetDigitArrayLength(int n) 
{ 
    if (n == 0) 
     return 1; 
    return 1 + (int)Math.Log10(n); 
} 

Esto funciona cuando n es no negativo.

+1

Tampoco funciona para cero, devuelve una matriz vacía en lugar de una matriz con un dígito. – Guffa

+0

@Guffa, ya lo dije. Dije que solo funciona para enteros positivos, y cero no es positivo. De hecho, dije que solo funciona para enteros estrictamente positivos, así que con la palabra "estrictamente" expuse explícitamente que el caso i = 0 no funciona. – JBSnorro

+0

cambie la función GetDigitArrayLength a int digits = 0; do { n/= 10; dígitos ++; } while (n! = 0); dígitos de retorno; – TheJackal

1

Usted puede hacer eso sin convertirlo en una cadena y vuelta:

public static int[] intToArray(int num) { 
    List<int> numbers = new List<int>(); 
    do { 
    numbers.Insert(0, num % 10); 
    num /= 10; 
    } while (num > 0); 
    return numbers.ToArray(); 
} 

sólo funciona para valores positivos, por supuesto, pero su código original también tienen esa limitación.

16

Una solución sencilla por LINQ

int[] result = yourInt.ToString().Select(o=> Convert.ToInt32(o)).ToArray() 
+0

+1 Es interesante observar que este enfoque es simplemente la implementación gratuita del código en la publicación libre de efectos secundarios: muchas operaciones imperativas comunes sobre listas homogéneas tienen contrapartes triviales y limpias "funcionales". –

+0

Sin embargo, las mayúsculas y minúsculas (por ejemplo, '-12') deben tenerse en cuenta, incluso si solo se trata de una restricción documentada en el dominio de funciones. La publicación original no hace esta restricción. –

1

lo haría así:

var result = new List<int>(); 
    while (num != 0) { 
     result.Insert(0, num % 10); 
     num = num/10; 
    } 
    return result.ToArray(); 

ligeramente menos eficiente pero posiblemente más elegante es:

return num.ToString.Select(c => Convert.ToInt32(c.ToString())).ToArray(); 

Tenga en cuenta que estos dos re gire 1,2,3,4,5,6 en lugar de 49,50,51,52,53,54 (es decir los códigos de bytes para los caracteres '1', '2', '3', '4', '5', '6') como lo hace tu código. Supongo que esta es la intención real?

10
int[] outarry = Array.ConvertAll(num.ToString().ToArray(), x=>(int)x); 

pero si quieres convertirlo a 1,2,3,4,5:

int[] outarry = Array.ConvertAll(num.ToString().ToArray(), x=>(int)x - 48); 
+0

No hay ToCharArray en int. La entrada es int no cadena –

+0

@Rune FS, ¿Qué? el titular es cadena, lo obtengo de la muestra 'OP '. –

+0

No pude ver en su respuesta que era solo una parte de la solución que es lo que me confundió –

1
string DecimalToBase(int iDec, int numbase) 
     { 
      string strBin = ""; 
      int[] result = new int[32]; 
      int MaxBit = 32; 
      for(; iDec > 0; iDec/=numbase) 
      { 
       int rem = iDec % numbase; 
        result[--MaxBit] = rem; 
      } 
      for (int i=0;i<result.Length;i++) 
       if ((int)result.GetValue(i) >= base10) 
        strBin += cHexa[(int)result.GetValue(i)%base10]; 
       else 
        strBin += result.GetValue(i); 
      strBin = strBin.TrimStart(new char[] {'0'}); 
      return strBin; 
     } 
     int BaseToDecimal(string sBase, int numbase) 
     { 
      int dec = 0; 
      int b; 
      int iProduct=1; 
      string sHexa = ""; 
      if (numbase > base10) 
       for (int i=0;i<cHexa.Length;i++) 
        sHexa += cHexa.GetValue(i).ToString(); 
      for(int i=sBase.Length-1; i>=0; i--,iProduct *= numbase) 
      { 
       string sValue = sBase[i].ToString(); 
       if (sValue.IndexOfAny(cHexa) >=0) 
        b=iHexaNumeric[sHexa.IndexOf(sBase[i])]; 
       else 
        b= (int) sBase[i] - asciiDiff; 
       dec += (b * iProduct); 
      } 
      return dec; 
     } 
+3

¿Podría explicar ese código, para que alguien sepa cómo es una respuesta a la pregunta planteada? –

1

que tuve requisito similar .. me tomó de muchas buenas ideas, y añadió un par de piezas faltantes ... donde mucha gente no manejaba valores cero o negativos.Esto es lo que ocurrió:

public static int[] DigitsFromInteger(int n) 
    { 
     int _n = Math.Abs(n); 
     int length = ((int)Math.Log10(_n > 0 ? _n : 1)) + 1; 
     int[] digits = new int[length]; 
     for (int i = 0; i < length; i++) 
     { 
      digits[(length - i) - 1] = _n % 10 * ((i == (length - 1) && n < 0) ? -1 : 1); 
      _n /= 10; 
     } 
     return digits; 
    } 

creo que esto es bastante limpio .. aunque, bien es cierto que estamos haciendo una comprobación condicional y varios cálculos extraños con cada iteración .. mientras yo creo que sean nominal, en este caso, se puede optimizar un paso más allá de esta manera:

public static int[] DigitsFromInteger(int n) 
    { 
     int _n = Math.Abs(n); 
     int length = ((int)Math.Log10(_n > 0 ? _n : 1)) + 1; 
     int[] digits = new int[length]; 
     for (int i = 0; i < length; i++) 
     { 
      //digits[(length - i) - 1] = _n % 10 * ((i == (length - 1) && n < 0) ? -1 : 1); 
      digits[(length - i) - 1] = _n % 10; 
      _n /= 10; 
     } 
     if (n < 0) 
      digits[0] *= -1; 
     return digits; 
    } 
Cuestiones relacionadas