Exponentiación modular en C ++ -- ++ campo con performance campo con algorithm camp codereview Relacionados El problema

Modular exponentiation in C++


6
vote

problema

Español

Escribí el siguiente código para un concurso y funcionó bien para mí. ¿Podría hacerlo un poco más rápido?

  #include<iostream> using namespace std;  int power(int,int,int);  int main(int argc,char** argv){     int base,exponent,mod;     cin>>base>>exponent>>mod;     cout<<power(base,exponent,mod)<<endl;     return 0; }  int power(int base,int exponent,int mod){     if(mod==1)return 0;     int ans=1;     for(int i=0;i<exponent;i++){         ans=(ans*base)%mod;     }     return ans; }   
Original en ingles

I wrote the following code for a contest and worked fine for me. Could I make it a bit faster?

#include<iostream> using namespace std;  int power(int,int,int);  int main(int argc,char** argv){     int base,exponent,mod;     cin>>base>>exponent>>mod;     cout<<power(base,exponent,mod)<<endl;     return 0; }  int power(int base,int exponent,int mod){     if(mod==1)return 0;     int ans=1;     for(int i=0;i<exponent;i++){         ans=(ans*base)%mod;     }     return ans; } 
        
   
   

Lista de respuestas

7
 
vote
vote
La mejor respuesta
 

La forma habitual es un poco más compleja, pero mucho más rápido cuando el exponente es grande. Se ve algo así:

  procedure_name5  

procedure_name6 CAMBIOS DERECHOS procedure_name7 (el exponente) Cada iteración a través del bucle, por lo que el número de iteraciones es proporcional al número de bits en el número (donde la tuya En la pregunta es proporcional al exponente en sí). En otras palabras, la suya es lineal sobre la magnitud de Exponent, y esta es una magnitud de exponente más lógica.

Revisión real del código

Dado que este es CODEREVIEW, NO (por ejemplo,) Desbordamiento de la pila, también echemos un vistazo a la revisión de su código.

Definiciones variables

Usted ha definido varias variables en una sola definición:

  procedure_name8  

Muchas personas lo encuentran más legible para definir una variable por definición:

  procedure_name9  

... o al menos use una línea separada para cada variable:

  =0  

Naming

El nombre de una función debe reflejar lo que realmente hace. Usando =1 para bordes de exponentiación modular en engañoso. Preferiría el nombre =2 o al menos =3 .

Formato

Al menos imo, un poco de espacio en blanco puede ayudar a la legibilidad bastante. Por un ejemplo, en lugar de:

  =4  

... prefiero ver un espacio después de cada coma:

  =5  

Además, donde hay control de flujo, las declaraciones controladas deben ser sangradas, por lo que esto:

  =6  

saldría como:

  =7  

Retorno de =8

Cuando la ejecución "fluye" fuera del extremo de =9 , hay un 998877665555443330 , para que pueda eliminar esa línea de su código (aunque algunos prefieren mantenerlo) .

Uso de self.name = param.attrib['name'] 1

Evitaría usar self.name = param.attrib['name'] 2 (siempre). La mayoría de las veces, realmente desea escribir una nueva línea, en cuyo caso 99887766555443333 es completamente adecuado. En la (relativamente rara) ocasión que realmente desea eliminar la transmisión como self.name = param.attrib['name'] 4 también, debe hacerlo explícitamente.

self.name = param.attrib['name'] 5

Tirando en la totalidad de self.name = param.attrib['name'] 6 como este es generalmente fruncido. Está bien para otros espacios de nombres (más sensiblemente diseñados), pero self.name = param.attrib['name'] 7 define una cantidad enorme de "cosas", la mayoría de las cuales realmente no desea directamente visible. < / p>

 

The usual way is a little more complex, but a lot faster when the exponent is large. It looks something like this:

template <class T> T mul_mod(T a, T b, T m) {      if (m == 0) return a * b;      T r = T();      while (a > 0) {         if (a & 1)             if ((r += b) > m) r %= m;         a >>= 1;         if ((b <<= 1) > m) b %= m;     }     return r; }  template <class T> T pow_mod(T a, T n, T m) {     T r = 1;      while (n > 0) {         if (n & 1)             r = mul_mod(r, a, m);         a = mul_mod(a, a, m);         n >>= 1;     }     return r; } 

