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

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

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

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

主函数:

 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 }

运行结果:

 

时间: 2024-09-27 21:09:29

用双向链表实现超长整数加减法的相关文章

程序-c语言课设 超长整数处理

问题描述 c语言课设 超长整数处理 解决方案 decimal大数据类型 解决方案二: 楼主 要求是几天内交?

C语言实现大整数加减运算详解_C 语言

前言     我们知道,在数学中,数值的大小是没有上限的,但是在计算机中,由于字长的限制,计算机所能表示的范围是有限的,当我们对比较小的数进行运算时,如:1234+5678,这样的数值并没有超出计算机的表示范围,所以可以运算.但是当我们在实际的应用中进行大量的数据处理时,会发现参与运算的数往往超过计算机的基本数据类型的表示范围,比如说,在天文学上,如果一个星球距离我们为100万光年,那么我们将其化简为公里,或者是米的时候,我们会发现这是一个很大的数.这样计算机将无法对其进行直接计算.     可

WEB常用测试用例—文本输入框

对于普通的文本输入框,通常要检查以下几点: 1. 中英文空格 2. 字符串首尾含空格 3. 字符串中间含空格 4. 字母 5. 数字 6. 中文 7. 特殊字符 8. null/NULL 9. 超长字符 10. html格式字符串 对于费用类的文本输入框,通常要检查以下几点: 1. 正常整数 2. 正常小数 3. 负数 4. 以0开头/结尾的整数 5. 以0开头/结尾的小数(不是0.多少这种) 6. 超长整数 7. 超长小数 8. 以小数点开头/结束 9. 中英文空格 10. 字母 11.特殊字

一个大神的工程(复旦 季同学)16bit RISC cpu

2014年8月25日更新更新内容为超越函数计算器和CPU指令实现部分           断断续续终于做好了视频和介绍就用日志一起发出来了.工程还未完工视频展示计算器功能电子表和字符显示器时序控制.        视频建议看的时候点右下角设置选超清+全屏观看选标清既不清楚有时候还会卡高清也看不清细节就算是超清也比我上传的原视频缩了.优酷60秒的广告还要缩画质满地节操真心抱歉...        本工程基于一个叫Minecraft的游戏我使用的版本是1.4.7.之所以使用一个游戏作为平台是因为这个

算法之【仿竖式算法】

另类四则运算之大整数加减法: 十进制的数值运算在计算机里都将转换成二进制的数值运算,而二进制的运算就是cpu中最根本的逻辑运算,最后再转化成十进制输出.这次介绍的方法是保留十进制的运算方式(小学生的列竖式计算),仅仅将每位数字转换成二进制.这种算法既在速度上有所提升,又能克服单个数据存储大小的限制.因此可以用来进行大整数的加减法(大整数通常指16位或32位以上整型数).至于竖式计算的原理就不说了哦,不然有损大家的智商!   核心:模拟竖式计算,将大整数的每一位分开来存储与计算.   C语言完整程

《深入理解C++11:C++ 11新特性解析与应用》——2.3 扩展的整型

2.3 扩展的整型 类别:部分人 程序员常会在代码中发现一些整型的名字,比如UINT.__int16.u64.int64_t,等等.这些类型有的源自编译器的自行扩展,有的则是来自某些编程环境(比如工作在Linux内核代码中),不一而足.而事实上,在C++11中一共只定义了以下5种标准的有符号整型: 标准同时规定,每一种有符号整型都有一种对应的无符号整数版本,且有符号整型与其对应的无符号整型具有相同的存储空间大小.比如与signed int对应的无符号版本的整型是unsigned int. 在实际

基础野:细说浮点数

Brief   本来只打算理解JS中0.1 + 0.2 == 0.30000000000000004的原因,但发现自己对计算机的数字表示和运算十分陌生,于是只好恶补一下.  本篇我们一起来探讨一下基础--浮点数的表示方式和加减乘除运算.   在深入前有两点我们要明确的:   1. 在同等位数的情况下,浮点数可表示的数值范围比整数的大:   2. 浮点数无法精确表示其数值范围内的所有数值,只能精确表示可用科学计数法m*2e表示的数值而已:      (如0.5的科学计数法是2-1,则可被精确存储:

分数加减法

分数加减法 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 编写一个C程序,实现两个分数的加减法 输入 输入包含多行数据 每行数据是一个字符串,格式是"a/boc/d". 其中a, b, c, d是一个0-9的整数.o是运算符"+"或者"-". 数据以EOF结束 输入数据保证合法 输出 对于输入数据的每一行输出两个分数的运算结果. 注意结果应符合书写习惯,没有多余的符号.分子.分母,并且化简至最简分数 样例输入 1/

JavaScript超大整数加法

什么是「超大整数」? JavaScript 采用 IEEE754标准 中的浮点数算法来表示数字 Number. 我也没花时间去详细了解 IEEE754标准 ,但对于处理超大整数,了解下面的几个知识点就足够了. 首先,JavaScript 实际上可以表示的最大数是: 1.7976931348623157e+308 Number.MAX_VALUE; // 1.7976931348623157e+308 虽然这个数可以正确表示出来,但会存在「精度丢失」的问题. 那什么是「精度丢失」? 我们看看下面的