fallo en estos ejercicios y no se por que (c++)

Gracias de antemano.

El primero es este

Me tendria que salir ANA 1 15 19 pero sin embargo me sale ANA 15 19.
No se por qué se come la primera posición.
¿Podríais por favor echarle un vistazo?

Este es el enunciado

[img]subefotos.com/ver/?1ab40103e67d06cf84148e7136109bb4o.jpg[/img]

y este mi codigo

#include <iostream>
using namespace std;
const unsigned MAX_PAL_DIST=20;
const unsigned MAX_REP=20;
typedef int TArrayPosiciones[MAX_REP];

struct TPalabra{
unsigned numpos;
string palabra;
TArrayPosiciones arrpos;
};

typedef TPalabra TArrayPalabras[MAX_PAL_DIST];

struct TVector{
unsigned numelem;
TArrayPalabras arrpal;
};

bool esPalindromo(const string& palabra){
   string aux="", aux2="";
for(unsigned cont=0; cont<palabra.size();cont++){
   aux+=palabra[cont];
}
for(int cont=palabra.size()-1; cont>=0;cont--){
   aux2+=palabra[cont];
}
return aux==aux2&&aux.size()>1;
}

bool primeraVez(const string& palabra, const TVector& vect){
bool laprimera=true;
int cont=0;
while(laprimera&&cont<vect.numelem){
   if(vect.arrpal[cont].palabra==palabra){
       laprimera=false;
   }
   ++cont;
}
return laprimera;
}

int buscaPalabra(const string& palabra, const TVector& vect){
int cont=0;
while(vect.arrpal[cont].palabra!=palabra){
   ++cont;
}
return cont;
}

void muestraPalabra(int pos, const TVector& vect){
cout<<vect.arrpal[pos].palabra<<" ";
for(unsigned cont=0;cont<vect.arrpal[pos].numpos;cont++){
   cout<<vect.arrpal[pos].arrpos[cont]<<" ";
}
}

void mostrarVector(const TVector& vect){
for(unsigned cont=0;cont<vect.numelem;cont++){
   muestraPalabra(cont, vect);
   cout<<endl;
}
}

int main(){
string palabra;
int cont=0;
TVector vect;
vect.numelem=0;
cout<<"Introduzca su texto (FIN para terminar)"<<endl;
cin>>palabra;
++cont;
while(palabra!="FIN"&&cont<MAX_PAL_DIST){
   if(esPalindromo(palabra)){
       if(primeraVez(palabra, vect)){
           vect.arrpal[vect.numelem].numpos=0;
           vect.arrpal[vect.numelem].palabra=palabra;
           vect.arrpal[vect.numelem].arrpos[0]=cont;
           ++vect.numelem;
           ++vect.arrpal[vect.numelem].numpos;
       }else{
           int pos=buscaPalabra(palabra, vect);
           vect.arrpal[pos].arrpos[vect.arrpal[pos].numpos]=cont;
           ++vect.arrpal[pos].numpos;
       }
   }
   ++cont;
   cin>>palabra;
}
mostrarVector(vect);
}


Y el segundo este

Imagen

con mi codigo intentado

#include <iostream>
using namespace std;
const unsigned MAX=5;
const unsigned MAX_REP=4;
const unsigned MAXNUMEROS=20;
typedef unsigned TPosiciones[MAX_REP];
typedef int TArrayNumeros[MAXNUMEROS];
struct TNumero{
    unsigned num;
    TPosiciones pos;
    unsigned ocupa;
};
typedef TNumero TSecuencia[MAX];

struct TNumeros{
TSecuencia numeros;
unsigned tam;
};

struct TNumerosAux{
unsigned numelem;
TArrayNumeros arrnum;
};

bool esta(int numero, const TNumeros& vect){
bool encontrado=false;
int cont=0;
while(cont<vect.tam&&!encontrado){
    if(vect.numeros[cont].num==numero){
        encontrado=true;
    }
    ++cont;
}
return encontrado;
}

int buscaPos(int numero, const TNumeros& vect){
int cont=0;
while(vect.numeros[cont].num!=numero){
    ++cont;
}
return cont;
}

int buscaYtacha(TNumerosAux& tachados, const TNumeros& vect){
int cont=0;
while(tachados.arrnum[cont]==-1){
    ++cont;
}
int mayor=cont;
for(unsigned cont2=0;cont2<vect.tam;cont2++){
    if((vect.numeros[cont2].num>vect.numeros[mayor].num)&&(tachados.arrnum[cont2]!=-1)){
        mayor=cont2;
    }
}
tachados.arrnum[mayor]=-1;
return mayor;
}

