C++;使用迭代器递归初始化向量会产生不一致的结果 我试图通过定义非常常见的合并算法在遇到不一致的程序行为时练习C++迭代器。我的问题不是如何实现mergesort(我都知道,也意识到它有许多示例答案),而是在使用迭代器创建递归向量时,我会收到不一致的最终结果
我知道我可以通过for循环将值复制到L和R数组中来解决这个问题,但是我想了解为什么使用迭代器不起作用。这是用C++ 14在克利永上运行的。这篇文章并没有回答我的问题,因为我正在创建类似于规定方法的向量C++;使用迭代器递归初始化向量会产生不一致的结果 我试图通过定义非常常见的合并算法在遇到不一致的程序行为时练习C++迭代器。我的问题不是如何实现mergesort(我都知道,也意识到它有许多示例答案),而是在使用迭代器创建递归向量时,我会收到不一致的最终结果,c++,c++11,iterator,clion,C++,C++11,Iterator,Clion,我知道我可以通过for循环将值复制到L和R数组中来解决这个问题,但是我想了解为什么使用迭代器不起作用。这是用C++ 14在克利永上运行的。这篇文章并没有回答我的问题,因为我正在创建类似于规定方法的向量 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.b
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;
}
void merge2(向量&arr,整数l,整数m,整数r)
{
向量L{arr.begin()+L,arr.begin()+m+1};
向量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;
而(i<(n1)和&j<(n2)){
如果(L[i]您在向量R
中使用的是索引i
而不是j
。请将R[i]
替换为R[j]
见下文
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++;
}
//...
}
void merge2(向量&arr,整数l,整数m,整数r)
{
//..
而(i<(n1)和&j<(n2)){
如果(L[i]您在向量R
中使用的是索引i
而不是j
。请将R[i]
替换为R[j]
见下文
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++;
}
//...
}
void merge2(向量&arr,整数l,整数m,整数r)
{
//..
而(i<(n1)和&j<(n2)){
如果(L[i]行int m=L+(r-L)/2;
是不正确的。你可能是指int m=(L+r-L)/2;
虽然我认为最好保持int m=(L+r)/2;
行int m=L+(r-L)/2;
是不正确的。你可能是指int m=(L+r-L)/2、
虽然我认为最好保持int m=(l+r)/2;
这在调试时会产生一个超出范围的错误,这可能会导致UB在释放模式下向量l{arr.begin()+l,arr.begin()+m+1};
应该是向量l(arr.begin()+l,arr.begin()+m+1);
。大括号表示更倾向于根据作为向量内容的列表内容(而不是迭代器对)选择构造函数。如果在第一种方法中找不到任何东西,则返回到考虑迭代器对,但您总是有意外触发第一种方法的风险。如果在每次mergesort调用时为子数组放置一些转储函数,则应该很容易找到错误。感谢M.M,我已将构造函数改为使用建议的()方法,而不是{}用于向量初始化。@user4242176为什么编辑问题以反映答案?这会使答案对稍后看到它的人来说完全多余。这会在调试时产生超出范围的错误,这可能导致UB处于释放模式vector L{arr.begin()+L,arr.begin()+m+1};
应该是vector L(arr.begin())+l、 arr.begin()+m+1);
。大括号表示更倾向于根据作为向量内容的列表内容(而不是迭代器对)选择构造函数。如果在第一种方法中找不到任何东西,则返回到考虑迭代器对,但您总是有意外触发第一种方法的风险。如果在每次mergesort调用时为子数组放置一些转储函数,则应该很容易找到错误。感谢M.M,我已将构造函数改为使用建议的()方法,而不是{}用于向量初始化。@user4242176为什么要编辑问题以反映答案?这使得答案对于稍后将看到它的人来说完全是多余的。谢谢,虽然这确实纠正了我在代码中忽略的错误,但不一致的行为仍然存在。所以我认为这并不能完全解决问题。@user4242176你确定吗?我正在接受g每次都回答正确。更改索引并重新生成程序谢谢,虽然这确实纠正了我在代码中忽略的错误,但不一致的行为仍然存在。因此我认为这并不能完全解决问题。@User42176你确定吗?我每次都收到正确的答案。更改索引并重新生成程序谢谢,我不相信我已经解决了这个问题。尝试建议的更改会产生错误代码11。谢谢,我不相信这个问题已经解决。尝试建议的更改会产生错误代码11。