elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


  Mostrar Mensajes
Páginas: 1 ... 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [29] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ... 125
281  Programación / Programación C/C++ / Re: Necesito ayuda con scrollbar c/c++ en juego 2d. en: 29 Julio 2014, 15:12 pm
Edit:
En main: creas un objeto llamando el constructor con 2 parámetros:   ScrollBar scroll( 0, 20 );

Pero el constructor solo tiene definido uno. El otro es _position?  :huh:

Vaya, al final se me olvidó actualizar el main... hice un cambio de última hora y le quité el primer parámetro a ScrollBar... ya que una barra de scroll únicamente se mueve en un plano. Elimina el 0 y listo.
282  Programación / Programación C/C++ / Re: Necesito ayuda con scrollbar c/c++ en juego 2d. en: 29 Julio 2014, 13:47 pm
La idea puede ser el disponer de un "viewport" que te facilite los datos del área visible en todo momento. Los datos de este viewport se verán afectados en el momento en el que se modifique el estado de la barra de scroll

Para empezar, el control de scroll. Este puede ser todo lo complejo que quieras, pero lo básico sería algo tal que:

Código
  1. class ScrollBar
  2. {
  3.  public:
  4.  
  5.    ScrollBar( int max )
  6.      : _max( max ),
  7.        _position( 0 )
  8.   { }
  9.  
  10.    void Slide( int value )
  11.    {
  12.      _position += value;
  13.  
  14.      _position = std::max( _position, 0 );
  15.      _position = std::min( _position, _max );
  16.    }
  17.  
  18.    void SlideUp( )
  19.    { Slide( -5 ); }
  20.  
  21.    void SlideDown( )
  22.    { Slide( +5 ); }
  23.  
  24.    int Position( ) const
  25.    { return _position; }
  26.  
  27.  private:
  28.  
  29.    int _position;
  30.    int _max;
  31. };

Como se ve, te limita la posición dentro de un rango determinado. Incluye un par de funciones para hacer desplazamientos rápidos, por ejemplo si pones los botones "arriba" y "abajo" característicos de las barras de scroll.

Ahora necesitamos definir el "viewport"... básicamente no deja de ser un rectángulo que podemos desplazar al gusto:

Código
  1. class ViewPort
  2. {
  3.  public:
  4.  
  5.    ViewPort( int x, int y, int width, int height )
  6.      : _x( x ), _y( y ), _width( width ), _height( height )
  7.   { }
  8.  
  9.    int X( ) const
  10.    { return _x; }
  11.  
  12.    int Y( ) const
  13.    { return _y; }
  14.  
  15.    int Width( ) const
  16.    { return _width; }
  17.  
  18.    int Height( ) const
  19.    { return _height; }
  20.  
  21.    int Left( ) const
  22.    { return _x; }
  23.  
  24.    int Right( ) const
  25.    { return _x + _width; }
  26.  
  27.    int Top( ) const
  28.    { return _y; }
  29.  
  30.    int Bottom( ) const
  31.    { return _y + _height; }
  32.  
  33.     void MoveTo( int x, int y )
  34.    {
  35.      _x = x;
  36.      _y = y;
  37.    }
  38.  
  39.  private:
  40.  
  41.    int _x;
  42.    int _y;
  43.    int _width;
  44.    int _height;
  45. };

Si ahora "cosemos" un poco los elementos, podemos tener un pequeño ejemplo... eso si... sin partes gráficas:

Código
  1. int main( )
  2. {
  3.  ScrollBar scroll( 0, 20 );
  4.  
  5.  ViewPort viewPort( 0, 0, 800, 600 );
  6.  
  7.  std::cout << "Desplazamiento hacia abajo:" <<  std::endl;
  8.  for ( int i = 0; i < 5; i++ )
  9.  {
  10.    scroll.SlideDown( );
  11.    viewPort.MoveTo( 0, scroll.Position( ) );
  12.    std::cout << "Posición: x=" << viewPort.X( ) << " y=" << viewPort.Y( ) << std::endl;
  13.  }
  14.  
  15.  std::cout << std::endl;
  16.  std::cout << "Desplazamiendo hacia arriba: " << std::endl;
  17.  for ( int i = 0; i < 5; i++ )
  18.  {
  19.    scroll.SlideUp( );
  20.    viewPort.MoveTo( 0, scroll.Position( ) );
  21.    std::cout << "Posición: x=" << viewPort.X( ) << " y=" << viewPort.Y( ) << std::endl;
  22.  }
  23. }

