dhu 单链表ADT模板应用算法设计:长整数加法运算(不使用单链表存储计算结果)

28 篇文章 5 订阅

目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的应用算法设计。

内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)

(2)ADT的应用:使用该ADT设计并实现单链表应用场合的算法设计。

应用:假设2个任意长度的整数x、y分别由带头结点的单链表A和B存储,现要求设计一个算法,实现任意长的整数进行加法运算,运算结果存储在字符串中。

参考函数原型:

template

void Long_Int_Add( LinkList &A, LinkList &B, string &result, const int &len_A, const int &len_B );

1647424776169028074.jpg

辅助函数原型:

(1)从长整数的低位开始拆分(4位为一组,即不超过9999的非负整数),依次存放在单链表的每个结点的数据域中;头结点的数据域存放正负数标志(正数或0:1,负数:-1)。

template

void Input_Int_Division( LinkList &L, string &str, int &length ); (length:长整数分割后的block数,恰为存储用单链表的长度)

(2)计算结果中间位格式控制

string Int_String( int result );

(3)两个长整数的绝对值大小比较(x>y 返回值为1;x<y 返回值为2;x=y 返回值为0;)

template

int Two_LongNum_Compare( LinkList &A, LinkList &B, const int &len_A, const int &len_B );

(4)单链表ADT基本操作:单链表的逆置(实际计算时,鉴于单链表的顺序查找的特性,存储在单链表中的长整数需逆置,由原始的高位到低位排列,逆置为低位到高位降序排列。)

template

void LinkList::ListReverse();

(5)单链表格式遍历:按照长整数的格式(4位为一组,组与组之间用,分隔)

template

bool ListTraverse(LinkList &LInt)

输入说明 :

第一行:长整数x

第二行:长整数y

输出说明 :

第一行:格式化后的长整数x(从低位到高位每4位用","分开)

第二行:格式化后的长整数y(从低位到高位每4位用","分开)

第三行:空行

第四行:格式化后的计算结果(从低位到高位每4位用","分开)

(输入与输出之间用一空行分隔)

题解

手搓了两个半小时才做出来 代码质量只能说惨不忍睹。。。