pow_mod right-shifts n (the exponent) each iteration through the loop, so the number of iterations is proportional to the number of bits in the number (where yours in the question is proportional to the exponent itself). In other words, yours is linear on the exponent's magnitude, and this is roughly logarithmic exponent's magnitude.

Actual code review

Since this is CodeReview, not (for example) Stack Overflow, let's also take a look at reviewing your code.

Variable Definitions

You've defined multiple variables in a single definition:

int base,exponent,mod; 

Many people find it more readable to define one variable per definition:

int base; int exponent; int mod; 

... or at least use a separate line for each variable:

int base,     exponent,     mod; 

Naming

A function's name should reflect what it really does. Using power for modular exponentiation borders on misleading. I'd rather the name included modular or at least mod.

formatting

At least IMO, a little white space can help readability quite a bit. For one example, instead of:

int power(int base,int exponent,int mod) 

...I'd rather see a space after each comma:

int power(int base, int exponent, int mod) 

In addition, where there's flow control, the controlled statements should be indented, so this:

if(mod==1)return 0; 

would come out like:

 if (mod==1)      return 0; 

return from main

When execution "flows" off the end of main, there's an implicit return 0;, so you can eliminate that line from your code (though some prefer to keep it).

Use of endl

I'd avoid using std::endl (ever). Most of the time you really just want to write out a new-line, in which case \n is entirely adequate. On the (relatively rare) occasion that you really also want to flush the stream as endl also does, you should do so explicitly.

using namespace std;

Pulling in the entirety of namespace std; like this is generally frowned upon. It's all right for other (more sensibly designed) namespaces, but std defines a huge amount of "stuff", most of which you really don't want directly visible.

 
 
 
 

Relacionados problema

56  Proyecto Euler Problema 1 en Python - Múltiples de 3 y 5  ( Project euler problem 1 in python multiples of 3 and 5 ) 
Me gustaría sugerencias para optimizar esta solución de fuerza bruta a problema 1 . El algoritmo actualmente comprueba cada entero entre 3 y 1000. Me gustarí...

6  Encontrar el siguiente palíndromo de una cadena de números  ( Finding the next palindrome of a number string ) 
Aquí está el problema: Un entero positivo se llama palíndromo si su representación en el El sistema decimal es el mismo cuando se lee de izquierda a dere...

5  Orden de número más grande en cadena  ( Largest number order in string ) 
Dada una cadena, suponiendo que la cadena sea solo números, reorganice la cadena a la que sea el mayor número posible. a continuación es mi solución al pr...

35  Demasiados bucles en la aplicación de dibujo  ( Too many loops in drawing app ) 
Tengo un método que tiene muchos bucles: #ifndef __RUNES_STRUCTURES_H #define __RUNES_STRUCTURES_H /* Runes structures. */ struct Game { char board[2...

1  Retire todos los nodos que no se encuentren en ningún camino con suma> = k  ( Remove all nodes which dont lie in any path with sum k ) 
Dado un árbol binario, una ruta completa se define como un camino desde la raíz a una hoja. La suma de todos los nodos en ese camino se define como la suma d...

1  Compruebe si dos cadenas son permutación entre sí  ( Check if two strings are permutation of each other ) 
private String sort(String word) { char[] content = word.toCharArray(); Arrays.sort(content); return new String(content); } private boolea...

8  Simple GCD Utility en Java  ( Simple gcd utility in java ) 
i anteriormente discutido El rendimiento se refiere a diferentes algoritmos GCD. Escribí una simple clase de Java que implementa el algoritmo binario GCD. E...

5  Proyecto EULER NO. 17: contando letras para escribir los números de 1 a 1000  ( Project euler no 17 counting letters to write the numbers from 1 to 1000 ) 
Soy muy nuevo en la programación y, cierto, estoy avergonzado de compartir mi código para la crítica. Este código funciona y produce la respuesta correcta a l...

2  Dos formas de aleatorias aleatoriamente las tarjetas  ( Two ways to randomly shuffle cards ) 
Aquí hay dos implementaciones que escribí para aleatorizar las tarjetas. El primer método ( dt5 ) Selecciona una tarjeta aleatoria, luego lo quita al frent...

25  Algoritmo para transformar una palabra a otra a través de palabras válidas  ( Algorithm to transform one word to another through valid words ) 
He estado practicando retroceso y quería saber cómo puedo mejorar mi código. Por ejemplo, no quiero usarlo global. Además, no estoy seguro de si mi código fun...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos