Подсчитайте, сколько различных векторов осталось после объединения

Я использую только std::vector в этой задаче, и каждый вектор упорядочен без дубликатов. Теперь я хочу объединить векторы с одинаковыми номерами. Таким образом, 2 3 может быть объединено с 3 4 5, но не с 4 5 или 1 5.

Пример:

Если у меня есть следующие векторы...

1
1
2 3 4
5
1 5
2
4 7

После объединения у меня должно остаться только 2 вектора:

1 5
2 3 4 7

Коды:

vector<int> a,b,c,d,e,f,g;
vector<vector<int>> myList;

a.push_back(1);
b.push_back(1);
c.push_back(2);
c.push_back(3);
c.push_back(4);
d.push_back(5);
e.push_back(1);
e.push_back(5);
f.push_back(2);
g.push_back(4);
g.push_back(7);

myList.push_back(a);
myList.push_back(b);
myList.push_back(c);
myList.push_back(d);
myList.push_back(e);
myList.push_back(f);
myList.push_back(g);

//this should print out the vectors in my above example
for (int i =0; i<myList.size(); i++) {
    for (int j=0; j<myList[i].size(); j++) {
        cout<<myList[i][j]<<" ";
    }
    cout<<endl;
}

Я пытался использовать set_union и set_intersection для достижения своей цели, но это не работает должным образом. Я подозреваю, что проблема связана с размером вектора, который я не меняю должным образом. Пожалуйста помоги. Спасибо!

РЕДАКТИРОВАТЬ:

Это глючный код, изначально у меня были проблемы с объединением, но сейчас оно работает автоматически. Теперь я думаю, что в основном не уверен, как использовать set_intersection, чтобы узнать, есть ли пересечение

vector<int>::iterator myIt;
vector<int> myTemp;
vector<int> myTemp2;
vector<int> myResult(20);
vector<int> myResult2(20);


while (!myList.empty()) {

    myTemp2 = myList.back();
    myList.pop_back();


    myIt = set_intersection(myTemp.begin(), myTemp.end(), 
                            myTemp2.begin(), myTemp2.end(), myResult.begin());

    //this is checking whether there is intersection but it doesn't work
    if (myResult.size()) {

        myIt = set_union(myTemp.begin(), myTemp.end(), 
                         myTemp2.begin(), myTemp2.end(), myResult2.begin());

        myTemp = myResult2;

    }


}

cout<<"after union: "<<endl;

for (auto it = myResult2.begin(); it != myResult2.end() ; it++) {
    cout<<*it<< " ";
}

person Arch1tect    schedule 10.04.2013    source источник
comment
Так что у вас есть до сих пор? Как это не работало, как ожидалось?   -  person Andy Prowl    schedule 11.04.2013
comment
set_union и set_intersection звучат разумно для начала. Почему бы не показать нам нерабочий код, и мы поможем вам его исправить.   -  person john    schedule 11.04.2013
comment
@AndyProwl добавил, пожалуйста, посмотрите.   -  person Arch1tect    schedule 11.04.2013
comment
@john добавил, пожалуйста, посмотрите.   -  person Arch1tect    schedule 11.04.2013


Ответы (2)


Если я правильно вас понял, не только ваш код, но и ваш подход совершенно неверен. Вы пытаетесь решить проблему типа связанных компонентов/непересекающихся множеств, но ваш метод, например, возвращает только один vector из ints...? Он обязательно должен вернуть vector из vector<int>s.

Следующий код наиболее близок к вашему, который, как мне кажется, должен работать. Он должен оставить result с желаемым результатом.

vector< vector<int> > result;

for(int i = 0; i < myList.size(); i++)
{

    bool match = false;
    int matchFirst = -1;

    for(int j = 0; j < result.size(); j++)
    {

        vector<int> myResult;
        vector<int> myResult2;

        set_intersection(myList[i].begin(), myList[i].end(),
                         result[j].begin(), result[j].end(),
                         back_inserter(myResult));

        if (myResult.size())
        {
            set_union(myList[i].begin(), myList[i].end(),
                      result[j].begin(), result[j].end(), back_inserter(myResult2));

            if(match)
            {
                vector<int> myResult3;
                set_union(myResult2.begin(), myResult2.end(),
                          result[matchFirst].begin(), result[matchFirst].end(), back_inserter(myResult3));
                result.erase(result.begin() + j, result.begin() + j + 1);
                result[matchFirst] = myResult3;
                j--;
            }
            else
            {
                matchFirst = j;
                result[j] = myResult2;
                match = true;
            }

        }

    }

    if(!match)
    {
        result.push_back(myList[i]);
    }
}

Изменить: исправлена ​​ошибка.

person not all wrong    schedule 10.04.2013

это не идеально

vector<int> myResult(20);

myIt = set_intersection(myTemp.begin(), myTemp.end(), 
     myTemp2.begin(), myTemp2.end(), myResult.begin());

Проблема в том, что set_intersection (и set_union) не меняют размер вектора. Делая myResult размером 20, вы даете себе достаточно места, но вы все равно получаете вектор размера 20 после того, как вы сделали пересечение, поэтому myResult.size() == 20 любые элементы, которые у вас есть в двух векторах, для начала.

Что вам нужно, так это использовать set_intersection, чтобы он добавлял элементы в целевой вектор. Для этого вам нужно back_inserter

#include <iterator>

vector<int> myResult;

set_intersection(myTemp.begin(), myTemp.end(), 
    myTemp2.begin(), myTemp2.end(), 
    back_inserter(myResult));

back_inserter добавляет элементы к вектору, используя push_back, поэтому myResult начинается с нулевого размера и заканчивается правильным размером в зависимости от того, сколько элементов находится на пересечении. Итак, вы можете просто проверить myResult.size() > 0, чтобы определить, есть ли какие-либо общие элементы.

Сделайте то же самое, когда вы вызываете set_union.

person john    schedule 10.04.2013