用双向链表实现超长整数加减法

简介: 学校数据结构的课程实验之一。 用到的数据结构:双向链表 主要功能:对由用户输入的两个任意长的整数进行加减运算 主函数: 1 int main() 2 { 3 4 short num;//临时数据段 5 char optr;//运算符 6 ...

学校数据结构的课程实验之一。

用到的数据结构:双向链表

主要功能:对由用户输入的两个任意长的整数进行加减运算

主函数:

 1 int main()
 2 {
 3     
 4     short num;//临时数据段
 5     char optr;//运算符
 6     char ch;//临时字符接收
 7     char choice = 'y';
 8 
 9     while (choice == 'y')
10     {
11         List<List_entry> *list1 = new List<List_entry>();
12         List<List_entry> *list2 = new List<List_entry>();
13         cout << "请输入第一个运算数,每三位用逗号分隔,以#结束:" << endl;
14         cin >> ch;
15         if (ch == '-') list1->sign = 1;
16         else cin.putback(ch);
17         while (ch != '#')
18         {
19             cin >> num;//读入一段(3位)整数
20             list1->insert_tail(num);//构建第一个运算数的链表
21             cin >> ch;//吸收用于分隔的逗号
22         }
23 
24         cout << "第一个运算数已保存,请输入第二个运算数:" << endl;
25         cin >> ch;
26         if (ch == '-') list2->sign = 1;
27         else cin.putback(ch);
28         while (ch != '#')
29         {
30             cin >> num;
31             list2->insert_tail(num);
32             cin >> ch;
33         }
34 
35         cout << "第二个运算数已保存,请输入运算符(+或-):" << endl;
36         cin >> optr;
37 
38         cout << "运算表达式为:" << endl;
39          list1->print();cout << endl;
40         cout << optr;
41         list2->print();
42         cout << endl;
43 
44         List<List_entry>* result = operate(list1, list2, optr);
45         cout << "运算结果为:" << endl;
46         result->print();
47         cout << endl;
48         delete result, list1, list2;
49         cout << "是否继续?[y/n]";
50         cin >> choice;
51     }
52     
53 }

链表结点定义

 1 template<class Node_entry>//结点定义
 2 struct Node
 3 {
 4     //数据成员
 5     Node_entry entry;
 6     Node<Node_entry> *back;
 7     Node<Node_entry> *next;
 8 
 9     //构造函数
10     Node(){}
11     Node(Node_entry new_entry, 
12         Node<Node_entry> *new_back=NULL, Node<Node_entry> *new_next=NULL)
13     :entry(new_entry), back(new_back), next(new_next){}
14 };

双链表的定义

 1 template<class List_entry>
 2 class List
 3 {
 4 public:
 5     unsigned int count;//结点个数
 6     Node<List_entry> *head, *tail;//链表头、尾结点
 7     short sign;//符号
 8 
 9     List()//构造函数
10     {
11         count=0;
12         head=tail=NULL;
13         sign=0;
14     }
15     Error_code insert_tail(const List_entry x)//插在末尾
16     {
17         Node<List_entry> *new_node=new Node<List_entry>(x);
18         if(head==NULL) head=tail=new_node;//第一个结点
19         else
20         {
21             tail->next = new_node;
22             new_node->back = tail;
23             tail = new_node;
24         }
25         count++;
26         return success;
27     }
28     Error_code insert_head(const List_entry x)//插在开头
29     {
30         Node<List_entry> *new_node=new Node<List_entry>(x);
31         if (head == NULL) head = tail = new_node;//第一个结点
32         else
33         {
34             head->back=new_node;
35             new_node->next=head;
36             head=new_node;
37         }
38         count++;
39         return success;
40     }
41     Error_code delete_head()
42     {
43         Node<List_entry> *out = head;
44         head = head->next;
45         delete out;
46         count--;
47         return success;
48     }
49     Error_code print()
50     {
51         if(sign==1) cout<<'-';//打印负号
52         if(count==0) return fail;
53         if (count==1 && head->entry == 0)//头结点为0且只有这一个结点,直接输出
54         {
55             cout << head->entry;
56             return success;
57         }
58         
59         while (head->entry == 0)//头结点为0,删除,直至遇到第一个不为0的头结点为止
60         {
61             delete_head();
62         }
63         Node<List_entry> *current=head;
64         if (count == 1)//只有一个结点,正常打印
65         {
66             cout << head->entry;
67             return success;
68         }
69         cout << current->entry << ',';//打印第一个结点,不做补位处理
70         current = current->next;
71         while(current != NULL && current != tail)
72         {
73             if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
74             else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
75             cout<<current->entry<<',';
76             current=current->next;
77         }
78         //最后一段结尾没有逗号,所以单独处理
79         if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
80         else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
81         cout<<current->entry;
82         return success;
83     }
84 };
List.h

用于比较链表值的大小的函数

 1 template<class List_entry>//比较链表的绝对值
 2 Compare_result compare(List<List_entry> *l1, List<List_entry> *l2)
 3 {
 4     if (l1->count > l2->count) return Greater;//结点数多,一定大
 5     else if (l1->count < l2->count) return Less;//结点数少,一定小
 6     else//结点数一致,从头结点开始比
 7     {
 8         Node<List_entry> *temp1, *temp2;
 9         temp1 = l1->head;
10         temp2 = l2->head;
11         for (unsigned int i = 0; i < l1->count; i++)
12         {
13             if (temp1->entry > temp2->entry) return Greater;
14             else if (temp1->entry < temp2->entry) return Less;
15             temp1 = temp1->next;
16             temp2 = temp2->next;
17         }
18         return Equal;
19     }
20 }

进行加减运算的函数流程图:

链表的成员函数----运算函数

 1 template<class List_entry>//运算
 2 List<List_entry>* operate(List<List_entry> *list1, List<List_entry> *list2, char optr)
 3 {
 4     List<List_entry> *result = new List<List_entry>();
 5     if (optr == '+')//输入了加法
 6     {
 7         if (list1->sign == 0 && list2->sign == 0)//a+b,两个正数相加
 8             result = Plus(list1, list2);
 9         else if (list1->sign == 0 && list2->sign == 1)//a+(-b)
10         {
11             if (compare(list1, list2) == Greater)//|a|>|b|时,将a+(-b)转为a-b
12                 result = Minus(list1, list2);//a-b
13             else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
14             {
15                 result = Minus(list2, list1);
16                 result->sign = 1;//-(b-a)
17             }
18             else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
19         }
20         else if (list1->sign == 1 && list2->sign == 0)//(-a)+b
21         {
22             if (compare(list2, list1) == Greater)//|b|>|a|时,转为b-a
23                 result = Minus(list2, list1);//b-a
24             else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
25             {
26                 result = Minus(list1, list2);//-(a-b)
27                 result->sign = 1;
28             }
29             else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
30         }
31         else //(-a)+(-b),转为-(a+b)
32         {
33             result = Plus(list1, list2);//-(a+b)
34             result->sign = 1;
35         }
36     }
37     else if (optr == '-')//输入了减法
38     {
39         if (list1->sign == 0 && list2->sign == 0)//a-b,需比较大小
40         {
41             if (compare(list1,list2)==Greater) 
42                 result = Minus(list1, list2);//|a|>|b|时,a-b
43             else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
44             {
45                 result = Minus(list2, list1);//-(b-a)
46                 result->sign = 1;
47             }
48             else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
49         }
50         else if (list1->sign == 0 && list2->sign == 1)//a+b,两个正数相加
51             result = Plus(list1, list2);
52         else if (list1->sign == 1 && list2->sign == 0)//(-a)-b,转为-(a+b)
53         {
54             result = Plus(list1, list2);//-(a+b)
55             result->sign = 1;    
56         }
57         else//(-a)-(-b),即为b-a
58         {
59             if (compare(list2,list1)==Greater) result = Minus(list2, list1);//|b|>|a|时,转为b-a
60             else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
61             {
62                 result = Minus(list1, list2);//-(a-b)
63                 result->sign = 1;
64             }
65             else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
66         }
67     }
68     return result;
69 }
operate

运算函数的辅助函数----加法

 1 template<class List_entry>
 2 List<List_entry>* Plus(List<List_entry>* list1, List<List_entry>* list2)
 3 {
 4     List<List_entry> *result = new List<List_entry>();//存放结果的链表
 5     Node<List_entry> *current1 = list1->tail;//初始化操作数
 6     Node<List_entry> *current2 = list2->tail;
 7     int carry = 0;//进位标记
 8     List_entry tempResult;//每段的结果
 9     int maxCount = list1->count>list2->count ? list1->count : list2->count;//最多的结点个数
10     Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
11     for (int i = 0; i<maxCount; i++)
12     {
13         if (current1 == NULL) current1 = zero;
14         if (current2 == NULL) current2 = zero;//早到的原地循环
15         tempResult = current1->entry + current2->entry + carry;
16         carry = 0;//加完进位后将carry置1
17         if (tempResult > limitedNum || tempResult==limitedNum)
18         {
19             carry = 1;//有进位
20             tempResult = tempResult % limitedNum;//取余数
21         }
22         result->insert_head(tempResult);//插入结果链表
23         current1 = current1->back;//向高位走
24         current2 = current2->back;
25     }
26     if (carry == 1) result->insert_head(1);
27     return result;
28 }

运算函数的辅助函数----减法

 1 template<class List_entry>
 2 List<List_entry>* Minus(List<List_entry> *list1, List<List_entry> *list2)
 3 {
 4     List<List_entry> *result = new List<List_entry>();//存放结果的链表
 5     Node<List_entry> *current1 = list1->tail;//初始化操作数
 6     Node<List_entry> *current2 = list2->tail;
 7     int borrow = 0;//借位标记
 8     List_entry tempResult;//每段的结果
 9     int maxCount = list1->count;//最多的结点个数(一定是大数减小数)
10     Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
11     List_entry first;//被减数
12     List_entry second;//减数
13     for (int i = 0; i<maxCount; i++)
14     {
15         if (current2 == NULL) current2 = zero;//早到的原地循环
16         first = current1->entry;
17         second = current2->entry;
18         first += borrow;//被减数减去借位
19         borrow = 0;
20         if (first<second)
21         {
22             borrow = -1;//有借位
23             first += limitedNum;
24         }
25         tempResult = first - second;
26         if (i == maxCount - 1 && tempResult==0) return result;//头结点为0,舍弃,直接返回
27         result->insert_head(tempResult);//插入结果链表
28         current1 = current1->back;
29         current2 = current2->back;
30     }
31     return result;
32 }

运行结果:

 

目录
相关文章
|
6月前
|
C语言
链表部分小题和双向链表
链表部分小题和双向链表
|
4月前
|
算法 程序员
【算法训练-链表 五】【链表求和】:链表相加(逆序)、链表相加II(顺序)
【算法训练-链表 五】【链表求和】:链表相加(逆序)、链表相加II(顺序)
50 0
|
4月前
|
算法 程序员
【算法训练-链表 七】【链表排序】:链表排序、链表的奇偶重排、重排链表
【算法训练-链表 七】【链表排序】:链表排序、链表的奇偶重排、重排链表
35 1
|
5月前
链表相加(二)
链表相加(二)
21 0
|
5月前
|
存储 算法
【霍罗维兹数据结构】单链表 | 动态链接的栈和队列 | 多项式 - POLYNOMIALS | 一些链表的操作
【霍罗维兹数据结构】单链表 | 动态链接的栈和队列 | 多项式 - POLYNOMIALS | 一些链表的操作
37 0
|
6月前
|
存储 人工智能 C++
剑指offer(C++)-JZ22:链表中倒数最后k个结点(数据结构-链表)
剑指offer(C++)-JZ22:链表中倒数最后k个结点(数据结构-链表)
|
6月前
|
存储 C++ 容器
剑指offer(C++)-JZ6:从尾到头打印链表(数据结构-链表)
剑指offer(C++)-JZ6:从尾到头打印链表(数据结构-链表)
|
8月前
|
C语言
C语言:相交链表
给你两个单链表的头节点 headA和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
828 0
|
11月前
|
存储 算法 NoSQL
【数据结构】一元多项式
【数据结构】一元多项式
57 0
|
C语言
相交链表(C语言)
相交链表(C语言)
86 0
相交链表(C语言)