sacar saber programa para otro numero multiplos multiplo los lenguaje determinar como algoritmo c++ comparison conditional-statements integer-arithmetic

c++ - saber - programa para sacar los multiplos de un numero



Determinar si un nĂșmero es un mĂșltiplo de diez o dentro de un conjunto particular de rangos (14)

Básicamente explicaste la respuesta tú mismo, pero aquí está el código por si acaso.

if((x % 10) == 0) { //do this } if((x > 10 && x < 21) || (x > 30 && x < 41) || (x > 50 && x < 61) || (x > 70 && x < 81) || (x > 90 && x < 101)) { //do this }

Tengo algunos bucles que necesito en mi programa. Puedo escribir el pseudo código, pero no estoy del todo seguro de cómo escribirlos lógicamente.

Necesito -

if (num is a multiple of 10) { do this } if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this } else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90

Esto es para un juego de mesa de serpientes y escaleras, si tiene más sentido para mi pregunta.

Imagino la primera instrucción if que necesitaré para usar el módulo, ¿sería correcto if (num == 100%10) ?

El segundo no tengo idea. Puedo escribirlo como if (num > 10 && num is < 21 || etc) pero tiene que haber algo más inteligente que eso.


Como otros han señalado, hacer las condiciones más concisas no acelerará la compilación o la ejecución, y tampoco ayuda necesariamente con la legibilidad.

Lo que puede ayudar es hacer que su programa sea más flexible, en caso de que más tarde decida que desea una versión de juego para un niño pequeño en una pizarra de 6 x 6, o una versión avanzada (que puede jugar toda la noche) en un 40 x 50 tablero.

Así que lo codificaría de la siguiente manera:

// What is the size of the game board? #define ROWS 10 #define COLUMNS 10 // The numbers of the squares go from 1 (bottom-left) to (ROWS * COLUMNS) // (top-left if ROWS is even, or top-right if ROWS is odd) #define firstSquare 1 #define lastSquare (ROWS * COLUMNS) // We haven''t started until we roll the die and move onto the first square, // so there is an imaginary ''square zero'' #define notStarted(num) (num == 0) // and we only win when we land exactly on the last square #define finished(num) (num == lastSquare) #define overShot(num) (num > lastSquare) // We will number our rows from 1 to ROWS, and our columns from 1 to COLUMNS // (apologies to C fanatics who believe the world should be zero-based, which would // have simplified these expressions) #define getRow(num) (((num - 1) / COLUMNS) + 1) #define getCol(num) (((num - 1) % COLUMNS) + 1) // What direction are we moving in? // On rows 1, 3, 5, etc. we go from left to right #define isLeftToRightRow(num) ((getRow(num) % 2) == 1) // On rows 2, 4, 6, etc. we go from right to left #define isRightToLeftRow(num) ((getRow(num) % 2) == 0) // Are we on the last square in the row? #define isLastInRow(num) (getCol(num) == COLUMNS) // And finally we can get onto the code if (notStarted(mySquare)) { // Some code for when we haven''t got our piece on the board yet } else { if (isLastInRow(mySquare)) { // Some code for when we''re on the last square in a row } if (isRightToLeftRow(mySquare)) { // Some code for when we''re travelling from right to left } else { // Some code for when we''re travelling from left to right } }

Sí, es detallado, pero deja en claro exactamente lo que está sucediendo en el tablero de juego.

Si estuviera desarrollando este juego para mostrarlo en un teléfono o tableta, crearía variables ROWS y COLUMNS en lugar de constantes, para que se puedan configurar dinámicamente (al comienzo de un juego) para que coincidan con el tamaño y la orientación de la pantalla. También permitiría cambiar la orientación de la pantalla en cualquier momento, a mitad del juego; todo lo que tienes que hacer es cambiar los valores de ROWS y COLUMNS, dejando todo lo demás (el número de casilla actual en el que está cada jugador, y el inicio / fin cuadrados de todas las serpientes y escaleras) sin cambios. Entonces ''solo'' tienes que dibujar bien el tablero y escribir el código para tus animaciones (supongo que ese fue el propósito de tus declaraciones if ) ...


Con un par de buenos comentarios en el código, puede escribirse de manera concisa y legible.

