大数除法

大数除法

Sample Input
3 //表示接下来有三组测试数据
66666666666666666 //第一组输入
22222222222222222
33333333333333333 //第二组输入
3
55555555555555555 //第三组输入
555555


Sample Output
3
11111111111111111
100000100000

1

#include <iostream>
#include<string.h>
#include<stdio.h>
#define MAX_LEN 200
char szLine1[MAX_LEN + 10];

char szLine2[MAX_LEN + 10];

int an1[MAX_LEN + 10]; //被除数, an1[0]对应于个位

int an2[MAX_LEN + 10]; //除数, an2[0]对应于个位

int aResult[MAX_LEN + 10]; //存放商, aResult[0]对应于个位

/* Substract函数:长度为 nLen1的大整数 p1减去长度为 nLen2的大整数 p2

减的结果放在 p1里,返回值代表结果的长度

如不够减返回-1,正好减完返回 0

 p1[0]、p2[0]是个位 */

int Substract( int * p1, int * p2, int nLen1, int nLen2)

{

    int i;

    if( nLen1 < nLen2 )

        return -1;

//下面判断 p1是否比 p2大,如果不是,返回-1

    bool bLarger = false;

    if( nLen1 == nLen2 )
    {

        for( i = nLen1-1; i >= 0; i -- )
        {

            if( p1[i] > p2[i] )

                bLarger = true;

            else if( p1[i] < p2[i] )
            {

                if ( ! bLarger )

                    return -1;

            }

        }

    }

    for( i = 0; i < nLen1; i ++ )   //做减法
    {

        p1[i] -= p2[i]; //要求调用本函数时给的参数能确保当 i>=nLen2时,p2[i] = 0

        if( p1[i] < 0 )
        {

            p1[i]+=10;

            p1[i+1] --;

        }

    }

    for( i = nLen1 -1 ; i >= 0 ; i-- )

        if( p1[i] )

            return i + 1;

    return 0;

}

int main()

{

    int t, n;

    char szBlank[20];

    scanf("%d", &n);

    for( t = 0; t < n; t ++ )
    {

        scanf("%s", szLine1);

        scanf("%s", szLine2);

        int i, j;

        int nLen1 = strlen( szLine1);

        memset( an1, 0, sizeof(an1));

        memset( an2, 0, sizeof(an2));

        memset( aResult, 0, sizeof(aResult));

        j=0;

        for( i = nLen1 - 1; i >= 0 ; i --)

            an1[j++] = szLine1[i] - '0';

        int nLen2 = strlen(szLine2);

        j=0;

        for( i = nLen2 - 1; i >= 0 ; i --)

            an2[j++] = szLine2[i] - '0';

        if( nLen1 < nLen2 )
        {

            printf("0\n");

            continue;

        }

        nLen1 = Substract( an1, an2, nLen1, nLen2) ;

        if( nLen1 < 0)
        {

            printf("0\n");

            continue;

        }

        else if( nLen1 == 0)
        {

            printf("1\n");

            continue;

        }

        aResult[0] ++; //减掉一次了,商加 1

        //减去一次后的结果长度是 nLen1

        int nTimes = nLen1 - nLen2;

        if( nTimes < 0) //减一次后就不能再减了

            goto OutputResult;

        else if( nTimes > 0 )
        {

            //将 an2 乘以 10的某次幂,使得结果长度和 an1相同

            for( i = nLen1 -1; i >= 0; i -- )
            {

                if( i >= nTimes )

                    an2[i] = an2[i-nTimes];

                else

                    an2[i] = 0;

            }

        }

        nLen2 = nLen1;

        for( j = 0 ; j <= nTimes; j ++ )
        {

            int nTmp;

            //一直减到不够减为止

            //先减去若干个 an2×(10 的 nTimes 次方),

            //不够减了,再减去若干个 an2×(10 的 nTimes-1 次方),......

            while( (nTmp = Substract(an1, an2+j, nLen1, nLen2-j)) >= 0)
            {

                nLen1 = nTmp;

                aResult[nTimes-j]++; //每成功减一次,则将商的相应位加 1

            }

        }

OutputResult:

        //下面的循环统一处理进位问题

        for( i = 0; i < MAX_LEN; i ++ )
        {

            if( aResult[i] >= 10 )
            {

                aResult[i+1] += aResult[i] / 10;

                aResult[i] %= 10;

            }

        }

        //下面输出结果

        bool bStartOutput = false;

        for( i = MAX_LEN ; i >= 0; i -- )

            if( bStartOutput)

                printf("%d", aResult[i]);

            else if( aResult[i] )
            {

                printf("%d", aResult[i]);

                bStartOutput = true;

            }

        if(! bStartOutput )

            printf("0\n");

        printf("\n");

    }
    return 0;

}


2

