Ver Mensaje Individual
  #2 (permalink)  
Antiguo 27/10/2016, 02:01
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 5 meses
Puntos: 204
Respuesta: Dar mas sencillez a este codigo

Cambios que yo haría:

1. Reducir el ámbito de todas las variables

Así pasa que valor1...valor4 únicamente se usan en la segunda parte del algoritmo, no tiene sentido que estén declaradas al inicio de la función. Al inicio de la función únicamente deberían estar declaradas 1 variables: retval

2. Simplicar el tipo de las variables

caracter no gana nada siendo signed char. Lo cambio a char. Con este cambio tonto consigo que esto:

se convierta en esto:

Código C++:
Ver original
  1. caracter = cadena[sizefilelic + 1];

Con esto queda más claro que el bucle:

Código C++:
Ver original
  1. if (caracter) {
  2.   do {
  3.     if (caracter == 0x1A)
  4.       break;
  5.     caracter = cadena[sizefilelic + 1];
  6.     ++sizefilelic;
  7.   } while (caracter);
  8. }

3. Traducir el codigo a cristiano

Se puede simplificar bastante, ya que lo único que hace es contar caracteres hasta llegar al caracter 0x1A o al final del string. La versión simplificada podría quedar tal que:

Código C++:
Ver original
  1. char* ptr;
  2. for( *ptr = cadena ; *ptr && *ptr != 0x1A; ++ptr);
  3. unsigned long sizefilelic = ptr - cadena;

Y con C++11 y lambdas:

Código C++:
Ver original
  1. unsigned long sizefilelic = [cadena]()
  2. {
  3.   char* ptr;
  4.   for( *ptr = cadena ; *ptr && *ptr != 0x1A; ++ptr);
  5.   return ptr - cadena;
  6. }();

La segunda parte del algoritmo únicamente se ejecutará si valor3 es distinto de 0... puesto que valor3 coge su valor de sizefilelic podemos hacer que esa parte se ejecute únicamente si el valor de esta última variable es distinto de 0... quedará un código un poco más legible:
Código C++:
Ver original
  1. if( sizefilelic )
  2. {
  3.   unsigned long contador = 0;
  4.   unsigned long valor2 = 0;
  5.   unsigned long valor3 = sizefilelic;
  6.   retval = valor3;
  7.  
  8.   unsigned long valor4 = valor3 + 1;
  9.   do {
  10.     unsigned long valor1 = static_cast<unsigned long>(*reinterpret_cast<unsigned char*>(contador + reinterpret_cast<unsigned long>(cadena)));
  11.     valor2 = valor2 ^ valor1 + contador;
  12.     ++contador;
  13.     valor3 = (*reinterpret_cast<unsigned char*>(valor2 % valor4 + reinterpret_cast<unsigned long>(cadena) + 1) + valor2 + (valor1 + valor2) * 2 + retval) * valor2;
  14.     retval = valor3;
  15.   } while (contador < sizefilelic);
  16. }

Como el bucle do..while se va a ejecutar al menos una vez, la instrucción retval=valor3 se puede eliminar con todo el cariño del mundo.

Código C++:
Ver original
  1. valor1 = static_cast<unsigned long>(*reinterpret_cast<unsigned char*>(contador + reinterpret_cast<unsigned long>(cadena)));

Esta línea lo único que hace es desplazarse un offset dado por contador sobre el buffer cadena... lo único que almacena valor1 es el caracter existente en dicha posición convertido a unsigned long.

Un homólogo sencillo:

Código C++:
Ver original
  1. valor1 = static_cast<unsigned long>(cadena[contador]);

Esto:

Código C++:
Ver original
  1. *reinterpret_cast<unsigned char*>(valor2 % valor4 + reinterpret_cast<unsigned long>(cadena) + 1)

En cristiano significa esto:

Código C++:
Ver original
  1. cadena[(valor2%valor4) + 1];

Y para rematar la jugada, la variable contador la podemos meter en un for para sustituir el do-while, con lo que nos queda la segunda parte del algoritmo tal que:

Código C++:
Ver original
  1. if( sizefilelic )
  2. {
  3.   unsigned long valor2 = 0;
  4.   unsigned long valor3 = sizefilelic;
  5.  
  6.   const unsigned long valor4 = valor3 + 1;
  7.   for( unsigned long contador=0; contador<sizefilelic; ++contador)
  8.   {
  9.     unsigned long valor1 = static_cast<unsigned long>(cadena[contador]);
  10.     valor2 = valor2 ^ valor1 + contador;
  11.     valor3 = (cadena[(valor2%valor4) + 1] + valor2 + (valor1 + valor2) * 2 + retval) * valor2;
  12.     retval = valor3;
  13.   }
  14. }

No puedo probar el algoritmo primero porque no tengo ansistring y segundo porque no tengo cadenas de prueba... pero a grandes rasgos el código debería ser el mismo.

PD.: espero que si empiezas a sacar dinero de todo esto te acuerdes de mí jejejeje

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.