2010-09-01 11 views
11

Ce n'est pas une question de devoirs. Tout ce que je peux penser est de diviser le nombre à plusieurs reprises par 10 (jusqu'à ce que le nombre est inférieur à 10) et de garder un compte, mais y at-il un truc pour ce genre de chose?Comment extraire chaque chiffre d'un nombre?

+1

Oui, c'est bonne solution. Quel genre de truc voulez-vous dire? –

+0

comme un mauvais tour je convertis en une chaîne ('sprintf' ou' snprintf'), puis 'atoi' la valeur char afin que je puisse obtenir le nombre. Il n'utilise pas modulo ou AFAIK l'opération de division. – MrMesees

Répondre

1

Si elle est un entier, vous pouvez convertir la représentation de chaîne en un tableau de caractères, puis convertir en un tableau d'octets (0-9)

+0

Je pense que la conversion en une représentation de chaîne ferait essentiellement à plusieurs reprises de diviser par 10. Au moins, c'est comme ça que je le ferais. –

+0

Que faire si c'est en hexadécimal? – munmunbb

+0

Un entier est un nombre entier, il est stocké dans la mémoire de la même manière, que vous le voyiez en décimal, hexadécimal, binaire ou autre. Demandez-vous comment extraire les caractères individuels dans la représentation * hex *? Si c'est le cas, obtenez simplement la représentation hexadécimale sous forme de chaîne, puis prenez les caractères dans cette chaîne. –

9

Eh oui, vous avez à peu près la façon mathématique fais le juste là.

while (num >= 10) 
    digit = num MOD 10 // and save this into an array or whatever 
    num = num/10 

à la fin de cela, num contiendra le dernier chiffre.

Voici une application Javascript:

function getDigits(num) { 
    var digits = []; 
    while (num >= 10) { 
     digits.unshift(num % 10); 
     num = Math.floor(num/10); 
    } 
    digits.unshift(num); 
    return digits; 
} 

Notez que cela ne fonctionne que pour les entiers non négatifs.

3

code Python en utilisant votre approche:

def digits(n): 
    ds = [] 
    while n > 0: 
    ds.append(n % 10) 
    n /= 10 
    ds.reverse() 
    return ds 

En utilisant convertation à la chaîne:

def digits(n):   
    return map(int, str(n)) 
7