// Check if it''s a multiple of 10 if (num % 10 == 0) { ... } // Check for whether tens digit is zero or even (1-10, 21-30, ...) if ((num / 10) % 2 == 0) { ... } else { ... }


El primero es fácil, solo necesita aplicar el operador de módulo a su valor num:

if ( ( num % 10 ) == 0)

Una vez que c ++ evalúa cada número que no es 0 como verdadero, también puede escribir:

if ( ! ( num % 10 ) ) //does not have a residue when devided by 10

Para el segundo creo que esto es más limpio de entender:

El patrón se repite cada 20, por lo que puede calcular el módulo 20. Todos los elementos que desee estarán en una fila, excepto los que pueden dividirse entre 20.

Para obtener esos también, simplemente use num-1 o mejor num + 19 para evitar el manejo de números negativos.

if ( ( ( num + 19 ) % 20 ) > 9 )

Esto supone que el patrón se repite para siempre, por lo que para 111-120 se aplicaría nuevamente, y así sucesivamente. De lo contrario, debe limitar los números a 100:

if ( ( ( ( num + 19 ) % 20 ) > 9 ) && ( num <= 100 ) )


Es posible que esté pensando demasiado en esto.

if (x % 10) { .. code for 1..9 .. } else { .. code for 0, 10, 20 etc. }

La primera línea if (x % 10) funciona porque (a) un valor que es un múltiplo de 10 se calcula como ''0'', otros números resultan en su restante, (b) un valor de 0 en un if se considera false , cualquier otro valor es true

Editar:

Para alternar de ida y vuelta en los años veinte, use el mismo truco. Esta vez, el número fundamental es 10 :

if (((x-1)/10) & 1) { .. code for 10, 30, .. } else { .. code for 20, 40, etc. }

x/10 devuelve cualquier número de 0 a 9 como 0 , 10 a 19 como 1 y así sucesivamente. La prueba en par o impar - el & 1 - le dice si es par o impar. Dado que sus rangos son realmente "11 a 20", reste 1 antes de la prueba.


Esto es para futuros visitantes más que un principiante. Para una solución más general, similar a un algoritmo, puede tomar una lista de valores iniciales y finales y verificar si un valor pasado está dentro de uno de ellos:

template<typename It, typename Elem> bool in_any_interval(It first, It last, const Elem &val) { return std::any_of(first, last, [&val](const auto &p) { return p.first <= val && val <= p.second; }); }

Para simplificar, utilicé una lambda polimórfica (C ++ 14) en lugar de un argumento de pair explícito. Esto probablemente también debería seguir usando < y == para ser consistente con los algoritmos estándar, pero funciona así siempre que Elem tenga <= definido para él. De todos modos, se puede usar así:

std::pair<int, int> intervals[]{ {11, 20}, {31, 40}, {51, 60}, {71, 80}, {91, 100} }; const int num = 15; std::cout << in_any_interval(std::begin(intervals), std::end(intervals), num);

Hay un ejemplo en vivo here .


Para el primero, para verificar si un número es un múltiplo de uso:

if (num % 10 == 0) // its divisible by 10

Para el segundo:

if(((num - 1) / 10) % 2 == 1 && num <= 100)

Pero eso es bastante denso, es mejor que solo enumeres las opciones explícitamente.

Ahora que ya has dado una mejor idea de lo que estás haciendo, escribiría el segundo como:

int getRow(int num) { return (num - 1) / 10; } if (getRow(num) % 2 == 0) { }

Es la misma lógica, pero al usar la función obtenemos una idea más clara de lo que significa.


Puedes probar lo siguiente:

// multiple of 10 if ((num % 10) == 0) { // Do something } else if (((num / 10) % 2) != 0) { //11-20, 31-40, 51-60, 71-80, 91-100 } else { //other case }


Sé que esta pregunta tiene muchas respuestas, pero arrojaré la mía aquí de todos modos ... Tomado de Steve McConnell''s Code Complete 2nd Edition: "Stair-Step Access Tables:
Otro tipo de acceso a la mesa es el método de escalera. Este método de acceso no es tan directo como una estructura de índice, pero no desperdicia tanto espacio de datos. La idea general de las estructuras escalonadas, ilustradas en la Figura 18-5, es que las entradas en una tabla son válidas para rangos de datos en lugar de puntos de datos distintos.