Como se puede apreciar... la barra de scroll limita el desplazamiento del área visible, impidendo que salga de los márgenes definidos.

Una vez echo esto queda "pintar" de forma efectiva el área apuntada por "ViewPort", pero eso ya debería ser facil conociendo las coordenadas del área a pintar... lo que tienes que hacer es coger todos los elementos de ese área y "desplazarlos". Me explico. Imagina que tienes un elemento en (20, 10) y el viewport tiene como coordenada superior (0, 2)... el elemento deberás desplazarlo ese (0, 2), es decir, deberás pintarlo en (20, 8) para que aparezca correctamente pintado en la ventana.

Si no queda muy clara la explicación avísame y te lo comento con más tranquilidad... me tengo que ir a comer XDDDD
283  Programación / Programación C/C++ / Re: Duda reconocimiento de voz c++ en: 28 Julio 2014, 12:36 pm
Hola alguien tiene idea de cómo programar en C++ el reconocimiento de voz, desde cero?

Yo te digo como empezar... el resto es cosa tuya:

Código
  1. int main( int argc, char** argv )
  2. {
  3.  // Tu codigo aqui
  4. }

Ahora en serio... crees que esa pregunta es seria??
284  Programación / Programación C/C++ / Re: funciones lineales cuadráticas y cubicas en: 28 Julio 2014, 12:04 pm
Una guia sobre esto... hay varias formas de hacer esto... cada una con sus ventajas y sus inconvenientes.

Yo personalmente "recompilaria" la función. Un polinomio se puede encapsular fácilmente como una sucesión de monomios del tipo:

Código
  1. class Monomio
  2. {
  3.  public:
  4.  
  5.    Monomio( double multiplicador, double exponente )
  6.      : _multiplicador( multiplicador),
  7.        _exponente( exponente )
  8.    {
  9.    }
  10.  
  11.    double operator( )( double x) const
  12.    {
  13.      return pow( x * multiplicador, _exponente );
  14.    }
  15.  
  16.    friend std::ostream& operator << ( std::ostream& out, const Monomio& monomio )
  17.    {
  18.      if ( monomio.multiplicador > 0 )
  19.        out << "+";
  20.  
  21.      out << monomio.multiplicador;
  22.  
  23.      if ( monomio._exponente != 0.0 )
  24.      {
  25.        out << "x";
  26.        if ( monomio._exponente != 1.0 )
  27.          out << "^" << monomio._exponente;
  28.      }
  29.  
  30.      return out;
  31.    }
  32.  
  33.  private:
  34.  
  35.    double multiplicador;
  36.    double _exponente;
  37. };

Y con esto el resto del proceso se simplifica enormemente:

Código
  1. class Polinomio
  2. {
  3.  public:
  4.  
  5.    Polinomio( const std::vector< Monomio >& monomios )
  6.      : _monomios( monomios )
  7.    { }
  8.  
  9.    double operator( )( double x) const
  10.    {
  11.      double resultado = 0.0f;
  12.  
  13.      for ( const auto& monomio : _monomios )
  14.      {
  15.        resultado += monomio( x);
  16.      }
  17.  
  18.      return resultado;
  19.    }
  20.  
  21.    friend std::ostream& operator<<( std::ostream& out, const Polinomio& poli )
  22.    {
  23.      out << "y=";
  24.  
  25.      for ( const auto& monomio : poli._monomios )
  26.        out << monomio;
  27.  
  28.      return out;
  29.    }
  30.  
  31.  private:
  32.  
  33.    std::vector< Monomio > _monomios;
  34. };
  35.  
  36. int main()
  37. {
  38.  std::vector< Monomio > monomios { { 1.0, 2.0 }, { -14.0, 1.0 }, { 48.0, 0.0 } };
  39.  
  40.  Polinomio poli( monomios );
  41.  
  42.  std::cout << "Función: " << poli << std::endl;
  43.  std::cout << "Resultados: " << std::endl;
  44.  for ( double x = 0; x < 10; x++ )
  45.  {
  46.    std::cout << "x=" << x << " - y=" << poli( x ) << std::endl;
  47.  }
  48. }

