usar resueltos leer funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c++

c++ - resueltos - ¿Cómo obtener los dígitos de un número sin convertirlo en una matriz de cadena/char?



leer cadena de caracteres en c (14)

¿Qué pasa con el floor(log(number))+1 ?

Con n dígitos y utilizando la base b 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 utilizar 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á usando).

¿Cómo obtengo los dígitos de un número en C ++ sin convertirlo en cadenas o matrices de caracteres?


¿Quieres algo así?

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;


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 te dará los dígitos. Los div 10s avanzarán el número.


Esas soluciones son todas recursivas o iterativas. ¿Podría un enfoque más directo ser un poco más eficiente?

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


Hace años, en respuesta a las preguntas anteriores, escribiría 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 así.

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: tabla de búsqueda indipendiente; C, C ++, Java, JavaScript, PHP compatible; obtener el número de dígitos, min comparisons: 3 ; obtener el 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 CPU clock.


He visto muchas respuestas, pero todas olvidaron usar do {...} while() loop, que en realidad es la forma canónica de resolver este problema y manejar 0 correctamente.

Mi solución se basa en this de 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);


La versión entera 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; }


Lo siguiente imprime los dígitos en orden ascendente (es decir, unidades, luego decenas, etc.):

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


No es tan genial como la respuesta de Martin York, sino que aborda un problema arbitrario:

Puede imprimir un entero positivo mayor que cero simplemente con recursión:

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

Esto imprimirá el último dígito menos significativo.


Obtenga todos los dígitos individuales en algo como una matriz, 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 }


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


Use 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.


Ya que todos están interviniendo 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"; }


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