#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <cstdio>
#include<string>
using namespace std;
#define MAXSIZE 100;
template<class ElemType>
struct LinkNode
{
    ElemType data;
    LinkNode<ElemType>* next;
    LinkNode(LinkNode<ElemType>* ptr = NULL)
    {
        next = ptr;
    }
    LinkNode(const ElemType& item, LinkNode<ElemType>* ptr = NULL)
    {
        next = ptr;
        data = item;
    }
    ElemType getData()//获取数据
    {
        return data;
    }
    void SetLink(LinkNode<ElemType>* link)
    {
        next = link;
    }
    void SetLink(ElemType value)
    {
        data = value;
    }
};//结点定义
template<class ElemType>
class CirLinkList
{
private:
    
public:
    LinkNode<ElemType>* head;
    LinkNode<ElemType>* tail;
    CirLinkList()
    {
        head = NULL;
        tail = NULL;
    }
    LinkNode<ElemType>* GetHead()
    {
        return head;
    }
    LinkNode<ElemType>* GetTail()
    {
        return tail;
    }
    void SetHead(LinkNode<ElemType>* p)
    {
        head = p;
    }
    bool ListTraverse() const;
    void push_back(ElemType element);
    void changeTail(LinkNode<ElemType>* p);
    LinkNode<ElemType>* getHead()
    {
        return head;
    }//输出头结点
    LinkNode<ElemType>* getTail()
    {
        return tail;
    }//输出尾结点
    void sum(CirLinkList <ElemType>& x)
    {
        LinkNode <ElemType>* p = x.getHead();
        tail->next = p;
        tail = x.getTail();
        p = x.GetTail();
        p->next = head;
        p = x.getHead();
        return;
    }
};
template <class ElemType>
void CirLinkList<ElemType>::changeTail(LinkNode<ElemType>* p)
{
    tail = p;
    return;
}
template <class ElemType>
void CirLinkList<ElemType>::push_back(ElemType element)
{
    if (head == NULL)
    {
        head = new LinkNode<ElemType>;
        head->data = element;
        tail = head;
        tail->next = NULL;
        return;
    }
    LinkNode<ElemType>* p = new LinkNode<ElemType>;
    p->data = element;
    p->next = NULL;
    tail->next = p;
    tail = p;
    return;
}
template <class ElemType>
bool sum(CirLinkList<ElemType> A, CirLinkList<ElemType> B,int add_)
{
    LinkNode <ElemType>* q, * p;
    q = A.GetHead(); p = B.getHead();
    while (q != NULL && p != NULL) {
        if (add_ == 0) {
            q->data += p->data;
            if (q->data >= 10000) {
                if (q->next != NULL) {
                    q->next->data++;
                    q->data -= 10000;
                }
                else {
                    q->data -= 10000;
                    A.push_back(1);
                    break;
                }
            }
        }
        else {
            q->data -= p->data;
            if (q->data < 0) {
                if (q->next != NULL) {
                    q->next->data--;
                    q->data += 10000;
                }
            }
        }
        q = q->next; p = p->next;
    }
    if (add_==0&&q!=NULL)
    if (q->data >= 10000) {
        if (q->next != NULL) {
            q->next->data++;
            q->data -= 10000;
        }
        else {
            A.push_back(1);
            q->data -= 10000;
        }
    }
    return 1;
}
template <class ElemType>
bool CirLinkList<ElemType>::ListTraverse() const
{
    LinkNode<ElemType>* p;
    bool fir = 0;
    p = head;
    if (p == NULL)
    {
        cout << "err" << endl;
        return 0;
    }
    while (1)
    {
        if (p == NULL)
            break;
        if (p != head) {
            if (p->data < 1000) cout << "0";
            if (p->data < 100) cout << "0";
            if (p->data < 10) cout << "0";
        }
        cout << p->data;
        if (p->next != NULL)
            cout << ",";
        else
            cout << endl;
        p = p->next;
    }
    return 1;
}
template<class ElemType>
void ReverseList(LinkNode <ElemType> * pCur, CirLinkList <ElemType>& ListHead)
{
    if ((NULL == pCur) || (NULL == pCur->next))
    {
        ListHead.head = pCur;
    }
    else
    {
        LinkNode <ElemType>* pNext = pCur->next;
        ReverseList(pNext, ListHead); //递归逆置后继结点
        pNext->next = pCur;            //将后继结点指向当前结点。
        pCur->next = NULL;
    }
}
int main()
{
    string str1, str2;
    cin >> str1 >> str2;
    int sum1 = 0, sum2 = 0;
    int i = 0;
    bool a1, a2;//0==+ 1==-
    if (str1[0] == '-')
        a1 = 1;
    else
        a1 = 0;
    if (str2[0] == '-')
        a2 = 1;
    else
        a2 = 0;
    CirLinkList <int> A,B,C,D;
    bool ok = 0;
    if (a1) {
        for (i = str1.size() - 1; i >= 1;) {
            int num = 0,k=i;
            num +=  + str1[i] - '0'; i--;
            if (i >= 1) {
                if (k == str1.size() - 1) sum1 = num;
                num += +(str1[i] - '0') * 10; i--;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (i >= 1) {
                if (k == str1.size() - 1) sum1 = num;
                num += (str1[i] - '0') * 100; i--;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (i >= 1) {
                if (k == str1.size() - 1) sum1 = num;
                num+=(str1[i] - '0') * 1000; i--;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (k == str1.size() - 1) sum1 = num;
            A.push_back(num); C.push_back(num);
        }
    }
    else {
        for (i = str1.size() - 1; i >= 0;) {
            int num = 0,k=i;
            num += +str1[i] - '0'; i--;
            if (i >= 0) {
                num += +(str1[i] - '0') * 10; i--;
                if (k == str1.size() - 1) sum1 = num;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (i >= 0) {
                if (k == str1.size() - 1) sum1 = num;
                num += (str1[i] - '0') * 100; i--;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (i >= 0) {
                if (k == str1.size() - 1) sum1 = num;
                num+=(str1[i] - '0') * 1000; i--;
            }
            else {
                A.push_back(num); C.push_back(num);
                break;
            }
            if (k == str1.size() - 1) sum1 = num;
            A.push_back(num); C.push_back(num);
        }
    }
    if (a2) {
        for (i = str2.size() - 1; i >= 1;) {
            int num = 0,k=i;
            num += +str2[i] - '0'; i--;
            if (i >= 1) {
                num += +(str2[i] - '0') * 10; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (i >= 1) {
                num += (str2[i] - '0') * 100; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (i >= 1) {
                num+=(str2[i] - '0') * 1000; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (k == str2.size() - 1) sum2 = num;
            B.push_back(num);  D.push_back(num);
        }
        
    }
    else {
        for (i = str2.size() - 1; i >= 0; ) {
            int num = 0,k=i;
            num += +str2[i] - '0'; i--;
            if (i >= 0) {
                num += +(str2[i] - '0') * 10; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (i >= 0) {
                num += (str2[i] - '0') * 100; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (i >= 0) {
                num+=(str2[i] - '0') * 1000; i--;
                if (k == str2.size() - 1) sum2 = num;
            }
            else {
                B.push_back(num); D.push_back(num);
                break;
            }
            if (k == str2.size() - 1) sum2 = num;
            B.push_back(num); D.push_back(num);
        }
        sum2 = (str2[0] - '0') * 1000 + (str2[1] - '0') * 100 + (str2[2] - '0') * 10 + str2[3] - '0';
    }
    if (sum1 < sum2) ok = 1;
    if (str1.size() > str2.size()) ok = 0;
    bool add_ = 0;
    if (a1 == a2)
        add_ = 0;
    else add_ = 1;
    if (a1 == 1) cout << "-";
       LinkNode <int>* q = C.GetHead();
    ReverseList(q, C);
    C.ListTraverse();
    if (a2 == 1) cout << "-";
    q = D.GetHead();
    ReverseList(q, D);
    D.ListTraverse();
    cout << endl ;
    if (ok == 0) { 
        sum(A, B, add_);
        LinkNode <int>* p = A.getHead();
        ReverseList(p, A);
        if (A.head->data == 0) {
            cout << "0";
            return 0;
        }
        if (a1 == 1) cout << "-";
        A.ListTraverse();
    }
    else {
        sum(B, A, add_);
        LinkNode <int>* p = B.getHead();
        ReverseList(p, B);
        if (B.head->data == 0) {
            cout << "0";
            return 0;
        }
        if (a2 == 1) cout << "-";
        B.ListTraverse();
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值