链表实现大整数 加减法 一个节点保存四位数字(C++实现)

可用来熟悉数据结构与C++语言内容。

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
class node {
public:
    node() {
        ch = "";
        next = nullptr;
    }
    node(string a) {
        ch = a;
        next = nullptr;
    }
    node(int a) {
        ch = to_string(a);
        while(ch.size() < 4) {
            ch = '0' + ch;
        }
        next = nullptr;
    }
    node(node *tmp) {
        ch = tmp->ch;
        next = nullptr;
    }

    string get() {
        return ch;
    }

public:
    string ch;
    node *next;
};

class List {
public:
    List() : head(new node),level(0),negative(false) {}
    List(string s) {
        level = 0;
        negative = false;
        if(s[0] == '-') {
            negative = true;
            s = s.substr(1);
        }
        head = new node;
        node* tmp = head;
        int n = s.size() % 4;
        if(n != 0) {
            string sub = s.substr(0,n);
            tmp->next = new node(sub);
            tmp = tmp->next;
            s = s.substr(n);
            level++;
        }
        while(!s.empty()) {
            string sub = s.substr(0,4);
            tmp->next = new node(sub);
            tmp = tmp->next;
            s = s.substr(4);
            level++;
        }
    }
 
    List(const List &t) {
        this->head = new node;
        node *tmp = head->next;
        node *my = this->head;
        this->level = t.level;
        this->negative = t.negative;
        while(tmp != nullptr) {
            my->next = new node(tmp);
            my = my->next;
            tmp = tmp->next;
        }
    }
    friend List operator+(const List& t,const List& a) {
        List ans;

        vector<int>pt(t.level);
        vector<int>pa(a.level);

        node* tmp = t.head->next;
        int k = 0;
        while(tmp != nullptr) {
            const char* ts = tmp->ch.data();
            pt[k++] = atoi(ts);
            tmp = tmp->next;
        }
        k = 0;
        tmp = a.head->next;
        while(tmp != nullptr) {
            const char* ts = tmp->ch.data();
            pa[k++] = atoi(ts);
            tmp = tmp->next;
        }

        int i = pt.size() - 1;
        int j = pa.size() - 1;
        tmp = ans.head->next;
        while(i >= 0 && j >= 0) {
            int u = pt[i] + pa[j] + carry;
            carry = 0;
            if(u > 10000) carry = 1;
            node *t = new node(u);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            i--;
            j--;
        }

        while(i >= 0) {
            int u = carry + pt[i];
            carry = 0;
            if(u > 10000) carry = 1;
            node *t = new node(u);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            i--;
        }

        while(j >= 0) {
            int u = carry + pa[j];
            carry = 0;
            if(u > 10000) carry = 1;
            node *t = new node(u);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            j--;            
        }

        if(carry) {
            node *t = new node(carry);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;            
            carry = 0;
        }

        return ans;
    }
    
