高精度
欢迎加入万人千题社区与英雄哥一起打卡
今天是打卡的地27天,可以看看英雄哥的对应专栏讲解和题目练习 奥里给
《算法零基础100讲》(第27讲) 字符串算法(七) - 高精度
基本模板
高精度加法
string add(string a,string b)//只限两个非负整数相加
{
string result;
int na[length]={0},nb[length]={0};//lenght可以根据题目顺序转换
int la=a.size(),lb=b.size();
for(int i=0;i<la;i++) na[la-1-i]=a[i]-'0';
for(int i=0;i<lb;i++) nb[lb-1-i]=b[i]-'0';
int lmax=la>lb?la:lb;
for(int i=0;i<lmax;i++) na[i]+=nb[i],na[i+1]+=na[i]/10,na[i]%=10;
if(na[lmax]) lmax++;
for(int i=lmax-1;i>=0;i--) ans+=na[i]+'0';
return ans;
}
高精度乘法
string multiply(string num1, string num2) {
string s;
int na[length]={0},nb[length]={0},nc[length]={0},La=num1.size(),Lb=num2.size();
//na存储被乘数,nb存储乘数,nc存储积,length可根据数据修改
for(int i=La-1;i>=0;i--) na[La-i]=num1[i]-'0';//将字符串表示的大整形数转成i整形数组表示的大整形数
for(int i=Lb-1;i>=0;i--) nb[Lb-i]=num2[i]-'0';
for(int i=1;i<=La;i++)
for(int j=1;j<=Lb;j++)
nc[i+j-1]+=na[i]*nb[j];//a的第i位乘以b的第j位为积的第i+j-1位(先不考虑进位)
for(int i=1;i<=La+Lb;i++)
nc[i+1]+=nc[i]/10,nc[i]%=10;//统一处理进位
if(nc[La+Lb]) s+=nc[La+Lb]+'0';//判断第i+j位上的数字是不是0
for(int i=La+Lb-1;i>=1;i--)
s+=nc[i]+'0';//将整形数组转成字符串
while(s[0]=='0'&&s.size()!=1){
s.erase(0,1);
}
return s;
}
题目
415. 字符串相加
class Solution {
public:
string addStrings(string num1, string num2) {
string result;
const int length=10005;
int na[length]={0},nb[length]={0};
int la=num1.size(),lb=num2.size();
for(int i=0;i<la;i++) na[la-1-i]=num1[i]-'0';
for(int i=0;i<lb;i++) nb[lb-1-i]=num2[i]-'0';
int lmax=la>lb?la:lb;
for(int i=0;i<lmax;i++) na[i]+=nb[i],na[i+1]+=na[i]/10,na[i]%=10;
if(na[lmax]) lmax++;
for(int i=lmax-1;i>=0;i--) result+=na[i]+'0';
return result;
}
};
43. 字符串相乘
class Solution {
public:
string multiply(string num1, string num2) {
string s;
int na[12000]={0},nb[12000]={0},nc[12000]={0},La=num1.size(),Lb=num2.size();
for(int i=La-1;i>=0;i--) na[La-i]=num1[i]-'0';
for(int i=Lb-1;i>=0;i--) nb[Lb-i]=num2[i]-'0';
for(int i=1;i<=La;i++)
for(int j=1;j<=Lb;j++)
nc[i+j-1]+=na[i]*nb[j];
for(int i=1;i<=La+Lb;i++)
nc[i+1]+=nc[i]/10,nc[i]%=10;
if(nc[La+Lb]) s+=nc[La+Lb]+'0';
for(int i=La+Lb-1;i>=1;i--)
s+=nc[i]+'0';
while(s[0]=='0'&&s.size()!=1){
s.erase(0,1);
}
return s;
}
};
67. 二进制求和
67. 二进制求和
直接将进制转成2进制就好
class Solution {
public:
string addBinary(string a, string b) {
string ans;
const int L=10005;
int na[L]={0},nb[L]={0};
int la=a.size(),lb=b.size();
for(int i=0;i<la;i++) na[la-1-i]=a[i]-'0';
for(int i=0;i<lb;i++) nb[lb-1-i]=b[i]-'0';
int lmax=la>lb?la:lb;
for(int i=0;i<lmax;i++) na[i]+=nb[i],na[i+1]+=na[i]/2,na[i]%=2;
if(na[lmax]) lmax++;
for(int i=lmax-1;i>=0;i--) ans+=na[i]+'0';
return ans;
}
};
1880. 检查某单词是否等于两单词之和
class Solution {
public:
bool isSumEqual(string firstWord, string secondWord, string targetWord) {
vector<string>hash={"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25"};
int sum1=0,sum2=0;
string s1,s2,s3;
for(int i = 0; i < firstWord.size(); i++){
s1+=hash[firstWord[i]-'a'];
if(s1.size()==1&&s1[0]=='0') s1.erase(0,1);
}
for(int i = 0; i <secondWord.size(); i++){
s2+=hash[secondWord[i]-'a'];
if(s2.size()==1&&s2[0]=='0') s2.erase(0,1);
}
for(int i = 0; i < targetWord.size(); i++){
s3+=hash[targetWord[i]-'a'];
if(s3.size()==1&&s3[0]=='0') s3.erase(0,1);
}
string result = addStrings(s1,s2);
if(s3.compare(result)==0) return true;
return false;
}
string addStrings(string num1, string num2) {
string ans;
const int L=10005;
int na[L]={0},nb[L]={0};
int la=num1.size(),lb=num2.size();
for(int i=0;i<la;i++) na[la-1-i]=num1[i]-'0';
for(int i=0;i<lb;i++) nb[lb-1-i]=num2[i]-'0';
int lmax=la>lb?la:lb;
for(int i=0;i<lmax;i++) na[i]+=nb[i],na[i+1]+=na[i]/10,na[i]%=10;
if(na[lmax]) lmax++;
for(int i=lmax-1;i>=0;i--) ans+=na[i]+'0';
return ans;
}
};
1556. 千位分隔数
1556. 千位分隔数
注意处理0
class Solution {
public:
string thousandSeparator(int n) {
int size=0;
string result;
if(n==0){
result+='0';
return result;
}
while(n){
result+=n%10+'0';
n/=10;
size++;
if(size%3==0&&n!=0) result+='.';
}
reverse(result.begin(),result.end());
return result;
}
};
1945. 字符串转化后的各位数字之和
class Solution {
public:
int getLucky(string s, int k) {
vector<string>hash={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26"};
string result;
for(int i=0;i<s.size();i++){
result+=hash[s[i]-'a'];
}
int sum=0;
for(int i =0;i<result.size();i++){
sum+=result[i]-'0';
}
while(k--){
if(k==0) return sum;
int temp=0;
while(sum){
temp+=sum%10;
sum/=10;
}
sum=temp;
if(sum<10) return sum;
}
return 0;
}
};
12. 整数转罗马数字
class Solution {
public:
string intToRoman(int num) {
string result;
while(num>=1000){ result+="M"; num-=1000;}
while(num>=900){ result+="CM"; num-=900;}
while(num>=500){ result+="D"; num-=500;}
while(num>=400){ result+="CD"; num-=400;}
while(num>=100){ result+="C"; num-=100;}
while(num>=90){ result+="XC"; num-=90;}
while(num>=50){ result+="L"; num-=50;}
while(num>=40){ result+="XL"; num-=40;}
while(num>=10){ result+="X"; num-=10;}
while(num>=9){ result+="IX"; num-=9;}
while(num>=5){ result+="V"; num-=5;}
while(num>=4){ result+="IV"; num-=4;}
while(num>=1){ result+="I"; num-=1;}
return result;
}
};
1796. 字符串中第二大的数字
class Solution {
public:
int secondHighest(string s) {
int hash[10]={0};
int size=0;
for(int i =0;i<s.size();i++){
if(s[i]>='0'&&s[i]<='9') {
// int temp = ;
hash[s[i]-'0']++;
}
}
int type=2;
for(int i=9;i>=0;i--){
if(hash[i]>0) type--;
if(type==0) return i;
}
return -1;
}
};
539. 最小时间差
[539. 最小时间差(https://leetcode-cn.com/problems/minimum-time-difference/)
class Solution {
public:
int findMinDifference(vector<string>& timePoints) {
int n = timePoints.size();
vector<int>sum(n,0);
for(int i = 0;i<n;i++){
string temp = timePoints[i];
sum[i] = ((temp[0]-'0')*10+temp[1]-'0')*60+(temp[3]-'0')*10+temp[4]-'0';
}
sort(sum.begin(),sum.end());
int result = 1440;
if(sum[0]<720){
sum.push_back(sum[0]+1440);
n++;
}
for(int i =1;i<n;i++ ){
if(sum[i]<720){
sum.push_back(sum[i]+1440);
n++;
}
result=min(result,sum[i]-sum[i-1]);
if(result == 0) return result;
}
return result;
}
};