C++实习:设计一个循环链表,用来表示大整数

1 题目要求
  • 链表的头结点值为-1,其余结点依次存放数据,各结点最多放四位整数,如下图表示233238766:

  • 利用上述数据结构解决大整数的表示,以及加法、减法运算(用两个链表表示操作数)。
  • 将上述数据结构应用于10位以上求素数问题和阶乘问题。
2 需求分析

本题是利用单向循环链表解决大整数的相关问题。首先要构建一个有数据域和指针域的结点类,再构建一个有头节点、尾结点和存储数据所需结点个数的链表类。

  1. 由于int型变量最多可以存放十位整数,所以大整数输入时应定义为string类,存入链表时再转化为整型。
  2. 需要解决如何将多位整数从低位开始每四位存入链表,且需将string类转化为int类再存入链表的data域。
  3. 加法减法运算需要考虑进位和借位问题,并将所得结果存储到另一个单向循环链表中。
  4. 输出存储在链表中的大整数时由于是单向循环链表低位在表头高位在表尾,输出时需要将在链表中所得的数据倒置,考虑使用STL中的vector容器。当某个结点数值为0时要控制输出补齐四个0。
  5. 大数阶乘考虑使用加法运算来实现乘法。由于参与循环的数据是链表类的,需要重载≤和++运算符确保循环条件的实现。重载≤运算符时需要从高位到低位依次比较仍需借助vector容器实现。
  6. 判断大数是否是素数需要利用除法实现。因为除法是从高位开始运算,需要重载[]运算符从而可以直接获取链表中某个结点所存储的数据。除法中还需要解决借位问题。判断是否是素数时的循环停止条件需要缩小,减少程序运行时间。
3 方案设计

1. 构造结点类。

结点类包含两个公有型的变量:最多存放四位整数的数据域data,指向下一个结点的指针类型的指针域next。一个公有型的成员函数:构造函数对数据域和指针域进行初始化。

2. 构造链表类。

链表类包含三个私有型的变量:结点类型的头指针head和尾指针tail。九个公有型的成员函数:无参构造函数,构造函数,加法函数Add(),减法函数Sub(),返回结点数的函数Length(),输出函数Display(),四个运算符的重载函数,求阶乘的函数Factor()。

3. 链表类的构造函数List(const string &str);

在构造函数中实现将大数每四位由string类型转化为int类型并且利用尾插法插入链表。定义一个int类型的变量len和count,len存储string类型的大数的长度,count存储该大数所需要的结点的个数。当len%4有余数时count=len/4+1,当len%4没有余数时count=len/4。利用所得count数进行循环尾插,利用string类中的substr函数获得四位子串并转化为整型依此存储结点的数据域中,完成链表类的构造。

4. 链表类加法函数List Add(const List &list);

加法函数实现存储在链表中的两个大数相加。加法是从低位开始运算即从头节点head后一个结点开始进行运算,定义int型变量flag表示进位,初始值设置为0当两个链表中的结点相加超过10000,即一个结点中存储的数据超过四位flag更新为1,表示向下一个结点进一位。还需要考虑当两个大数的结点数不同的情况,结点数多的根据进位情况更改数值后直接接在新链表中。当两个链表都走到尾结点tail但flag仍为1则需要开辟新的结点将进位存入数据域data,并接在新链表的最后使其成为新链表的尾结点。

5. 链表类减法函数List Sub(const List &list);

减法函数实现存储在链表中的两个大数相减。减法是从低位开始运算即从头节点head后一个结点开始进行运算,定义int型变量flag表示借位,初始值设置为0,当两个链表中的结点相减小于0时则要加上10000,flag更新为-1表示向下一个结点借一位。也需要考虑当两个大数的结点数不同的情况,结点数多的根据借位情况更改数值后直接接在新链表中。若最后一个结点经过借位后数=数据域存储的数值变为0,则修改指针指向去掉该结点。小数减大数的情况,可在主函数中输出负号解决。

6. 链表类重载<=运算符bool operator <=(const List &list);

重载<=运算函数实现存

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
双向循环链表是一种链式存储结构,每个节点包含一个指向前驱节点和后继节点的指针。在C++语言中,可以通过定义一个双向循环链表类来实现该数据结构。 以下是一个简单的双向循环链表类的实现: ```cpp class Node { public: int value; Node* prev; Node* next; Node(int v) : value(v), prev(nullptr), next(nullptr) {} }; class DoublyLinkedList { public: DoublyLinkedList() : head(nullptr), tail(nullptr), size(0) {} ~DoublyLinkedList() { while (head != nullptr) { Node* temp = head; head = head->next; delete temp; } tail = nullptr; size = 0; } bool empty() const { return size == 0; } int length() const { return size; } void push_front(int v) { Node* newNode = new Node(v); if (empty()) { head = tail = newNode; } else { newNode->next = head; head->prev = newNode; head = newNode; } tail->next = head; head->prev = tail; size++; } void push_back(int v) { if (empty()) { push_front(v); } else { Node* newNode = new Node(v); newNode->prev = tail; tail->next = newNode; tail = newNode; tail->next = head; head->prev = tail; size++; } } void pop_front() { if (size == 1) { delete head; head = tail = nullptr; size = 0; } else if (!empty()) { Node* temp = head; head = head->next; head->prev = tail; tail->next = head; delete temp; size--; } } void pop_back() { if (size == 1) { pop_front(); } else if (!empty()) { Node* temp = tail; tail = tail->prev; tail->next = head; head->prev = tail; delete temp; size--; } } private: Node* head; Node* tail; int size; }; ``` 该类包含两个私有成员变量 `head` 和 `tail`,分别指向链表的头节点和尾节点,以及一个整型变量 `size` 表示链表的长度。类的公有成员函数包括: - `empty()`:判断链表是否为空。 - `length()`:返回链表的长度。 - `push_front(int v)`:在链表头部插入一个值为 `v` 的节点。 - `push_back(int v)`:在链表尾部插入一个值为 `v` 的节点。 - `pop_front()`:删除链表头部的节点。 - `pop_back()`:删除链表尾部的节点。 注意,在插入第一个节点时,需要将 `head` 和 `tail` 都指向该节点,并且将该节点的 `next` 和 `prev` 指针都指向自身。在删除最后一个节点时,需要特别处理,即将 `head` 和 `tail` 都置为 `nullptr`。 可以使用以下代码进行测试: ```cpp #include <iostream> int main() { DoublyLinkedList list; std::cout << "Empty: " << list.empty() << std::endl; std::cout << "Length: " << list.length() << std::endl; list.push_back(1); list.push_front(2); list.push_back(3); std::cout << "Empty: " << list.empty() << std::endl; std::cout << "Length: " << list.length() << std::endl; list.pop_front(); list.pop_back(); std::cout << "Empty: " << list.empty() << std::endl; std::cout << "Length: " << list.length() << std::endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值