Figura 18-5 El enfoque escalonado clasifica cada entrada al determinar el nivel al que golpea una "escalera". El "paso" al que golpea determina su categoría.

Por ejemplo, si está escribiendo un programa de calificación, el rango de entrada "B" puede ser del 75 por ciento al 90 por ciento. Aquí hay una variedad de grados que quizás deba programar algún día:

Para usar el método de paso de escalera, coloque el extremo superior de cada rango en una tabla y luego escriba un bucle para verificar una puntuación en el extremo superior de cada rango. Cuando encuentre el punto en el que el puntaje excede por primera vez el rango superior, ya sabe cuál es el grado. Con la técnica de paso de escalera, debe tener cuidado de manejar los puntos finales de los rangos correctamente. Aquí está el código en Visual Basic que asigna calificaciones a un grupo de estudiantes basado en este ejemplo:

Aunque este es un ejemplo simple, puede generalizarlo fácilmente para manejar múltiples estudiantes, múltiples esquemas de calificación (por ejemplo, diferentes grados para diferentes niveles de puntos en diferentes asignaciones) y cambios en el esquema de calificación ".

Code Complete 2nd Edition páginas 426 - 428 (Capítulo 18). Espero que esto ayude y lo siento, no convertí el código en c ++, pero ya conoces ese antiguo dicho chino: "¡No le des pescado a un mendigo, dale una caña de pescar!" :)


Si está utilizando GCC o cualquier compilador que admita Case Ranges , puede hacerlo, pero su código no será portátil.

