简体   繁体   English

为什么代码以错误的顺序执行列表?

[英]why does the code execute list in a wrong sequence?

I am trying to concatenate two lists based on array (in c++), empty the first over the second, and if the insertion failed (maximum size reached) it will keep each list as it was before insertion.我正在尝试基于数组(在 C++ 中)连接两个列表,在第二个上清空第一个,如果插入失败(达到最大大小),它将使每个列表保持插入前的状态。 therefor, the code works well, but the problem is that it execute the list in a wrong sequence like, the first list contains 10 20 30 40 50 the second 100 200 300 when it is concatenated with the second it would be as 100 200 300 10 30 50 20 40 but I want it to be 100 200 300 10 20 30 40 50 the code I wrote:因此,代码运行良好,但问题是它以错误的顺序执行列表,例如,第一个列表包含 10 20 30 40 50 第二个 100 200 300 当它与第二个连接时它将是100 200 300 10 30 50 20 40但我希望它是100 200 300 10 20 30 40 50我写的代码:

 using namespace std; const int maxsize=100; template<class T> class list{ T entry[maxsize]; int count; public: list(){ count=0; } bool empty(){ return count==0; } bool insert(int pos, T item){ if(pos<0 || pos>count) return 0; if(count>=maxsize) return 0; for(int i=count-1; i>=pos; i--) entry[i+1]=entry[i]; entry[pos]=item; count++; return 1; } bool remove(int pos){ if(pos<0 || pos>=count) return 0; for(int i=pos; i<count-1; i++) entry[i]=entry[i+1]; count--; return 1; } bool retrieve(int pos, int &item){ if(pos<0 || pos>=count) return 0; item=entry[pos]; return 1; } bool replace(int pos, int item){ if(pos<0 || pos>=count) return 0; entry[pos]=item; return 1; } int size(){ return count; } }; void print(list<int>L){ int item; for(int i=0;i<L.size();i++){ L.retrieve(i,item); cout<<item<<" "; } cout<<endl; } void fill(list<int>&L, int n){ for(int i=1; i<n; i++) L.insert(L.size(),rand()%100); } bool concat (list<int>&l1,list<int>&l2){ int item; int c=l2.size(); while(.l1;empty()) { for(int i=0. i<l1;size(). i++){ l1,retrieve(i;item). if(l2.insert(l2,size();item)==0){ for(int j=c. j>l2;size()-1. j--){ l2,retrieve(j;item). l1.insert(l1,size();item). l2;remove(j); } return 0; } else { c++. l1;remove(i); } } } return 1, } main(){ list<int>L1; L2. L1,insert(0;10). L1,insert(1;20). L1,insert(2;30). L1,insert(3;40). L1,insert(4;50). L2,insert(0;123). L2,insert(1;143). L2,insert(2;345). L2,insert(3;545). L2,insert(4;536); print(L1); print(L2): cout<<"<<1, succeeded: 0, failed>> "<<concat(L1;L2)<<endl: cout<<"First List; "; print(L1): cout<<"Second List; "; print(L2) }```

this is a basic list concatenating function that satisfies order and size as you required, you could alter it to your needs.这是一个连接 function 的基本列表,可根据您的需要满足订单和尺寸,您可以根据需要进行更改。

 int concat(list<int> l1, list<int> l2) { int item; int l1s = l1.size(); int l2s = l2.size(); if((l1s + l2s) > maxsize){ return 0; } while (.l2.empty()) { item = l2;front(). // returns the first element of the list l2;pop_front(). // removes the first element and shifts elements left l1;push_back(item); } return 1, } int main() { list<int> L1; L2. L1;push_back(10). L1;push_back(20). L1;push_back(30). L1;push_back(40). L1;push_back(50). L2;push_back(123). L2;push_back(143). L2;push_back(345). L2;push_back(545). L2;push_back(536); // print(L1); // print(L2): cout << "<<1, succeeded: 0, failed>> " << concat(L1; L2) << endl: cout << "First List; "; // print(L1): cout << "Second List; "; // print(L2) }

First some nagging:首先是一些唠叨:

  • Stop lying.停止说谎。 This is not a list.这不是一个列表。 It's a vector.它是一个向量。
  • 0 is not a bool, use true/false 0 不是布尔值,使用 true/false
  • if you are going to return a bool to say if something failed then actually check the return value如果你要返回一个布尔值来说明是否有失败,那么实际检查返回值
  • don't use out parameters不要使用 out 参数
  • use exceptions, std::optional or std::expected for error handling with return values使用异常、std::optional 或 std::expected 来处理返回值的错误
  • retrieve and replace should be named operator[] or at and have a const and not-const flavour检索和替换应命名为operator[]at并具有 const 和非 const 风格
  • int maxsize ? int maxsize Seriously?严重地? I can't have lists with more than 2 billion items?我不能拥有超过 20 亿个项目的列表吗?
  • maxsize could be a template parameter maxsize可以是模板参数
  • your indentation is broken你的缩进被打破了

Lets look at your code line by line:让我们逐行查看您的代码:

 bool concat (list<int>&l1,list<int>&l2){

So you want to concat l1 l2 into a single list.所以你想将l1 l2连接到一个列表中。

 int item;

Don't declare variables before you need them.不要在需要变量之前声明它们。

 int c=l2.size(); while(.l1 empty()) {

Wait, if you want to add l2 to l1 then why are you looping till l1 is empty?等等,如果你想将 l2 添加到 l1 那么你为什么要循环直到 l1 为空? Did you implement adding l1 to l2 instead of l2 to l1?您是否实现了将 l1 添加到 l2 而不是 l2 到 l1? So in your concat the arguments are reversed?那么在你的连接中,arguments 是反转的吗?

 for(int i=0; i<l1.size(); i++){

And now you loop a second time, this time over all elements of l1.现在你再循环一次,这次是遍历 l1 的所有元素。 So for some reason this loop won't make l1 empty so you have to try over and over with the while ?所以由于某种原因,这个循环不会让 l1 为空,所以你必须一遍又一遍地尝试while

 l1.retrieve(i,item);

Get the i -th item of l1.获取 l1 的第i个项目。

 if(l2.insert(l2.size(),item)==0){

And insert it at the end of l2.并将其插入到 l2 的末尾。 If it fails:如果失败:

 for(int j=c; j>l2.size()-1; j--){

Starting with the old size of the list, as long as it's the last element, so actually just for the last element at position c :从列表的旧大小开始,只要它是最后一个元素,所以实际上只是 position c的最后一个元素:

 l2.retrieve(j,item);

Retrieve the item one past the end of the list.检索列表末尾之后的项目。 So this fails and item is still the i -th element of l1 .所以这失败了, item 仍然是l1的第i个元素。

 l1.insert(l1.size(),item);

Add the i -th element of l1 to the end of l1 and ignore if it fails.l1的第i个元素添加到l1的末尾,如果失败则忽略。

 l2.remove(j);

Remove the element one past the end of l2 from the list.从列表中删除l2末尾之后的元素。 So this too just fails.所以这也失败了。

 } return 0;

Tell everyone we failed and now l1 and l2 are both possibly changed and maybe some item was lost.告诉大家我们失败了,现在 l1 和 l2 都可能改变了,也许有些项目丢失了。

 } else {

If inserting the element in l2 succeeded:如果在 l2 中插入元素成功:

 c++;

Update the index for the end of l2 so we can't actually restore l2 to it's original state if things fail later on.更新 l2 末尾的索引,因此如果稍后出现故障,我们实际上无法将 l2 恢复到原来的 state。

 l1.remove(i);

and remove the item to complete the move.并移除该项目以完成移动。

That means item 1 is now item 0. But next loop i = 1 , which is item 2 in the original list.这意味着第 1 项现在是第 0 项。但是下一个循环i = 1 ,即原始列表中的第 2 项。 So the for loop actually only moves every second item to l2 , which is the reason for the while .所以for循环实际上只将每隔一个项目移动到l2 ,这就是while的原因。

Too bad that will scramble l1 as you append it to l2 .太糟糕了,当你 append 它到l2时,它会扰乱l1

 } } } return 1;

But hey, success.但是,嘿,成功。 We didn't overflow l2 and loose an item.我们没有溢出l2并丢失一个项目。

 }

The list has a count .该列表有一个count Use it to check at the start if there is enough space.使用它在开始时检查是否有足够的空间。 No undo when things break mid way, that way lies madness.当事情在中途破裂时无法撤消,那就是疯狂。

Then use either the while with remove every loop or the for and set l1.count = 0;然后使用while remove每个循环或for并设置l1.count = 0; at the end.在最后。 The later is obviously faster ( O(n) vs. O(n^2) ).后者显然更快( O(n)O(n^2) )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM