高精度-

题目链接:https://www.oj.swust.edu.cn/problem/show/1529

:高精度减法

思路:最核心的就是大数减小数,再看是否加负号。
1、因为输入的数可能会有前导零,所以我们先用realstr判断有效字符的位置,然后用exchange把有效字符存起
2、然后我们判断是不是输入的数前者大于后者,因为我们已经存了有效字符,所以我们直接比较有效字符的长度,长的就是大的,如果字符串长度相等,就用strcmp比较一下,然后再用s_to_i函数将字符串转换为数值存在相应的数组中(低位在前,便于进行减法运算)
3、接下来就是进行减法运算了。跑一遍for用ans数组存对应位相减的值,再跑一遍for,如果小于零就借位,分别改变当前位和下一位的值。
4、接下来要把ans中的前导零给去掉,然后输出。

The End

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
const int maxn=1000;

char ss1[maxn],ss2[maxn],es1[maxn],es2[maxn];
int min_[maxn],max_[maxn];
int ans[maxn];
int minL,maxL;
bool flag;

int realstr(char s[])//返回值是从哪个字符(下标)开始不是0,或者只有0
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        if(s[i]=='0')
            continue;
        return i;
    }
    return len-1;
}
void exchange(char ss[],char es[],int sl,int el)//将有效字符存起
{
    for(int i=sl;i<el;i++)
    {
        es[i-sl]=ss[i];
    }
}
void s_to_i(char s[],int m[])//将字符转换为数值
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        m[i]=s[len-1-i]-'0';
    }
}
void input()
{
    memset(es1,0, sizeof(es1));//这里必须得要,因为es1,es2是单个字符赋值来的,所以说必须要初始化
    memset(es2,0, sizeof(es2));
    exchange(ss1,es1,realstr(ss1),strlen(ss1));
    scanf("%s",ss2);
    exchange(ss2,es2,realstr(ss2),strlen(ss2));
    maxL=strlen(es1);
    minL=strlen(es2);
    memset(min_,0,sizeof(min_));
    memset(max_,0,sizeof(max_));
    if(maxL<minL||(maxL==minL&&strcmp(es1,es2)<0))
    {
        flag=true;
        s_to_i(es1,min_);
        s_to_i(es2,max_);
        int t=minL;
        minL=maxL;
        maxL=t;
    }
    else
    {
        s_to_i(es2,min_);
        s_to_i(es1,max_);
    }
}
void output()
{
    memset(ans,0, sizeof(ans));
    for(int i=0;i<maxL;i++)
    {
        ans[i]=max_[i]-min_[i];
    }
    for(int i=0;i<maxL;i++)
    {
        if(ans[i]<0)
        {
            int k=-ans[i]/10+1;//表示借了几位
            ans[i]+=k*10;
            ans[i+1]-=k;
        }
    }
    for(int i=maxL-1;i>=0;i--)
    {
        if(ans[i])
        {
            maxL=i+1;
            break;
        }
        if(i==0&&ans[i]==0)
            maxL=1;
    }
    if(flag)
        printf("-");
    for(int i=maxL-1;i>=0;i--)
    {
        printf("%d",ans[i]);
    }
    printf("\n");
}

int main()
{
    while(scanf("%s",ss1)!=EOF)
    {
        flag=false;
        input();
        output();
        memset(ss1,0,sizeof(ss1)); //这里其实没用,因为每次都是scanf来的字符串,所以是自动清零的后面,我试过了
        memset(ss2,0,sizeof(ss2));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/88429280