    friend List operator-(const List &t,const List &a) {

        List ans; 
        vector<int>pt(t.level);
        vector<int>pa(a.level);

        node* tmp = t.head->next;
        int k = 0;
        while(tmp != nullptr) {
            const char* ts = tmp->ch.data();
            pt[k++] = atoi(ts);
            tmp = tmp->next;
        }
        k = 0;
        tmp = a.head->next;
        while(tmp != nullptr) {
            const char* ts = tmp->ch.data();
            pa[k++] = atoi(ts);
            tmp = tmp->next;
        }
 
        //smaller - bigger
        if(t.level < a.level) {
            vector<int>tmp(pt);
            pt = pa;
            pa = tmp;
            ans.negative = true;
        }

        if(t.level == a.level) {
            int k = 0;
            while(k < t.level) {
                if(pt[k] < pa[k]) break;
                k++;
            }
            if(k != t.level) {
                vector<int>tmp(pt);
                pt = pa;
                pa = tmp;
                ans.negative = true;
            }
        }
        
        int i = pt.size() - 1;
        int j = pa.size() - 1;

        while(i >= 0 && j >= 0) {
            int u = pt[i] - pa[j] - carry;
            carry = 0;
            string p = "";
            if(u < 0) {
                u += 10000;
                carry = 1;
                p = to_string(u);
                while(p.size() < 4) {
                    p = '0' + p;
                }
            }else {
                p = to_string(u);
                while(p.size() < 4) {
                    p = '0' + p;
                }                
            }
            node *t = new node(p);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            i--;
            j--;
        }
        while(i >= 0) {
            string p = "";
            if(carry) {
                pt[i] -= carry;
                carry = 0;
            }
            p = to_string(pt[i]);
            while(p.size() < 4) {
                p = '0' + p;
            }  
            node *t = new node(p);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            i--;            
        }
        while(j >= 0) {
            string p = "";
            if(carry) {
                pa[j] -= carry;
                carry = 0;
            }
            p = to_string(pa[j]);
            while(p.size() < 4) {
                p = '0' + p;
            }  
            node *t = new node(p);
            ans.head->next = t;
            t->next = tmp;
            tmp = t;
            j--;              
        }
        return ans;
    }
    void print() {
        if(negative == true) cout<<'-';
        node *tmp = head->next;
        string ans = "";
        while(tmp != nullptr) {

            if(tmp == head->next) {
                const char* ts = tmp->ch.data();
                ans = ans + ts;
                // int u = atoi(ts);
                // if(u != 0)
                //     cout<<u;
            }else {
                ans = ans + tmp->ch;
                //cout<<tmp->ch;
            }
            
            tmp = tmp->next;
        }
        while(ans[0] == '0') ans = ans.substr(1);

        cout<<ans<<endl;
    }

public:
    static int carry;
    node *head;
    int level;
    bool negative;
};
int List::carry = 0;
int main()
{
    string a,b;
    while(cin>>a>>b) {
        List t1(a),t2(b);
        List ans = t1 + t2;
        List ans2 = t1 - t2;
        t1.print();
        t2.print();
        ans.print();
        ans2.print();

    }
    system("pause");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表实现大整数加减法操作的思路如下: 1. 将两个大整数转换成链表,每个节点存储一个数字。 2. 遍历两个链表,从低位到高位逐一相加或相减两个节点的值,得到当前位的结果。 3. 如果相加或相减后的结果超过了10,需要将进位或借位记录下来,作为下一次计算的额外数值。 4. 如果两个链表长度不一致,需要先将短的链表用0节点补齐长度。 5. 最后得出的结果可能包含前导0,需要去除。 6. 将最终结果转换成链表返回。 下面是基于Python语言实现的代码,具体注释见代码中: ``` class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: # 建立哑节点,简化边界条件判断 dummy = ListNode(0) curr = dummy carry = 0 # 进位值 while l1 or l2: # 取出两个链表当前节点的值,如果没有节点则默认为0 val1 = l1.val if l1 else 0 val2 = l2.val if l2 else 0 # 计算当前位的和,加上上一次进位值 total = carry + val1 + val2 # 计算当前位的进位值,如果有则为1,否则为0 carry = 1 if total >= 10 else 0 # 计算当前位的实际值 curr.next = ListNode(total % 10) curr = curr.next # 遍历两个链表 if l1: l1 = l1.next if l2: l2 = l2.next # 判断最高位是否有进位值 if carry > 0: curr.next = ListNode(carry) return dummy.next def subTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: # 建立哑节点,简化边界条件判断 dummy = ListNode(0) curr = dummy borrow = 0 # 借位值 while l1 or l2: # 取出两个链表当前节点的值,如果没有节点则默认为0 val1 = l1.val if l1 else 0 val2 = l2.val if l2 else 0 # 计算当前位的差,减去上一次借位值 sub = val1 - val2 - borrow # 计算当前位的借位值,如果有则为1,否则为0 borrow = 1 if sub < 0 else 0 # 计算当前位的实际值 curr.next = ListNode((sub + 10) % 10) curr = curr.next # 遍历两个链表 if l1: l1 = l1.next if l2: l2 = l2.next # 判断最高位是否有借位值 if borrow > 0: curr.next = ListNode(borrow) # 去除前导0 while dummy.next and dummy.next.val == 0: dummy.next = dummy.next.next return dummy.next ``` 使用样例: ``` # 两个大整数相加 l1 = ListNode(2, ListNode(4, ListNode(3))) l2 = ListNode(5, ListNode(6, ListNode(4))) result = addTwoNumbers(l1, l2) while result: print(result.val) result = result.next # 输出:7 0 8 # 两个大整数相减 l3 = ListNode(9, ListNode(2, ListNode(3))) l4 = ListNode(5, ListNode(6, ListNode(4))) result = subTwoNumbers(l3, l4) while result: print(result.val) result = result.next # 输出:3 6 9 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值