Para graficar las funciones tendrás que pelearte con alguna librería gráfica... pero al menos ya tienes la pareja de valores (x,y)
285  Programación / Programación C/C++ / Re: Extraña asignación en un array con -1 en: 28 Julio 2014, 11:30 am
Código
  1. c = *s++;

Es equivalente a:

Código
  1. c = *s;
  2. s++;

Es decir, asigno a 'c' el valor apuntado por 's' y después hago que 's' apunte al siguiente carácter.

Código
  1. if (c == sc)
  2. {
  3.  s[-1] = '\0';
  4. }

Si 'c' se corresponde con el delimitador, entonces tengo que eliminar ese delimitador... pero claro, el único puntero que tengo, 's', está apuntando al siguiente carácter... bueno, pues retrocedo una posición y listo.
286  Programación / Programación C/C++ / Re: Obtener codificacion de caracteres de un archivo de texto en C en: 26 Julio 2014, 18:09 pm
Hasta donde llego, la única forma de detectarlo es procesar el fichero y localizar combinaciones propias de uno de los formatos. Me explico:

* ASCII: Define 128 caracteres y es la base para casi todas las codificaciones comunes.

* UTF8 tiene dos formatos diferentes, con BOM y sin BOM... BOM o "Bit Order Mask" es una identificación que se añade al principio del fichero... si te la encuentras pues está claro que la codificación es UTF8... si no te la encuentras puede que sea UTF8... o no, dependerá de las secuencias que encuentres en el archivo. Las primeras 128 posiciones de UTF8 coinciden con las ASCII.

* Etc: Cada codificación tiene sus peculiaridades, lo mejor es buscar en Internet o concretar un poco más la pregunta.
287  Programación / Programación C/C++ / Re: [Solucionado] Problema en codigo C++, no se ejecuta el else en: 26 Julio 2014, 01:08 am
Perdona una cosa 718208. El caso es que en todos los códigos que te veo publicar, usas clases, cuando lo más acertados ería una función. En caso de que solo muestres una parte del código, pues vale. Pero si ese es todo el código, recuerda que tus clases consumen memoria, y al final acaban haciendo lo mismo que una función.

Consumen memoria... esa clase consume el equivalente a un int... 4 bytes ... tampoco hay que dramatizar jejejeje

Yo es que soy partidario de poner todo en clases... permite organizar el código mejor... lo que sucede es que funciones como estas pueden perfectamente ser estáticas, no hace falta crear una instancia de la clase para manejarlas.
288  Programación / Programación C/C++ / Re: Como calcular cuantos dígitos tiene un entero en: 25 Julio 2014, 09:32 am
ya que es la diferencia entre un ciclo con una división (operacion matematica simple posible de hacer por el procesador con un solo paso)

Perdón por la intromisión, pero la división es la operación más costosa con diferencia de las interpretadas como básicas: suma, resta, producto, división. Y cuando digo costosa me refiero en una proporción que puede llegar a ser de 8 a 1.

Dicho esto me ha surgido la duda de saber cual era el algoritmo más óptimo... manos a la obra salió algo tal que:

Código
  1. #include <iostream>
  2. #include <chrono>
  3. #include <math.h>
  4.  
  5. int DigitosV1( int numero )
  6. {
  7.  int digitos;
  8.  for ( digitos = 0; numero > 0; digitos++, numero /= 10 ) ;
  9.  return digitos;
  10. }
  11.  
  12. int DigitosV2( int numero )
  13. {
  14.  return log( numero ) + 1;
  15. }
  16.  
  17. const int NUMERO = 1234567890;
  18. const int MAXBUCLE = 1000000000;
  19.  
  20. int main( )
  21. {
  22.  int temp;
  23.  std::chrono::time_point<std::chrono::system_clock> start, end;
  24.  start = std::chrono::system_clock::now( );
  25.  for ( int i=0; i < MAXBUCLE; i++ )
  26.  {
  27.    temp = DigitosV1( NUMERO );
  28.  }
  29.  end = std::chrono::system_clock::now();
  30.  
  31.  std::chrono::duration<double> elapsed_seconds = end-start;
  32.  
  33.  std::cout << "Tiempo division: " << elapsed_seconds.count() << "s\n";
  34.  
  35.  start = std::chrono::system_clock::now( );
  36.  for ( int i=0; i < MAXBUCLE; i++ )
  37.  {
  38.    temp = DigitosV2( NUMERO );
  39.  }
  40.  end = std::chrono::system_clock::now();
  41.  
  42.  elapsed_seconds = end-start;
  43.  
  44.  std::cout << "Tiempo logaritmo: " << elapsed_seconds.count() << "s\n";
  45. }
  46.  

¿Qué sucede con los resultados? Son contundentes (aviso, abstenerse personas sensibles):

Editado: Estos resultados son con el programa compilado en modo debug... lo siento.

Código:
Tiempo division: 43.1613s
Tiempo logaritmo: 29.538s

Luego por 5 cabezas de ventaja, la opción del logaritmo es más óptima que la opción de la división.



Edito: Para probar opciones menos extremistas, he reducido el número de prueba a uno con 5 dígitos y he ejecutado el programa... los resultados son los siguientes:

Editado: Estos resultados son con el programa compilado en modo debug... lo siento.

Código:
Tiempo division: 19.1429s
Tiempo logaritmo: 29.564s

Se ve por tanto que la opción del logaritmo es estable en el tiempo, mientras que la división, obviamente, ha reducido su tiempo a la mitad ( tiene la mitad de dígitos ).

Dicho esto me surgió una nueva duda... log trabaja con "double"... y si la idea es trabajar con números más grandeS??

Un poco de refactorización y listo:

Código
  1. #include <iostream>
  2. #include <chrono>
  3. #include <limits>
  4. #include <math.h>
  5.  
  6. const int INT5 = 12345;
  7. const int INT7 = 1234567;
  8. const int INT10 = 1234567890;
  9.  
  10. const double DOUBLE5 = 12345.0;
  11. const double DOUBLE7 = 1234567.0;
  12. const double DOUBLE10 = 1234567890.0;
  13.  
  14. template< class T >
  15. int DigitosDIV( T numero )
  16. {
  17.  int digitos;
  18.  T divisor = 10;
  19.  T min = 1; // para que el bucle funcione con decimales
  20.  for ( digitos = 0; numero >= min; digitos++, numero /= divisor ) ;
  21.  return digitos;
  22. }
  23.  
  24. template< class T >
  25. int DigitosLOG( T numero )
  26. {
  27.  return log( numero ) + 1;
  28. }
  29.  
  30. template< class T >
  31. std::chrono::duration< double > Bucle( T numero, int(*func)(T) )
  32. {
  33.  int temp;
  34.  
  35.  auto start = std::chrono::system_clock::now( );
  36.  
  37.  const int max = std::numeric_limits< int >::max( );
  38.  for ( int i=0; i < max; i++ )
  39.  {
  40.    temp = func( numero );
  41.  }
  42.  auto end = std::chrono::system_clock::now( );
  43.  
  44.  return end - start;
  45. }
  46.  
  47. int main( )
  48. {
  49.  auto DivInt5  = Bucle( INT5,  DigitosDIV< int > );
  50.  auto DivInt7  = Bucle( INT7,  DigitosDIV< int > );
  51.  auto DivInt10 = Bucle( INT10, DigitosDIV< int > );
  52.  
  53.  auto LogInt5  = Bucle( INT5,  DigitosLOG< int > );
  54.  auto LogInt7  = Bucle( INT7,  DigitosLOG< int > );
  55.  auto LogInt10 = Bucle( INT10, DigitosLOG< int > );
  56.  
  57.  auto DivDouble5  = Bucle( DOUBLE5,  DigitosDIV< double > );
  58.  auto DivDouble7  = Bucle( DOUBLE7,  DigitosDIV< double > );
  59.  auto DivDouble10 = Bucle( DOUBLE10, DigitosDIV< double > );
  60.  
  61.  auto LogDouble5  = Bucle( DOUBLE5,  DigitosLOG< double > );
  62.  auto LogDouble7  = Bucle( DOUBLE7,  DigitosLOG< double > );
  63.  auto LogDouble10 = Bucle( DOUBLE10, DigitosLOG< double > );
  64.  
  65.  std::cout << "Tiempo division (int 5):     " << DivInt5.count( )     << " s\n";
  66.  std::cout << "Tiempo division (int 7):     " << DivInt7.count( )     << " s\n";
  67.  std::cout << "Tiempo division (int 10):    " << DivInt10.count( )    << " s\n\n";
  68.  std::cout << "Tiempo log (int 5):          " << LogInt5.count( )     << " s\n";
  69.  std::cout << "Tiempo log (int 7):          " << LogInt7.count( )     << " s\n";
  70.  std::cout << "Tiempo log (int 10):         " << LogInt10.count( )    << " s\n\n";
  71.  std::cout << "Tiempo division (double 5):  " << DivDouble5.count( )  << " s\n";
  72.  std::cout << "Tiempo division (double 7):  " << DivDouble7.count( )  << " s\n";
  73.  std::cout << "Tiempo division (double 10): " << DivDouble10.count( ) << " s\n\n";
  74.  std::cout << "Tiempo log (double 5):       " << LogDouble5.count( )  << " s\n";
  75.  std::cout << "Tiempo log (double 7):       " << LogDouble7.count( )  << " s\n";
  76.  std::cout << "Tiempo log (double 10):      " << LogDouble10.count( ) << " s\n\n";
  77. }

