2017-09-10 2 views
-2

I
Ex ein duplizierte Element aus einem größeren Vektor zu entfernen bin versucht:Entfernen Sie doppeltes Element aus dem Vektor der Vektoren C++

6 11 
7 8 
6 16 17 

soll ich:

6 11 
7 8 
16 17 

Was ich habe:

vector<vector<int>>B; 
vector<vector<int>>::iterator b_list; 
vector<vector<int>>::iterator b_it; 
vector<int>::iterator b_list_it; 
vector<int>::iterator b_it_it; 
for (b_list = B.begin(); b_list != B.end()-1; ++b_list) 
{ 
    for (b_it = b_list+1; b_it != B.end(); ++b_it) 
    { 
     for (int i = 0; i < (*b_list).size(); ++i) 
     { 
      for (int j = 0; j < (*b_it).size(); ++j) 
      { 
       if ((*b_list)[i] == (*b_it)[j]) 
       { 
        if ((*b_list).size() > (*b_it).size()) 
         { 
          (*b_list).erase((*b_list).begin()); 
         } 
         if ((*b_list).size() < (*b_it).size()) 
         { 
          (*b_it).erase((*b_it).begin()); 
         } 
       } 
      } 
     } 
    } 
} 

In diesem Fall entfernt erase() nichts. Warum könnte es so sein? Und was könnte stattdessen verwendet werden?

Vielen Dank!

+1

Beachten Sie, dass 'erase()' die Iterator Stabilität auswirkt. – user0042

+0

Vielleicht möchten Sie etwas Zeit mit dem Studium der [Standard-Algorithmen] (http://en.cppreference.com/w/cpp/algorithm) –

Antwort

1

Da das OP zweidimensionalen Vektor hat. Nicht sicher, ob OP will die Daten in sortierten (eindeutige kann in diesem Fall verwendet werden) Aber unter Annahme, sie sind nicht sortiert ein Set wird als Tracker verwendet. Behält eine Spur von eindeutigen Werten. if (ret.second!=false) fogRow.push_back(s); Eine Kopie Vektor verwendet, bei denen in jeder Zeit eindeutige Werte sind dort wird es geschoben

// 
// main.cpp 
// ranged 
// 
// Created by Hariom Singh on 9/9/17. 
// Copyright © 2017 Hariom Singh. All rights reserved. 
// 

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

int main() { 
    std::vector<std::vector<int> > val {{6,11},{7,8},{6,16,17}}; 
    std::vector<std::vector<int> > uniquevalcopy; 
    std::set<int> tracker; 
    for (const auto &row : val) 
    { 
     std::vector <int> fogRow; 
     for (const auto &s : row) 
     { 
      std::cout << s << ' '; 
      auto ret = tracker.insert(s); 
      if (ret.second!=false) 
      fogRow.push_back(s); 

     } 
     uniquevalcopy.push_back(fogRow); 
     std::cout << std::endl; 
    } 

    std::cout<<"after removal"<<"\n"; 
    for (const auto &row : uniquevalcopy) 
    { 
     for (const auto &s : row) 
     { 
      std::cout << s << ' '; 

     } 
     std::cout << std::endl; 
    } 
    return 0; 
} 

Ausgang

6 11 
7 8 
6 16 17 
after removal 
6 11 
7 8 
16 17 
Program ended with exit code: 0 
4

Sie können dies leichter tun viel von den STL Einrichtungen mit als

vector<int> vec{1,2,3,5,2,3,8}; 
set<int> s(vec.cbegin(), vec.cend()); 
vec = vector<int>(s.cbegin(), s.cend()); 

folgt Ich bin mir ziemlich sicher, dass dies als jeder Algorithmus effizienter sein wird, mit dem Sie kommen werden.

+0

Sie schlagen mich auf die Tatsache, dass sie nur Sätze verwenden sollten. Guter Gedanke. +1. – Annabelle

+0

OP hat zweidimensionalen Vektor –

+0

es ist klar, dass was für einen Vektor getan werden kann, kann für einen Vektor von Vektoren mit einer Schleife erfolgen. –

1

Sie können die Funktion "unique" verwenden, die die Position des letzten zu entfernenden Elements zurückgibt. Die Funktion "unique" entfernt alle Vorkommen und hinterlässt nur eine einzige Instanz davon.

Ein Beispiel ist:

vector<int>::iterator it; 
vector<int> nums = {1, 2, 3, 5, 2, 1}; 

std::sort(nums.begin(), nums.end()); //sort ascending 
it = std::unique(nums.begin(), nums.end()); //remove occurrences 

nums.resize(std::distance(nums.begin(), it)) //resize to remove missing empty slots in container 

for(auto num : nums){ 
    std:cout<< num; 
} 

Ausgang ist 1235

+3

Beachten Sie, dass 'std :: unique' nur aufeinanderfolgende doppelte Elemente entfernt. Sie müssen die Vektorfaust sortieren. – Csq

+0

Danke. Redigiert es. – josephnicholas

0

Sie nicht Iteratoren Referenzierung über gelöschte Position nach vector :: erase() aufrufen

Schauen Sie zum Beispiel verwenden können here.

Iteratoren, Zeiger und Referenzen zeigen und darüber hinaus zu positionieren, werden ungültig gemacht, mit allen Iteratoren, Zeiger und Referenzen auf Elemente vor Position auf die gleichen Elemente zu halten sind garantiert beziehen sie vor dem Aufruf bezieht wurden.

Verwandte Themen