#include <stdio.h>
#include <string.h>
#define MAX_LEN 110
int an1[MAX_LEN];
int an2[MAX_LEN];
int tmpAn2[MAX_LEN];
int anResult[MAX_LEN];
char szLine1[MAX_LEN];
char szLine2[MAX_LEN];
char szNouse[MAX_LEN];
int Substract( int nMaxLen, int * an1, int * an2)
//大整数an1减去an2。两者最多 nMaxLen 位,an1必须不小于an2, 差放在an1里
//返回差的最高非0位的位置
{   int nStartPos = 0;
    for( int i = 0;i < nMaxLen ; i ++ ) {
        an1[i] -= an2[i];       //逐位相减
        if( an1[i] < 0 ) {      //看是否要借位
            an1[i] += 10;
            an1[i+1] --;    //借位
        }
        if( an1[i] )
            nStartPos = i; //记录最高位的位置
    }
    return nStartPos;
}
int Length( int nMaxLen,int * an)
//求大整数的位数。0 算 0 位
{
    int i;
    for( i = nMaxLen -1 ; an[i] == 0 && i >= 0; i -- );
    if( i >= 0 )
        return i + 1;
    return 0;
}
void ShiftLeft( int nMaxLen,int * an1, int * an2, int n)
//将大整数an1左移n位,即乘以10的n次方,结果放到an2里
{
    memcpy( an2,an1,nMaxLen * sizeof(int));
    if( n <= 0 )
        return;
    for( int i = nMaxLen -1 ; i >= 0; i -- )
        if( i - n >= 0)
            an2[i] = an1[i-n];
        else
            an2[i] = 0;
}
int * Max(int nMaxLen, int * an1, int * an2)
//求大整数an1和an2里面大的那个
//如果都是0,则返回NULL
{
    bool bBothZero = true;
    for( int i = nMaxLen -1; i >= 0 ; i -- ) {
        if( an1[i] > an2[i] )
            return an1;
        else if( an1[i] < an2[i] )
            return an2;
        else if( an1[i] )
            bBothZero = false;
    }
    if( bBothZero)
        return NULL;
    return an1;
}
int main()
{
    int n;
    scanf("%d",&n);
    getchar();
    while(n -- ) {
        gets(szLine1);
        gets(szLine2);

        int i, j;
        //库函数memeset将地址an1开始的sizeof(an1)字节内容置成0
        //sizeof(an1)的值就是an1的长度
        //memset函数在string.h中声明
        memset( an1, 0, sizeof(an1));
        memset( an2, 0, sizeof(an2));
        //下面将szLine1中存储的字符串形式的整数转换到an1中去,
        //an1[0]对应于个位
        int nLen1 = strlen( szLine1);
        for(j = 0, i = nLen1 - 1;i >= 0 ; i --)
            an1[j++] = szLine1[i] - '0';
        int nLen2 = strlen(szLine2);
        for( j = 0, i = nLen2 - 1;i >= 0 ; i --)
            an2[j++] = szLine2[i] - '0';
        int nHighestPos = 0;
        memset(anResult,0,sizeof(anResult));
        int nShiftLen = Length(MAX_LEN,an1) - Length(MAX_LEN,an2);
        //只要an1大于an2,就不停相减
        while( Max(MAX_LEN,an1,an2) == an1 ) {
            //算出an1的10的nShiftLen次方倍
            ShiftLeft(MAX_LEN, an2, tmpAn2,nShiftLen);
            //重复减去an1的10的nShiftLen次方倍,看能减几次
            while( Max(MAX_LEN,an1,tmpAn2) == an1) {
                Substract(MAX_LEN, an1,tmpAn2);
                //记录商对应位
                anResult[nShiftLen] ++;
            }
            //记录结果最高位的位置
            if( nHighestPos == 0 && anResult[nShiftLen])
                nHighestPos = nShiftLen;
            nShiftLen --;
        }
        for( i = nHighestPos; i >= 0; i -- )
            printf("%d", anResult[i]);
        printf("\n");
    }
    return 0;
}

3

