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


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

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

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

    主函数:

     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 }

    运行结果:

  • 相关阅读:
    联合主键有什么用?
    在Spring Boot中使用数据库事务
    Integer.valueOf
    Linux上安装Zookeeper以及一些注意事项
    一个开源的会议管理系统,适合初学者练手(老司机请忽略)
    一个开源的会议管理系统,适合初学者练手(老司机请忽略)
    IntelliJ IDEA中创建Web聚合项目(Maven多模块项目)
    从高考到程序员之毕业流水帐
    Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享
    Shiro中的授权问题(二)
  • 原文地址:https://www.cnblogs.com/helenawang/p/4418650.html
Copyright © 2020-2023  润新知