用双向链表实现大数加减法

  写了5个小时,C++面向对象的东西都不会写了。。。以后要多写C++少写python。。。关于读入字符串处理的那部分写得太挫就不放了。

#include "List.hpp"

List

  1 #pragma once
  2 #include <cstdio>
  3 #include <cassert>
  4
  5 namespace kirai {
  6     template<class type> class List {
  7     private:
  8         typedef struct ListNode {
  9             type data;
 10             ListNode* pre;
 11             ListNode* next;
 12             ListNode() : data(data) { pre = NULL; next = NULL; }
 13             ListNode(const type& dd, ListNode*& pp, ListNode*& nn) :
 14                 data(dd), pre(pp), next(nn) {}
 15         }ListNode;
 16         ListNode* head;
 17     public:
 18         List() : head(new ListNode()) { head->pre = head->next = head; };
 19         int size() const;
 20         bool empty() const;
 21         void push_back(const type&);
 22         type last() const;
 23         void pop_back();
 24         void modifyLast(const type&);
 25         void insert(const type& ele, int idx);
 26         type get(int idx) const;
 27         type& operator [](int idx);
 28         type remove(int idx);
 29         void modify(const type& ele, int idx);
 30         int find(const type&) const;
 31         void clear();
 32         ~List() = default;
 33     };
 34
 35     template<class type>
 36     int List<type>::size() const {
 37         int tot = 0;
 38         ListNode* p = head->next;
 39         while (p != head) {
 40             tot++;
 41             p = p->next;
 42         }
 43         return tot;
 44     }
 45
 46     template<class type>
 47     bool List<type>::empty() const {
 48         return head == head->next ? 1 : 0;
 49     }
 50
 51     template<class type>
 52     void List<type>::push_back(const type& element) {
 53         ListNode* p = new ListNode(element, head->pre, head);
 54         head->pre = head->pre->next = p;
 55     }
 56
 57     template<class type>
 58     type List<type>::last() const {
 59         assert(!empty());
 60         return head->pre->data;
 61     }
 62
 63     template<class type>
 64     void List<type>::pop_back() {
 65         assert(!empty());
 66         ListNode* p = head->pre->pre;
 67         delete head->pre;
 68         head->pre = p;
 69         p->next = head;
 70     }
 71
 72     template<class type>
 73     void List<type>::modifyLast(const type& element) {
 74         assert(!empty());
 75         head->pre->data = element;
 76     }
 77
 78     template<class type>
 79     void List<type>::insert(const type& element, int idx) {
 80         idx++;
 81         assert(idx > 0 && idx <= size() + 1);
 82         ListNode* p = head;
 83         while (idx--) p = p->next;
 84         ListNode* cur = new ListNode(element, p->pre, p);
 85         p->pre = p->pre->next = cur;
 86     }
 87
 88     template<class type>
 89     type List<type>::get(int idx) const {
 90         idx++;
 91         assert(!empty() && idx > 0 && idx <= size());
 92         ListNode* p = head->next;
 93         while (--idx) p = p->next;
 94         return p->data;
 95     }
 96     template<class type>
 97     type& List<type>::operator [](int idx) {
 98         idx++;
 99         assert(!empty() && idx > 0 && idx <= size());
100         ListNode* p = head->next;
101         while (--idx) p = p->next;
102         return p->data;
103     }
104     template<class type>
105     type List<type>::remove(int idx) {
106         idx++;
107         assert(!empty() && idx > 0 && idx <= size());
108         ListNode* p = head->next;
109         while (--idx) p = p->next;
110         p->pre->next = p->next;
111         p->next->pre = p->pre;
112         type d = p->data;
113         delete p;
114         return d;
115     }
116
117     template<class type>
118     void List<type>::modify(const type& ele, int idx) {
119         idx++;
120         assert(!empty() && idx > 0 && idx <= size());
121         ListNode* p = head->next;
122         while (--idx) p = p->next;
123         p->data = ele;
124     }
125
126     template<class type>
127     int List<type>::find(const type& ele) const {
128         ListNode* p = head->next;
129         int idx = 0;
130         while (p != head) {
131             if (p->data == ele) return idx;
132             p = p->next;
133             idx++;
134         }
135         return -1;
136     }
137     template<class type>
138     void List<type>::clear() {
139         assert(!empty());
140     }
141 }

