The first line of the input gives the positive number of test cases, T (<=1000). Then T test cases follow, each consists of a single line containing three integers A, B and C, separated by single spaces.
For each test case, output in one line "Case #X: true" if A+B>C, or "Case #X: false" otherwise, where X is the case number (starting from 1).
3 1 2 3 2 3 4 9223372036854775807 -9223372036854775808 0
Case #1: false Case #2: true Case #3: false
md!!!只有我是自己实现string型的加减法和大小比较的吗 #include<bits/stdc++.h> using namespace std; int AcompairB(string a, string b){//a大1,b大-1,等0 int al = a.size(); int bl = b.size(); if (a[0] == '-'&&b[0] != '-'){ return -1; } if (a[0] != '-'&&b[0] == '-'){ return 1; } if (a[0] != '-'&&b[0] != '-'){ if (al>bl)return 1; if (al<bl)return -1; if (al == bl){ for (int i = 0; i<al; i++){ if (a[i] - b[i]>0)return 1; if (a[i] - b[i]<0)return -1; } return 0; } } if (a[0] == '-'&&b[0] == '-'){ if (al>bl)return -1; if (al<bl)return 1; if (al == bl){ for (int i = 0; i<al; i++){ if (a[i] - b[i]>0)return -1; if (a[i] - b[i]<0)return 1; } return 0; } } return -10; } string MyAdd(string a, string b){ int cp = AcompairB(a, b); string s1, s2;//s1大 if (cp == 1){ s1 = a; s2 = b; } else if (cp == -1){ s1 = b; s2 = a; } else{ s1 = a; s2 = b; } //都正 int s1Size = s1.size(); int s2Size = s2.size(); int p = 1; int bef = 0; while (p <= s2Size){ int c = s1[s1Size - p] + s2[s2Size - p] + bef - '0' - '0'; bef = 0; if (c>=10){ bef = 1; c -= 10; } s1[s1Size - p] = c + '0'; p++; } while (bef != 0 && p <= s1Size){ int c = s1[s1Size - p] + bef - '0'; bef = 0; if (c>=10){ bef = 1; c -= 10; } s1[s1Size - p] = c + '0'; p++; } if (bef != 0){ s1 = '1' + s1; } return s1; } string myMinus(string a, string b, bool &isNeg){ int cp = AcompairB(a, b); string s1, s2;//s1大 if (cp == 1){ s1 = a; s2 = b; isNeg = false; } else if (cp == -1){ s1 = b; s2 = a; isNeg = true; } else{ return "0"; } int s1Size = s1.size(); int s2Size = s2.size(); int p = 1; int bef = 0; while (p <= s2Size){ int c = s1[s1Size - p] - s2[s2Size - p] + bef /*- '0' - '0'*/;//哇这里不用-'0'前面消去了 bef = 0; if (c<0){ bef = -1; c += 10; } s1[s1Size - p] = c + '0'; p++; } while (bef != 0 && p <= s1Size){ int c = s1[s1Size - p] + bef - '0'; bef = 0; if (c<0){ bef = -1; c += 10; } s1[s1Size - p] = c + '0'; p++; } if (bef != 0){ s1[0] = s1[0] - 1; } int q = 0; while (s1[q] == '0'){ q++; } string res = s1.substr(q); return res; } int main(){ int N; cin >> N; vector<int> res; while (N--){ string A, B, C; cin >> A >> B >> C; string AB; if (A[0] == '-'&&B[0] == '-'){ AB = '-' + MyAdd(A.substr(1), B.substr(1)); } else if (A[0] != '-'&&B[0] != '-'){ AB = MyAdd(A, B); } else if (A[0] != '-'&&B[0] == '-'){ bool isNeg; AB = myMinus(A, B.substr(1), isNeg); if (isNeg)AB = '-' + AB; } else if (A[0] == '-'&&B[0] != '-'){ bool isNeg; AB = myMinus(B, A.substr(1), isNeg); if (isNeg)AB = '-' + AB; } res.push_back(AcompairB(AB, C)); } for (int i = 1; i <= res.size(); i++){ if (res[i-1] == 1){ printf("Case #%d: true\n",i); } else{ printf("Case #%d: false\n", i); } } return 0; }
import java.math.BigInteger; import java.util.*; public class Main{ public static void main(String[] args){ Scanner in =new Scanner(System.in); int n=in.nextInt(); for(int i=0;i<n;i++){ BigInteger a=in.nextBigInteger(); BigInteger b=in.nextBigInteger(); BigInteger c=in.nextBigInteger(); if(a.add(b).compareTo(c)>0){ System.out.println("Case #"+(i+1)+": true"); }else System.out.println("Case #"+(i+1)+": false"); } } }
//long double水过,注意scanf如何输入的。 //当然cin就不用管了,另外python和java自带大数就更不用说了。(编程语言带来的差异呀。。。 #include <bits/stdc++.h> using namespace std; long double A,B,C; int T,kase; int main(){ scanf("%d",&T); while(T--){ scanf("%Lf %Lf %Lf",&A,&B,&C); if(A+B>C) printf("Case #%d: true\n",++kase); else printf("Case #%d: false\n",++kase); } return 0; }
#include<iostream> #include<ctype.h> using namespace std; struct bigint{ int digit[1001],tag; void read(){ int i,j; char c; while(!isdigit(c=getchar())&&c!='-'); if(c=='-'){ this->tag=1; c=getchar(); } else this->tag=0;//看符号 while(c=='0')c=getchar();//去零 for(i=1000;isdigit(c);c=getchar()){ this->digit[--i]=c-'0'; } for(j=0;j<1000-i;j++){ this->digit[j]=this->digit[j+i]; } if(!j)this->tag=0; while(j<1001)this->digit[j++]=0;//把数字写完,填好0 } bigint operator+(bigint&m){ int a[1001],b[1001],c[1001],i,j; bigint n; if(this->tag){ for(i=0;i<1001&&!this->digit[i];i++)a[i]=0; if(i<1001){ a[i]=10-this->digit[i]; while(++i<1001)a[i]=9-this->digit[i]; } } else{ for(i=0;i<1001;i++)a[i]=this->digit[i]; } if(m.tag){ for(i=0;i<1001&&!m.digit[i];i++)b[i]=0; if(i<1001){ b[i]=10-m.digit[i]; while(++i<1001)b[i]=9-m.digit[i]; } } else{ for(i=0;i<1001;i++)b[i]=m.digit[i]; } for(i=j=0;i<1001;i++){ c[i]=a[i]+b[i]+j; if(c[i]>9){ c[i]-=10; j=1; } else j=0; } if(!c[1000]){ n.tag=0; for(i=0;i<1001;i++)n.digit[i]=c[i]; } else{ n.tag=1; for(i=0;!c[i];i++)n.digit[i]=0; n.digit[i]=10-c[i]; while(++i<1001)n.digit[i]=9-c[i]; } return n; } bool operator>(bigint&m){ int i; if(this->tag!=m.tag)return this->tag<m.tag; for(i=1000;i>=0&&this->digit[i]==m.digit[i];i--); if(i<0)return false; return this->tag?this->digit[i]<m.digit[i]:this->digit[i]>m.digit[i]; } }; int N; bigint A,B,C,sum; int main() { cin>>N; for(int i=1;i<=N;i++){ A.read(); B.read(); C.read(); sum=A+B; cout<<"Case #"<<i<<": "; if(sum>C)cout<<"true\n"; else cout<<"false\n"; } }
#include <iostream> using namespace std; int main() { int T; cin>>T; for(int i=1;i<=T;i++) { long long a,b,c,ans; bool flag = false; cin>>a>>b>>c; ans = a + b; if(a<0 && b<0 && ans>=0) flag = false; else if(a>0 && b>0 && ans<=0) flag = true; else flag = (ans > c); cout<<"Case #"<<i<<": "<<(flag?"true":"false")<<endl; } return 0; }
import java.math.BigInteger; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in=new Scanner(System.in); int n=in.nextInt(); for(int i=1;i<=n;i++){ BigInteger bi1=new BigInteger(in.next()); BigInteger bi2=new BigInteger(in.next()); BigInteger bi3=new BigInteger(in.next()); System.out.print("Case #"+i+": "); if(bi1.add(bi2).compareTo(bi3)>0){ System.out.println("true"); }else{ System.out.println("false"); } } } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); for(int i = 1;i<=n;i++){ String a = in.next(); String b = in.next(); String c = in.next(); String result = add(a, b); if(result.charAt(0)=='-'&&c.charAt(0)=='-') System.out.printf("Case #%d: %b\n",i, compareNegative(result, c)); else if(result.charAt(0)=='-') System.out.printf("Case #%d: false\n",i); else if(c.charAt(0)=='-') System.out.printf("Case #%d: true\n",i); else System.out.printf("Case #%d: %b\n",i, result.length()==c.length()? result.compareTo(c)>0: result.length()>c.length()); } } private static String add(String a,String b){ int aStart = 0; int bStart = 0; if(a.charAt(0)=='-'&&b.charAt(0)=='-'){ aStart = 1; bStart = 1; }else if(a.charAt(0)=='-') return sub(b, a.substring(1)); else if(b.charAt(0)=='-') return sub(a, b.substring(1)); char[] result = new char[Math.max(a.length()-aStart, b.length()-bStart)+1]; int i = a.length()-1; int j = b.length()-1; int k = result.length-1; int f = 0;//进位 while(i>=aStart||j>=bStart){ int aval = i >= aStart ? a.charAt(i--) - '0' : 0; int bval = j >= bStart ? b.charAt(j--) - '0' : 0; int sum = f + aval + bval; f = sum/10; sum %= 10; result[k--] = (char)(sum+'0'); } if(f!=0) result[k--] = (char)(f+'0'); if(aStart==1&&bStart==1) return "-"+new String(result,k+1,result.length-k-1); return new String(result,k+1,result.length-k-1); } private static String sub(String a,String b){ // a - b boolean flag = false; if(a.length()<b.length() || (a.length()==b.length()&&a.compareTo(b)<0)){ String temp = b; b = a; a = temp; flag = true; } char[] result = new char[a.length()]; char[] ach = a.toCharArray(); char[] bch = b.toCharArray(); int f = 0; int i = a.length()-1; int j = b.length()-1; int k = result.length-1; while(i>=0){ int aval = getInt(ach[i--]); int bval = j >= 0 ? getInt(bch[j--]) : 0; int sub = aval; int l = i;//前一位 while(sub<bval){ int before = getInt(ach[l]);//向前借数 if(before>0){ sub += 10; ach[l] = getChar(before-1); } l--; } result[k--] = getChar(sub-bval); } if(flag) return "-"+getResult(result,k+1); return getResult(result,k+1); } private static String getResult(char[] s,int start){ StringBuilder sb = new StringBuilder(); boolean flag = true; for(int i = start;i<s.length;i++){ if(flag&&s[i]=='0') continue; flag = false; sb.append(s[i]); } return sb.length()==0?"0":sb.toString(); } private static boolean compareNegative(String a,String b) { if(a.length()>b.length()) return false; if(a.length()<b.length()) return true; int i = 1; for(;i<a.length();i++){ if(a.charAt(i)!=b.charAt(i)) return a.charAt(i) - b.charAt(i)<0; } return false; } private static int getInt(char c){ return c-'0'; } private static char getChar(int a){ return (char)(a+'0'); } }
using System; class Prob{ public static void Main(String[] args){ int T=int.Parse(Console.ReadLine()); int Case=0; while(T-->0){ string[] tk=Console.ReadLine().Split(new char[]{' '}); Decimal a=Decimal.Parse(tk[0]); Decimal b=Decimal.Parse(tk[1]); Decimal c=Decimal.Parse(tk[2]); Console.Write("Case #"+(++Case)+": "); Console.WriteLine(a+b>c?"true":"false"); } } }
#include<iostream> using namespace std ; int main() { int T ; cin >> T ; for( int i = 1; i <= T; ++i ) { long double a, b, c, ans ; cin >> a >> b >> c ; cout << "Case #"<< i <<": " << (a+b>c ? "true" : "false") << endl ; } return 0 ; }
#include<iostream> #include<fstream> #define LOCAL using namespace std ; const long long mid = 2 << 62 ; int main() { #ifdef LOCAL #define cin fin ifstream fin("F:\\input.txt") ; #endif int T ; cin >> T ; for( int i = 1; i <= T; ++i ) { long long a, b, c, ans ; bool flag = true ; //ture:a+b > c; false: a+b <= c cin >> a >> b >> c ; ans = a + b ; if( a < 0 && b < 0 && ans >= 0) { flag = false ; }//Overflow, a+b<c else if( a > 0 && b > 0 && ans <= 0 ) { flag = true ; } //Overflow, a+b>c else flag = ( ans > c ) ; cout << "Case #"<< i <<": " << (flag ? "true" : "false") << endl ; } return 0 ; }
a + b >= 0 ;
ans = a + b ; ans >= 0 ;似乎是因为只有赋值以后才能正确判断a+b是否溢出。 第一种写法如果放在解法二的溢出判断里面,无法通过pat官网的后面两组测试数据。而第二种写法能正确通过所有测试数据。 至于其中原因,我不得而知。 各位如果有谁知道麻烦告诉我!
#include <cstdio> using namespace std; long long a, b, c; bool solve(long long n1, long long n2, long long n3){ if(n1 > 0 && n2 >0){ if(n3 < 0) return true; else return n1 > n3 - n2; } if(n1 < 0 && n2 < 0){ if(n3 >= 0) return false; else return n1 > n3 - n2; } else return n1 + n2 > n3; } int main(){ int n; scanf("%d", &n); for(int i=1; i<=n; i++){ bool flag; scanf("%lld %lld %lld", &a, &b, &c); flag = solve(a, b, c); if(flag) printf("Case #%d: true\n", i); else printf("Case #%d: false\n", i); } return 0; }
#include <iostream> using namespace std; int main() { int t; cin >> t; long long a, b, c; for (int i = 0; i < t; i++) { scanf("%lld %lld %lld", &a, &b, &c); long long sum = a + b; // 避免UB和IB,可以在任何平台和编译器上正确运行 bool overflowed = ((b > 0 && a > INT64_MAX - b) || (b < 0 && a < INT64_MIN - b)); if (overflowed && a > 0) printf("Case #%d: true\n", i + 1); else if (overflowed && a < 0) printf("Case #%d: false\n", i + 1); else if (sum > c) printf("Case #%d: true\n", i + 1); else printf("Case #%d: false\n", i + 1); } return 0; }
#include<bits/stdc++.h> using namespace std; int main() { int n; while(cin>>n) { for(int i=1; i<=n; i++) { long long a,b,c; cin>>a>>b>>c; if(a>0&&b>0) { if(a+b<0) { cout<<"Case #"<<i<<": true"<<endl; } else if(a+b>c) { cout<<"Case #"<<i<<": true"<<endl; } else { cout<<"Case #"<<i<<": false"<<endl; } } else if(a<0&&b<0) { if(a+b>=0) { cout<<"Case #"<<i<<": false"<<endl; } else if(a+b>c) { cout<<"Case #"<<i<<": true"<<endl; } else { cout<<"Case #"<<i<<": false"<<endl; } } else if(a+b>c) { cout<<"Case #"<<i<<": true"<<endl; } else { cout<<"Case #"<<i<<": false"<<endl; } } } return 0; }
#include<iostream> #include<algorithm> #include<string.h> #include<queue> #include<string> using namespace std; int main() { int N; cin >> N; for (int i = 0; i < N; i++) { //if (N != 63) { // continue; //} long long a, b, c; long long a1, b1, c1; long long a2, b2, c2; cin >> a >> b >> c; a1 = a / 100000000, a2 = a % 100000000; b1 = b / 100000000, b2 = b % 100000000; c1 = c / 100000000, c2 = c % 100000000; if (a1+b1>c1) { cout << "Case #" << i + 1 << ": true" << endl; } else if(a1 + b1 < c1) { /*if (i == 48&&N!=63) { cout << "警告:" << a << "#" << b << "#" << c << endl; }*/ cout << "Case #" << i + 1 << ": false" << endl; } else { if (a2 + b2 > c2) { cout << "Case #" << i + 1 << ": true" << endl; } else if (a2 + b2 < c2) { /*if (i == 48&&N!=63) { cout << "警告:" << a << "#" << b << "#" << c << endl; }*/ cout << "Case #" << i + 1 << ": false" << endl; } else { cout << "Case #" << i + 1 << ": false" << endl; } } } return 0; }
对于计算机而言,基本的数据类型一般最多为64位数据表示范围,这个范围是有限的,没法无限的表示所有的数据,那么有没有一种方式能够表示所有的大数,并完成加减乘除呢?
答案肯定是有的,由于数据都是由一位一位的数字所组成,我们只需要用数组中的每一位表示一位数字,便可完成对大数的模拟了。
那么我们说明时候需要用到大数模拟呢?对竞赛人而言,有很多题目实际上就是高精度大数模拟类型,而对于普通的程序员而言,大数模拟也仅是在做某个逻辑运算而保证不会溢出的最佳策略,那么大家难道不好奇如何实现一个大数模拟类吗?
现在就从封装一个简单的加减类开始了解这样一个大数模拟是怎么实现的👀
bool f; //是否是负数的标记 char *nums; //存储非符号的大数各个位 int length; //nums的数据长度 int capacity; //nums的可用容量
//缺省构造函数 BigInteger() : length(0), capacity(1), f(false) { nums = new char[capacity]; } //用于转化普通字符串的构造函数 BigInteger(const char *n) : length(strlen(n)), f(false) { int start = 0; if (n[0] == '-') { f = true; start++; } while (start<length&&n[start] == '0')start++; capacity = length * 10; nums = new char[capacity]; std::copy(n + start, n + length, nums); length = length - start; } //拷贝构造函数 BigInteger(BigInteger &a) { capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); } //移动构造函数:这里调用了等于号,根据a的类型来决定用哪个等于号 BigInteger(BigInteger &&a) :length(0){ *this = a; } //析构函数 ~BigInteger() { delete[] nums; }
//调用std的swap实现对基本数据的交换 static void Swap(BigInteger &a, BigInteger &b) { std::swap(a.length, b.length); std::swap(a.capacity, b.capacity); std::swap(a.f, b.f); std::swap(a.nums, b.nums); }
//不看符号比较nums的大小:表示a是否比b大 static bool compare(const BigInteger &a,const BigInteger &b) { //比较纯nums大小(不看符号 int n1 = a.length; int n2 = b.length; if (n1 != n2)return n1 > n2; //返回a和b哪个大,true则位a大 int i = 0; while (i < n1 && a.nums[i] == b.nums[i])i++; //a b一样长的情况下,比较两个的值 if (i == n1) return false; return a.nums[i] > b.nums[i]; }
//表示a和b是否相等 bool isEqual(BigInteger &a, BigInteger &b) { if (a.f != b.f || (a.length != b.length))return false; int i = 0; while (i < a.length && a.nums[i] == b.nums[i])i++; return i == a.length && a.f == b.f; }
不看符号的加法,符号这方面由重载加法运算符控制。
static BigInteger add(BigInteger &a, BigInteger &b) { //不看符号的加法 a.reverse();//尾端对齐 b.reverse(); BigInteger t; int up = 0; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta + tb + up; t.push_back(base % 10 + '0'); up = base / 10; } if (up) t.push_back(up + '0'); t.reverse();//返回原位 a.reverse(); b.reverse(); return t; }
不看符号的减法,默认了a的nums大小(不看符号)是比b大的。
static BigInteger minus(BigInteger &a, BigInteger &b) { a.reverse(); b.reverse(); BigInteger t; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta - tb; if (base < 0) { base += 10; a[i + 1]--; } t.push_back(base + '0'); } t.reverse(); a.reverse(); b.reverse(); return t; }
char &operator[](int i) { return nums[i]; }
用了两个版本--右值引用和左值引用版本
BigInteger &operator=(BigInteger&& a) { //Swap&Copy方式实现右值赋值重载 Swap(*this, a); return *this; }
BigInteger &operator=(const BigInteger &a) {//深拷贝 if (length != 0)//如果不是初始化调用的 = ,则肯定需要先把原来的内存delete掉 delete[]nums; capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); return *this; }
重载了小于号,好处在于可以直接利用stl进行各种排序操作了。
注意:一定要写成const版本的成员函数,不然STL库无法调用,因为STL库中的所有比较都是基于const对象。
bool operator<(const BigInteger &a) const { if (f && !a.f) { //其中一个为负数,则那个是更小的 return true; } else if (!f && a.f) return false; if (f) { //两者都为负数的情况,左边的值要更大则为true return compare(*this, a); }//两者均为正数,则值更小的在左边为true return compare(a, *this); }
利用静态成员函数完成无符号的加减,然后在这里进行判断各种符号情况,根据不同的符号情况进行不同的加法处理。
BigInteger operator+(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况,直接相加,再改符号 res = add(*this, a); flag = true; } else if (a.f && !f) {//左正右负 if (compare(a, *this)) { //看负数对应的nums是否比正数大 flag = true; res = minus(a, *this); } else { flag = false; res = minus(*this, a); } } else if (!a.f && f) { if (compare(*this, a)) { //与上一个相同 flag = true; res = minus(*this, a); } else { flag = false; res = minus(a, *this); } } else { //同时为正数就是最简单的加法 flag = false; res = add(*this, a); } res.f = flag; return res; }
同样是分类讨论,同样是根据不同的类型调用minus和add函数。
0
,而被处理为 -0
。BigInteger operator-(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况--左边-右边==(不看符号)右边-(不看符号)左边 if (compare(a, *this)) { flag = false; res = minus(a, *this); } else { if (isEqual(*this, a)) flag = false; else flag = true; res = minus(*this, a); } } else if (a.f && !f) { //左边为正,右边为负--左边-右边==左边+右边 flag = false; res = add(a, *this); } else if (!a.f && f) { //右边为正,左边为负--左边-右边==两边为负的加法 flag = true; res = add(a, *this); } else { //同时为正数--左边-右边==左边-右边(分类讨论正负 if (compare(a, *this)) { //右边>左边,符号为负 res = minus(a, *this); flag = true; } else { //右边<左边,符号为正 res = minus(*this, a); flag = false; } } res.f = flag; return res; }
向外提供的get接口
int getCap() { return capacity; } int getLength() { return length; } bool isNegative() { return f; } bool isEmpty() { return length == 0; }
进行赋值操作所必备的push_back和reverse函数
void push_back(char x) { if (length >= capacity) {//扩容操作 capacity *= 2; char *t = nums; nums = new char[capacity]; std::copy(t, t + length, nums); delete[]t; } nums[length++] = x; } void reverse() {//反转操作 int l = 0, r = length - 1; while (l < r) { std::swap(nums[l], nums[r]); l++; r--; } }
无关紧要的 read()
输入接口 和 print()
输出测试接口
void print() { if (f) printf("-"); nums[length] = '\0'; int i = 0; while (nums[i] == '0')i++; printf("%s", nums + i); } void read() {//利用getchar()给对象赋上数据 char c = getchar(); if (c == '-') { f = true; c = getchar(); } while (c == '0') c = getchar();//将前导0消耗掉 while (c != '\n') { push_back(c);//不断的调用push_back即可 c = getchar(); } }
如果在声明类的同时进行定义,则内部的成员函数默认就是内联的。所以我们一般把短小的代码进行内联,以下的实现均是以该规律进行。
// // Created by Alone on 2021/10/7. // #ifndef MY_TINY_STL_BIGINTEGER_H #define MY_TINY_STL_BIGINTEGER_H #include <algorithm> #include <iostream> #include <cstring> class BigInteger { bool f; char *nums; int length; int capacity; public: //构造函数 BigInteger() : length(0), capacity(1), f(false) { //缺省构造函数 nums = new char[capacity]; } BigInteger(const char *n); BigInteger(const BigInteger &a); BigInteger(BigInteger &&a); ~BigInteger() { //析构函数 delete[] nums; } public: //静态函数 static void Swap(BigInteger &a, BigInteger &b); static bool compare(const BigInteger &a, const BigInteger &b); bool isEqual(BigInteger &a, BigInteger &b); static BigInteger add(BigInteger &a, BigInteger &b); static BigInteger minus(BigInteger &a, BigInteger &b); public: //运算符重载 char &operator[](int i) { return nums[i]; } BigInteger &operator=(BigInteger &&a) { //Swap&Copy方式实现右值赋值重载 Swap(*this, a); return *this; } BigInteger &operator=(const BigInteger &a); bool operator<(const BigInteger &a) const; BigInteger operator+(BigInteger &a); BigInteger operator-(BigInteger &a); public: //对象的基本成员函数 int getCap() { return capacity; } int getLength() { return length; } bool isNegative() { return f; } bool isEmpty() { return length == 0; } void reverse(); void push_back(char x); void print(); void read(); }; #endif //MY_TINY_STL_BIGINTEGER_H
// // Created by Alone on 2021/10/7. // #include "BigInteger.h" //@构造函数实现 BigInteger::BigInteger(const char *n) : length(strlen(n)), f(false) { //用于初始值的构造函数 int start = 0; if (n[0] == '-') { f = true; start++; } while (start < length && n[start] == '0')start++; capacity = length * 10; nums = new char[capacity]; std::copy(n + start, n + length, nums); length = length - start; } BigInteger::BigInteger(const BigInteger &a) { //拷贝构造函数 capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); } BigInteger::BigInteger(BigInteger &&a) : length(0) { //移动构造函数 *this = a; } //@静态函数实现 void BigInteger::Swap(BigInteger &a, BigInteger &b) { std::swap(a.length, b.length); std::swap(a.capacity, b.capacity); std::swap(a.f, b.f); std::swap(a.nums, b.nums); } bool BigInteger::compare(const BigInteger &a, const BigInteger &b) { int n1 = a.length; int n2 = b.length; if (n1 != n2)return n1 > n2; //返回a和b哪个大,true则位a大 int i = 0; while (i < n1 && a.nums[i] == b.nums[i])i++; //a b一样长的情况下,比较两个的值 if (i == n1) return false; return a.nums[i] > b.nums[i]; } bool BigInteger::isEqual(BigInteger &a, BigInteger &b) { if (a.f != b.f || (a.length != b.length))return false; int i = 0; while (i < a.length && a.nums[i] == b.nums[i])i++; return i == a.length && a.f == b.f; } BigInteger BigInteger::add(BigInteger &a, BigInteger &b) { a.reverse();//尾端对齐 b.reverse(); BigInteger t; int up = 0; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta + tb + up; t.push_back(base % 10 + '0'); up = base / 10; } if (up) t.push_back(up + '0'); t.reverse();//返回原位 a.reverse(); b.reverse(); return t; } BigInteger BigInteger::minus(BigInteger &a, BigInteger &b) { a.reverse(); b.reverse(); BigInteger t; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta - tb; if (base < 0) { base += 10; a[i + 1]--; } t.push_back(base + '0'); } t.reverse(); a.reverse(); b.reverse(); return t; } //@运算符重载实现 BigInteger &BigInteger::operator=(const BigInteger &a) { if (length != 0)//如果不是初始化调用的 = ,则肯定需要先把原来的内存delete掉 delete[]nums; capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); return *this; } BigInteger BigInteger::operator+(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况,直接相加,再改符号 res = add(*this, a); flag = true; } else if (a.f && !f) {//左正右负 if (compare(a, *this)) { //看负数对应的nums是否比正数大 flag = true; res = minus(a, *this); } else { flag = false; res = minus(*this, a); } } else if (!a.f && f) { if (compare(*this, a)) { //与上一个相同 flag = true; res = minus(*this, a); } else { flag = false; res = minus(a, *this); } } else { //同时为正数就是最简单的加法 flag = false; res = add(*this, a); } res.f = flag; return res; } BigInteger BigInteger::operator-(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况--左边-右边==(不看符号)右边-(不看符号)左边 if (compare(a, *this)) { flag = false; res = minus(a, *this); } else { if (isEqual(*this, a)) flag = false; else flag = true; res = minus(*this, a); } } else if (a.f && !f) { //左边为正,右边为负--左边-右边==左边+右边 flag = false; res = add(a, *this); } else if (!a.f && f) { //右边为正,左边为负--左边-右边==两边为负的加法 flag = true; res = add(a, *this); } else { //同时为正数--左边-右边==左边-右边(分类讨论正负 if (compare(a, *this)) { //右边>左边,符号为负 res = minus(a, *this); flag = true; } else { //右边<左边,符号为正 res = minus(*this, a); flag = false; } } res.f = flag; return res; } bool BigInteger::operator<(const BigInteger &a) const { if (f && !a.f) { //其中一个为负数,则那个是更小的 return true; } else if (!f && a.f) return false; if (f) { //两者都为负数的情况,左边的值要更大则为true return compare(*this, a); }//两者均为正数,则值更小的在左边为true return compare(a, *this); } //@基本成员函数 void BigInteger::reverse() { int l = 0, r = length - 1; while (l < r) { std::swap(nums[l], nums[r]); l++; r--; } } void BigInteger::push_back(char x) { if (length >= capacity) { capacity *= 2; char *t = nums; nums = new char[capacity]; std::copy(t, t + length, nums); delete[]t; } nums[length++] = x; } void BigInteger::print() { if (f) printf("-"); nums[length] = '\0'; int i = 0; while (nums[i] == '0')i++; printf("%s", nums + i); } void BigInteger::read() { char c = getchar(); if (c == '-') { f = true; c = getchar(); } while (c == '0') c = getchar();//将前导0消耗掉 while (c != '\n') { push_back(c);//不断的调用push_back即可 c = getchar(); } }
运行的测试代码:
打印输出
python输出
与python输出无异,故通过测试。但碍于测试数据太过少,不是很有说服力,还有后面的解题测试。
测试代码(方便测试只输入了10个数据):
排序输出:
正好最近刷的PAT甲级就涉及到大数的加减hhh!
题目描述
OJ平台
解题代码
#include "bits/stdc++.h" class BigInteger { bool f; char *nums; int length; int capacity; public://构造函数 BigInteger() : length(0), capacity(1), f(false) { //缺省构造函数 nums = new char[capacity]; } BigInteger(const char *n) : length(strlen(n)), f(false) { //用于初始值的构造函数 int start = 0; if (n[0] == '-') { f = true; start++; } while (start < length && n[start] == '0')start++; capacity = length * 10; nums = new char[capacity]; std::copy(n + start, n + length, nums); length = length - start; } BigInteger(const BigInteger &a) { //拷贝构造函数 capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); } BigInteger(BigInteger &&a) : length(0) { //移动构造函数 *this = a; } ~BigInteger() { //析构函数 delete[] nums; } public://静态成员函数 static void Swap(BigInteger &a, BigInteger &b) { std::swap(a.length, b.length); std::swap(a.capacity, b.capacity); std::swap(a.f, b.f); std::swap(a.nums, b.nums); } static bool compare(const BigInteger &a, const BigInteger &b) { //比较纯nums大小(不看符号 int n1 = a.length; int n2 = b.length; if (n1 != n2)return n1 > n2; //返回a和b哪个大,true则位a大 int i = 0; while (i < n1 && a.nums[i] == b.nums[i])i++; //a b一样长的情况下,比较两个的值 if (i == n1) return false; return a.nums[i] > b.nums[i]; } bool isEqual(BigInteger &a, BigInteger &b) { if (a.f != b.f || (a.length != b.length))return false; int i = 0; while (i < a.length && a.nums[i] == b.nums[i])i++; return i == a.length && a.f == b.f; } static BigInteger add(BigInteger &a, BigInteger &b) { //不看符号的加法 a.reverse();//尾端对齐 b.reverse(); BigInteger t; int up = 0; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta + tb + up; t.push_back(base % 10 + '0'); up = base / 10; } if (up) t.push_back(up + '0'); t.reverse();//返回原位 a.reverse(); b.reverse(); return t; } static BigInteger minus(BigInteger &a, BigInteger &b) { //不看符号的减法,默认了a的长度或者大小是比***的(所以外界不要乱调用 a.reverse(); b.reverse(); BigInteger t; int len = a.length > b.length ? a.length : b.length; for (int i = 0; i < len; i++) { int ta = i < a.length ? a[i] - '0' : 0; int tb = i < b.length ? b[i] - '0' : 0; int base = ta - tb; if (base < 0) { base += 10; a[i + 1]--; } t.push_back(base + '0'); } t.reverse(); a.reverse(); b.reverse(); return t; } public://成员函数和重载运算符 char &operator[](int i) { return nums[i]; } BigInteger &operator=(BigInteger &&a) { //Swap&Copy方式实现右值赋值重载 Swap(*this, a); return *this; } BigInteger &operator=(const BigInteger &a) {//深拷贝 if (length != 0)//如果不是初始化调用的 = ,则肯定需要先把原来的内存delete掉 delete[]nums; capacity = a.capacity; length = a.length; f = a.f; nums = new char[capacity]; std::copy(a.nums, a.nums + length, nums); return *this; } int getCap() { return capacity; } int getLength() { return length; } bool isNegative() { return f; } bool isEmpty() { return length == 0; } void reverse() { int l = 0, r = length - 1; while (l < r) { std::swap(nums[l], nums[r]); l++; r--; } } void push_back(char x) { if (length >= capacity) { capacity *= 2; char *t = nums; nums = new char[capacity]; std::copy(t, t + length, nums); delete[]t; } nums[length++] = x; } bool operator<(const BigInteger &a) const { if (f && !a.f) { //其中一个为负数,则那个是更小的 return true; } else if (!f && a.f) return false; if (f) { //两者都为负数的情况,左边的值要更大则为true return compare(*this, a); }//两者均为正数,则值更小的在左边为true return compare(a, *this); } BigInteger operator+(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况,直接相加,再改符号 res = add(*this, a); flag = true; } else if (a.f && !f) {//左正右负 if (compare(a, *this)) { //看负数对应的nums是否比正数大 flag = true; res = minus(a, *this); } else { flag = false; res = minus(*this, a); } } else if (!a.f && f) { if (compare(*this, a)) { //与上一个相同 flag = true; res = minus(*this, a); } else { flag = false; res = minus(a, *this); } } else { //同时为正数就是最简单的加法 flag = false; res = add(*this, a); } res.f = flag; return res; } BigInteger operator-(BigInteger &a) { BigInteger res; bool flag; if (a.f && f) { //同为负数情况--左边-右边==(不看符号)右边-(不看符号)左边 if (compare(a, *this)) { flag = false; res = minus(a, *this); } else { if (isEqual(*this, a)) flag = false; else flag = true; res = minus(*this, a); } } else if (a.f && !f) { //左边为正,右边为负--左边-右边==左边+右边 flag = false; res = add(a, *this); } else if (!a.f && f) { //右边为正,左边为负--左边-右边==两边为负的加法 flag = true; res = add(a, *this); } else { //同时为正数--左边-右边==左边-右边(分类讨论正负 if (compare(a, *this)) { //右边>左边,符号为负 res = minus(a, *this); flag = true; } else { //右边<左边,符号为正 res = minus(*this, a); flag = false; } } res.f = flag; return res; } void print() { if (f) printf("-"); nums[length] = '\0'; int i = 0; while (nums[i] == '0')i++; printf("%s", nums + i); } void read() {//利用getchar()给对象赋上数据 char c = getchar(); if (c == '-') { f = true; c = getchar(); } while (c=='\n'||c == '0'||c == ' ') c = getchar();//将前导0消耗掉和空格 while (c != '\n'&&c != ' '&& c != '\t') { push_back(c);//不断的调用push_back即可 c = getchar(); } } }; int main() { using namespace std; int n; cin >> n; for (int i = 1; i <= n; i++) { char a[100], b[100], c[100]; printf("Case #%d: ", i); cin >> a >> b >> c; BigInteger a1(a), b2(b), c2(c); BigInteger t = c2 - b2; if (t < a1) cout << "true\n"; else cout << "false\n"; } return 0; }
正确输出
很多人,可能觉得做项目一定得是那种高大上,又或者是那种贪吃蛇小游戏、扫雷小游戏类型,实际上只要你有兴趣,任何一个东西都能成为你的练手项目,并且收获收获也许比你跟风去弄几个小游戏更大。
做这个小项目,我的收获是,对C++的语法更加的了解了,关于移动构造器、拷贝构造器、赋值重载这块弄得更清楚了,最大的收获在于强化了一个类的设计思路,这个是最重要的。
多写一些类的实现,不仅有利于对算法和语言语法的理解,更大的收获在于对各个功能的设计思路,作为程序员,我们最需要的就是这样的逻辑思维,从接到需求开始,我们应该能迅速的抽象出各种实现方案,然后进行不断的优化,得出属于自己的代码!
#include<cstdio> #include<cstring> int main() { int n, l[2][3], a[3], b[30], i, j, c, len; char s[3][30]; scanf("%d", &n); for (i = 1; i <= n; i++) { scanf("%s%s%s", s[0], s[1], s[2]); printf("Case #%d: ", i); for (j = 0; j < 3; j++) { l[0][j] = l[1][j] = strlen(s[j]); } if (s[0][0] == '-') a[0] = -1, l[1][0]--; else a[0] = 1; if (s[1][0] == '-') a[1] = -1, l[1][1]--; else a[1] = 1; if (s[2][0] == '-') a[2] = 1, l[1][2]--; else a[2] = -1; c = 0; len = l[1][0] > l[1][1] ? l[1][0] : l[1][1]; len = len > l[1][2] ? len : l[1][2]; for (j = 0; j < len; j++) { b[j] = c; if (j < l[1][0]) b[j] += a[0] * (s[0][l[0][0] - 1 - j] - '0'); if (j < l[1][1]) b[j] += a[1] * (s[1][l[0][1] - 1 - j] - '0'); if (j < l[1][2]) b[j] += a[2] * (s[2][l[0][2] - 1 - j] - '0'); c = (b[j] + 30) / 10 - 3; b[j] -= c * 10; } if (c > 0) printf("true\n"); else if (c < 0) printf("false\n"); else { for (j = 0; j < len; j++) { if (b[j] != 0) break; } if (j == len) printf("false\n"); else printf("true\n"); } } return 0; }
#include<iostream> #include<vector> #include<string> using namespace std; string add(string a,string b) { string ans; ans.resize(a.size() > b.size() ? a.size() : b.size()); int i = a.size()-1; int j = b.size()-1; int k = ans.size() - 1; int cf = 0; while (i>=0&&j>=0) { char tmp = '0' + (a[i] - '0' + b[j] - '0' + cf) % 10; cf = (a[i] - '0' + b[j] - '0' + cf) / 10; ans[k] = tmp; i--; j--; k--; } while (i >= 0) { ans[k] = '0'+(a[i]-'0'+cf)%10; cf = (a[i] - '0'+ cf) / 10; k--; i--; } while (j >= 0) { ans[k] = '0' + (b[j] - '0' + cf) % 10; cf = (b[j] - '0' + cf) / 10; k--; j--; } if (cf == 1) { ans = "1" + ans; } return ans; } string sub(string a,string b) {//保证是大减小 string ans; ans.resize(a.size()); int i = a.size() - 1; int j = b.size() - 1; int k = ans.size() - 1; int cf = 0; while (j >= 0) { if (a[i] - b[j] - cf < 0) { ans[k] = '0'+(a[i] - b[j] - cf+10)%10; cf = 1; } else { ans[k] = '0' + a[i] - b[j] - cf; cf = 0; } i--; j--; k--; } while (i >= 0) { if (a[i]-'0' - cf < 0) { ans[k] = '0' + (a[i]-'0' - cf + 10) % 10; cf = 1; } else { ans[k] =a[i] - cf; cf = 0; } k--; i--; } return ans; } int judge(string a, string b) {//a大b返回1,b大a返回-1,相等返回0 int al = a.size(); int bl = b.size(); if (a[0] == '-'&&b[0] != '-'){ return -1; } else if (a[0] != '-'&&b[0] == '-'){ return 1; } else if (a[0] != '-'&&b[0] != '-'){ if (al>bl)return 1; else if (al<bl)return -1; else{ for (int i = 0; i < al; i++) { if (a[i] - b[i] > 0)return 1; if (a[i] - b[i] < 0)return -1; } } return 0; } else{ if (al>bl)return -1; else if (al<bl)return 1; else{ for (int i = 0; i<al; i++){ if (a[i] - b[i]>0)return -1; if (a[i] - b[i]<0)return 1; } } return 0; } return -10; } int main() {//1 -20202220 202002 1 int numofCase; string A, B, C, ans; cin >> numofCase; for (int i = 1; i <= numofCase; i++) { cin >> A >> B >> C; printf("Case #%d: ", i); if (A[0] != '-' && B[0] != '-') { ans = add(A, B); } else if (A[0] == '-' && B[0] == '-') { B.erase(0, 1); A.erase(0, 1); ans = "-" + add(A, B); } else if (A[0] != '-' && B[0] == '-') { B.erase(0, 1); int tmp = judge(A, B);//比较a,b的绝对值大小 if (tmp == 1 || tmp == 0) { ans = sub(A, B); } else { ans = "-" + sub(B, A); } } else if (A[0] == '-' && B[0] != '-') { A.erase(0, 1); int tmp = judge(A, B); if (tmp == 1) { ans = "-" + sub(A, B); } else { ans = sub(B, A); } } if (judge(ans, C) == 1) { printf("true\n"); } else { printf("false\n"); } } }
//PAT通过测试代码 #include <bits/stdc++.h> using namespace std; typedef long long LL; int main(){ int t,flag; LL a,b,c,res; scanf("%d",&t); for(int i = 1; i <= t; i++){ scanf("%lld%lld%lld",&a,&b,&c); res = a+b; if(a>0&&b>0&&res<=0) flag = 1; else if(a<0&&b<0&&res>=0) flag = 0; else flag = (a+b > c?1:0); printf("Case #%d: ",i),flag?printf("true\n"):printf("false\n"); } return 0; }