【问题标题】:Implementing Lazy Sorting algorithm using C++使用 C++ 实现惰性排序算法
【发布时间】:2017-10-12 07:13:48
【问题描述】:

我们的教授给我们做了一个编程练习:

Juan Tamad 是个懒惰的人。他的任务是对数字列表进行排序, 但他超级懒惰。他厌倦了弄清楚如何交换所有的 周围的数字,直到所有这些都按递增顺序排列。于是,他来了 用他自己的算法来保证新列表是 排序。以下是它的工作原理:

对于大小为 n 的列表,我们将需要 n-1 次迭代。在每次迭代中,

检查第n个数是否小于第n+1个数。如果是, 那么这两个数字已经排序,我们可以跳过这个 迭代如果不是,我们不断递减第一个 n 直到这两个数字有序为止。

例如,假设输入是

10 5 7 6 1

在第一次迭代中,我们比较 10 和 5。10 大于 5,所以我们 递减直到更小:

4 5 7 6 1

现在我们比较 5 和 7。5 小于 7,所以我们不需要做 任何东西,我们跳过这个迭代。去下一个,比较 7 和 6. 7 大于 6,所以我们减少前三个数字 直到它小于 6 并且我们得到这个:

2 3 5 6 1

现在我们比较 6 和 1。同样,6 大于 1,所以我们递减 前四个数字,直到它小于 1,我们得到:

-4 -3 -1 0 1

我们完成了。现在列表已完全排序。

你的任务是实现 Juan Tamad 的排序算法 一个 C++ 程序。您的程序读取输入 n 和 n 的列表 数字。您的程序使用 Juan Tamad 对数字进行排序 算法。

所以我想知道是否有人可以至少在阐明问题方面提供帮助。 到目前为止,我的想法是:

#include<iostream>
using namespace std;

int main(){

  int n;
  cin >> n;

  int a[n];

  for(int i = 0; i< n; i++)
  cin>> a[i];

  for(int i = 0; i< n; i++)
    cout<< a[i] << " ";

//______________________________________
  for(int i = 0; i < n-1; i++){
    for(int j = i + 1; j < n-1; j++){
      if(a[i] > a[j])
        a[i]--;
      }

  }

  for(int i = 0; i < n; i++)
    cout << a[i] << " ";

  return 0;
}

样本运行:

$./a.out
Enter value of n: 5 
Enter 5 numbers: 10 5 7 6 1
Output: -4 -3 -1 0 1

$./a.out
Enter value of n: 10 
Enter 10 numbers: 10 9 8 7 6 5 4 3 2 1
Output: -8 - 7 - 6 -5 -4 -3 -2 -1 0 1

$./a.out
Enter value of n: 6 
Enter 6 numbers: 1 2 3 1 2 3
Output: -2 -1 0 1 2 3

$./a.out
Enter value of n: 10
Enter 6 numbers: 5 7 11 6 16 2 9 16 6 16
Output: -27 -25 -21 -20 -10 -9 -2 5 6 16

$./a.out
Enter value of n: 1
Enter 6 numbers: 100
Output: 100

【问题讨论】:

  • 那么你的问题是什么?到目前为止你写的代码有问题吗?
  • 是的,先生,输出错误
  • 样本运行:$./a.out 输入 n 的值:5 输入 5 个数字:10 5 7 6 1 输出:-4 -3 -1 0 1 $./a.out 输入值的 n:10 输入 10 个数字:10 9 8 7 6 5 4 3 2 1 输出:-8 - 7 - 6 -5 -4 -3 -2 -1 0 1 $./a.out 输入 n 的值:6输入 6 个数字:1 2 3 1 2 3 输出:-2 -1 0 1 2 3 $./a.out 输入 n 的值:10 输入 6 个数字:5 7 11 6 16 2 9 16 6 16 输出:-27 -25 -21 -20 -10 -9 -2 5 6 16 $./a.out 输入 n 的值:1 输入 6 个数字:100 输出:100
  • 我认为您的截止日期和您的教授与该问题无关。而且,作为@MichaelHancock,在这里很难看到任何问题。
  • 我需要一个能用新手的话解释算法的人吗?

标签: c++ algorithm sorting


【解决方案1】:

这里有一些要点:

for(int i = 0; i < n-1; i++)

而不是去[first, last) 我会去(first, last] 这是因为你需要查看以前的值。但你的方法也行。

for(int j = i + 1; j < n-1; j++)

这里你无条件地通过i的右边。这是错误的。您需要:

  • 首先检查是否v[i + 1] &gt;= v[i]。如果没有,则元素就位。您可以继续
  • 否则。您需要递减所有元素[first, i)。为此,for 应如下所示:

    for (int j = 0; j

  • 并且您不需要实际递减1。您可以看到元素之间的差异,然后减去。例如,当您遇到 6 1 元素时,您需要从所有元素中减去 6 (6 - 1 + 1),直到 i

剩下的看你自己了。

【讨论】:

    【解决方案2】:

    这是上述惰性算法的超级惰性实现:它只有O(n) 复杂度:

    template <class It>
    auto lazy_sort(It begin, It end) -> void
    {
        auto rbegin = std::make_reverse_iterator(end);
        auto rend = std::make_reverse_iterator(begin);
    
        auto it = rbegin;
        if (it == rend)
            return;
        auto prev_val = *it;
        ++it;
    
        int diff = 0;
    
        for (; it != rend; ++it)
        {
            diff += std::max(0, *it - prev_val + 1);
    
            prev_val = *it;
            *it -= diff;
        }
    }
    
    BOOST_AUTO_TEST_CASE(test_lazy_sort)
    {
        std::vector<int> v = {10, 5, 7, 6, 1};    
    
        lazy_sort(v.begin(), v.end());
    
        BOOST_CHECK((v == std::vector<int>{-4, -3, -1, 0, 1}));
    }
    

    【讨论】:

    • (差点错过_reverse_。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多