switch(num) { case 11 ... 20: case 31 ... 40: case 51 ... 60: case 71 ... 80: case 91 ... 100: // do something break; default: // do something else break; }


Si nunca antes ha usado un lenguaje de programación orientada a objetos (OOP), encontrará que OOP le hará la vida más fácil que nunca.

La respuesta OOP de su código está aquí:

(Espero que escribas tus códigos orientados a objetos en el próximo año)

#include <iostream> #include <exception> #include <stdexcept> using namespace std; class checker { public: checker(void) : m_num(0) { // Nothing. } ~checker(void) { // Nothing. } inline void set_num(int num) { if (num < 0) { throw invalid_argument("Invalid argument: num."); } m_num = num; return; } inline int get_num(void) const { return m_num; } protected: int m_num; }; /**********************************************************/ class multiple_checker : public checker { public: static const int MULTIPLE_OF = 10; multiple_checker(void) { // Nothing. } ~multiple_checker(void) { // Nothing. } virtual void do_this_for_multiple_checker(void) = 0; void check_multiple_of(void) { #if defined _DEBUG if (MULTIPLE_OF == 0) { throw exception("MULTIPLE_OF should not be zero."); } #endif if (m_num % MULTIPLE_OF == 0) { do_this_for_multiple_checker(); } return; } }; /**********************************************************/ class range_checker : public checker { public: range_checker(void) { // Nothing. } ~range_checker(void) { // Nothing. } virtual void do_this_1_for_range_checker(void) = 0; virtual void do_this_2_for_range_checker(void) = 0; void check_in_range(void) { return; } void check_range(void) { if (is_in_range()) { do_this_1_for_range_checker(); } else { do_this_2_for_range_checker(); } } private: bool is_in_range(void) const { if ( (m_num > 10 && m_num < 21) || (m_num > 30 && m_num < 41) || (m_num > 50 && m_num < 61) || (m_num > 70 && m_num < 81) || (m_num > 90 && m_num < 101) ) { return true; } else { return false; } } }; /**********************************************************/ class game : public multiple_checker, public range_checker { public: game(void) { // Nothing. } ~game(void) { // Nothing. } virtual void do_this_for_multiple_checker(void) { cout << "Number is a multiple of " << MULTIPLE_OF << "." << endl; } virtual void do_this_1_for_range_checker(void) { cout << "Number is in range." << endl; } virtual void do_this_2_for_range_checker(void) { cout << "Number is not in range." << endl; } }; /**********************************************************/ int main(int argc, char* argv[]) { game* g = new game(); g->multiple_checker::set_num(50); g->range_checker::set_num(13); g->check_multiple_of(); g->check_range(); delete g; g = NULL; return 0; }


if (num es un múltiplo de 10) {haz esto}

if (num % 10 == 0) { // Do something }

if (num está dentro de 11-20, 31-40, 51-60, 71-80, 91-100) {haz esto}

El truco aquí es buscar algún tipo de similitud entre los rangos. Por supuesto, siempre puedes usar el método de "fuerza bruta":

if ((num > 10 && num <= 20) || (num > 30 && num <= 40) || (num > 50 && num <= 60) || (num > 70 && num <= 80) || (num > 90 && num <= 100)) { // Do something }

Pero puede notar que, si resta 1 de num , tendrá los rangos:

10-19, 30-39, 50-59, 70-79, 90-99

En otras palabras, todos los números de 2 dígitos cuyo primer dígito es impar. A continuación, debes elaborar una fórmula que exprese esto. Puedes obtener el primer dígito dividiendo por 10, y puedes probar que es impar verificando el resto de 1 cuando lo dividas por 2. Poniendo todo eso en conjunto:

if ((num > 0) && (num <= 100) && (((num - 1) / 10) % 2 == 1)) { // Do something }

Dado el compromiso entre el código más largo pero que se puede mantener y el código "inteligente" más corto, elegiría más y más claro cada vez. Por lo menos, si intenta ser inteligente, por favor incluya un comentario que explique exactamente lo que está tratando de lograr.

Ayuda a suponer que el próximo desarrollador que trabaje en el código está armado y sabe dónde vive. :-)


Para el primero:

if (x % 10 == 0)

se aplicará a:

10, 20, 30, .. 100 .. 1000 ...

Para el segundo:

if (((x-1) / 10) % 2 == 1)

se aplicará para:

11-20, 31-40, 51-60, ..

Básicamente, primero hacemos x-1 para obtener:

10-19, 30-39, 50-59, ..

Luego los dividimos por 10 para obtener:

1, 3, 5, ..

Entonces, verificamos si este resultado es impar.


Una petición de legibilidad

Si bien ya tiene algunas buenas respuestas, me gustaría recomendarle una técnica de programación que haga que su código sea más legible para un futuro lector: puede ser usted en seis meses, un colega le pide que realice una revisión del código, su sucesor, ... .

Esto es para envolver cualquier declaración "inteligente" en una función que muestre exactamente (con su nombre) lo que está haciendo. Si bien hay un impacto minúsculo en el rendimiento (de "sobrecarga de llamadas de función"), esto es realmente insignificante en una situación de juego como esta.

En el camino puede desinfectar sus entradas, por ejemplo, probar valores "ilegales". Por lo tanto, puede terminar con un código como este: ¿cuánto más legible es? Las "funciones auxiliares" pueden esconderse en algún lugar (no es necesario que estén en el módulo principal: su nombre deja claro lo que hacen):

#include <stdio.h> enum {NO, YES, WINNER}; enum {OUT_OF_RANGE=-1, ODD, EVEN}; int notInRange(int square) { return(square < 1 || square > 100)?YES:NO; } int isEndOfRow(int square) { if (notInRange(square)) return OUT_OF_RANGE; if (square == 100) return WINNER; // I am making this up... return (square % 10 == 0)? YES:NO; } int rowType(unsigned int square) { // return 1 if square is in odd row (going to the right) // and 0 if square is in even row (going to the left) if (notInRange(square)) return OUT_OF_RANGE; // trap this error int rowNum = (square - 1) / 10; return (rowNum % 2 == 0) ? ODD:EVEN; // return 0 (ODD) for 1-10, 21-30 etc. // and 1 (EVEN) for 11-20, 31-40, ... } int main(void) { int a = 12; int rt; rt = rowType(a); // this replaces your obscure if statement // and here is how you handle the possible return values: switch(rt) { case ODD: printf("It is an odd row/n"); break; case EVEN: printf("It is an even row/n"); break; case OUT_OF_RANGE: printf("It is out of range/n"); break; default: printf("Unexpected return value from rowType!/n"); } if(isEndOfRow(10)==YES) printf("10 is at the end of a row/n"); if(isEndOfRow(100)==WINNER) printf("We have a winner!/n"); }