【发布时间】:2020-03-27 04:26:37
【问题描述】:
我正在尝试检查是否使用分治算法对向量进行排序,这是我到目前为止编写的代码:
#include <iostream>
#include <vector>
using namespace std;
bool isOrdered(std::vector <int> v, int left, int right)
{
int mid = (left + right)/2;
if (left == right){
if (left == 0)
return true;
else
return v[left-1] <= v[left];
}
else if (left + 1 == right)
{
if (v[left] <= v[right])
return true;
else
return false;
}
else if (left > right)
{
if (v[left] > v[right])
return true;
else
return false;
}
else
{
return isOrdered(v, left, mid) && isOrdered(v, mid+1, right);
}
}
int main()
{
std::vector <int> v = {2, 2, 3, 2, 2};
cout << isOrdered(v, 0, v.size() - 1);
return 0;
}
它似乎不适用于某些情况,并且在调试时我不断添加特定的基本情况以使其适用于一个输入,但这不会使它适用于另一个输入,我一直这样做,直到我意识到我有算法错误。我基本上是这样想的:将向量划分为子向量,如果所有子向量都是有序的,那么整个向量都是有序的。然而,这种方法很快就失效了。如果输入长度不是 2 的幂,那么它最终会将其分解为某些长度为 1 的子向量,这些子向量始终是有序的。例如,如果输入是2 2 3 2 2 怎么办?子向量是 {2, 2}, {3} 和 {2, 2},它们都是有序的,但整个向量不是。
那么我应该如何看待这个问题呢?我试图通过添加 return v[left-1] <= v[left]; 行使其适用于长度为 1 的子向量,但它仍然崩溃。
【问题讨论】:
-
一旦有 2 个组,您需要停止,以便所有组重叠。那将是
{2,2,3,2,2}应该递归到组{2,2}, {2,3}, {3,2}, {2,2}。 -
顺便说一句,通过 const 引用而不是复制传递你的向量。
-
@NathanOliver-ReinstateMonica 我也想到了这一点.. 不确定它是否算作分而治之,但无论哪种方式,我什至如何递归地进行呢?
-
@Lastrevio2 在
right - left == 1时停止递归。此外,(left + right)/2有可能溢出。要解决这个问题,请参阅:stackoverflow.com/questions/24317360/… -
@NathanOliver-ReinstateMonica:仅当我们使用
signed索引时才会出现潜在问题 ;-)(在有符号/无符号索引之间引发战争 ^_^)
标签: c++ algorithm recursion vector divide-and-conquer