【问题标题】:I have a problem with std::unique (algorithm) C++ [duplicate]我对 std::unique (algorithm) C++ 有疑问 [重复]
【发布时间】:2020-05-23 11:29:40
【问题描述】:

我很难找到 2 个最小数字。我得到一个错误的输出。

例子:

  • 输入:{-1, 2, 5, 3, 8, -1, 3, 5, 0}
  • 输出:{-1, -1}
  • 正确答案:{-1, 2}

我认为unique 存在问题,因为它不会删除所有相同的数字。

有更好的方法吗?

以下是我的代码:

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

void input(std::vector<int> &vec) {
    int num;
    std::cin >> num;
    if (num == 0){
        return;
    }
    
    vec.push_back(num);

    return input(vec);
}

int main() {
    std::vector<int> vec;
    input(vec);

    unique(vec.begin(), vec.end()); // It doesnt work correctly

    std::vector<int>::iterator it = min_element(vec.begin(), vec.end());
    std::cout << "\n" << *it << " ";
    vec.erase(it);

    it = min_element(vec.begin(), vec.end());
    std::cout << *it << " ";

    return 0;
}

【问题讨论】:

  • std::unique 仅在它们连续时删除重复项。这里一个简单的for 循环可以找到第二个最小值
  • 体面的文档清楚地说明了你错过了什么。例如,cppreference:“从每个等效元素的连续组中删除除第一个元素之外的所有元素”。要使唯一元素连续,必须首先对范围进行排序。
  • 我不明白正确答案应该是{-1, 2}, (-1

标签: c++ algorithm stl


【解决方案1】:

您的数组需要进行排序,unique 才能正常工作。

【讨论】:

    【解决方案2】:

    @Mikhail,回答了你的问题。但是,如果您排序然后使用std::unique,您将做的工作超出您的需要。

    您实际上可以用较低的复杂性解决这个问题,只需一个循环遍历集合,找到两个最小的唯一值。我没有检查下面的代码编译,但它会是这样的。

    #include <numeric>
    #include <utility>
    #include <limits>
    #include <vector>
    #include <iostream>
    #include <cassert>
    
    using namespace std;
    
    pair<int, int> find_2_min_values(const vector<int>& collection)
    {
        assert(collection.size() > 1);
        auto res = make_pair(numeric_limits<int>::max(),
                             numeric_limits<int>::max());
        
        for (const auto& i : collection)
        {
            if (i < res.first)
                res.first = i;
            else if (i < res.second)
                res.second = i; 
        }
    
        return res;
    }
    
    int main()
    {
        vector<int> col = {-1, 2, 5, 3, 8, -1, 3, 5, 0};    
        auto res = find_2_min_values(col);
    
        cout << "first: " << res.first << "\n" 
             << "second: " << res.second << endl;
    }
    
    

    有一些边缘情况无法正确处理,例如按降序排列的集合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-30
      • 2017-02-22
      • 2019-05-06
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 2020-10-17
      • 2021-05-23
      相关资源
      最近更新 更多