c++ 如果用户输入5,则显示链表的最后5个元素,反之亦然

js81xvg6  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(158)

我被困在我的大学作业中了。
我有一个包含20个元素的链接列表,我必须从用户处获取值,如果用户输入5,则打印链接列表的最后5个元素

void traverse(List list) {
    Node *savedCurrentNode = list.currentNode;
    list.currentNode = list.headNode;
    
    for(int i = 1; list.next() == true; i++)
    {
            std::cout << "Element " << i << " " << list.get() << endl;
    }
    
    list.currentNode = savedCurrentNode;
}

我正在尝试这个方法,但是这个方法打印了我的链表的所有元素

6jygbczu

6jygbczu1#

对于您所拥有的少量代码,请回顾:

// Why are you passing the list by value? That is wasteful.
void traverse(List list) {
    // I don't see you taking a value anywhere; surely you know how to do that

    // What is happening here? Can't you just assign the head to something
    // directly?
    Node *savedCurrentNode = list.currentNode;
    list.currentNode = list.headNode;
    
    // Like you said, this traverses the entire list, it's also poorly
    // formed. You literally don't need i.
    // for (; list.next(); /* However your list increments here */)
    for(int i = 1; list.next() == true; i++)
    {
            std::cout << "Element " << i << " " << list.get() << endl;
    }
    
    // What is the purpose of this?
    list.currentNode = savedCurrentNode;
}

对于正在编写链表的人来说,这段代码似乎有根本性的缺陷。我对处理链表的人的期望是他们即将停止作为一个初学者,但我在代码中没有看到这一点,也没有看到链表类的结构是什么。至少可以说,链表类是 * 怪异 * 的。
首先要说明的是,我的期望源于我把链表作业放在我的课程表中的什么位置,它也比这个链表更符合我的习惯。
如果你花时间仔细考虑这个项目,那么这个任务就变得微不足道了。大多数学生跳过了计划步骤,给自己制造了不必要的麻烦。
既然知道需要列表的总大小,为什么不直接将其作为成员数据呢?任何添加到列表中的函数都会相应地增加值。任何从列表中减去值的函数都会相应地减少值。这样,您就可以随时知道列表的大小。
知道列表的大小是最重要的。然后你需要做必要的算术来推进列表以满足你的要求。现在你可以打印了。

#include <iostream>

class SList {
 public:
  SList() = default;

  //
  // Rule of 5 intentionally left out
  //

  void push_front(int val) {
    m_head = new Node{val, m_head};
    ++m_size;  // The magic happens here
  }

  std::size_t size() const { return m_size; }

  void traverse_last(int numElements, std::ostream& sout = std::cout) const {
    int placement = m_size;
    Node* walker = m_head;

    // Move our walker node the appropriate amount of steps
    while (walker && placement > numElements) {
      walker = walker->next;
      --placement;
    }

    // Now that we're in position, we can print
    while (walker) {
      sout << walker->data << ' ';
      walker = walker->next;
    }
    sout << '\n';
  }

 private:
  struct Node {
    int data;
    Node* next = nullptr;
  };

  Node* m_head = nullptr;
  std::size_t m_size = 0ULL;
};

int main() {
  SList test;

  for (int i = 5; i > 0; --i) {
    test.push_front(i);
  }

  std::cout << "Size: " << test.size() << '\n';

  for (int i = 1; i <= 5; ++i) {
    test.traverse_last(i);
  }
  test.traverse_last(10);
}

输出量:

❯ ./a.out 
Size: 5
5 
4 5 
3 4 5 
2 3 4 5 
1 2 3 4 5 
1 2 3 4 5
bzzcjhmw

bzzcjhmw2#

void traverse(List list, int printFrom)
{
    Node *savedCurrentNode = list.currentNode;
    list.currentNode = list.headNode;
    
    for(int i=1; list.next(); i++)
    {
        if(i > printFrom)
        {
            cout << "Element " << (i - printFrom) << " " << list.get() << endl; 
        }
    }
    
    list.currentNode = savedCurrentNode;
}

通过这个解决了我的问题,printFrom是一个变量,它的值是跳过的元素的数量,就像如果我的链表大小为20,用户想看到最后5个,那么printFrom存储15个,跳过15个值,并打印最后5个

相关问题