Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: burnssss en 30 Octubre 2013, 16:10 pm



Título: CREACION SUBCADENAS A PARTIR DE CADENA BINARIA
Publicado por: burnssss en 30 Octubre 2013, 16:10 pm
Con el siguiente codigo pretendo extraer las subcadenas de longitud 4 y hacer un recuento del numero de cada patron. Para ello, convierto cada patron en un numero entero y a partir de ahi inicio el contador. No sé muy bien si las combinaciones las hace correctamente:
por ejemplo si tengo la secuencia:

s=[1 (1), 0 (2), 1 (3), 1 (4), 0 (5), 0 (6), 1 (7), 0 (8), 0 (9), 1 (10) , 1 (11), 1 (12),

1 (13), 0 (14), 0 (15), 0 (16), 1 (17), 1 (18), 1 (19), 0 (20) ];

Los numeros entre parentesis son solo para indicar el orden.
Las subcadenas de longitud 4 serian:

01: 1 (01) 0 (02) 1 (03) 1 (04) -> [1,0,1,1],

02: 1 (01) 1 (03) 0 (05) 1 (07) -> [1,1,0,1],

03: 1 (01) 1 (04) 1 (07) 1 (10) -> [1,1,1,1],

04: 1 (01) 0 (05) 0 (09) 1 (13) -> [1,0,0,1],

05: 1 (01) 0 (06) 1 (11) 0 (16) -> [1,0,1,0],

06: 1 (01), 1 (07), 1 (13), 1 (19) -> [1,1,1,1],

07: 0 (02) 1 (03) 1 (04) 0 (05) -> [0,1,1,0],

08: 0 (02) 1 (04) 0 (06) 0 (08) -> [0,1,0,0],

09: 0 (02) 0 (05) 0 (08) 1 (11) -> [0,0,0,1],

10: 0 (02) 0 (06) 1 (10) 0 (14) -> [0,0,1,0],

11: 0 (02), 1 (07), 1 (12), 1 (17) -> [0,1,1,1],

12: 0 (02) 0 (08) 0 (14) 0 (20) -> [0,0,0,0],

13: 1 (03) 1 (04) 0 (05) 0 (06) -> [1,1,0,0],

14: 1 (03) 0 (05) 1 (07) 0 (09) -> [1,0,1,0],

15: 1 (03) 0 (06) 0 (09) 1 (12) -> [1,0,0,1],

16: 1 (03) 1 (07) 1 (11) 0 (15) -> [1,1,1,0],

17: 1 (03), 0 (08), 1 (13), 1 (18) -> [1,0,1,1],

18: 1 (04) 0 (05) 0 (06) 1 (07) -> [1,0,0,1],

19: 1 (04) 0 (06) 0 (08) 1 (10) -> [1,0,0,1],

20: 1 (04) 1 (07) 1 (10) 1 (13) -> [1,1,1,1],

21: 1 (04) 0 (08) 1 (12) 0 (16) -> [1,0,1,0],

22: 1 (04) 0 (09) 0 (14) 1 (19) -> [1,0,0,1],

23: 0 (05) 0 (06) 1 (07) 0 (08) -> [0,0,1,0],

24: 0 (05) 1 (07) 0 (09) 1 (11) -> [0,1,0,1],

25: 0 (05) 0 (08) 1 (11) 0 (14) -> [0,0,1,0],

26: 0 (05) 0 (09) 1 (13) 1 (17) -> [0,0,1,1],

27: 0 (05) 1 (10) 0 (15) 0 (20) -> [0,1,0,0],

28: 0 (06) 1 (07) 0 (08) 0 (09) -> [0,1,0,0],

29: 0 (06) 0 (08) 1 (10) 1 (12) -> [0,0,1,1],

30: 0 (06) 0 (09) 1 (12) 0 (15) -> [0,0,1,0],

31: 0 (06), 1 (10), 0 (14), 1 (18) -> [0,1,0,1],

32: 1 (07) 0 (08) 0 (09) 1 (10) -> [1,0,0,1],

33: 1 (07) 0 (09) 1 (11) 1 (13) -> [1,0,1,1],

34: 1 (07), 1 (10), 1 (13), 0 (16) -> [1,1,1,0],

35: 1 (07), 1 (11), 0 (15), 1 (19) -> [1,1,0,1],

36: 0 (08) 0 (09) 1 (10) 1 (11) -> [0,0,1,1],

