Удалить дубликаты векторов внутри вектора вектора - PullRequest
2 голосов
/ 02 октября 2011

У меня есть вектор вектора (loops), который содержит целочисленные значения.Некоторые внутренние векторы дублируются, но их порядок элементов не одинаков.Теперь я хочу получить вектор вектора без дубликатов внутренних векторов.Вот пример для моего vec vec:

loops = ((9 18 26 11 9), (9 11 26 18 9), (9 18 25 16 9), (11 45 26 11),(11 26 45 11), (16 49 25 16), (16 25 49 16), (18 9 11 26 18), (18 9 16 25 18), (25 16 49 25), (26 11 45 26))

Чтобы определить, является ли какой-либо внутренний вектор дубликатом другого внутреннего вектора;Я разработал функцию IsDuplicate.Это говорит мне, что (9 18 26 11 9) and (9 11 26 18 9) являются дубликатами, тогда я могу удалить второй или все другие дубликаты.

Чтобы удалить дублирующиеся векторы внутри моего вектора вектора, я реализовал следующие коды.

Vector<vector<int> > loops;
Vector<vector<int> > ::iterator no1, no2;
Int setno1, setno2;

for (no1=loops.begin(), setno1=0; no1!=loops.end(); no1++, setno1++){
       set1 = *no1;
       for (no2=loops.begin()+setno1, setno2=setno1; no2!=loops.end(); setno2++){
            set2 = *no2;
            if (set2.IsDuplicate(set1))  loops.erase(loops.begin()+setno2);
            else no2++;
       }

  }

это заняло очень много времени, и я подумал, что моя программа падает.Итак, пожалуйста, помогите мне исправить эту проблему.

Кроме того, я пытался с этим.это работает, но я получил неправильный ответ.любая помощь, пожалуйста.

01   int first=0; bool duplicates=false;  
02   do {     
03        set1 = loops[first];     
04        for (no2=loops.begin()+1, setno2=1;  no2!=loops.end();  setno2++){     
05             set2 = *no2;      
06             if (set2.IsPartOf(set1)){      
07                 loops.erase(loops.begin()+setno2);     
08                 duplicates = true;      
09             }      
10             else no2++;     
11        }      
12        first++;      
13       } while(!duplicates); 

1 Ответ

5 голосов
/ 02 октября 2011

Идиоматическим способом является использование идиомы Erase / Remove с пользовательским предикатом. Чтобы проверить наличие дублирующихся векторов и без изменения содержимого ваших векторов, напишите предикат, который принимает свои аргументы по значению, отсортируйте векторы и используйте std::equal.

bool equal_vector(std::vector<int> a, std::vector<int> b) {
  std::sort(a.begin(), a.end());
  std::sort(b.begin(), b.end());

  return std::equal(a.begin(), a.end(), b.begin());
}

// use it like this
v.erase( remove_if(v.begin(), v.end(), equal_vector), v.end() );

Относительно того, почему ваш текущий код не работает: стирание элемента из vector делает недействительными все другие итераторы для того вектора, который существует в настоящее время, поэтому vector::erase возвращает действительный итератор в позицию после удаляемого элемента.

stdlib также предоставляет контейнеры set и multiset, которые выглядят намного лучше подходящими для ваших целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...