使用迭代器对向量的C 递归初始化产生不一致的结果
C++ recursive initialization of vectors using iterators produce inconsistent results
我试图通过在遇到不一致的程序行为时定义非常常见的Mergesort算法来练习C 迭代器。我的问题不是如何实施Mergesort(我知道并意识到有很多示例答案(,而是使用迭代器创建递归矢量时,我会收到不一致的最终结果。
我知道我可以通过for循环将值复制到L和R数组中来解决问题,但是我想了解为什么使用迭代器不起作用。这是用C 14在Clion上运行的。这篇文章是从向量提取子向量的最佳方法?我没有回答我的问题,因为我创建了类似于规定的方法的向量。
void merge2(vector<int> &arr, int l, int m, int r)
{
vector<int> L{arr.begin()+l, arr.begin()+m+1};
vector<int> R{arr.begin()+m+1,arr.begin()+r+1};
int i = 0, j = 0, k = l;
int n1 = m - l + 1;
int n2 = r - m;
while (i < (n1) && j < (n2)){
if (L[i]<=R[i]){ //R[i] is replaced by R[j]
arr[k] = L[i++];
}
else {
arr[k] = R[j++];
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while(j < n2){
arr[k] = R[j];
j++;
k++;
}
}
/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void merge2Sort(vector<int> &arr, int l, int r)
{
if (l < r)
{
// Same as (l+r)/2, but avoids overflow for
// large l and h
// int m = (l+r-l)/2;
// int m = l+(r-l)/2;
int m = (l+r)/2;
// Sort first and second halves
merge2Sort(arr, l, m);
merge2Sort(arr, m+1, r);
merge2(arr, l, m, r);
}
}
int main(int argc, char **argv){
vector<int> arr = {12, 11, 13, 5, 6, 7};
merge2Sort(arr, 0, arr.size()-1);
for(auto i = arr.begin(); i != arr.end(); i++){
cout << *i << " ";
}
return 0;
}
有时我会收到正确的答案5 6 7 11 12 13,而其他时间不正确的答案5 6 7 11 13 12.答案不应因尝试而变化。
正确答案以反映答案和评论。答案更正索引错误并依赖迭代器。还从迭代初始化时向量的评论中注意到((,而不是{}。
template <class It>
void merge(It left, It middle, It right)
{
// Beeing generic, you need to retrieve the type.
using value_type = typename std::iterator_traits<It>::value_type;
// You can copy only the first half
std::vector<value_type> left_side_copy(left, middle);
It L = left_side_copy.begin();
It R = middle;
while (L != left_side_copy.end() && R != right)
{
if ( *L <= *R )
{
*left = *L;
++L;
}
else {
*left = *R;
++R;
}
++left;
}
// Copy only the leftovers, if there are any
std::copy(L, left_side_copy.end(), left);
}
template <class It>
void merge_sort(It left, It right)
{
if (auto dist = std::distance(left, right); dist > 1)
{
It middle = left + dist / 2;
merge_sort(left, middle);
merge_sort(middle, right);
merge(left, middle, right);
}
}
int main(void)
{
std::vector<int> arr {
5, 12, 11, 13, 5, 4, 7, 13, 6
};
merge_sort(arr.begin(), arr.end());
for(auto const &i : arr) {
std::cout << ' ' << i;
}
std::cout << 'n';
}
您正在使用索引i
,而不是向量R
中的j
。用R[j]
替换R[i]
,请参见下面的
void merge2(vector<int> &arr, int l, int m, int r)
{
//..
while (i < (n1) && j < (n2)){
if (L[i]<=R[j]){ //R[i] is replaced by R[j]
arr[k] = L[i++];
}
else {
arr[k] = R[j++];
}
k++;
}
//...
}
线int m = l+(r-l)/2;
不正确。您可能是指int m = (l+r-l)/2;
,尽管我认为最好保留int m = (l+r)/2;
。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- C++初始化的结果是什么?
- std::atomic_flag初始化结果
- 使用迭代器对向量的C 递归初始化产生不一致的结果
- 即使在C 中越过初始化阵列的极限后,结果也是如此
- CUDA AtomicADD即使在初始化结果后也会产生错误的结果
- 初始化和显示整数向量时出现意外结果
- 使用函数调用结果在C++03中初始化多个成员
- 使用表达式的结果初始化对象时使用哪个构造函数
- 初始化变量时的不同结果
- 如何用函数的结果初始化静态成员数组
- 用两种不同的方式初始化指针会得到两种结果
- 如何使用c++ 11初始化函数结果的const向量?
- 使用中间结果初始化多个属性
- c++虚拟公共继承初始化奇怪的结果
- 我可以用函数调用的结果初始化一个全局变量吗
- 这两个矢量初始化是否实现相同的结果
- 在没有先前初始化的情况下使用映射订阅运算符的结果是否安全