void inicializa(TNumerosAux& tachados){
for(unsigned cont=0;cont<tachados.numelem;cont++){
    tachados.arrnum[cont]=0;
}
}

void muestra(int posicion, const TNumeros& vect){
cout<<vect.numeros[posicion].num<<": ";
for(unsigned cont=0;cont<vect.numeros[posicion].ocupa;cont++){
        cout<<vect.numeros[posicion].pos[cont]<<" ";
}
}

void analizaMayores(int m, const TNumeros& vect){
TNumerosAux tachados;
tachados.numelem=vect.tam;
inicializa(tachados);
for(unsigned cont=0;cont<m;cont++){
    muestra(buscaYtacha(tachados, vect), vect);
    cout<<endl;
}
}

int main(){
int m, numero, cont=0;
TNumeros vect;
vect.tam=0;
do{
    cout<<"Introduzca un numero natural menor que 30"<<endl;
    cin>>m;
}while(m<=0||m>30);
cout<<"Introduzca una secuencia de numeros acabada en 0"<<endl;
cin>>numero;
while(numero!=0){
        if(!esta(numero , vect)){
    vect.numeros[vect.tam].ocupa=0;
    vect.numeros[vect.tam].num=numero;
    vect.numeros[vect.tam].pos[0]=cont;
    ++vect.tam;
    ++vect.numeros[vect.tam].ocupa;
        }else{
            int posi= buscaPos(numero, vect);
            vect.numeros[posi].pos[vect.numeros[posi].ocupa]=cont;
            ++vect.numeros[posi].ocupa;
        }
        ++cont;
        cin>>numero;
}
analizaMayores(m, vect);
}


En este directamente es que no me salen los 5 numeros mayores
debug mode con breakpoints es tu amigo.

Su puedo sugerir algo, olvida ese código y empieza de cero. Simplifica...
Pegarle un vistazo a la nomenclatura estaría bien también, pero bueno, no es lo importante en este caso.
Vamos a ver si te puedo echar un cable, que hay algo que no me cuadra.

Si te fijas, te falla en la primera palabra de la lista ANA. Tu haces y míralo como que es la primera palabra que añades y en el comentario te señalo el error que veo:

if(primeraVez(palabra, vect)){
           vect.arrpal[vect.numelem].numpos=0;
           vect.arrpal[vect.numelem].palabra=palabra;
           vect.arrpal[vect.numelem].arrpos[0]=cont;
           ++vect.numelem;
           ++vect.arrpal[vect.numelem].numpos; /* ¿por qué incrementas la posición del siguiente elemento de lista si esa palabra no ha sido añadida aun? .
Esto debió hacerse antes de ++vect.numelem, para corregir lo que te pasa después, si no me he perdido */


Bien, ahora supongamos que estamos en la segunda palabra ANA, con lo cual nos vamos a la else y nos encontramos:

       }else{
           int pos=buscaPalabra(palabra, vect);
           vect.arrpal[pos].arrpos[vect.arrpal[pos].numpos]=cont;
           ++vect.arrpal[pos].numpos;
       }


Veamos, cuando añadimos la palabra ANA, vec.numelem era = 0 es decir que lo que hicimos al encontrar la palabra la primera vez, fue:

vect.arrpal[0].numpos=0;
vect.arrpal[0].palabra=palabra;
vect.arrpal[0].arrpos[0]=cont; // cont = 1 por que se encontró en la primera posición

La segunda vez, buscaPalabra() nos dirá que ANA se encuentra en pos = 0, ¿verdad?. Luego:

vect.arrpal[0].arrpos[vect.arrpal[0].numpos]=cont;
++vect.arrpal[0].numpos;

¿me sigues hasta aquí?

Porque si te fijas, vect.arrpal[0].numpos == 0 que es el valor que asignaste al añadir la palabra ANA la primera vez y por tanto:

vect.arrpal[0].arrpos[0]=cont; // cont ahora es 15

sobreescribe la primera entrada, la que añadiste.

Como ahora haces un ++vect.arrpal[0].numpos;, ahora almacena 1 por lo que la siguiente vez, ahora si, se almacena la posición 19 sin sobreescribir.

vect.arrpal[0].arrpos[1]=cont; // cont ahora es 19

Si al añadir la palabra, hubiera hecho:

vect.arrpal[vect.numelem].numpos=1;

