Borrar números repetidos en vector

Iniciado por aleaProg, 8 Mayo 2015, 06:19 AM

0 Miembros y 1 Visitante están viendo este tema.

aleaProg

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.

#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);
}
}
}
}


:-\

eferion

#1
Código (cpp) [Seleccionar]
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 (cpp) [Seleccionar]
for(i=0; i<pos; i++)
{
 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 (cpp) [Seleccionar]

void vecBorrar(vector<int>&vecNumeros)
{
 // Declaramos y rellenamos el contenedor "set"
 std::set< int > temporal( vecNumeros.begin( ), vecNumeros.end( ) );

 // Vaciamos el vector
 vecNumeros.clear( );

 // Volcamos el contenido de "set", al vector. Aquí ya no hay duplicados
 vecNumeros.insert( vecNumeros.begin( ), temporal.begin( ), temporal.end( ) );
}


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

Código (cpp) [Seleccionar]

void vecBorrar(vector<int>&vecNumeros)
{
 // Declaramos y rellenamos el contenedor "set"
 std::set< int > temporal;

 for( int i=0; i < vecNumeros.size( ); i++ )
 {
   if( temporal.count( vecNumeros[ i ] ) == 0 )
     temporal.insert( vecNumeros[ i ] ); // Número no duplicado
   else
   {
     vecNumeros.erase( vecNumeros.begin( ) + i ); // Número duplicado. Lo borramos
     i--; // Hay que retroceder una posición para evitar saltarnos elementos
   }
 }
}


Un saludo

aleaProg

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??

aleaProg

eferion muchísimas gracias pude hacer el código por tus consejos  ;-)  ;-) , así me quedo:
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  ;-)

eferion

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 :)

Peregring-lk

#5
Si el órden de los elementos no importa, puedes utilizar un `set` auxiliar (no he probado el código):

Código (c++) [Seleccionar]

void eliminarRepetidos(vector<int>& v)
{
   set<int> sinReps;

   for (auto& i : v)
      sinReps.insert(i); // Los elementos repetidos no se insertan en un set.

   vector<int> nuevo;

   for (auto& i : sinReps)
       nuevo.push_back(i);

   // `nuevo` no tendrá elementos repetidos. Efecto secundario: ahora estará ordenado.
   // Sustituimos `v` por `nuevo`.
   v = nuevo;
}