37: 0 (08), 1 (10), 1 (12), 0 (14) -> [0,1,1,0],

38: 0 (08), 1 (11), 0 (14), 1 (17) -> [0,1,0,1],

39: 0 (08), 1 (12), 0 (16), 0 (20) -> [0,1,0,0],

40: 0 (09), 1 (10), 1 (11), 1 (12) -> [0,1,1,1],

41: 0 (09), 1 (11), 1 (13), 0 (15) -> [0,1,1,0],

42: 0 (09), 1 (12), 0 (15), 1 (18) -> [0,1,0,1],

43: 1 (10), 1 (11), 1 (12), 1 (13) -> [1,1,1,1],

44: 1 (10), 1 (12), 0 (14), 0 (16) -> [1,1,0,0],

45: 1 (10), 1 (13), 0 (16), 1 (19) -> [1,1,0,1],

46: 1 (11), 1 (12), 1 (13), 0 (14) -> [1,1,1,0],

47: 1 (11), 1 (13), 0 (15), 1 (17) -> [1,1,0,1],

48: 1 (11), 0 (14), 1 (17), 0 (20) -> [1,0,1,0],

49: 1 (12), 1 (13), 0 (14), 0 (15) -> [1,1,0,0],

50: 1 (12), 0 (14), 0 (16), 1 (18) -> [1,0,0,1],

51: 1 (13), 0 (14), 0 (15), 0 (16) -> [1,0,0,0],

52: 1 (13), 0 (15), 1 (17), 1 (19) -> [1,0,1,1],

53: 0 (14), 0 (15), 0 (16), 1 (17) -> [0,0,0,1],

54: 0 (14), 0 (16), 1 (18), 0 (20) -> [0,0,1,0],

55: 0 (15), 0 (16), 1 (17), 1 (18) -> [0,0,1,1],

56: 0 (16), 1 (17), 1 (18), 1 (19) -> [0,1,1,1],

57: 1 (17), 1 (18), 1 (19), 0 (20) -> [1,1,1,0],

y al final obtener un recuento de las veces que se repite cada patrón y su frecuencia relativa:

0 0 0 0 ------ 161.697 - 0,0606515378844711

0 0 0 1 ------ 163.593 - 0,0613627156789197

0 0 1 0 ------ 164.201 - 0,0615907726931733

0 0 1 1 ------ 166.680 - 0,0625206301575394

0 1 0 0 ------ 164.105 - 0,0615547636909227

0 1 0 1 ------ 166.501 - 0,0624534883720930

0 1 1 0 ------ 167.099 - 0,0626777944486122

0 1 1 1 ------ 168 835 - 0,0633289572393098

1 0 0 0 ------ 164.086 - 0,0615476369092273

1 0 0 1 ------ 166.963 - 0,0626267816954239

1 0 1 0 ------ 166.931 - 0,0626147786946737

1 0 1 1 ------ 169 470 - 0,0635671417854464

1 1 0 0 ------ 166.622 - 0,0624988747186797

1 1 0 1 ------ 169.326 - 0,0635131282820705

1 1 1 0 ------ 169 251 - 0,0634849962490623

1 1 1 1 ------ 170 640 - * 0,0640060015003751

Para ello intento utilizar el siguiente codigo:
Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <stdlib.h>
  4. #include <vector>
  5. #include <string>
  6.  
  7. using namespace std;
  8.  
  9. int main() {
  10. string cadena;
  11. char pr;
  12. // ofstream fo ("entreno.txt");
  13. ifstream fi("entreno.txt");
  14. int numero;
  15. int patron_int;
  16.   }
  17.  
  18. //  fo.close();
  19. getline(fi, cadena);
  20. vector<int>v(cadena.size());
  21. vector<int>patron(4);
  22. vector<long long>patrones(16);
  23. float N;
  24.  
  25. //cout << cadena;
  26. //numero = Int32.Parse(cadena[0]);
  27. //pr=cadena[0].c_str();
  28. //cout << numero;
  29. //cout << cadena[0];
  30. for(int i=0; i<cadena.size(); i++) {
  31. // if (cadena[i]=='1') v[i]=0;
  32. // else if (cadena[i]=='1') v[i]=1;
  33. v[i]=cadena[i]-48;
  34. // cout << v[i];
  35. }
  36.  
  37. for(int i=0;i<v.size()-3;i++) {
  38. for(int j=i;j<v.size()-3;j++) {
  39. patron[3]=v[i];
  40. patron[2]=v[j+1];
  41. patron[1]=v[j+2];
  42. patron[0]=v[j+3];
  43. //cout << patron[3] << patron[2] << patron[1] << patron[0] << endl;
  44. patron_int= patron[0] + patron[1]*2 + patron[2]*4 + patron[3]*8;
  45. //cout << patron_int << endl;
  46. patrones[patron_int]++;
  47. //if(i==v.size()/5) system("pause");
  48.  
  49. //system("pause");
  50. }
  51. N=(100*i)/(v.size()-3);
  52. // cout << N << "%" << endl;
  53.  
  54. }
  55.  
  56. for(int i=0; i<patrones.size(); i++) {
  57. cout << i << " se repite " << patrones[i] << " veces." << endl;
  58. }
  59. //cout << v.size();
  60. system("pause");
  61. fi.close();
  62. return 0;
  63. }
  64.  

