¡Secretitos en reunión es de mala educación!.
¿Vamos como activas/descargas el dichosito plugin?
¿Vamos como activas/descargas el dichosito plugin?
¡¡¡¡ Saluditos! ..... !!!!
este es el codigo completo
el error se presenta al entrar en la segunda funcion denominada shannon-fano
Echando un vistazo rápido al código, veo un desbordamiento aquí:Código:
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <vector>
using namespace std;
////////////
struct datos
{
std::vector<float> simbolos;
std::vector<float> frecuencias;
int tamanodic;
}cd1;
/////////////////////declaracion de funciones
datos histograma(vector<float> &traza);
void shannonfano(datos &vida);
int main()
{
FILE *archivo;
char caracter;
std::vector<float> ayudante;
std::vector<float> traza;
float ayuda;
char numPtr[1];
float por=5;
archivo = fopen("D:\\entrada10.txt","r");
if (archivo == NULL){
printf("\nError de apertura del archivo. \n\n");
}else{
printf("\nEl contenido del archivo de prueba es \n\n");
while (feof(archivo) == 0)
{
caracter = fgetc(archivo);
numPtr[1]=caracter;
ayuda=float(numPtr[1]-48);
int kk=0;
ayudante.push_back(ayuda);
////////////////////////////////// aqui empezamos a tranformar
if (ayuda==-38)
{
if (ayudante[0]==-3)/////saber si es negativo
{ kk=1;
ayudante.erase (ayudante.begin());
}//////////
ayudante.pop_back();
int i=0;
float suma=0;
int cifras=0;/////dice cuantas cifras enteras tiene
while (i<ayudante.size()) ///////saber cuantas cifras enteras tiene
{ if(ayudante[i]==-2)//contador de cifras enteras
{cifras=i;
i=ayudante.size();
}
else
{i++;
cifras=i;
}
;
} //////////termina while
int ii=0;
int cifraaux=cifras;
float aux=0;
int k=0;
while (cifras>1)/////parte entera
{aux=ayudante[ii];
k=cifras;
while (k>1) ///////multiplicaciones parte entera
{aux=aux*10;
k--;
}
cifras--;
ii++;
suma=suma+aux;
}
suma=suma+ayudante[ii];
int deci=ayudante.size()-cifraaux-1;
ii=ayudante.size()-1;
while (deci>0)////parte decimal
{aux=ayudante[ii];
k=deci;
while(k>0)///haciendo decimales
{aux=aux/10;
k--;
}
deci--;
ii--;
suma=suma+aux;
}
if (kk==1)/////////signo negativo
{traza.push_back(suma*-1);
}
else
{traza.push_back(suma);
}
ayudante.clear();
}
//////////////////////////////////termina transformacion
}
}
fclose(archivo);
/////////////////////FUNCIONES%%%%%%%%%%%%%
histograma (traza);
cout<<"\n="<<cd1.tamanodic;
shannonfano(cd1);
getch();
}
//////////funcion HISTOGRAMA
////////%%%%%%%%%%&&&&&&&&&&&
datos histograma(vector<float> &traza)
{
//cargamos el primer valor
int contfre=0;
cd1.simbolos.push_back(traza[0]);
for (int ii=0;ii<traza.size();ii++)
{if (traza[ii]==traza[0])
{contfre++;}
}
cd1.frecuencias.push_back(contfre);
for (int i=1;i<traza.size();i++)
{int cont=0;
int contfre=0;
for (int ii=0;ii<cd1.simbolos.size();ii++)
{if (traza[i]==cd1.simbolos[ii])
{cont++;
break;}
}
if (cont==0)
{cd1.simbolos.push_back(traza[i]);
for (int ii=i;ii<traza.size();ii++)
{if (traza[ii]==traza[i])
{contfre++;}
}
cd1.frecuencias.push_back(contfre);
}
}
cd1.tamanodic=cd1.simbolos.size();
for(int ii=0;ii<cd1.simbolos.size();ii++)
{cout<<"\n simbolos["<<ii<<"]="<<cd1.simbolos[ii];
cout<<"\n frecuencias["<<ii<<"]="<<cd1.frecuencias[ii];}
float sumama=0;
for(int ii=0;ii<cd1.simbolos.size();ii++)
{sumama=sumama+cd1.frecuencias[ii];}
cout<<"\n sumama="<<sumama;
return cd1;
}
///////////FUNCION SHANNON_FANO
///////////////////////////&&&&&&&&&&&&%%%%%%%%%%%%%%%
void shannonfano(datos &vida)
{
std::vector<float> ayudante;//copia de los simbolos
//%%%%%%%%%%%%
int pp=vida.tamanodic;
float masayuda=0;
for (int i=0;i<pp;i++)
{ masayuda=vida.simbolos[i];
ayudante.push_back(masayuda);//
}
//%%%%%%%%%%
bool dic[vida.tamanodic][20];//dic=diccionario
for (int i=0;i<pp;i++)
{for(int ii=0;ii<20;ii++)
dic[i][ii]=0;
}
std::vector<int> numb;//numero de bits a tomar para la codificacion permite saber cuantos bits debo tomar para cada simbolo
std::vector<int> fin;// nos dice cual fue el simbolo que salio
int nci=0;
int contafin=0;//se guardara en fin
int numcol=0;//numero de columna en dic
int numfil=0;//numero de fila en dic
//%%%%%%%%%%%%%%%
std::vector<float> sfin; //las frecuencias pasan a este vector cuando ya se obtiene el codigo para el respectivo simbolo
std::vector<float> xfin;//el simbolo pasa a este vector cuando ya tiene un codigo asignado
int contaite=0;//numero de iteraciones, se guarda en numb
//%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%
float temp;
float temp2;
//metodo burbuja en caso de que sea necesario ordenar
for (int i=0;i<pp;i++)
{
for (int j=i;j<pp;j++)
{
if (vida.frecuencias[i]<vida.frecuencias[j])
{
temp=vida.frecuencias[i];
temp2=vida.simbolos[i];
vida.frecuencias[i]=vida.frecuencias[j];
vida.simbolos[i]=vida.simbolos[j];
vida.frecuencias[j]=temp;
vida.simbolos[j]=temp2;
}
}
}
for(int ii=0;ii<100;ii++)
{cout<<"\n simbolos["<<ii<<"]="<<vida.simbolos[ii];
cout<<"\n frecuencias["<<ii<<"]="<<vida.frecuencias[ii];}
// aqui termina el ordenamiento de frecuencias y simbolos
float sum=0;
for (int i=0;i<vida.frecuencias.size();i++)
{sum=sum+vida.frecuencias[i];
}
cout<<"\n suma="<<sum;
// empezamos con el arbol
int z=1;
std::vector<float> c; //guarda la suma de frecuencias
std::vector<int> cc;//guarda cuantos simbolos suman cada frecuencia
c.push_back(sum);
cout<<"\n c[0]="<<c[0];
cc.push_back(vida.frecuencias.size());
cout<<"\n cc[0]="<<cc[0];
std::vector<float> d;
cout<<"\n maximo tamaño"<<d.max_size();
std::vector<int> dd;
//la idea del programa es ir observando los datos en c, para ir armando d,
//al finalizar el ciclo d se guarda en c y vuelve a empezar
int pa=0;
int XXX=0;
int compa=1;
int kkkkk=c.size();
for (;;)// ciclo para cambiar de celda
{
if (vida.frecuencias.empty())//el programa finaliza cuando el vector frecuencias esta vacio, osea q todos los simbolos ya tienen
//su respectivo codigo
{break;}
if (XXX>0) //para q copie d en c despues de la primera iteración
{
int kkkkk=d.size();
cout<<"\n kkk="<<kkkkk;
c.clear();
cc.clear();
for (int i=0;i<kkkkk;i++)
{ c.push_back(d[i]); //copio d en c
cc[i]=dd[i];// copio dd en cc
}
} int kkkkk=d.size();
XXX++;
d.clear();
dd.clear();
int t=0;
int v=0;
int w=0;
int u=0;
for (;;)//en este ciclo se cambia de columna en el vector c
{
float tem=c[w];
u=0;
if (cc[w]>1)//necesitamos mas de un simbolo para dividir el valor guardado en c[w]
{float sumpar=0;
while (sumpar<=tem/2)//operacion principal de shannon-fano, ir dividiendo en la mitad las frecuencias
{sumpar=sumpar+vida.frecuencias[v];
u=u+1;
v=v+1;
}
if (u>1) //quito una para q qde siempre por debajo de la mitad o en la mitad
{
sumpar=sumpar-vida.frecuencias[v-1];
u=u-1;
}
d.push_back(sumpar);
dd.push_back(u);
d.push_back(c[w]-d[t]);
dd.push_back(cc[w]-dd[t]);
v=0;
for (int i=0;i<d.size();i++)
{v=v+dd[i];
}
t=t+2;
w=w+1;
if (w+1>kkkkk)
{
break;
}
}// termina if para armar d
else {w=w+1;}
}//termina for para armar d
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// armamos los codigos %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
numfil=0;
for (int au=0;au<dd.size();au++)
{ nci=dd[au];
int p=0;
int pop=1;
int qre=1;
//cout<<"\n numfil="<<numfil;
while (p<nci)
{ while (pop<=fin.size())//buscamos los simbolos que ya tienen un codigo, para no poner bits en sus codigos
{ if (numfil==fin[pop-1])
{cout<<"\n no entre a fila="<<numfil;
numfil++;
pop=1;
}
else
{pop++;
}
qre++;
}
int rem=au%2;//miramos si la posicion es par o impar, asi sabemos si debemos poner 0 o 1
if (rem==0)
{
//cout<<"\n numfil="<<numfil;
dic[numfil][numcol]=0;
}
else
{
dic[numfil][numcol]=1;
}
numfil++;
p++;
}
}
numcol++;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//armando vectores finales
float pot=0;//para sfin
float potx=0;//para xfin
int knk=dd.size();
int gigo=0;
int sumita=0;
contaite++;
for (int i=0;i<knk;i++)//en esta parte eliminamos los simbolos que ya tienen un codigo, y los copiamos en xfin, al igual
// su respectiva frecuencia se copia en sfin
{ if (dd[gigo]==1)
{if (gigo==0)
{pot=vida.frecuencias[0];
potx=vida.simbolos[0];
sfin.push_back(pot);
xfin.push_back(potx);
vida.simbolos.erase (vida.simbolos.begin());
vida.frecuencias.erase (vida.frecuencias.begin());
dd.erase (dd.begin());
d.erase(d.begin());
int ayuda=0;
while (ayudante[ayuda]!=potx)//busca la posicion en la que se encuentra el simbolo a sacar
{ayuda++;
}
numb.push_back(contaite);
fin.push_back(ayuda);//fin nos dice las filas de dic a las cuales no les debemos poner mas bits
}
else
{
sumita=0;
for (int i=0;i<gigo;i++)
{sumita=sumita+dd[i];
}
pot=vida.frecuencias[sumita];
potx=vida.simbolos[sumita];
sfin.push_back(pot);
xfin.push_back(potx);
vida.simbolos.erase (vida.simbolos.begin()+sumita);
vida.frecuencias.erase (vida.frecuencias.begin()+sumita);
dd.erase (dd.begin()+gigo);
d.erase(d.begin()+gigo);
numb.push_back(contaite);//numb nos dice el numero de bits que tiene cada codigo
int ayuda=0;
while (ayudante[ayuda]!=potx)
{ayuda++;
}
fin.push_back(ayuda);
}
}
else {gigo++;}
}
for(int ii=0;ii<xfin.size();ii++)
{cout<<"\n xfin["<<ii<<"]="<<xfin[ii];}
for(int ii=0;ii<xfin.size();ii++)
{cout<<"\n numb["<<ii<<"]="<<numb[ii];}
}
int funca=0;
}
Código
Si ayudante[0] es igual a -3, borrará 2 elementos del vector. Pero ayudante en ese momento tendrá un solo elemento *_*
while (feof(archivo) == 0) { caracter = fgetc(archivo); numPtr[1]=caracter; ayuda=float(numPtr[1]-48); int kk=0; ayudante.push_back(ayuda); ////////////////////////////////// aqui empezamos a tranformar if (ayuda==-38) { if (ayudante[0]==-3)/////saber si es negativo { kk=1; ayudante.erase (ayudante.begin()); }////////// ayudante.pop_back();
Tú código es identado:
Código
#include <stdio.h> #include <conio.h> #include <iostream> #include <vector> using namespace std; //////////// struct datos { std::vector<float> simbolos; std::vector<float> frecuencias; int tamanodic; } cd1; /////////////////////declaracion de funciones datos histograma(vector<float> &traza); void shannonfano(datos &vida); int main() { FILE *archivo; char caracter; std::vector<float> ayudante; std::vector<float> traza; float ayuda; char numPtr[1]; float por=5; archivo = fopen("D:\\entrada10.txt","r"); if (archivo == NULL) { printf("\nError de apertura del archivo. \n\n"); } else { printf("\nEl contenido del archivo de prueba es \n\n"); while (feof(archivo) == 0) { caracter = fgetc(archivo); numPtr[1]=caracter; ayuda=float(numPtr[1]-48); int kk=0; ayudante.push_back(ayuda); ////////////////////////////////// aqui empezamos a tranformar if (ayuda==-38) { if (ayudante[0]==-3)/////saber si es negativo { kk=1; ayudante.erase (ayudante.begin()); }////////// ayudante.pop_back(); int i=0; float suma=0; int cifras=0;/////dice cuantas cifras enteras tiene while (i<ayudante.size()) ///////saber cuantas cifras enteras tiene { if(ayudante[i]==-2)//contador de cifras enteras { cifras=i; i=ayudante.size(); } else { i++; cifras=i; } ; } //////////termina while int ii=0; int cifraaux=cifras; float aux=0; int k=0; while (cifras>1)/////parte entera { aux=ayudante[ii]; k=cifras; while (k>1) ///////multiplicaciones parte entera { aux=aux*10; k--; } cifras--; ii++; suma=suma+aux; } suma=suma+ayudante[ii]; int deci=ayudante.size()-cifraaux-1; ii=ayudante.size()-1; while (deci>0)////parte decimal { aux=ayudante[ii]; k=deci; while(k>0)///haciendo decimales { aux=aux/10; k--; } deci--; ii--; suma=suma+aux; } if (kk==1)/////////signo negativo { traza.push_back(suma*-1); } else { traza.push_back(suma); } ayudante.clear(); } //////////////////////////////////termina transformacion } } fclose(archivo); /////////////////////FUNCIONES%%%%%%%%%%%%% histograma (traza); cout<<"\n="<<cd1.tamanodic; shannonfano(cd1); getch(); } //////////funcion HISTOGRAMA ////////%%%%%%%%%%&&&&&&&&&&& datos histograma(vector<float> &traza) { //cargamos el primer valor int contfre=0; cd1.simbolos.push_back(traza[0]); for (int ii=0; ii<traza.size(); ii++) { if (traza[ii]==traza[0]) { contfre++; } } cd1.frecuencias.push_back(contfre); for (int i=1; i<traza.size(); i++) { int cont=0; int contfre=0; for (int ii=0; ii<cd1.simbolos.size(); ii++) { if (traza[i]==cd1.simbolos[ii]) { cont++; break; } } if (cont==0) { cd1.simbolos.push_back(traza[i]); for (int ii=i; ii<traza.size(); ii++) { if (traza[ii]==traza[i]) { contfre++; } } cd1.frecuencias.push_back(contfre); } } cd1.tamanodic=cd1.simbolos.size(); for(int ii=0; ii<cd1.simbolos.size(); ii++) { cout<<"\n simbolos["<<ii<<"]="<<cd1.simbolos[ii]; cout<<"\n frecuencias["<<ii<<"]="<<cd1.frecuencias[ii]; } float sumama=0; for(int ii=0; ii<cd1.simbolos.size(); ii++) { sumama=sumama+cd1.frecuencias[ii]; } cout<<"\n sumama="<<sumama; return cd1; } ///////////FUNCION SHANNON_FANO ///////////////////////////&&&&&&&&&&&&%%%%%%%%%%%%%%% void shannonfano(datos &vida) { std::vector<float> ayudante;//copia de los simbolos //%%%%%%%%%%%% int pp=vida.tamanodic; float masayuda=0; for (int i=0; i<pp; i++) { masayuda=vida.simbolos[i]; ayudante.push_back(masayuda);// } //%%%%%%%%%% bool dic[vida.tamanodic][20];//dic=diccionario for (int i=0; i<pp; i++) { for(int ii=0; ii<20; ii++) dic[i][ii]=0; } std::vector<int> numb;//numero de bits a tomar para la codificacion permite saber cuantos bits debo tomar para cada simbolo std::vector<int> fin;// nos dice cual fue el simbolo que salio int nci=0; int contafin=0;//se guardara en fin int numcol=0;//numero de columna en dic int numfil=0;//numero de fila en dic //%%%%%%%%%%%%%%% std::vector<float> sfin; //las frecuencias pasan a este vector cuando ya se obtiene el codigo para el respectivo simbolo std::vector<float> xfin;//el simbolo pasa a este vector cuando ya tiene un codigo asignado int contaite=0;//numero de iteraciones, se guarda en numb //%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%% float temp; float temp2; //metodo burbuja en caso de que sea necesario ordenar for (int i=0; i<pp; i++) { for (int j=i; j<pp; j++) { if (vida.frecuencias[i]<vida.frecuencias[j]) { temp=vida.frecuencias[i]; temp2=vida.simbolos[i]; vida.frecuencias[i]=vida.frecuencias[j]; vida.simbolos[i]=vida.simbolos[j]; vida.frecuencias[j]=temp; vida.simbolos[j]=temp2; } } } for(int ii=0; ii<100; ii++) { cout<<"\n simbolos["<<ii<<"]="<<vida.simbolos[ii]; cout<<"\n frecuencias["<<ii<<"]="<<vida.frecuencias[ii]; } // aqui termina el ordenamiento de frecuencias y simbolos float sum=0; for (int i=0; i<vida.frecuencias.size(); i++) { sum=sum+vida.frecuencias[i]; } cout<<"\n suma="<<sum; // empezamos con el arbol int z=1; std::vector<float> c; //guarda la suma de frecuencias std::vector<int> cc;//guarda cuantos simbolos suman cada frecuencia c.push_back(sum); cout<<"\n c[0]="<<c[0]; cc.push_back(vida.frecuencias.size()); cout<<"\n cc[0]="<<cc[0]; std::vector<float> d; cout<<"\n maximo tamaño"<<d.max_size(); std::vector<int> dd; //la idea del programa es ir observando los datos en c, para ir armando d, //al finalizar el ciclo d se guarda en c y vuelve a empezar int pa=0; int XXX=0; int compa=1; int kkkkk=c.size(); for (;;)// ciclo para cambiar de celda { if (vida.frecuencias.empty())//el programa finaliza cuando el vector frecuencias esta vacio, osea q todos los simbolos ya tienen //su respectivo codigo { break; } if (XXX>0) //para q copie d en c despues de la primera iteración { int kkkkk=d.size(); cout<<"\n kkk="<<kkkkk; c.clear(); cc.clear(); for (int i=0; i<kkkkk; i++) { c.push_back(d[i]); //copio d en c cc[i]=dd[i];// copio dd en cc } } int kkkkk=d.size(); XXX++; d.clear(); dd.clear(); int t=0; int v=0; int w=0; int u=0; for (;;)//en este ciclo se cambia de columna en el vector c { float tem=c[w]; u=0; if (cc[w]>1)//necesitamos mas de un simbolo para dividir el valor guardado en c[w] { float sumpar=0; while (sumpar<=tem/2)//operacion principal de shannon-fano, ir dividiendo en la mitad las frecuencias { sumpar=sumpar+vida.frecuencias[v]; u=u+1; v=v+1; } if (u>1) //quito una para q qde siempre por debajo de la mitad o en la mitad { sumpar=sumpar-vida.frecuencias[v-1]; u=u-1; } d.push_back(sumpar); dd.push_back(u); d.push_back(c[w]-d[t]); dd.push_back(cc[w]-dd[t]); v=0; for (int i=0; i<d.size(); i++) { v=v+dd[i]; } t=t+2; w=w+1; if (w+1>kkkkk) { break; } }// termina if para armar d else { w=w+1; } }//termina for para armar d //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // armamos los codigos %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% numfil=0; for (int au=0; au<dd.size(); au++) { nci=dd[au]; int p=0; int pop=1; int qre=1; //cout<<"\n numfil="<<numfil; while (p<nci) { while (pop<=fin.size())//buscamos los simbolos que ya tienen un codigo, para no poner bits en sus codigos { if (numfil==fin[pop-1]) { cout<<"\n no entre a fila="<<numfil; numfil++; pop=1; } else { pop++; } qre++; } int rem=au%2;//miramos si la posicion es par o impar, asi sabemos si debemos poner 0 o 1 if (rem==0) { //cout<<"\n numfil="<<numfil; dic[numfil][numcol]=0; } else { dic[numfil][numcol]=1; } numfil++; p++; } } numcol++; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //armando vectores finales float pot=0;//para sfin float potx=0;//para xfin int knk=dd.size(); int gigo=0; int sumita=0; contaite++; for (int i=0; i<knk; i++) //en esta parte eliminamos los simbolos que ya tienen un codigo, y los copiamos en xfin, al igual // su respectiva frecuencia se copia en sfin { if (dd[gigo]==1) { if (gigo==0) { pot=vida.frecuencias[0]; potx=vida.simbolos[0]; sfin.push_back(pot); xfin.push_back(potx); vida.simbolos.erase (vida.simbolos.begin()); vida.frecuencias.erase (vida.frecuencias.begin()); dd.erase (dd.begin()); d.erase(d.begin()); int ayuda=0; while (ayudante[ayuda]!=potx)//busca la posicion en la que se encuentra el simbolo a sacar { ayuda++; } numb.push_back(contaite); fin.push_back(ayuda);//fin nos dice las filas de dic a las cuales no les debemos poner mas bits } else { sumita=0; for (int i=0; i<gigo; i++) { sumita=sumita+dd[i]; } pot=vida.frecuencias[sumita]; potx=vida.simbolos[sumita]; sfin.push_back(pot); xfin.push_back(potx); vida.simbolos.erase (vida.simbolos.begin()+sumita); vida.frecuencias.erase (vida.frecuencias.begin()+sumita); dd.erase (dd.begin()+gigo); d.erase(d.begin()+gigo); numb.push_back(contaite);//numb nos dice el numero de bits que tiene cada codigo int ayuda=0; while (ayudante[ayuda]!=potx) { ayuda++; } fin.push_back(ayuda); } } else { gigo++; } } for(int ii=0; ii<xfin.size(); ii++) { cout<<"\n xfin["<<ii<<"]="<<xfin[ii]; } for(int ii=0; ii<xfin.size(); ii++) { cout<<"\n numb["<<ii<<"]="<<numb[ii]; } } int funca=0; }
Es muy díficil de depurar estre código. El código no se ve muy claro lo que te hace dudar que el error esté en cualquier parte.
Primera regla, los nombres de variable deben ser claros y deben diferenciarse entre sí. Es absurdo nombres así:
Código
int kkkkk=c.size();
Código
int kkkkk=d.size();
Pones una k de menos y ya tienes dos variables distintas en distinto contexto. Preparate para los bugs "extraños".
Segunda regla, el usar funciones de más no es una mala práctica. De hecho para separar visualmente distintas subtareas del código, así es más fácil saber lo que hace cada cosa.