高精度的实现及递归的结合

前置知识点:
1 如何向字符串类型数据里中添加单个字符
例如:字符串str string str="234"
在他的前面添加字符‘1’使之变成“1234”的方法
str=char(1+'0')+str;
或者 str =‘1’+str;

2 string函数的应用

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string str="abcdefab";
1. cout<<str.find_first_not_of('h')<<endl;
    //第二个参数为0,默认从原串下标为0开始查找。第一个a就和带查字符不同,故输出a的下标0。
2. cout<<str.find_first_not_of("twj",1)<<endl;
   //从下标为1开始查,第一个b就和待查子串任一字符不同,故输出b的下标1。
3.   cout<<str.find_first_not_of("wbj",1)<<endl;
//从下标为1开始,第一个b与待查子串中的b一样,故b不符合,继续c再和子串任一字符比较,结果都不同,故输出c的下标2。
4.cout<<str.find_first_not_of("abcdefg")<<endl;
   //原串任一字符都出现在子串中,故找不到,返回npos。
5.cout<<str.find_last_not_of('h')<<endl;
//第二个参数为0,默认从npos逆向查。原串倒数第一个字符b和h就不同,故输出b的小标7。
6.cout<<str.find_last_not_of("ab",6)<<endl;
//从原串下标为6开始逆向查询,第一个a和待查串中的字符a相同,不符合,故继续逆向比较。f和待查子串任一字符不同,故输出f的下标5。
7.cout<<str.find_last_not_of("abcdefhu")<<endl;
  //原串任一字符都出现在子串中,故找不到,返回npos。
 return 0;
}

//有效的下标应该在0~len-1范围内。len=str.size();

高精度的实现的三种形式

  1. 字符串数据类型
  2. 结构体数据类型

第一种字符串数据类型

#include<bits/stdc++.h>
using namespace std;
//比较大小**
int compare(string s1,string s2)
{
    if(s1.length()>s2.length())return 1;
    else if(s1.length()<s2.length())return -1;
    else return s1.compare(s2);
}//加法**
string add(string s1,string s2)
{
    string s3;
    int len1=s1.length();
    int len2=s2.length();
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
        {
            s1="0"+s1;
         } 
    }
    else {
        for(int i=1;i<=len1-len2;i++)
        {
            s2="0"+s2;
        }
    }
    len1=s1.length();
    int carry=0;
    int temp;
    for(int i=len1-1;i>=0;i--)
    {
        temp=s1[i]-'0'+s2[i]-'0'+carry;
        carry=temp/10;
        temp%=10;
        s3=char(temp+'0')+s3;
    }
    if(carry!=0)s3=char(carry+'0')+s3;
    return s3;
}
//s1>s2(减法)
string sub(string s1,string s2)
{
    string s3;
    int tmp=s1.length()-s2.length();
    int carry=0;
    for(int i=s2.length()-1;i>=0;i--)
    {
        if(s1[tmp+i]<s2[i]+carry)
        {
            s3=char(s1[tmp+i]-s2[i]-carry+'0'+10)+s3;
            carry=1; 
        }
        else {
            s3=char(s1[tmp+i]-s2[i]-carry+'0')+s3;
            carry=0;
        }
    }
    for(int i=tmp-1;i>=0;i--)
    {
        if(s1[i]-carry>='0')
        {
            s3=char(s1[i]-carry)+s3;
            carry=0;
        }
        else {
            s3=char(s1[i]-carry+10)+s3;
            carry=1;
        }
    }
    s3.erase(0,s3.find_first_not_of('0'));
    //s3.erase(0,s3.find_first_not_of('0'));
    return s3;    
}
//(乘法)
string mul(string s1,string s2)
{
    string s3;
    int len1=s1.length();
    int len2=s2.length();
    string tempstr;
    for(int i=len2-1;i>=0;i--)
    {
        tempstr="";
        int temp=s2[i]-'0';
        int t=0;
        int carry=0;
        if(temp!=0)
        {
            for(int j=1;j<=len2-1-i;j++)
              tempstr+="0";
            for(int j=len1-1;j>=0;j--)
            {
                t=(temp*(s1[j]-'0')+carry)%10;
                carry=(temp*(s1[j]-'0')+carry)/10;
                tempstr=char(t+'0')+tempstr;
            }
            if(carry!=0) tempstr=char(carry+'0')+tempstr;
        }
        s3=add(s3,tempstr);
    }
    s3.erase(0,s3.find_first_not_of('0'));
    return s3;
}

