2011-01-02 20 views
11

ho dovuto dividere un int "123456" ogni valore di esso ad un int [] e ho già una soluzione, ma non so c'è un modo migliore: La mia soluzione era:Integer a intero array 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

leggi la mia risposta amico, è il modo più semplice se avete sentito parlare 'LINQ' –

+0

@Hans Passant, sono abbastanza sicuro circa l'Array Lunghezza perché il numero più lungo che ho può essere 999996 quindi 6 è la lunghezza massima di un array, e anche le prestazioni non sono un problema a causa di quella limitazione del numero. – Burimi

risposta

10

Credo che sarà meglio che convertire avanti e indietro. A differenza della risposta di JBSnorro, inverto dopo aver convertito in un array e quindi evito lo IEnumerable, che credo contribuisca a un codice un po 'più veloce. Questo metodo funziona con numeri non negativi, pertanto 0 restituirà new int[1] { 0 }.

Se dovesse funzionare con numeri negativi, è possibile fare un n = Math.Abs(n) ma non penso che abbia senso.

Inoltre, se dovesse essere più performante, potrei creare l'array finale per cominciare facendo una combinazione binaria di if-statement per determinare il numero di cifre.

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

Avevo pensato se volevo creare prima un array o invertire prima l'elenco. Ma ho pensato, perché non farli allo stesso tempo (usando i metodi di estensione IEnumerable). Mi rendo conto che questa è solo una micro-ottimizzazione, poiché la lista non sarà lunga. L'altra (più importante) discussione che ho avuto è stata l'eleganza. – JBSnorro

+0

Penso che i tuoi punti siano perfettamente validi :) Volevo solo che Burim Shala sapesse perché ho fatto quello che ho fatto e perché penso che sia meglio. Vedo che hai aggiornato la tua risposta, che è bello :) –

+0

Un approccio migliore a questo è in realtà trovare il numero di cifre prima (può essere fatto velocemente) e quindi costruire l'array. Ciò eviterebbe 'List' e' Reverse'. –

5

Utilizzare la conversione da int a stringa e viceversa probabilmente non è così veloce. Vorrei usare il seguente

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(); 
} 

Devo notare che questo funziona solo per interi strettamente positivi.

EDIT:

mi si avvicinò con un'alternativa. Se le prestazioni sono davvero un problema, questo sarà probabilmente più veloce, anche se puoi essere sicuro solo controllando te stesso per l'utilizzo e l'applicazione specifici.

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); 
} 

Questo funziona quando n è non negativo.

+1

Non funziona neanche per zero, restituisce una matrice vuota invece di una matrice con una cifra. – Guffa

+0

@Guffa, l'ho già detto. Ho detto che funziona solo per numeri interi positivi e zero non è positivo. In effetti ho detto che funziona solo con numeri strettamente positivi, quindi con la parola "strict" ho esplicitamente affermato che case i = 0 non funziona. – JBSnorro

+0

cambia la funzione GetDigitArrayLength in int digit = 0; do { n/= 10; cifre ++; } while (n! = 0); cifre di ritorno; – TheJackal

1

È possibile farlo senza convertirlo in una stringa e ritorno:

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(); 
} 

funziona solo per valori positivi, naturalmente, ma il vostro codice originale hanno anche questa limitazione.

16

Una soluzione semplice da LINQ

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

+1 È interessante notare che questo approccio è solo la bella implementazione del codice in chiaro con effetti collaterali nel post: molte operazioni imperative comuni su liste omogenee hanno banali e pulite contro-parti "funzionali". –

+0

Tuttavia, i casi limite (ad esempio, '-12') devono essere presi in considerazione, anche se si tratta solo di una limitazione documentata sul dominio delle funzioni. Il post originale non crea questa restrizione. –

1

lo farei in questo modo:

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

Un po 'meno performante, ma forse più elegante è:

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

Si noti che questi entrambi re girare 1,2,3,4,5,6 anziché 49,50,51,52,53,54 (vale a dire i codici byte per i caratteri '1', '2', '3', '4', '5', '6') come fa il tuo codice. Presumo che questo sia l'intento reale?

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

, ma se si desidera convertire a 1,2,3,4,5:

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

Non c'è ToCharArray su int. L'input non è una stringa –

+0

@Rune FS, Cosa? titolare è una stringa, l'ho preso dal campione 'OP's. –

+0

Impossibile vedere dalla tua risposta che è stata solo una parte della soluzione che è ciò che mi ha confuso –

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

Puoi spiegare quel codice, quindi qualcuno potrebbe sapere come è una risposta alla domanda posta? –

1

ho avuto requisito simile .. ho preso da molte buone idee, e ha aggiunto un paio di pezzi mancanti .. dove molte persone non stavano gestendo valori zero o negativi.questo è quello che si avvicinò con:

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; 
    } 

penso che questo sia abbastanza pulita .. anche se, è vero che stiamo facendo un controllo condizionale e diversi calcoli estranei con ogni iterazione .. mentre penso che siano nominale in questo caso, è possibile ottimizzare un ulteriore passo avanti in questo modo:

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; 
    }