学校数据结构的课程实验之一。
用到的数据结构:双向链表
主要功能:对由用户输入的两个任意长的整数进行加减运算
主函数:
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 }
运行结果: