2009-09-09 19 views
30

¿Cómo obtengo los dígitos de un número en C++ sin convertirlo en cadenas o matrices de caracteres?¿Cómo obtener los dígitos de un número sin convertirlo en una matriz de cadena/char?

+0

Do u quieren obtener el número de dígitos o todos los dígitos de ese número en las variables independientes o arreglo de enteros ? – vpram86

+1

¿Qué quieres decir? ¿Desea contar la cantidad de dígitos? ¿Desea extraer el 5º dígito de un número? –

+0

¿Puedes dar un ejemplo? –

Respuesta

39

Los siguientes impresiones de los dígitos en orden ascendente de importancia (es decir, unidades, luego decenas, etc.):

do { 
    int digit = n % 10; 
    putchar('0' + digit); 
    n /= 10; 
} while (n > 0); 
+1

if (n == 0) no se imprimen dígitos. – xtofl

+0

@xtofl: Gracias, corregido. –

+0

¿Esperas algo cuando n == 0? Esperaría que fuera una entrada inválida, un comportamiento indefinido o una afirmación. –

0

Utilice una secuencia de operaciones mod 10 y div 10 (cualquiera que sea la sintaxis en C++) para asignar los dígitos uno a la vez a otras variables.

En pseudocódigo

lsd = number mod 10 
number = number div 10 
next lsd = number mod 10 
number = number div 10 

etc ...

doloroso! ... pero sin cadenas o matrices de caracteres.

1

Primer dígito (menos significativo) = num% 10, segundo dígito = piso (num/10)% 10, tercer dígito = piso (num/100)% 10. etc

+0

Solución agradable y general. Sin embargo, pasar por la función 'piso 'flotante no tiene mucho sentido. ¡Echa un vistazo a la solución de Martin también! – xtofl

+0

Bueno ... en realidad no usaría piso() pero lo incluí en caso de que el OP estuviera usando flotadores o lo que sea ... solo para hacerlo explícito. Si usa int, entonces no hay problema, no es necesario. – mpen

6

Algo como esto:

int* GetDigits(int num, int * array, int len) { 
    for (int i = 0; i < len && num != 0; i++) { 
    array[i] = num % 10; 
    num /= 10; 
    } 
} 

el MOD 10 le conseguirán los dígitos. Los div 10s avanzarán el número.

+4

Puede que no tenga 'len' - es mejor terminar cuando' num' llegue a 0. –

+0

Buen punto. Necesitamos len para asegurarnos de no sobrepasar el array. Agregó un cheque para num siendo 0 sin embargo. –

+2

Esto se puede refactorizar fácilmente para generar dígitos para cualquier base. Por ahora genera dígitos solo para la base 10 ... – SadSido

8

¿Quieres algo como esto?

int n = 0; 
    std::cin>>n; 

    std::deque<int> digits; 
    if(n == 0) 
    { 
     digits.push_front(0); 
     return 0; 
    } 

    n = abs(n); 
    while(n > 0) 
    { 
     digits.push_front(n % 10); 
     n = n /10; 
    } 
    return 0; 
+3

+1 para usar contenedores estándar en lugar de matrices –

+0

sí, +1 para std: D – ntcong

+1

pequeño problema para el número cero, aunque ... – xtofl

13

Dado que todo el mundo está haciendo sonar sin saber la pregunta.
Aquí está mi intento de futilidad:

#include <iostream> 

template<int D> int getDigit(int val)  {return getDigit<D-1>(val/10);} 
template<>  int getDigit<1>(int val) {return val % 10;} 

int main() 
{ 
    std::cout << getDigit<5>(1234567) << "\n"; 
} 
+0

¡Bonito! ¡Y también funciona a cero! – xtofl

+1

Aunque la complejidad del tiempo de ejecución es O (sizeof (int)^2) al calcular todos los dígitos. Hmm ... ¿Y cómo sabes en qué dígito comenzar? – xtofl

+0

Técnicamente, la complejidad del tiempo de ejecución es O (1) porque el código no cambiará para diferentes valores de entrada. Nota La notación de Big O es una medida de cómo el tiempo de ejecución se escala en relación con los argumentos de entrada. –

19

¿Qué hay de floor(log(number))+1?

Con n dígitos y usando la base b se puede expresar cualquier número hasta pow(b,n)-1. Entonces para obtener el número de dígitos de un número x en la base b puede usar la función inversa de exponenciación: logaritmo base-b. Para tratar con resultados no enteros, puede usar el truco floor()+1.

PD: Esto funciona para enteros, no para números con decimales (en ese caso, debe saber cuál es la precisión del tipo que está utilizando).

+1

+1 log usando log. – dmeister

+2

Después de dos años, todavía no entiendo por qué esta respuesta no fue tan buena como las demás. – tunnuz

+0

No puede usar 'ceil (log (x))' en lugar de 'floor (log (x)) + 1' como' ceil' devuelve valores incorrectos cuando 'log (x)% 1 == 0' (por ejemplo, cuando 'x = 100' esperas obtener _3_ (usando' floor + 1') en lugar de _2_ (usando solo 'ceil'). – cruizh

11

he visto muchas respuestas, pero todas se olvidó de usar do {...} while() bucle, que es en realidad la forma canónica para resolver este problema y manejar adecuadamente 0.

Mi solución se basa en this uno por Naveen.

int n = 0; 
std::cin>>n; 

std::deque<int> digits; 
n = abs(n); 
do { 
    digits.push_front(n % 10); 
    n /= 10; 
} while (n>0); 
0

No es tan fría como la respuesta de Martin York, pero frente a sólo un problema arbitraria:

puede imprimir un número entero positivo mayor que cero y no simplemente con la repetición:

#include <stdio.h> 
void print(int x) 
{ 
    if (x>0) { 
     print(x/10); 
     putchar(x%10 + '0'); 
    } 
} 

Esta voluntad imprima el dígito menos significativo al último. Hace

0

años, en respuesta a las preguntas anteriores que iba a escribir el siguiente código:

int i2a_old(int n, char *s) 
{ 
    char d,*e=s;//init begin pointer 
    do{*e++='0'+n%10;}while(n/=10);//extract digits 
    *e--=0;//set end of str_number 
    int digits=e-s;//calc number of digits 
    while(s<e)d=*s,*s++=*e,*e--=d;//reverse digits of the number 
    return digits;//return number of digits 
} 

creo que la función printf (...) hace algo por el estilo.

Ahora voy a escribir esto:

int i2a_new(int n, char *s) 
{ 
    int digits=n<100000?n<100?n<10?1:2:n<1000?3:n<10000?4:5:n<10000000?n<1000000?6:7:n<100000000?8:n<1000000000?9:10; 
    char *e=&s[digits];//init end pointer 
    *e=0;//set end of str_number 
    do{*--e='0'+n%10;}while(n/=10);//extract digits 
    return digits;//return number of digits 
} 

Ventajas: mesa de de búsqueda autónoma; C, C++, Java, JavaScript, compatible con PHP; obtener número de dígitos, min comparisons: 3; obtener número de dígitos, max comparisons: 4; código rápido; una comparación es muy simple y rápida: cmp reg, immediate_data -> 1 reloj de la CPU.

+0

Su código está roto. Acepta números negativos pero no funciona con ellos, y hace suposiciones sobre el tamaño de 'int' – LtWorf

3

versión Entero es trivial:

int fiGetDigit(const int n, const int k) 
{//Get K-th Digit from a Number (zero-based index) 
    switch(k) 
    { 
     case 0:return n%10; 
     case 1:return n/10%10; 
     case 2:return n/100%10; 
     case 3:return n/1000%10; 
     case 4:return n/10000%10; 
     case 5:return n/100000%10; 
     case 6:return n/1000000%10; 
     case 7:return n/10000000%10; 
     case 8:return n/100000000%10; 
     case 9:return n/1000000000%10; 
    } 
    return 0; 
} 
0

obtener todos los dígitos individuales en algo así como un conjunto - dos variantes:

int i2array_BigEndian(int n, char a[11]) 
{//storing the most significant digit first 
    int digits=//obtain the number of digits with 3 or 4 comparisons 
    n<100000?n<100?n<10?1:2:n<1000?3:n<10000?4:5:n<10000000?n<1000000?6:7:n<100000000?8:n<1000000000?9:10; 
    a+=digits;//init end pointer 
    do{*--a=n%10;}while(n/=10);//extract digits 
    return digits;//return number of digits 
} 

int i2array_LittleEndian(int n, char a[11]) 
{//storing the least significant digit first 
    char *p=&a[0];//init running pointer 
    do{*p++=n%10;}while(n/=10);//extract digits 
    return p-a;//return number of digits 
} 
3

recursión simple:

#include <iostream> 

// 0-based index pos 
int getDigit (const long number, int pos) 
{ 
    return (pos == 0) ? number % 10 : getDigit (number/10, --pos); 
} 

int main (void) { 
    std::cout << getDigit (1234567, 4) << "\n";  
} 
+0

Brillantemente simple y conciso –

3

Estas soluciones son todo recursivo o iterativo. ¿Podría un enfoque más directo ser un poco más eficiente?

izquierda a derecha:

int getDigit(int from, int index) 
{ 
    return (from/(int)pow(10, floor(log10(from)) - index)) % 10; 
} 

de derecha a izquierda:

int getDigit(int from, int index) 
{ 
    return (from/pow(10, index)) % 10; 
} 
Cuestiones relacionadas