te habría funcionado bien esto, sin necesidad de un incremento superfluo
Muchas gracias ya conseguí el primero.
Pero el segundo me da el siguiente error a pesar de haber corregido el mismo error que había cometido en el primer ejercicio, en el segundo.
no solo no me da los 5 mayores (al meter m = 5 ) sino que me da "stack smashing detected"
Hola, perdona pero no he podido mirar el segundo ejercicio por que ando muy liado esta semana y además, tendría que revisar y analizar el código de cabeza (en mi PC/Tablet no tengo nada para programar) y llevo muuucho tiempo sin programar (y menos en C++ [+risas] ) . Tampoco se veía la imagen, pero seguro que es alguna tontería, pero como a mi me gustaba decir cuando programaba, en realidad los programadores no sabemos programar y vamos progresando por los fallos que cometemos al programar, al corregirlos. Si no has tropezado un millón de veces, es que no sabes programar [carcajad] (siempre es bueno usar alguna cosa que nos ayude a depurar, como rutinas que generen logs cuando estamos perdidos). Pero lo mas importante, es que tu mismo encuentres los fallos, porque eso te hace aprender mucho (y los fallos te ayudarán a que controles la forma de construir tu código para evitar despistes, etc). Saludos
Cuál es el código que te falla, el segundo? Resúbelo (por si has hecho algun cambio respecto al primer post, y supongo que si ya que dices que ahora te da un "stack smash error".

Y comenta los códigos siempre que hagas algo cawento (no lo digo a malas de todas formas xD)

EDIT: De todas formas veo que en el ejercicio se te pide introducir un número ilimitado de palabras. Y tu estás definiendo tus variables en el stack asi que es probable que estés usando demasiada memoria (el stack es limitado!). Mejor pasa los arrays al heap.
Ya consegui hacer el segundo pero ahora fallo en este.
Me da que el numero de ocurrencias es cero y por mas que miro el codigo no se por que

https://ibb.co/kjrubk

#include <iostream>
using namespace std;
const unsigned TAM1=11;
const unsigned TAM2=4;
typedef unsigned TNumeros[TAM1];
typedef unsigned TPermutacion[TAM2];
typedef bool TTachados[TAM2];

void inicializa(TTachados& tachados){
for(unsigned cont=0;cont<TAM2;cont++){
    tachados[cont]=false;
}
}

bool esta(int num, const TPermutacion& permutacion, const TTachados& tachados){
bool encontrado=false;
int cont=0;
while(cont<TAM2&&!encontrado){
    if(permutacion[cont]==num&&tachados[cont]==false){
        encontrado=true;
    }
    ++cont;
}
return encontrado;
}

bool todosTachados(const TTachados& tachados){
bool loestan=true;
int cont=0;
while(loestan&&cont<TAM2){
    if(tachados[cont]!=true){
        loestan=false;
    }
    ++cont;
}
return loestan;
}

bool esOcurrencia(int pos, const TNumeros& numeros,const TPermutacion& permutacion, TTachados& tachados){
for(int cont=pos;cont<TAM2+pos;cont++){
    if(esta(numeros[cont], permutacion, tachados)){
        tachados[cont-pos]=true;
    }
}
return todosTachados(tachados);
}

unsigned numOcurrencias(const TNumeros& numeros, const TPermutacion& permutacion){
TTachados arrtachados;
int suma=0, cont=0;
inicializa(arrtachados);
while(cont+TAM2<=TAM1){
    if(esOcurrencia(cont, numeros, permutacion, arrtachados)){
        ++suma;
    }
    inicializa(arrtachados);
    ++cont;
}
return suma;
}

void leeNumeros(TNumeros& arrnum){
for(unsigned cont=0;cont<TAM1;cont++){
    cin>>arrnum[cont];
}
}

void leePermutacion(TPermutacion& arrper){
for(unsigned cont=0;cont<TAM2;cont++){
    cin>>arrper[cont];
}
}

int main(){
TNumeros arrnum;
TPermutacion arrper;
cout<<"Introduzca los numeros"<<endl;
leeNumeros(arrnum);
cout<<"Introduzca la permutacion"<<endl;
leePermutacion(arrper);
cout<<"El numero de ocurrencias es de "<<numOcurrencias(arrnum, arrper);
}
Stackoverflow es el sitio adecuado para esto.
@MistGun te he hecho caso y he preguntado alli pero como son tas estrictos a la hora de formular las preguntas me han dejado un dia sin poder preguntar.
Así que aprovecho para preguntar un enunciado a ver si alguien me puede decir como hago el puñetero cuadrado magico por que aunque he visto una web en la que lo explican sigo sin ver como saca los numeritos.

Imagen
8 respuestas