2010-01-03 11 views
5

mi programa genera números aleatorios con un máximo de 6 dígitos con¿Cómo puedo hacer que mi programa haga algo cuando aparece un "número de múltiples dígitos con todos los dígitos idénticos"?

int number = arc4random % 1000000; 

quiero que mi programa haga algo cuando un número como 66 o 4444 o 77777 aparece (número de varios dígitos con todos idénticos). Podría escribir manualmente:

switch (number) { 
    case 11: blabla...; 
    case 22: blabla...; 
    (...) 
    case 999999: blabla; 
} 

Eso me costaría muchos códigos de programa. (45 casos ...)

Existe una manera fácil de resolver el problema.

Respuesta

7

Ésta es una forma de comprobar que todos los dígitos son los mismos:

bool AllDigitsIdentical(int number) 
{ 
    int lastDigit = number % 10; 
    number /= 10; 
    while(number > 0) 
    { 
     int digit = number % 10; 
     if(digit != lastDigit) 
      return false; 
     number /= 10; 
    } 

    return true; 
} 
+1

Gracias, creo que esta es la manera correcta. Sólo tengo un problema. Cuando trato de usar esto, el compilador dice en la línea Dos en}: "Las funciones anidadas están deshabilitadas, use -fines-funciones para volver a habilitarlas". ¿Qué significa esto? – Flocked

+0

Este es otro problema, se debe abordar en una pregunta diferente. Por cierto, ¿cómo no noté esta respuesta? :) Escribí básicamente lo mismo ... 20 minutos después:/ –

+0

Oh, mis simpatías :) – Flocked

2

Puede calcular cuántos dígitos, luego dividir un número de seis dígitos por 111111, un número de 5 dígitos por 11111, etc., y ver si el resultado es un número entero.

Disculpe si no sugiero ningún código de Objective-C, no sé ese idioma.

+0

No funciona. Por ejemplo, cuando devide 976 con 111 el resultado es 8.79 aka 8, por lo que automáticamente salta al * número de multidigital con todos los dígitos idénticos * -case – Flocked

+0

en un mundo perfecto, funcionaría, pero averiguar el número de dígitos va ser casi tan doloroso (si aún no es una cadena) y luego también requiere conversiones a números en coma flotante y luego verificar si el resultado es un número entero (y si arroja imprecisión en coma flotante, fallará al azar) –

+0

@ Bloqueado, estoy seguro de que puede encontrar una manera de detectar que el 976/111 es * no * un número entero, por lo tanto, 976 es * no * divisible por 111, y no es uno de los números que está buscando. @Grant, descubrir cuántos dígitos no deberían ser demasiado difíciles, y con un * lote * menor que los 45 casos de Flocked en la pregunta. Solo proporcioné un algoritmo aproximado. Dejo que los expertos de Objective-C implementen. – pavium

0

Convierta a una cadena y compruebe si cada carácter en la cadena, comenzando en la posición 1, es el mismo que el anterior.

+1

-1 esto va a ser muy ineficiente (velocidad y memoria), convertir números a cadenas es generalmente la peor manera en que podría manipularlos –

+0

¿Cómo puedo convertir Int en una cadena y cómo puedo verificar los caracteres? ? – Flocked

+0

Como Grant ha sugerido, esto sería ineficiente. Vea su solución mucho mejor a continuación, que no implica la conversión a una cadena. En cuanto a cómo convertir un Int en una cadena, no estoy muy familiarizado con Objective-C, así que no puedo ayudar. – Tarydon

2

Siempre que use el operador de mod (lo siento, no conozco el objetivo C), pero estoy bastante seguro de que debe haber un operador de mod como% y modding basado en 1.

Por ejemplo:

66% 11

Se sabe que es el mismo número de dígitos debido mod devuelve 0 en este caso.

mismo digo:

7777% 1111

+0

No funciona. Antes de poder hacer eso, tengo que saber la longitud del dígito, porque no puedo usar 7777% 11 (no devuelve 0). Podría probar cada caso con un número, pero cuando mi número obtiene por ejemplo 143, el% 11 también devuelve 0, incluso 143 no es un número con los mismos dígitos. – Flocked

1

Usted puede hacer esto de forma recursiva con el operador de dividir y multiplicar (una división con resto podría simplificar, aunque)

por ejemplo,