Y su correspondiente resultado (ahora sí en modo release):

Código
  1. Tiempo division (int 5):     23.6144 s
  2. Tiempo division (int 7):     33.9994 s
  3. Tiempo division (int 10):    49.798 s
  4.  
  5. Tiempo log (int 5):          60.28 s
  6. Tiempo log (int 7):          60.415 s
  7. Tiempo log (int 10):         60.8651 s
  8.  
  9. Tiempo division (double 5):  81.3541 s
  10. Tiempo division (double 7):  113.471 s
  11. Tiempo division (double 10): 162.253 s
  12.  
  13. Tiempo log (double 5):       60.7651 s
  14. Tiempo log (double 7):       60.8521 s
  15. Tiempo log (double 10):      60.7481 s

La conclusión final... cada uno que saque las suyas... pero simplificando yo obtengo las siguientes:

* El logaritmo es más estable... ideal para tareas de tiempo real.
* La división es, de media, más rápida si se trabaja con enteros... el logaritmo es más eficiente con decimales.
* Es curioso como se nota la bajada de tiempos de la división en modo release frente a modo debug
289  Programación / Programación C/C++ / Re: Problema en codigo C++ en: 25 Julio 2014, 09:04 am
Blaster, perfectamente podrías ahorrarte la variable "escala". Además, teniendo en cuenta que "numero" es una especie de "engendro" por almacenar un número en base 2 como si estuviese en base 10, el código incluso se podría optimizar un poquito más:

Código
  1. void Binario::confirmarNumero(int numero)
  2. {
  3.    int decimal = 0;
  4.  
  5.    while (numero > 0)
  6.    {
  7.        int numeroSacado = numero & 0x01;
  8.  
  9.        decimal = decimal * 2 + numeroSacado;
  10.  
  11.        numero /= 10;
  12.    }
  13.    cout << "El equivalente decimal es: " << decimal << endl;
  14. }

Pero no logo entender cual es el error ahora  :-\

Código
  1. while ((numero / numero) != 0)

¿Qué intentabas ahí exactamente?