Pero debido a que no soy un programador experto en C++, quisiera mejorarlo y modificarlo de forma que me calculara subcuerdas de 4-20.
Primero me podrías decir que debo modificar y despues os pregunto dudas para asi intentar aprender a programar en C++.
Muchas gracias


Título: Re: CREACION SUBCADENAS A PARTIR DE CADENA BINARIA
Publicado por: eferion en 31 Octubre 2013, 08:45 am
El que quiere aprender a programar en c++ no empieza con tareas de este tipo.

La impresión que da es que simplemente quieres salir del paso porque esto te urge y después si te he visto no me acuerdo.

El hecho de que no te hay acontestado nadie en casi un día entero no es porque no haya gente en el foro, sino porque piensan más o menos lo mismo que yo.


Título: Re: CREACION SUBCADENAS A PARTIR DE CADENA BINARIA
Publicado por: Vaagish en 31 Octubre 2013, 19:08 pm
Citar
getline(fi, cadena);
La secuencia de binarios esta toda en una sola linea? Los miles que tenes o están de a 20?

Si la secuencia de binarios estan agrupadas de a 20 podrias usar algo asi:
Código:
	while(!Archivo.eof()){
getline(Archivo, Cadena);
                .....
                .....
}
Bien, despues hay otro asunto, porque tu secuencia no se forma cortando la cadena solamente, sino que:
Citar
01: 1 (01) 0 (02) 1 (03) 1 (04) -> [1,0,1,1],
02: 1 (01) 1 (03) 0 (05) 1 (07) -> [1,1,0,1],
03: 1 (01) 1 (04) 1 (07) 1 (10) -> [1,1,1,1],
04: 1 (01) 0 (05) 0 (09) 1 (13) -> [1,0,0,1],
Los valores se van salteando, es esto así, verdad? De eso se encargan los "for".
Calculo que debe haber una mejor forma que pasar a enteros, para no consumir tanta ram, pero no te olvides que este tipo de cálculos, y en especial los bucles pueden consumirte toda la ram.. una opción para no trancar el programa seria meter la parte de los bucles en un nuevo thread, eso liberaría a la función principal (el main) y a lo mejor, que funcione un poco mejor..

Saludos!



Algo así te puede servir para el bucle principal, pero hay que arreglarlo, porque en cierto momento se desborda el array

Código:
while(!Archivo.eof()){
  getline(Archivo, Cadena);
    for(p=0; p<=15; p++){
      for(j=1; j<7; j++){
        for(i=p; i<=j*f; i=i+j){
          cout << Cadena[i];
        }
        cout << endl;
      }
      f = f + 1;
    }
}


Título: Re: CREACION SUBCADENAS A PARTIR DE CADENA BINARIA
Publicado por: rir3760 en 1 Noviembre 2013, 01:51 am
No es necesario utilizar la función miembro eof ya que se puede verificar directamente el estado del stream (y por ende si la lectura fue exitosa) con:
Código
  1. while (getline(Archivo, Cadena)){
  2.  
  3.   // ...
  4.  
  5. }

Y para leer cada secuencia primero se descartan los caracteres antes del primer dígito, a continuación se leen pares de caracteres donde el primero es '0' o '1' y el segundo ',' o ']' con este ultimo indicando el final de la secuencia.

Ya para terminar coincido con lo dicho por eferion: tiene toda la apariencia de ser un trabajo de clase.

Un saludo