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

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

int main()
{

    short num;//临时数据段
    char optr;//运算符
    char ch;//临时字符接收
    char choice = 'y';

    while (choice == 'y')
    {
        List *list1 = new List();
        List *list2 = new List();
        cout << "请输入第一个运算数,每三位用逗号分隔,以#结束:" << endl;
        cin >> ch;
        if (ch == '-') list1->sign = 1;
        else cin.putback(ch);
        while (ch != '#')
        {
            cin >> num;//读入一段(3位)整数
            list1->insert_tail(num);//构建第一个运算数的链表
            cin >> ch;//吸收用于分隔的逗号
        }

        cout << "第一个运算数已保存,请输入第二个运算数:" << endl;
        cin >> ch;
        if (ch == '-') list2->sign = 1;
        else cin.putback(ch);
        while (ch != '#')
        {
            cin >> num;
            list2->insert_tail(num);
            cin >> ch;
        }

        cout << "第二个运算数已保存,请输入运算符(+或-):" << endl;
        cin >> optr;

        cout << "运算表达式为:" << endl;
         list1->print();cout << endl;
        cout << optr;
        list2->print();
        cout << endl;

        List* result = operate(list1, list2, optr);
        cout << "运算结果为:" << endl;
        result->print();
        cout << endl;
        delete result, list1, list2;
        cout << "是否继续?[y/n]";
        cin >> choice;
    }

}

链表结点定义

template<class Node_entry>//结点定义
struct Node
{
    //数据成员
    Node_entry entry;
    Node<Node_entry> *back;
    Node<Node_entry> *next;

    //构造函数
    Node(){}
    Node(Node_entry new_entry, 
        Node<Node_entry> *new_back=NULL, Node<Node_entry> *new_next=NULL)
    :entry(new_entry), back(new_back), next(new_next){}
};

双链表的定义

template<class List_entry>
class List
{
public:
    unsigned int count;//结点个数
    Node<List_entry> *head, *tail;//链表头、尾结点
    short sign;//符号

    List()//构造函数
    {
        count=0;
        head=tail=NULL;
        sign=0;
    }
    Error_code insert_tail(const List_entry x)//插在末尾
    {
        Node<List_entry> *new_node=new Node<List_entry>(x);
        if(head==NULL) head=tail=new_node;//第一个结点
        else
        {
            tail->next = new_node;
            new_node->back = tail;
            tail = new_node;
        }
        count++;
        return success;
    }
    Error_code insert_head(const List_entry x)//插在开头
    {
        Node<List_entry> *new_node=new Node<List_entry>(x);
        if (head == NULL) head = tail = new_node;//第一个结点
        else
        {
            head->back=new_node;
            new_node->next=head;
            head=new_node;
        }
        count++;
        return success;
    }
    Error_code delete_head()
    {
        Node<List_entry> *out = head;
        head = head->next;
        delete out;
        count--;
        return success;
    }
    Error_code print()
    {
        if(sign==1) cout<<'-';//打印负号
        if(count==0) return fail;
        if (count==1 && head->entry == 0)//头结点为0且只有这一个结点,直接输出
        {
            cout << head->entry;
            return success;
        }

        while (head->entry == 0)//头结点为0,删除,直至遇到第一个不为0的头结点为止
        {
            delete_head();
        }
        Node<List_entry> *current=head;
        if (count == 1)//只有一个结点,正常打印
        {
            cout << head->entry;
            return success;
        }
        cout << current->entry << ',';//打印第一个结点,不做补位处理
        current = current->next;
        while(current != NULL && current != tail)
        {
            if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
            else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
            cout<<current->entry<<',';
            current=current->next;
        }
        //最后一段结尾没有逗号,所以单独处理
        if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
        else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
        cout<<current->entry;
        return success;
    }
};

List.h

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

template<class List_entry>//比较链表的绝对值
Compare_result compare(List<List_entry> *l1, List<List_entry> *l2)
{
    if (l1->count > l2->count) return Greater;//结点数多,一定大
    else if (l1->count < l2->count) return Less;//结点数少,一定小
    else//结点数一致,从头结点开始比
    {
        Node<List_entry> *temp1, *temp2;
        temp1 = l1->head;
        temp2 = l2->head;
        for (unsigned int i = 0; i < l1->count; i++)
        {
            if (temp1->entry > temp2->entry) return Greater;
            else if (temp1->entry < temp2->entry) return Less;
            temp1 = temp1->next;
            temp2 = temp2->next;
        }
        return Equal;
    }
}

进行加减运算的函数流程图:
用双向链表实现超长整数加减法_第1张图片
链表的成员函数—-运算函数