bool IsNumberValid(int number) 
{ 
    if(number > 10) 
    { 
     int newNumber = number/10; 
     int difference = number - newNumber * 10; 
     number = newNumber; 
     do 
     { 
      newNumber = number/10; 
      if((number - newNumber * 10) != difference) 
      { 
       // One of the number didn't match the first number, thus its valid 
       return true; 
      } 
      number = newNumber; 
     } while(number); 
     // all of the numbers were the same, thus its invalid 
     return false; 
    } 
    // number was <= 10, according to your specifications, this should be valid 
    return true; 
} 
1

convierta el número en una cadena, verifique la longitud para obtener el número de dígitos, luego modéelo con el número apropiado. pseudocódigo siguiente, donde num_to_check es el número que comienza con (es decir, 777)

string my_num = (string)num_to_check; 
int num_length = my_num.length; 
int mod_result; 
string mod_num = "1"; 
int mod_num_int; 

for(int i = 1; i < num_length - 1; i++) 
{ 
    mod_num = mod_num + "1"; 
} 

mod_num_int = (int)mod_num; 
mod_result = num_to_check % mod_num_int; 

//If mod_result == 0, the number was divisible by the appropriate 111... string with no remainder 
1

Aquí hay una versión recursiva, sólo para alondras. Una vez más, no es la forma más eficiente, pero probablemente la más corta de código.

bool IsNumberValid (int number) { 
    if (number < 10) return true; 
    int n2 = number/10; 
    // Check if the last 2 digits are same, and recurse in to check 
    // other digits: 
    return ((n2 % 10) == (number % 10)) && IsNumberValid (n2); 
} 

En realidad, esta es la recursión de cola, por lo que un compilador decente debe generar código muy eficiente.

+0

La recursión no será tan profunda, así que creo que está bastante bien. Pero mirándolo, creo que también debería ser bastante fácil reescribir en un bucle ... – epatel

0

Suponiendo Objective-C tiene un tipo 'int' análogo estándar C99:

#include <assert.h> 
#include <stdbool.h> 

extern bool all_same_digit(int number); // Should be in a header! 

bool all_same_digit(int number) 
{ 
    static const struct 
    { 
     int lo_range; 
     int divisor; 
    } control[] = 
    { 
     { 100000, 111111 }, 
     { 10000, 11111 }, 
     { 1000, 1111 }, 
     { 100, 111 }, 
     {  10,  11 }, 
    }; 
    static const int ncontrols = (sizeof(control)/sizeof(control[0])); 
    int i; 

    assert(number < 10 * control[0].lo_range); 
    for (i = 0; i < ncontrols; i++) 
    { 
     if (number > control[i].lo_range) 
      return(number % control[i].divisor == 0); 
    } 
    return(false); 
} 

es probable que pueda trabajar a cabo una variación en la lo_range y divisor son cada uno dividido por diez en cada iteración, a partir de los valores en control[0].

0
#include <stdlib.h> 
#include <stdio.h> 

int main() { 
    int a = 1111; 
    printf("are_all_equal(%d) = %d\n",a,are_all_equal(a)); 
    a = 143; 
    printf("are_all_equal(%d) = %d\n",a,are_all_equal(a)); 
    a = 1; 
    printf("are_all_equal(%d) = %d\n",a,are_all_equal(a)); 
    a = 101; 
    printf("are_all_equal(%d) = %d\n",a,are_all_equal(a)); 
    return 0; 
} 

int are_all_equal(int what) { 
    int temp = what; 
    int remainder = -1; 
    int last_digit = -1; 
    while (temp > 0) { 
     temp = temp/10; 
     remainder = temp%10; 
     if (last_digit != -1 && remainder != 0) { 
      if (last_digit != remainder) return 0; 
     } 
     last_digit = remainder; 
    } 
    return 1; 
} 

Similar, pero no exactamente igual a las otras respuestas (que no noté que estaban allí).

0

digitsequal = (((number < 1000000) && (number > 111110) && (number % 111111 == 0)) || 
       ... 
       ((number < 1000) && (number > 110) && (number % 111 == 0)) || 
       ((number < 100) && (number > 10) && (number % 11 == 0)) 
      ); 

Gracias a las operaciones booleanas que de acceso directo, esto debe ser una solución bastante buena en cuanto al número promedio de comparaciones, se requiere a lo sumo sólo una operación de módulo por número, no tiene un bucle, que puede ser un buen formato para se ven simétricos, y es obvio lo que prueba. Pero, por supuesto, optimización prematura, ya sabes, pero dado que muchas otras soluciones ya están dadas ...;)

Cuestiones relacionadas