//高精度除法(未掌握)
//两个正数相除,商为quotient,余数为residue
//需要高精度减法和乘法
void div(string s1,string s2,string &quotient,string &residue)
{
    quotient=residue="";//清空
    if(s2=="0")//判断除数是否为0
    {
        quotient=residue="ERROR";
        return;
    }
    if(s1=="0")//判断被除数是否为0
    {
        quotient=residue="0";
        return;
    }
    int res=compare(s1,s2);
    if(res<0)
    {
        quotient="0";
        residue=s1;
        return;
    }
    else if(res==0)
    {
        quotient="1";
        residue="0";
        return;
    }
    else
    {
        int len1=s1.length();
        int len2=s2.length();
        string tempstr;
        tempstr.append(s1,0,len2-1);
        for(int i=len2-1;i<len1;i++)
        {
            tempstr=tempstr+s1[i];
            tempstr.erase(0,tempstr.find_first_not_of('0'));
            if(tempstr.empty())
              tempstr="0";
            for(char ch='9';ch>='0';ch--)//试商
            {
                string str,tmp;
                str=str+ch;
                tmp=mul(s2,str);
                if(compare(tmp,tempstr)<=0)//试商成功
                {
                    quotient=quotient+ch;
                    tempstr=sub(tempstr,tmp);
                    break;
                }
            }
        }
        residue=tempstr;
    }
    quotient.erase(0,quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient="0";
}

第二种 结构体数据类型

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4;
//构建结构体
struct bign{
    int d[maxn];
    int len;
    bign(){
        memset(d,0,sizeof(d));
        len=0;
    }
};
//数据转化
bign charge(char str[])
{
    bign a;
    a.len=strlen(str);
    for(int i=0;i<a.len;i++)
    {
        a.d[i]=str[a.len-i-1]-'0';
    }
    return a;
}
//比较大小
int compare(bign a,bign b)
{
    if(a.len<b.len)return 1;
    else if(a.len<b.len)return -1;
    else {
        for(int i=a.len-1;i>=0;i--)
        {
            if(a.d[i]>b.d[i])return 1;
            else if(a.d[i]<b.d[i])return -1;
        }
        return 0;
    }
}
//加法
bign add(bign a,bign b)
{
    bign c;
    int carry=0;
    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;
}
//减法
bign sub(bign a,bign b)
{
    bign c;
    for(int i=0;i<a.len||i<b.len;i++)
    {
        if(a.d[i]<b.d[i]);
        {
        a.d[i+1]--;
        a.d[i]+=10;    
        }
        c.d[c.len++]=a.d[i]-b.d[i];
     } 
     while(c.len-1>=1&&c.d[c.len-1]==0)
     {
         c.len--;
     }
     return c;
}
//乘法
bign multi1(bign a,bign b)
{
    bign c;
    int carry=0;
    for(int i=0;i<a.len;i++)
    {
        int temp=a.d[i]*b.d[i];
        c.d[c.len++]=temp%10;
        carry=temp/10; 
    }
    while(carry!=0)
    {
        c.d[c.len++]=carry%10;
        carry/=10;
    }
    return c;
}
//输出
void print(bign a)
{
    for(int i=a.len-1;i>=0;i--)
    {
        printf("%d",a.d[i]);
}
}

高精度的具体应用
(1)与递推的结合
参考博客;C++string中find_first_not_of()函数和find_last_not_of()函数

全部评论

相关推荐

11-04 14:10
东南大学 Java
_可乐多加冰_:去市公司包卖卡的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务