List.hpp

 1 #pragma once
 2 #include "lib/List"
 3
 4 using kirai::List;
 5
 6 #define positive 1
 7 #define negative 0
 8
 9 class BigInteger {
10 public:
11     BigInteger() { _symbol = positive; }
12     BigInteger(const char*);
13     ~BigInteger() = default;
14     BigInteger add(const BigInteger&);
15     BigInteger sub(const BigInteger&);
16     bool symbol()const { return this->_symbol; }
17     void setSymbol(bool isPositive) { this->_symbol = isPositive; }
18     void setNum(List<short> s) { data = s; }
19     void show();
20     int cmp(const BigInteger&);
21     BigInteger addTwoPositive(const BigInteger&, const BigInteger&);
22     BigInteger bigSubSmall(const BigInteger&, const BigInteger&);
23     bool _symbol;
24     List<short> data;
25 };

BigInteger.h

  1 #include "BigInteger.h"
  2 #include <cassert>
  3 #include <iostream>
  4 #include <iomanip>
  5
  6 #define positive 1
  7 #define negative 0
  8
  9 int BigInteger::cmp(const BigInteger& A) {
 10     // 比较两个数的绝对值大小,如果this大返回1,A大返回-1,相等返回0
 11     int la = this->data.size();
 12     int lb = A.data.size();
 13     if (la > lb) return 1;
 14     if (la < lb) return -1;
 15     // 长度相等的时候,从高位比到低位
 16     for (int i = la - 1; i >= 0; i--) {
 17         if (this->data.get(i) > A.data.get(i)) return 1;
 18         if (this->data.get(i) < A.data.get(i)) return -1;
 19     }
 20     return 0;
 21 }
 22
 23 BigInteger BigInteger::add(const BigInteger& B) {
 24     assert(!this->data.empty() && !B.data.empty());
 25     // 拷贝
 26     BigInteger ta = *this;
 27     BigInteger tb = B;
 28     BigInteger ans;
 29
 30     // 全都是负数到时候,传入参数的时候做相加操作
 31     if (negative == this->symbol() && negative == B.symbol()) {
 32         ta.setSymbol(positive); tb.setSymbol(positive);
 33         ans = addTwoPositive(ta, tb);
 34         ans.setSymbol(negative);
 35     }
 36     // 全都是正数的时候,直接相加
 37     if (positive == this->symbol() && positive == B.symbol()) {
 38         ans = addTwoPositive(ta, tb);
 39         ans.setSymbol(positive);
 40     }
 41     // 一正一负的情况,比较一下绝对值大小
 42     else {
 43         int flag;
 44         // A正B负
 45         if (positive == this->symbol() && negative == B.symbol()) {
 46             flag = this->cmp(B);
 47             if (flag == 1) {    //相当于非负数减法
 48                 ta.setSymbol(positive); tb.setSymbol(positive);
 49                 ans = bigSubSmall(ta, tb);
 50                 ans.setSymbol(positive);
 51             }
 52             if (flag == 0) {    //直接返回0即可
 53                 ta.setSymbol(positive); tb.setSymbol(positive);
 54                 ans.data.push_back(0);
 55                 ans.setSymbol(positive);
 56             }
 57             if (flag == -1) {    //相当于负数的绝对值减正数,结果为负
 58                 ta.setSymbol(positive); tb.setSymbol(positive);
 59                 ans = bigSubSmall(tb, ta);
 60                 ans.setSymbol(negative);
 61             }
 62         }
 63         // A负B正
 64         if (negative == this->symbol() && positive == B.symbol()) {
 65             flag = this->cmp(B);
 66             if (flag == 1) {    //相当于负数的绝对值减正数,结果为负
 67                 ta.setSymbol(positive); tb.setSymbol(positive);
 68                 ans = bigSubSmall(ta, tb);
 69                 ans.setSymbol(negative);
 70             }
 71             if (flag == 0) {    //直接返回0即可
 72                 ta.setSymbol(positive); tb.setSymbol(positive);
 73                 ans.data.push_back(0);
 74                 ans.setSymbol(positive);
 75             }
 76             if (flag == -1) {    //相当于非负数减法
 77                 ta.setSymbol(positive); tb.setSymbol(positive);
 78                 ans = bigSubSmall(tb, ta);
 79                 ans.setSymbol(positive);
 80             }
 81         }
 82     }
 83     return ans;
 84 }
 85
 86 BigInteger BigInteger::sub(const BigInteger& B) {
 87     assert(!this->data.empty() && !B.data.empty());
 88     // 拷贝
 89     BigInteger* A = const_cast<BigInteger*>(this);
 90     BigInteger ta = *this;
 91     BigInteger tb = B;
 92     BigInteger ans;
 93
 94     // A正B负,做加法,结果为正
 95     if (positive == this->symbol() && negative == B.symbol()) {
 96         ta.setSymbol(positive); tb.setSymbol(positive);
 97         addTwoPositive(ta, tb);
 98         ans.setSymbol(positive);
 99     }
100     // A负B正,做加法,结果为负
101     if (negative == this->symbol() && positive == B.symbol()) {
102         ta.setSymbol(positive); tb.setSymbol(positive);
103         addTwoPositive(ta, tb);
104         ans.setSymbol(negative);
105     }
106     else {
107         int flag;
108         // 两个数都是正
109         if (positive == this->symbol() && positive == B.symbol()) {
110             flag = this->cmp(B);
111             if (flag == 1) {    //相当于大减小,结果为正
112                 ta.setSymbol(positive); tb.setSymbol(positive);
113                 ans = bigSubSmall(ta, tb);
114                 ans.setSymbol(positive);
115             }
116             if (flag == 0) {    //直接返回0即可
117                 ta.setSymbol(positive); tb.setSymbol(positive);
118                 ans.data.push_back(0);
119                 ans.setSymbol(positive);
120             }
121             if (flag == -1) {    //相当于小减大,反着减结果为负
122                 ta.setSymbol(positive); tb.setSymbol(positive);
123                 ans = bigSubSmall(tb, ta);
124                 ans.setSymbol(negative);
125             }
126         }
127         //两个数都是负
128         if (negative == this->symbol() && negative == B.symbol()) {
129             ta.setSymbol(positive); tb.setSymbol(positive);
130             flag = this->cmp(B);
131             if (flag == 1) {    //相当于大的减小的,结果为负
132                 ta.setSymbol(positive); tb.setSymbol(positive);
133                 ans = bigSubSmall(ta, tb);
134                 ans.setSymbol(negative);
135             }
136             if (flag == 0) {    //直接返回0即可
137                 ta.setSymbol(positive); tb.setSymbol(positive);
138                 ans.data.push_back(0);
139                 ans.setSymbol(positive);
140             }
141             if (flag == -1) {    //相当于小的减大的,结果为正
142                 ta.setSymbol(positive); tb.setSymbol(positive);
143                 ans = bigSubSmall(tb, ta);
144                 ans.setSymbol(positive);
145             }
146         }
147     }
148     return ans;
149 }
150
151 // A + B 全正
152 BigInteger BigInteger::addTwoPositive(const BigInteger& A, const BigInteger& B) {
153     using namespace std;
154     BigInteger ans;
155     int la = A.data.size();
156     int lb = B.data.size();
157     int len = la < lb ? la : lb;
158     for (int i = 0; i < len; i++) {
159         ans.data.push_back(0);
160         ans.data[i] = A.data.get(i) + B.data.get(i);
161     }
162     for (int i = len; i < la; i++) {
163         ans.data.push_back(0);
164         ans.data[i] = A.data.get(i);
165     }
166     for (int i = len; i < lb; i++) {
167         ans.data.push_back(0);
168         ans.data[i] = A.data.get(i);
169     }
170     // 处理进位
171     len = la > lb ? la : lb;
172     bool up = 0;    // 进位标记
173     short cur;
174     for (int i = 0; i < len; i++) {
175         if (up == 1) {
176             ans.data[i] += cur;
177             up = 0;
178         }
179         if (ans.data.get(i) >= 10000) {
180             cur = ans.data[i] / 10000;
181             short tmp = ans.data[i] % 10000;
182             ans.data[i] = tmp;
183             up = 1;
184         }
185         else up = 0;
186     }
187     if (up) {    //最后一位还需要进位
188         while (cur) {
189             ans.data.push_back(cur);
190             cur /= 10000;
191         }
192     }
193     return ans;
194
195 }
196
197 // A - B (A > B) 全正
198 BigInteger BigInteger::bigSubSmall(const BigInteger& A, const BigInteger& B) {
199     BigInteger ans;
200     int la = A.data.size();
201     int lb = B.data.size();
202     int len = la < lb ? la : lb;
203     for (int i = 0; i < len; i++) {
204         ans.data.push_back(0);
205         ans.data[i] = A.data.get(i) - B.data.get(i);
206     }
207     for (int i = len; i < la; i++) {
208         ans.data.push_back(0);
209         ans.data[i] = A.data.get(i);
210     }
211     len = la > lb ? la : lb;
212     // 处理借位
213     bool down = 0;
214     for (int i = 0; i < len; i++) {
215         if (down == 1) {
216             ans.data[i] -= 1;
217             down = 0;
218         }
219         if (ans.data[i] < 0) {
220             ans.data[i] += 10000;
221             down = 1;
222         }
223         else down = 0;
224     }
225     return ans;
226 }
227
228 void BigInteger::show() {
229     using namespace std;
230     int len = data.size();
231     if (this->symbol() == negative) {
232         cout << "-";
233     }
234     cout << data[len - 1];
235     if (len == 1) {
236         cout << endl;
237         return;
238     }
239     for (int i = len - 2; i >= 0; i--) {
240         cout << "," << std::setw(3) << std::setfill(‘0‘) << data[i];
241     }
242     cout << endl;
243 }

