devolver vector único

Iniciado por indict, 30 Junio 2013, 17:06 PM

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

indict

Hola de nuevo,

querría hacer una función que devolviera un vector con solo únicos elementos, es decir sin elementos repetidos. Para ello he creído ordenar primeramente el vector ya que así se puede trabajar de forma mas sencilla.  El programa me devuelve correctamente el vector con elementos no repetidos, lo único que al final del vector aparece una combinación de números que sobra, debida por algún error.

Si pudieras decirme si sería posible rectificar ese error. Gracias :).

Código (cpp) [Seleccionar]
#include<iostream>
#include<vector>
using namespace std;

void ordena_seleccion(vector<int>& v) {
    for (int i = 0; i < v.size(); i++) {
        int min = i;
        for (int c = i + 1; c < v.size(); c++) {
            if (v[min] > v[c]) min = c;
        }
        int aux = v[i];
        v[i] = v[min];
        v[min] = aux;
    }
}


vector<int>unico(vector<int>&v){
ordena_seleccion(v);
int i=0;
vector<int>p;

while(i<v.size()){
        if(v[i]!=v[i+1]){
        p.push_back(v[i]);
        p.push_back(v[i+1]);
        i=i+2;}
        i++; }
        return p;      }

int main(){
      int n,e;
    cout<<"introduzca el tamaño del vector "<<endl;
    cin>>n;
   
    vector<int>v(n);
    for(int i=0;i<n;i++){
            cout<<"elemento"<<endl;
            cin>>e;
            v[i]=e;
            }
   
    vector<int>p=unico(v);
    cout<<endl;
    cout<<"[";
    for(int i=0;i<v.size();i++){
            cout<<p[i]<<"  ";
            }
    cout<<"]"<<endl;
    system("pause");
    return 0;}

satu

Buenas!!

He mirado el código por encima y no lo puedo probar pero creo que el fallo está en:
Código (cpp) [Seleccionar]

for(int i=0;i<v.size();i++){
           cout<<p[i]<<"  ";
           }


Debes cambiar v.size() por p.size() en el for

Prueba a ver si es eso y dinos qué tal

Saludos!!
Breakbeat como forma de vida

rir3760

El problema se debe a la función donde obtienes los elementos sin repeticiones:
Código (cpp) [Seleccionar]
vector<int> unico(vector<int>&v)
{
   ordena_seleccion(v);
   unsigned i=0;
   vector<int>p;
   
   while (i < v.size()){
      if (v[i] != v[i+1]){
         p.push_back(v[i]);
         p.push_back(v[i+1]);
         i = i + 2;
      }
     
      i++;
   }
   
   return p;
}

Supongamos que el vector pasado como argumento contiene los valores 0, 1 y 2, entonces:

1) La variable "i" toma el valor 0.
2) Se entra al bucle ya que 0 es menor que 3.
3) Ya que el elemento v[0] es diferente de v[1] agregas ambos.

Aquí el error:

4) Se incrementa "i" en dos unidades, "i" es igual a 2.
5) Se incrementa "i" en una unidad, "i" es igual a 3.
6) Termina el bucle ya que el valor de i no es menor que el numero de elementos en el vector.

La corrección es simple, agregas el primer valor de forma manual y los restantes siempre y cuando el valor procesado sea distinto del anterior:
Código (cpp) [Seleccionar]
vector<int> unico(vector<int>& v)
{
   ordena_seleccion(v);
   vector<int> p;
   p.push_back(v[0]);
   
   for (unsigned i = 1; i < v.size(); i++)
      if (v[i] != v[i - 1])
         p.push_back(v[i]);
   
   return p;
}


También debes modificar la parte donde se imprime el vector sin duplicados, solo debes seguir la indicación de satu, la condición en el bucle:
Código (cpp) [Seleccionar]
for (unsigned i = 0; i < v.size(); i++){
   cout << p[i] << "  ";
}

Debe ser "i < p.size()".

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

satu

Buenas!!

Propongo otra forma: utilizar el contenedor set como forma de eliminar repetidos y ordenamiento:

Código (cpp) [Seleccionar]

#include <iostream>
#include <vector>
#include <set>

using namespace std;

void unico(vector<int> &v){
    set<int> aux;
    set<int>::const_iterator it;

    aux.insert(v.begin(), v.end());

    v.clear();

    for(it = aux.begin(); it != aux.end(); it++) {
        v.push_back(*it);
    }
}

int main(){
    int n, e;
    cout << "Introduzca el tamaño del vector " << endl;
    cin >> n;

    vector<int> v;
    for(int i = 0; i < n; i++) {
        cout << "elemento" << endl;
        cin >> e;
        v.push_back(e);
    }

    unico(v);
    cout << endl;
    cout << "[";
    for(unsigned i = 0; i < v.size(); i++) {
        cout << v[i] << "  ";
    }
    cout << "]" << endl << endl << "Pulsa Enter para salir..." << endl << endl;
    cin.sync();
    cin.get();
    return 0;
}


Saludetes
Breakbeat como forma de vida

indict

Gracias rir3760 y satu por todas vuestras aportaciones y ayudas ¡sois increibles! :D