算法笔记-大数运算

何为大数运算

题目已知数字超过了int、long范围

题目

leetcode 43. Multiply Strings 字符串相乘
leetcode 66. Plus One 加一
leetcode 415. Add Strings 字符串相加
leetcode 7. Reverse Integer 整数反转
leetcode 2. Add Two Numbers 两数相加
leetcode 445. Add Two Numbers II 两数相加2

如何解决大数运算

string

每个位置的字符(‘0’~‘9’)即为该位置的数字

#include <iostream>
#include <vector>
using namespace std;
// 大数+大数
string addStrings(string num1, string num2) {
	string ans;
	// 大整数加法 -- 从低位到高位
	int i=num1.length()-1,j=num2.length()-1,carry=0;
	while(i>=0||j>=0||carry!=0){ //carry!=0是整合最高位进位为1的情况 
		int n1 = i<num1.length()?num1[i]-'0':0; //补充前导0
		int n2 = j<num2.length()?num2[j]-'0':0; //补充前导0
		int temp = n1+n2+carry;
		carry = temp/10;
		ans.append(1,temp%10+'0');
		i--;
		j--;
	}
	reverse(ans.begin(),ans.end());
	return ans;
}
// 大数*大数
string multiply(string num1, string num2) {
	string ans;
	if(num1=="0"||num2=="0") {
		return "0";
	}
	//
	int len1 = num1.length();
	int len2 = num2.length();
	
	auto arr = vector<int> (len1+len2);
	for(int i=len1-1; i>=0; i--) {
		int n1 = num1[i]-'0';
		for(int j=len2-1; j>=0; j--) {
			int n2 = num2[j]-'0';
			arr[i+j+1]+=n1*n2;
		}
	}
	// 处理进位
	for(int i=len1+len2-1;i>0;i--){
		arr[i-1]+=arr[i]/10;
		arr[i]=arr[i]%10;
	} 
	// int -> string
	int begin = arr[0]==0?1:0;
	for(int i=begin;i<len1+len2;i++){
		ans.append(1,arr[i]+'0');
	}
	return ans;
}
int main(int argc,char * argv[]) {
	//
	string num1, num2;
	cin>>num1>>num2;
	string multi = multiply(num1,num2);
	cout<<multi;
	return 0;
}

int数组

每个索引的数字(0~9)即该位置的数字

#include <iostream>
#include <cstring>
using namespace std;
// 1 大整数存储
struct bign {
	int d[100];
	int len;
	bign() {
		memset(d, 0, 100);
		len = 0;
	}
};
bign change(string s) {
	bign b;
	b.len=s.length();
	for(int i=s.length()-1; i>=0; i--) {
		b.d[s.length()-1-i]=s[i]-'0';
	}
	return b;
}
void printb(bign b) {
	for(int i=b.len-1; i>=0; i--) {
		printf("%d",b.d[i]);
	}
}
// 2 大整数相加
bign addb(bign a, bign b) {
	int i=0,carry=0;
	bign c;
	for(int i=0; i<a.len||i<b.len; i++) {
		int temp = a.d[i]+b.d[i]+carry;
		c.d[c.len++]=temp%10;
		carry=temp/10;
	}
	if(carry!=0)c.d[c.len++]=carry;
	return c;
}
// 3 大整数相减
bign subb(bign a,bign b) {
	bign c;
	for(int i=0; i<a.len||i<b.len; i++) {
		int temp=a.d[i]-b.d[i];
		if(temp<0) {
			a.d[i+1]--;
			temp+=10;
		}
		c.d[c.len++]=temp;
	}
	while(c.len>1&& c.d[c.len-1]==0) {
		c.len--; //高位0 
	}
	return c; 
}
// 4 大整数相乘 
bign multib(bign a,int b){
	bign c;
	int carry;
	for(int i=0;i<a.len;i++){
		int temp = a.d[i]*b+carry;
		c.d[c.len++]=temp%10;
		carry = temp/10; 
	}
	while(carry!=0){
		c.d[c.len++]=carry%10;
		carry /= 10; 
	} 
	return c;
} 
// 5 大整数相除
bign divideb(bign a,int b){
	bign c;
	c.len=a.len;
	int r = 0; //余数 
	for(int i=a.len-1;i>=0;i--){
		r = r*10+a.d[i];
		if(r<b){
			c.d[i]=0;
		}else{
			c.d[i]=r/b;
			r = r%b;
		}
	}
	while(c.len>1&&c.d[c.len-1]==0){
		c.len--; //删除前导0 
	}
	return c;
} 
int main(int argc,char * argv[]) {
	string a,b;
	cin>>a>>b;
	bign ba = change(a);
	bign bb = change(b);
//	printb(addb(ba,bb));
//	printb(subb(ba,bb));
//	printb(multib(ba,2));
	printb(divideb(ba,2));
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值