A ver, esta parte concreta, lo que se dice funcionar... funciona, pero no es la mejor manera de hacerlo.Si tu idea es que el bucle se repita hasta que "numero sea 0" ¿por qué no usas los operadores de comparación ('==', '!=', '>', '<', '>=', '<=')??

Hay varias alternativas para expresar lo mismo y de forma mucho más clara. Que al final es de lo que se trata, hacer código legible. Te presento tres alternativas ordenadas de la más clara a la menos clara desde mi punto de vista:

* Opción 1: Comprobar si el número es distinto de 0
Código
  1. while ( numero != 0 )

* Opción 2: Comprobar si el número es mayor de 0
Código
  1. while( numero > 0 )

* Opción 3: Comprobar si el número es igual o mayor que 1
Código
  1. while( numero >= 1 )

El problema en sí, que hace qeu no te funcione, es que no estás utilizando en ningún momento la variable "escala"... le asignas valores, eso sí... pero no haces uso de esos valores en ningún momento.

Y luego te faltaría sacar por pantalla el número final.

PD: con respecto a lo que me dijiste sobre string no entendí muy bien a qué te refieres

101 (10 = 1100101 (2 <-- Queda claro que representar un número en base 2 ocupa más memoria que representarlo en base 10.

El número más alto que puedes almacenar en un int es el 2147483647 (2^31 - 1). Si usas este mismo int para almacenar un número en representación binaria, entonces no podrás almacenar números mayores que el 1111111111, que en decimal quedaría representado por el número 1023. Queda claro que el código de tu programa limita muchísimo el rango de números con el que es capaz de trabajar.

La idea que propongo es almacenar el número en una cadena de caracteres y recorrer esos caracteres para ir calculando el número final. Algo del tipo:

Código
  1. std::string cadena;
  2. std::cout << "Introduce un número en binario" << std::endl;
  3. std::cin >> cadena;
  4.  
  5. int numero = 0;
  6. for ( unsigned int i = 0; i < cadena.length( ); i++ )
  7. {
  8.  numero *= 2;
  9.  if ( cadena[ i ] == '1' )
  10.    numero++;
  11. }
  12.  
  13. std::cout << "El equivalente en decimal es: " << numero << std::endl;

Creo que el código resultante es bastante sencillo y fácil de entender.
290  Programación / Programación C/C++ / Re: ayuda con strings en: 24 Julio 2014, 17:40 pm
El tamaño de los arrays solo hay que ponerlo, salvo que se me olvide algún caso concreto, en las siguientes circunstancias:

* Cuando los declaras en el stack (es decir, no usas memoria dinámica):

Código
  1. char cadena[200];

* Cuando pasas un array multidimensional ubicado en el stack como parámetro de una función:

Código
  1. void procesarMatriz( int matriz[10][20] );

Cuando usas un arreglo, una vez creado, el compilador ya sabe qué es lo que está manejando... no necesitas recordárselo cada dos líneas. Además que tu código es peligroso:

Código
  1. char cadena[4];
  2. strcpy( cadena, "abc" ); // Ok
  3.  
  4. printf( "%c %c %c", cadena[ 0 ], cadena[ 1 ], cadena[ 2 ] );

Fíjate que al pasar el índice recupero uno de los elementos del arreglo... funciones como strstr, strcpy... necesitan un puntero que indice dónde deben empezar a leer / escribir... si en vez de eso les pasas otra cosa acabarán escribiendo en zonas de memoria que no te corresponden y el programa, en el mejor de los casos, fallará estrepitosamente.

En el ejemplo que te he puesto, si hubieses puesto

Código
  1. strcpy( cadena[4], "abc" );

Estarías indicando que quieres que se copie en la dirección apuntada por el cuarto elemento de cadena, la secuencia "abc"... puedes acabar escribiendo en cualquier parte de la memoria por error.

Si no eres capaz de entender lo que intento explicarte no te asustes, eso únicamente quiere decir que deberías comprarte un buen libro de C y seguirlo desde el principio antes de continuar con este tipo de prácticas... los inicios en la programación nunca son fáciles.
Páginas: 1 ... 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [29] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ... 125
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines