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