簡體   English   中英

在兩個向量C ++中刪除類似元素

[英]Deleting like elements in two vectors C++

我正在嘗試搜索兩個向量(每個大小)以查找相同的元素,然后刪除這兩個元素。

我的實現如下:

for (int i = vec1.size() - 1; i >= 0; i--) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1[i] == vec2[j]) {
             vec1.erase(vec1.begin() + i);
             vec2.erase(vec2.begin() + j);
          }
     }
}

但是,盡管這在大多數情況下都可行,但我遇到了一些不可行的地方。 是通過這些向量進行迭代的方式,還是只是將這一切弄錯了?

問題是,從vec1vec2刪除元素后,當您遍歷vec2 ,您將繼續訪問vec1[i] 如果您在刪除vec1的最后一個元素之后執行此操作,則會導致未定義的行為,因為vec1[i]不再有效。 if要解決此問題,請在您的語句中添加break語句。

for (int i = vec1.size() - 1; i >= 0; i--) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1[i] == vec2[j]) {
             vec1.erase(vec1.begin() + i);
             vec2.erase(vec2.begin() + j);
             break; // Look at next element in vec1
          }
     }
}

還有一種更有效的方法( O(n*log(n)+m*log(m)+n+m)代替O(n*m)來實現n=vec1.size()m=vec2.size() )。 它涉及對向量進行排序。 我留給你找出答案。

實際上,您根本不需要向后迭代。 在這種情況下,您的代碼可以是:

for (int i = 0; i < vec1.size(); i++) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1[i] == vec2[j]) {
             vec1.erase(vec1.begin() + i);
             vec2.erase(vec2.begin() + j);
          }
     }
}

但是,請稍等...刪除元素后會發生什么? 然后,其索引之后的所有元素都減小1,因此我們將跳過下一項! 要解決此問題,我們可以添加此小修改:

             vec1.erase(vec1.begin() + i--);
             vec2.erase(vec2.begin() + j--);
                                       ^^^^

即使我們通過擦除來更改大小,這也將起作用,因為我們正在每個循環中檢查vec2的大小! 但是,如果我們最終刪除了vec1的最后一項, vec1怎么vec1 我們,直到我們反復一路過關斬將不要再比較其尺寸vec2 ,這將是你的一個問題vec1 = {2}, vec2 = {2, 2, 2}例子。 為了解決這個問題,我們可以突破內部循環並重復對vec2進行檢查。

將它們放在一起(並將您的下標運算符更改為.at()調用,以便我們進行邊界檢查),您將獲得:

for (int i = 0; i < vec1.size(); i++) {
     for (int j = 0; j < vec2.size(); j++) {
          if (vec1.at(i) == vec2.at(j)) {
             vec1.erase(vec1.begin() + i--);
             vec2.erase(vec2.begin() + j--);
             break;
          }
     }
}

(在此處查看實際操作: ideone

如果可以排序,則可以執行以下操作:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {

  std::vector<int> ex {3, 1, 2, 3, 3, 4, 5}, as {2, 3, 6, 1, 1, 1}, tmp;

  std::sort(std::begin(ex), std::end(ex));
  std::sort(std::begin(as), std::end(as));

  as.erase(
    std::remove_if(
      std::begin(as),std::end(as),
      [&](int const& s){
        bool found = std::binary_search(std::begin(ex), std::end(ex), s);
        if (found) {
          tmp.push_back(s);
        }
        return found;}), std::end(as));
  for (auto const& i : tmp) {
    ex.erase(std::remove(std::begin(ex),std::end(ex), i), std::end(ex));
  }

}

嘗試使用std::set_difference從另一個向量中減去一個向量,然后在std::merge的幫助下將這些減法std::merge 但是必須對向量進行排序才能使用這些功能,因此請首先使用std::sort 代碼在這里:

void TraceVector( std::vector<int> v, const std::string& title )
{
    if ( !title.empty() )
    {
        std::cout << title << std::endl;
    }

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, ","));
    std::cout << std::endl;
}

int main() {

    std::vector<int> Vec1 {7, 1, 2, 5, 5, 5, 8, 9};
    std::vector<int> Vec2 {3, 2, 5, 7, 10};
    std::vector<int> Difference1; // Contains subtraction Vec1 - Vec2
    std::vector<int> Difference2;// Contains subtraction Vec2 - Vec1
    std::vector<int> Merged; // RESULT Merged vector after subtractions

    //Need to be sorted
    std::sort(Vec1.begin(), Vec1.end());
    std::sort(Vec2.begin(), Vec2.end());

    TraceVector(Vec1, "Vec1 sorted is: ");
    TraceVector(Vec2, "Vec2 sorted is: ");

    //Make subtractions
    std::set_difference(Vec1.begin(), Vec1.end(), Vec2.begin(), Vec2.end(),
                        std::inserter(Difference1, Difference1.begin()));
    std::set_difference(Vec2.begin(), Vec2.end(), Vec1.begin(), Vec1.end(),
                        std::inserter(Difference2, Difference2.begin()));


    TraceVector(Difference1, "Difference is: ");
    TraceVector(Difference2, "Difference is: ");

    //Merge subtrctions
    std::merge(Difference1.begin(), Difference1.end(), Difference2.begin(), Difference2.end(), back_inserter(Merged));
    TraceVector(Merged, "Merged is: ");
}

輸出為:

Vec1 sorted is: 
1,2,5,5,5,7,8,9,
Vec2 sorted is: 
2,3,5,7,10,
Difference is: 
1,5,5,8,9,
Difference is: 
3,10,
Merged is: 
1,3,5,5,8,9,10,
Program ended with exit code: 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM