Удаление повторяющихся векторов внутри вектора вектора

#c #vector #iterator

#c #вектор #итератор

Вопрос:

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

циклы = ((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 2618),( 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. «разбился» как? Неперехваченное исключение? Может быть, ошибка сегментации?

2. Почему бы не создать вектор из множеств или мультимножеств? Тогда было бы намного проще идентифицировать дубликаты. Или даже набора наборов.

3. @KerrekSB Равны ли множества (1,1,2) и (1,2,2)?

Ответ №1:

Идиоматический способ заключается в использовании идиомы 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() );
  

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

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

Комментарии:

1. спасибо за ответ. но я, я использую DevC , и я не могу использовать идиоматический способ (я пытался использовать этот способ ранее для удаления элементов внутри вектора, но мог бы сделать. поэтому я надеюсь, что разработчик не сможет распознать эти идиомы.), если вы можете, пожалуйста, добавьте традиционный способ сделать то же самое. затем я могу учиться и внедрять. Кроме того, я не могу использовать set, поскольку мой реальный класс objct не является целым числом (это мой собственный класс PointNumber), но унаследован от целых чисел и для простоты размещен как interger. — заранее спасибо-

2. @g_niro У меня нет опыта работы с DevC , но это кажется невозможным. Вы включаете правильные заголовки? Вам нужно, по крайней мере algorithm , и vector для того, чтобы все вышеперечисленное работало. Если algorithm заголовок не поддерживает remove или sort вам следует как можно скорее переключиться на жизнеспособную платформу.

3. @g_niro Также разница int and PointNumber никоим образом не влияет на этот код, если PointNumber он operator< определен.

4. @g_niro Итак, я не понимаю, что мешает этому решению работать на вас. Возможно, вы захотите показать нам код и ошибки в отдельном вопросе.

5. извините, я мог бы сказать вам, что я не могу изменить порядок элементов, так как мне понадобятся эти значения orderd позже. (я думаю, нет способа использовать сортировку).