【问题标题】:Sorting vector elements in descending order按降序对向量元素进行排序
【发布时间】:2019-11-04 17:48:17
【问题描述】:

请告诉我我的方法有什么问题。 当我运行代码时,计算需要很长时间才能看到结果。

#include <iostream>
#include <vector>
using namespace std;

vector<int> vec;
vector<int> sort(vector<int> x) {
    vector<int> y;
    int i = 1;
    reset:for(i = 1; i <= x.size(); i++){
        for (int j = 1; j <= x.size();) {
            if (j == i) {
                j++;
            }
            else {
                if (x[i - 1] > x[j - 1]) {
                    j++;
                }
                else {
                    i++;
                    goto reset;
                }
            }
        }
        y.push_back(x[i - 1]);
        x.erase(x.begin() + i - 1);
    }
          return y;
}

int main(){
    vec.push_back(5);
    vec.push_back(9);
    vec.push_back(3);
    vec.push_back(6);
    vec.push_back(2);

    for (int i = 1; i <= vec.size(); i++) {
        cout << sort(vec)[i-1] << " ";
    }
}

我将这个给定的 5 个整数序列按降序排序。请帮忙。

我的计划是在整个向量 x 中搜索最大的整数,然后将其移动到向量 y 并重复该过程。

【问题讨论】:

  • 每次你想打印一个对性能没有帮助的元素时,你都在对向量进行排序。
  • 你增加i,然后调用goto reset; -> 那会去哪里,在goto之后i会发生什么?
  • 如果花费的时间太长,我认为您的意思是它永远不会完成并且它陷入了无限循环。在调试器中单步执行,您将确切地看到该循环在做什么。
  • 请查看编辑以了解我想要做什么。
  • 有什么理由不使用std::sort

标签: c++


【解决方案1】:

为什么不能只使用 std:sort?你可以这样做:

sort(vec.begin(), vec.end(), [](const int a, const int b) {return a > b; });  //1

正如 cmets 中所建议的,有两种替代方案:

std::sort(vec.begin(), vec.end(), std::greater<>());  //2

和:

std::sort(vec.rbegin(), vec.rend());  //3

(2) 和 (3) 避免了自定义比较函数,并且 (2) 可以说更明确地说明了它的意图。但我对性能很感兴趣,所以我对这三者进行了快速的替补比较。

使用 Clang 12.0,(1) 最快:

Clang 结果here

但是,在 GCC 10.3 中,这三个几乎相同:

GCC 结果here

有趣的结果!使用 GCC,您可以选择自己喜欢的版本;否则我会选择(1)或(2)。

【讨论】:

  • 使用反向迭代器可以消除对自定义比较函数的需要。
  • std::sort(vec.begin(), vec.end(), std::greater&lt;&gt;{});
  • 或 std::sort(vec.rbegin(), vec.rend());
  • @AwesomeJSF 请参阅上面的更新。
  • @jignatius 谢谢,很有趣
【解决方案2】:

简单的冒泡排序示例

我认为由于goto reset 语句,您的sort 函数正在进入无限循环。如果你想实现一个简单的冒泡排序算法,你可以这样做:

#include <iostream>
#include <utility>
#include <vector>

void bubble_sort(std::vector<int>& v) {
    if(v.size() == 0) return; 

    for(int max = v.size(); max > 0; max--) {
        for(int i = 1; i < max; i++) {
            int& current = v[i - 1]; 
            int& next = v[i];
            if(current < next) 
                std::swap(current, next); 
        }
    }
}

这个函数接受一个向量,对于向量中的每一对连续的元素,如果它们是无序的,它会交换它们。这导致最小的元素“冒泡”到向量的顶部。重复该过程,直到所有元素都井井有条。

如果我们对其进行测试,我们会看到它打印出正确的答案:

int main() {
    std::vector<int> test = {5, 9, 3, 6, 2}; 

    bubble_sort(test);

    for(int i : test) {
        std::cout << i << ' '; 
    }
    std::cout << '\n';
}

使用std::sort 更快地完成此操作

标准库提供了一个sort 函数,它几乎可以对任何东西进行排序。 std::sort 实现得非常好,比冒泡排序效率更高,而且非常好用。

默认情况下,std::sort 按升序排列,但很容易更改它以降序运行。有两种方法可以做到这一点。第一种方法使用反向迭代器对向量进行排序(允许您假装向量是逆序的),第二种方法使用std::greater 对向量进行排序,这告诉std::sort 以逆序对事物进行排序。

// Way 1:
std::sort(test.rbegin(), test.rend()); 

// Way 2:
auto compare_func = std::greater<>(); 
std::sort(test.begin(), test.end(), compare_func); 

我们可以使用std::sort重写程序:

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

int main() {
    std::vector<int> test = {5, 9, 3, 6, 2}; 

    auto compare_function = std::greater<>(); 
    std::sort(test.begin(), test.end(), compare_function); 


    for(int i : test) {
        std::cout << i << ' '; 
    }
    std::cout << '\n';
}

【讨论】:

  • 如果您尝试使用代码自行计算,goto 语句不应导致无限循环。请解释如何实现无限循环。
  • 您可能还会提到最简洁的解决方案:std::sort(test.rbegin(), test.rend()),它不需要函数 arg。
  • 这是一个无限循环,因为每次跳转到resetij 的值都会重置为1,所以它会重新开始循环。在某些情况下,这会导致在存储过程中反复重新开始而没有任何进展。
猜你喜欢
  • 2012-02-19
  • 2013-01-03
  • 1970-01-01
  • 2022-02-12
  • 2018-10-08
  • 2022-11-28
  • 2021-12-06
  • 2022-01-02
  • 2022-07-20
相关资源
最近更新 更多