Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: aleaProg en 8 Mayo 2015, 06:19 am



Título: Borrar números repetidos en vector
Publicado por: aleaProg en 8 Mayo 2015, 06:19 am
Hola chicos soy nuevo en esto de la programación, me dejaron un ejercicio pero la verdad no he dado como hacerlo, el ejercicio es utilizando un vector, hacer la función para llenarlo, imprimirlo, contarlo, borrar los números repetidos y volver a imprimir sin los duplicados, ya hice la función de llenado e imprimir, la de contar no se porque no me retorna el valor aunque si funciona, con la que definitivamente no he podido ha sido la de borrar los duplicados, aquí les dejo mi código para que porfa me ayuden gracias.

Código:
#include <iostream>
#include <vector>

using namespace std;
void vecLlenar(vector<int>&vecNumeros);
void vecImprimir(vector<int>&vecNumeros);
int vecContar(vector<int>&vecNumeros);

void vecBorrar(vector<int>&vecNumeros);


int main(int argc, char** argv)
{
vector<int>vecNumeros;

vecLlenar(vecNumeros);
vecImprimir(vecNumeros);
vecContar(vecNumeros);

vecBorrar(vecNumeros);
cout<<"\nNumeros sin repetir"<<endl;
vecImprimir(vecNumeros);

return 0;
}
void vecLlenar(vector<int>&vecNumeros)
{
int resp;
int numeroTem;
do{
cout<<"\nDigite un numero: ";
cin>>numeroTem;

vecNumeros.push_back(numeroTem);

cout<<"Digite 1 para continuar 2 para salir: ";
cin>>resp;

}while(resp==1);
}

void vecImprimir(vector<int>&vecNumeros)
{
int i;
for(i=0; i<vecNumeros.size(); i++)
{
cout<<"\nNumero No. "<<i+1<<": ";
cout<<vecNumeros.at(i)<<endl;
}

}
int vecContar(vector<int>&vecNumeros)
{
int i;
int suma=0;
for(i=0; i<vecNumeros.size(); i++)
{
suma++;
}

return suma;
}

void vecBorrar(vector<int>&vecNumeros)
{
int i, x, pos;
pos=vecContar(vecNumeros);


for(i=0; i<pos; i++)
{
for(x=1; x<pos; x++)
{

if(vecNumeros.at(i)==vecNumeros.at(x))
{
vecNumeros.erase(vecNumeros.begin()+1);
}
}
}
}

 :-\


Título: Re: Borrar números repetidos en vector
Publicado por: eferion en 8 Mayo 2015, 09:52 am
Código
  1. vecNumeros.erase(vecNumeros.begin()+1);

Esa línea está borrando SIEMPRE el segundo elemento del vector. Dado que supongo que tu idea es eliminar el elemento "x", tal vez deberías plantearte el cambiar ese "+1" por un "+x".

Por otro lado:

Código
  1. for(i=0; i<pos; i++)
  2. {
  3.  for(x=1; x<pos; x++)

Fíjate que se va a dar el caso que i==x, en tal circuntancia acabarías detectando, erróneamente, que tienes un elemento duplicado cuando no es así. "x" debería empezar en "i+1" para no comparar un elemento del vector consigo mismo. Además, cada vez que eliminas un elemento deberías retroceder el índice "x" una posición para no saltarte elementos (si borras v[ x ], el elemento que estaba en v[ x+1 ] pasa a estar en v[ x ])

PD.: un truco para cuando termines la práctica... el contenedor "set" tiene dos características importantes: sus elementos están ordenados y no admite duplicados. Estas propiedades las puedes aprovechar, en tu caso, de dos formas diferentes:

1.  Aprovechando que no admite duplicados. Desventaja: los elementos del vector aparecerán descolocados)

Código
  1. void vecBorrar(vector<int>&vecNumeros)
  2. {
  3.  // Declaramos y rellenamos el contenedor "set"
  4.  std::set< int > temporal( vecNumeros.begin( ), vecNumeros.end( ) );
  5.  
  6.  // Vaciamos el vector
  7.  vecNumeros.clear( );
  8.  
  9.  // Volcamos el contenido de "set", al vector. Aquí ya no hay duplicados
  10.  vecNumeros.insert( vecNumeros.begin( ), temporal.begin( ), temporal.end( ) );
  11. }

2. Preguntando al set si el elemento existe... si existe es que está duplicado:

Código
  1. void vecBorrar(vector<int>&vecNumeros)
  2. {
  3.  // Declaramos y rellenamos el contenedor "set"
  4.  std::set< int > temporal;
  5.  
  6.  for( int i=0; i < vecNumeros.size( ); i++ )
  7.  {
  8.    if( temporal.count( vecNumeros[ i ] ) == 0 )
  9.      temporal.insert( vecNumeros[ i ] ); // Número no duplicado
  10.    else
  11.    {
  12.      vecNumeros.erase( vecNumeros.begin( ) + i ); // Número duplicado. Lo borramos
  13.      i--; // Hay que retroceder una posición para evitar saltarnos elementos
  14.    }
  15.  }
  16. }

Un saludo


Título: Re: Borrar números repetidos en vector
Publicado por: aleaProg en 11 Mayo 2015, 02:43 am
gracias por la ayuda... pero aun no he podido resolverlo >:D  >:D cuando ejecuto el set me dice que no esta declarado, necesito alguna librería en especial??


Título: Re: Borrar números repetidos en vector
Publicado por: aleaProg en 11 Mayo 2015, 03:39 am
eferion muchísimas gracias pude hacer el código por tus consejos  ;-)  ;-) , así me quedo:
Código:
void vecBorrar(vector<int>&vecNumeros)
{
int i, x;
for(i=0; i<vecContar(vecNumeros); i++)
{
for(x=(i+1); x<vecContar(vecNumeros); x++)
{
if(vecNumeros.at(i)!=vecNumeros.at(x))
{
vecNumeros.at(i);
}
else
{
vecNumeros.erase(vecNumeros.begin()+i);
i--;
}
}
}
}
  ;D  ;D  ;-)


Título: Re: Borrar números repetidos en vector
Publicado por: eferion en 11 Mayo 2015, 08:55 am
Perdona, la respuesta que te puse no estaba bien redactada... hay que tener cuidado con los corchetes. En mi caso hay texto que desapareció.

Al igual que para usar la clase "vector" has de añadir "#include <vector>", para la clase "set" tienes que poner su include correspondiente :)


Título: Re: Borrar números repetidos en vector
Publicado por: Peregring-lk en 17 Mayo 2015, 00:46 am
Si el órden de los elementos no importa, puedes utilizar un `set` auxiliar (no he probado el código):

Código
  1. void eliminarRepetidos(vector<int>& v)
  2. {
  3.    set<int> sinReps;
  4.  
  5.    for (auto& i : v)
  6.       sinReps.insert(i); // Los elementos repetidos no se insertan en un set.
  7.  
  8.    vector<int> nuevo;
  9.  
  10.    for (auto& i : sinReps)
  11.        nuevo.push_back(i);
  12.  
  13.    // `nuevo` no tendrá elementos repetidos. Efecto secundario: ahora estará ordenado.
  14.    // Sustituimos `v` por `nuevo`.
  15.    v = nuevo;
  16. }
  17.