template<class List_entry>//运算
List<List_entry>* operate(List<List_entry> *list1, List<List_entry> *list2, char optr)
{
    List<List_entry> *result = new List<List_entry>();
    if (optr == '+')//输入了加法
    {
        if (list1->sign == 0 && list2->sign == 0)//a+b,两个正数相加
            result = Plus(list1, list2);
        else if (list1->sign == 0 && list2->sign == 1)//a+(-b)
        {
            if (compare(list1, list2) == Greater)//|a|>|b|时,将a+(-b)转为a-b
                result = Minus(list1, list2);//a-b
            else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
            {
                result = Minus(list2, list1);
                result->sign = 1;//-(b-a)
            }
            else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
        }
        else if (list1->sign == 1 && list2->sign == 0)//(-a)+b
        {
            if (compare(list2, list1) == Greater)//|b|>|a|时,转为b-a
                result = Minus(list2, list1);//b-a
            else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
            {
                result = Minus(list1, list2);//-(a-b)
                result->sign = 1;
            }
            else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
        }
        else //(-a)+(-b),转为-(a+b)
        {
            result = Plus(list1, list2);//-(a+b)
            result->sign = 1;
        }
    }
    else if (optr == '-')//输入了减法
    {
        if (list1->sign == 0 && list2->sign == 0)//a-b,需比较大小
        {
            if (compare(list1,list2)==Greater) 
                result = Minus(list1, list2);//|a|>|b|时,a-b
            else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
            {
                result = Minus(list2, list1);//-(b-a)
                result->sign = 1;
            }
            else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
        }
        else if (list1->sign == 0 && list2->sign == 1)//a+b,两个正数相加
            result = Plus(list1, list2);
        else if (list1->sign == 1 && list2->sign == 0)//(-a)-b,转为-(a+b)
        {
            result = Plus(list1, list2);//-(a+b)
            result->sign = 1;    
        }
        else//(-a)-(-b),即为b-a
        {
            if (compare(list2,list1)==Greater) result = Minus(list2, list1);//|b|>|a|时,转为b-a
            else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
            {
                result = Minus(list1, list2);//-(a-b)
                result->sign = 1;
            }
            else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
        }
    }
    return result;
}

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

template<class List_entry>
List<List_entry>* Plus(List<List_entry>* list1, List<List_entry>* list2)
{
    List<List_entry> *result = new List<List_entry>();//存放结果的链表
    Node<List_entry> *current1 = list1->tail;//初始化操作数
    Node<List_entry> *current2 = list2->tail;
    int carry = 0;//进位标记
    List_entry tempResult;//每段的结果
    int maxCount = list1->count>list2->count ? list1->count : list2->count;//最多的结点个数
    Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
    for (int i = 0; i<maxCount; i++)
    {
        if (current1 == NULL) current1 = zero;
        if (current2 == NULL) current2 = zero;//早到的原地循环
        tempResult = current1->entry + current2->entry + carry;
        carry = 0;//加完进位后将carry置1
        if (tempResult > limitedNum || tempResult==limitedNum)
        {
            carry = 1;//有进位
            tempResult = tempResult % limitedNum;//取余数
        }
        result->insert_head(tempResult);//插入结果链表
        current1 = current1->back;//向高位走
        current2 = current2->back;
    }
    if (carry == 1) result->insert_head(1);
    return result;
}

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

template<class List_entry>
List<List_entry>* Minus(List<List_entry> *list1, List<List_entry> *list2)
{
    List<List_entry> *result = new List<List_entry>();//存放结果的链表
    Node<List_entry> *current1 = list1->tail;//初始化操作数
    Node<List_entry> *current2 = list2->tail;
    int borrow = 0;//借位标记
    List_entry tempResult;//每段的结果
    int maxCount = list1->count;//最多的结点个数(一定是大数减小数)
    Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
    List_entry first;//被减数
    List_entry second;//减数
    for (int i = 0; i<maxCount; i++)
    {
        if (current2 == NULL) current2 = zero;//早到的原地循环
        first = current1->entry;
        second = current2->entry;
        first += borrow;//被减数减去借位
        borrow = 0;
        if (first<second)
        {
            borrow = -1;//有借位
            first += limitedNum;
        }
        tempResult = first - second;
        if (i == maxCount - 1 && tempResult==0) return result;//头结点为0,舍弃,直接返回
        result->insert_head(tempResult);//插入结果链表
        current1 = current1->back;
        current2 = current2->back;
    }
    return result;
}

运行结果:
用双向链表实现超长整数加减法_第2张图片

用双向链表实现超长整数加减法_第3张图片

你可能感兴趣的:(数据结构)