#include <stdio.h>
#include <string.h>
#define MAX_LEN 200
char szLine1[MAX_LEN + 10];
char szLine2[MAX_LEN + 10];
int an1[MAX_LEN + 10]; //被除数, an1[0]对应于个位
int an2[MAX_LEN + 10]; //除数, an2[0]对应于个位
int aResult[MAX_LEN + 10]; //存放商,aResult[0]对应于个位
/* Substract 函数:长度为 nLen1 的大整数p1 减去长度为nLen2 的大整数p2
减的结果放在 p1 里,返回值代表结果的长度
如不够减返回-1,正好减完返回 0
p1[0]、p2[0] 是个位 */
int Substract( int * p1, int * p2, int nLen1, int nLen2)
{
    int i;
    if( nLen1 < nLen2 )
        return -1;
//下面判断p1 是否比p2 大,如果不是,返回-1
    bool bLarger = false;
    if( nLen1 == nLen2 )
    {
        for( i = nLen1-1; i >= 0; i -- )
        {
            if( p1[i] > p2[i] )
                bLarger = true;
            else if( p1[i] < p2[i] )
            {
                if ( ! bLarger )
                    return -1;
            }
        }
    }
    for( i = 0; i < nLen1; i ++ )   //做减法
    {
        p1[i] -= p2[i]; //要求调用本函数时给的参数能确保当i>=nLen2 时,p2[i] = 0
        if( p1[i] < 0 )
        {
            p1[i]+=10;
            p1[i+1] --;
        }
    }
    for( i = nLen1 -1 ; i >= 0 ; i-- )
        if( p1[i] )
            return i + 1;
    return 0;
}
int main()
{
    int t, n;
    char szBlank[20];
    scanf("%d", &n);
    for( t = 0; t < n; t ++ )
    {
        scanf("%s", szLine1);
        scanf("%s", szLine2);
        int i, j;
        int nLen1 = strlen( szLine1);
        memset( an1, 0, sizeof(an1));
        memset( an2, 0, sizeof(an2));
        memset( aResult, 0, sizeof(aResult));
        j = 0;
        for( i = nLen1 - 1; i >= 0 ; i --)
            an1[j++] = szLine1[i] - '0';
        int nLen2 = strlen(szLine2);
        j = 0;
        for( i = nLen2 - 1; i >= 0 ; i --)
            an2[j++] = szLine2[i] - '0';
        if( nLen1 < nLen2 )
        {
            printf("0\n");
            continue;
        }
        nLen1 = Substract( an1, an2, nLen1, nLen2) ;
        if( nLen1 < 0 )
        {
            printf("0\n");
            continue;
        }
        else if( nLen1 == 0)
        {
            printf("1\n");
            continue;
        }
        aResult[0] ++; //减掉一次了,商加1
//减去一次后的结果长度是 nLen1
        int nTimes = nLen1 - nLen2;
        if( nTimes < 0) //减一次后就不能再减了
            goto OutputResult;
        else if( nTimes > 0 )
        {
//将 an2 乘以10 的某次幂,使得结果长度和 an1 相同
            for( i = nLen1 -1; i >= 0; i -- )
            {
                if( i >= nTimes )
                    an2[i] = an2[i-nTimes];
                else
                    an2[i] = 0;
            }
        }
        nLen2 = nLen1;
        for( j = 0 ; j <= nTimes; j ++ )
        {
            int nTmp;
//一直减到不够减为止
//先减去若干个 an2×(10 的 nTimes 次方),
//不够减了,再减去若干个 an2×(10 的 nTimes-1 次方),......
            while( (nTmp = Substract(an1, an2+j, nLen1, nLen2-j)) >= 0)
            {
                nLen1 = nTmp;
                aResult[nTimes-j]++; //每成功减一次,则将商的相应位加1
            }
        }
OutputResult:
//下面的循环统一处理进位问题
        for( i = 0; i < MAX_LEN; i ++ )
        {
            if( aResult[i] >= 10 )
            {
                aResult[i+1] += aResult[i] / 10;
                aResult[i] %= 10;
            }
        }
//下面输出结果
        bool bStartOutput = false;
        for( i = MAX_LEN ; i >= 0; i -- )
            if( bStartOutput)
                printf("%d", aResult[i]);
            else if( aResult[i] )
            {
                printf("%d", aResult[i]);
                bStartOutput = true;
            }
        if(! bStartOutput )
            printf("0\n");
        printf("\n");
    }
    return 0;
}
Python中,当我们对两个整数进行除法时,结果将是一个浮点数。但是,如果我们想要得到整数除法的结果,我们可以使用“//”运算符。此外,我们可以使用“%”运算符来获得余数。但是,当我们处理大数除法时,我们需要注意一些问题。 一种解决大数除法的方法是使用Python的Decimal模块。Decimal模块提供了高精度的十进制算术运算。我们可以使用Decimal模块中的divide()函数来执行大数除法。下面是一个示例代码: ```python from decimal import * a = Decimal('123456789012345678901234567890') b = Decimal('987654321098765432109876543210') c = a / b print(c) ``` 输出结果为: ``` 0.1249999999999999999999999999 ``` 另一种解决大数除法的方法是使用Python的long division算法。这种算法可以手动模拟除法过程,从而避免使用浮点数。下面是一个示例代码: ```python a = '123456789012345678901234567890' b = '987654321098765432109876543210' # 将字符串转换为数字列表 a = [int(x) for x in a] b = [int(x) for x in b] # 执行长除法 q = [] r = [] for d in a: r.append(d) s = 0 while len(r) >= len(b): t = b.copy() m = len(r) - len(t) t = [0] * m + t s += 1 for i in range(len(t)): r[i] -= t[i] if r[i] < 0: r[i] += 10 r[i+1] -= 1 while len(r) > 0 and r[-1] == 0: r.pop() q.append(s) # 将数字列表转换为字符串 q = ''.join([str(x) for x in q]) r = ''.join([str(x) for x in r]) print(q) print(r) ``` 输出结果为: ``` 0 123456789012345678901234567890 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值