BigInteger.cpp

时间: 2024-10-10 07:05:33

用双向链表实现大数加减法的相关文章

大数加减法总结

大数加减法总结(包括整数或者负数): 1.先解决不带符号的数的加减法 2.根据加数或者减数的符号位判断该选择加法还是减法计算,并且赋予结果对应的符号 需要注意的是:不带符号的减法产生的结果可能高位为'0',要进行处理. string bigNumberMinusWithoutSign(const char* num1, const char *num2){ string res = ""; bool flag1 = false; // 正负标志位 int flag = 0;//退位标志

POJ 2756 Autumn is a Genius 大数加减法

Description Jiajia and Wind have a very cute daughter called Autumn. She is so clever that she can do integer additions when she was just 2 years old! Since a lot of people suspect that Autumn may make mistakes, please write a program to prove that A

大数加减法 - java实现

计算机处理的各种数据类型都有个范围,超出范围的就处理不了. 如果做超大数运算加减乘除,普通方法肯定是不行的,那么我们遇到大数的运算怎么处理呢?今天介绍一种大数加减乘除运算的方法 思路: 1. 将两个特大的整数利用字符数组作为存储介质. 2. 逐位计算 遍历结果逢十进一. 3. 对存储结果的数组进行翻转处理. 下面上代码: 1 public class LargeIntSub { 2 public static void main(String[] args) { 3 4 String a="67

大数加减法 C语言 包含负数

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #define MAXSIZE 10 void Add(char a[], char b[], char c[]); void Sub(char a[], char b[], char c[]); int Get_len(char a[]); bool Max_a(char a[], char b[]); int main(void) { char a[MAXSIZE]; char b[MAXS

大数加减法

1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define MAX 10005 5 6 struct bigint 7 { 8 char num[MAX]; 9 int flag; // 1:positive -1:negative 10 int dgts; 11 bigint(void) 12 { 13 memset(num, '0', sizeof(num)); 14 } 15 }; 16

大数加减法实现

传送门 1 /* 2 * input: an expression seperated by a '-' or '+'; for example: a-b, a+b 3 * ouput: the answer of the input expression 4 */ 5 #include <stdio.h> 6 #include <string.h> 7 8 #define MAX_N 205 9 10 char a[MAX_N], b[MAX_N], ans[MAX_N]; 11

大数加减法模板

1 #include <iostream> 2 #include <string.h> 3 #include <string> 4 using namespace std; 5 char s1[10005],s2[10005]; 6 int a[10005],b[10005],c[10005]; 7 int flag; 8 int main() 9 { 10 cin>>s1; 11 cin>>s2; 12 int len1=strlen(s1),

1410121949-hd-1sting

1sting Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3442    Accepted Submission(s): 1332 Problem Description You will be given a string which only contains '1'; You can merge two adjacent '1

从一道NOI练习题说递推和递归

一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法. 这个问题可以用递归来进行解决,但是解题时间1秒明显不够用.怎么办呢,可以考虑找到“规律”,然后推导公式解决问题,开始画图分析: 这是4个台阶时的全部7种走法,记作f(4)=7.现在观察右侧绿色走过的部分,1234四种情况是3个台阶时的4种走,法记