Pourquoi mettre en œuvre la conversion vous-même quand il y a déjà une façon très fiable pour le faire? (Et puisque ce n'est pas les devoirs).

En pseudo-C:

char digits[10]; 
sprintf(digits, "%d", number); 

Maintenant vos chiffres de tableau de caractères (string) devrait se composer de chaque chiffre du numéro. La plupart des autres langages de script contiennent également une fonction sprintf.

Cela fonctionnera si vous voulez la base 8 ou la base 16 ou binaire, etc. Utilisez simplement un spécificateur de format différent.

+0

mais non généralisable à des bases autres que 16, 10 ou 8.(binaire n'a pas de spécificateur "%" pour la version standard de sprintf) –

+0

Ensuite, si vous voulez les utiliser comme chiffres réels, vous devez soustraire ''0 '' de chacun d'entre eux. Quant à savoir pourquoi ... peut-être que vous faites des problèmes mathématiques de calcul récréatif et vous ne voulez pas ce petit supplément de frais généraux. Je suis sûr qu'il y a des problèmes de projet euler en utilisant les chiffres d'un nombre! – Cascabel

+0

Je déteste cette conversion en chaînes. Je vais le déprécier dès que possible. Je pense juste que c'est vraiment une mauvaise solution. – Bart

4

La réponse mathématique est de moduler par 10 et ajouter chaque résultat à une liste, puis inverser l'ordre de la liste. Voici un algorithme C# de base qui le fera:

List<byte> digits = new List<byte>(); 

while(number > 10) 
{ 
    digits.Add(number % 10); 
    number %= 10; 
} 
//add the last digit 
digits.Add(number); 

byte temp; 
for(var i=0;i<digits.Count/2;i++) 
{ 
    temp = digits[i]; 
    digits[i] = digits[digits.Count-(i+1)]; 
    digits[digits.Count-(i+1)] = temp; 
} 

D'autres « trucs » impliquent généralement une conversion de chaîne.Voici un C# one-liner LINQ qui donnera le même résultat que ci-dessus:

var digits = number.ToString().Select(c=>byte.Parse(c)).ToList(); 
1

Un algorithme plus efficace, si vos numéros d'entrée peuvent être importantes, est de diviser par une puissance de 10, disons 1000, et en utilisant une table de consultation:

s = ""; // or use a string builder appropriate to your language... 
table = {"000", "001", ..., "999"}; 
tableInitial = {"unused", "1", "2", ..., "9", "10", ..., "999"}; 
while(n >= 1000) { 
    m = n%1000; 
    n /= 1000; 
    s = table[m] + s; 
} 
s = tableInitial[n] + s; 
+0

modding est effectivement une opération de log (n) pour n'importe quel nombre N. Il ne devient pas beaucoup plus efficace, même pour les grands nombres. – KeithS

+1

@KeithS: Asymptotiquement, la division binaire - réduire le nombre mod 10^k avec k environ log_100 N pour une entrée N - donne une accélération tant que vous utilisez la division rapide (FFT ou même Karatsuba). Pratiquement parlant, réduire mod la plus petite puissance de dix moins que la racine carrée du plus grand entier qui correspond à un mot est tout aussi rapide que la réduction du mod 10, donc vous obtenez presque une accélération de 9x sur les grands nombres sur une machine 64 bits. Vous pouvez combiner les deux approches en passant de la méthode asymptotique à la pratique une fois que vous avez atteint un certain seuil. D'après mon expérience, il y a environ 1000 chiffres, mais cela varie. – Charles

0

la solution de python donnée pourrait être encore optimisé en utilisant

zerostr = ord('0') 
def digits(n): 
    return map(lambda x: ord(x)-zerostr, str(n)) 

en fait, lorsque leLa conversionest probablement complètement optimisée, pour obtenir la valeur numérique, il est préférable d'utiliser la valeur de caractère intrinsèque de la chaîne numérique, qui dans chaque encodage (y compris EBCDIC) donne la valeur numérique au moyen d'une soustraction int au lieu d'une analyse str.

0

Voici les fonctions de tableau réversibles en JavaScript qui traitent des entiers ou des chaînes:

function reverse(array) 
{ 
    var left = null; 
    var right = null; 
    var length = array.length; 
    for (left = 0, right = length - 1; left < right; left += 1, right -= 1) 
    { 
     var temporary = array[left]; 
     array[left] = array[right]; 
     array[right] = temporary; 
    } 
    return array; 
} 

function toDigitsArrayFromInteger(integer, isReverse) 
{ 
    var digits = []; 

    if (integer > 0) 
    { 
     var floor = window.Math.floor; 
     while (integer > 0) 
     { 
      digits.push(floor(integer % 10)); 
      integer = floor(integer/10); 
     } 

     // Array is populated in reverse order. Un-reverse it to make it normal. 
     if (!isReverse) 
     { 
      digits = reverse(digits); 
     } 
    } 
    else if (integer < 0) 
    { 
     digits = toDigitsArrayFromInteger(-integer, isReverse); 
    } 
    else if (integer === 0) 
    { 
     digits.push(0); 
    } 

    return digits; 
} 

function toDigitsArrayFromString(string, isReverse) 
{ 
    var digits = []; 

    string += ""; // Coerce to string. 

    var i = null; 
    var length = string.length; 
    for (i = 0; i < length; i += 1) 
    { 
     var integer = parseInt(string.charAt(i), 10); 
     if (isFinite(integer)) 
     { 
      digits.push(integer); 
     } 
    } 

    if (isReverse) 
    { 
     digits = reverse(digits); 
    } 

    return digits; 
} 

Une fois que vous avez les chiffres comme un tableau, vous pouvez inverser le tableau facilement pour obtenir les chiffres à partir de la gauche ou de la droite.

La fonction chaîne est plus polyvalente car elle peut trouver n'importe quel chiffre dans une chaîne, alors que la fonction entière est limitée aux entiers.

Indicateurs de référence: http://jsperf.com/todigitsarray

Les points de repère entre les deux fonctions montrent que dans 10 Firefox et Chrome 12, la fonction de chaîne est de 30% à 60% plus rapide que la fonction de nombre entier. Dans Opera 12, la fonction integer est légèrement plus rapide d'environ 10%.

0

Je ne sais pas si je comprends bien ce que vous voulez bien ...

Est-ce que le travail ci-dessous pour vous ?? Il est écrit en C# ...

public static List<int> ExtractDigit() 
{ 
    // Input example 
    int number = 12345; 

    // Convert Integer to string 
    string numberedString = number.ToString(); 

    // Create a list of integers 
    var numList = new List<int>(); 

    // Convert each character in string back to int and add to list. 
    foreach (char c in numberedString) 
    { 
     numList.Add(Convert.ToInt32(c.ToString())); 
    } 

    return numList; 
} 

J'espère que j'étais d'aide.

0

Le programme suivant fonctionnerait également.

public class Main { 
    public static void main(String[] args) { 
     int i1 =123456; 
     String s =new StringBuilder(String.valueOf(i1)).toString(); 
     char a[]=s.toCharArray(); 
     for(char c : a) { 
      Integer i = Integer.parseInt(c+""); 
      System.out.println(i); 
     } 
    } 
} 
0

JavaScript:

function digits(num) { 
    return String(num).split('').map(v => +v); 
} 
Questions connexes