高精度计算-大整数除法

问题描述

求两个大的正整数相除的商

输入数据

第 1 行是测试数据的组数 n,每组测试数据占 2 行,第 1 行是被除数,第 2 行是除数。

每组测试数据之间有一个空行,每行数据不超过 100 个字符

输出要求

n 行,每组测试数据有一行输出是相应的整数商

解题思路

基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?以 7546 除以 23 为例来看一下:开始商为 0。先减去 23 的 100 倍,就是 2300,发现够减 3 次,余下 646。于是商的值就增加 300。然后用 646减去 230,发现够减 2 次,余下 186,于是商的值增加 20。最后用 186 减去 23,够减 8 次,因此最终商就是 328。所以本题的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 200
int x[MAX_LEN + 20], y[MAX_LEN + 20], z[MAX_LEN + 20];
char a[MAX_LEN + 20], b[MAX_LEN + 20];

void debug_print(const int x[], int len)
{
    int i;
    for (i = 0; i < len; i++)
        printf("%d", x[i]);
    printf("\n");
}

void char_to_int(const char s[ ], int x[ ])
{
    int i = 0;
    int len = strlen(s);

    memset(x, 0, MAX_LEN + 20);
    int j  = 0;
    for (i = len - 1; i >= 0; i--)
    {
        x[j++] = s[i] - ‘0‘;
    }
}

int cal_length( const int x[])
{
    int i = 0;
    int count = 0;
    for (i = MAX_LEN - 1; i >= 0;  i--)
    {
        if (x[i])
        {
            count = i + 1;
            break;
        }

    }

    return count;
}

int  big_int_sub( int x[], const int y[])
{
    int i = 0;
    const int lenx = cal_length(x);
    const int leny = cal_length(y);

    //判断x 是否大于 y

    if (lenx < leny)
        return -1;
    else if (lenx == leny)
    {
        for (i = lenx - 1; i >= 0; i--)
        {
            if (x[i] < y[i])
                return -1;
            else if (x[i] == y[i])
                continue;
            else
                break;

        }
    }

    //逐位想减
    for (i = 0; i < MAX_LEN; i++)
    {

        x[i] = x[i] - y[i];

        if (x[i] < 0)
        {
            x[i] = x[i] + 10;
            x[i + 1] --;
        }
    }

    return 1;
}

void big_int_div(int x[], const int y[], int z[])
{
    int i , j = 0;
    int *copy_y = NULL;
    memset(z, 0, MAX_LEN + 20);
    const int lenx = cal_length(x);
    int leny = cal_length(y);
    int times = lenx - leny;

    copy_y = (int *)malloc(sizeof(int ) * MAX_LEN);
    memcpy(copy_y, y, sizeof(int) * MAX_LEN);

    //  将复制的copy_y右移times位,跟x的长度相等
    for (i = lenx - 1; i >= 0; i--)
    {
        if (i >= times)
            copy_y[i] = copy_y[i - times];
        else
            copy_y[i] = 0;        //低位补0
    }

    //x开始减copy_y,减到不够减之后,再减去 copy_y右移times - 1位 直到最后不够减

    leny = lenx;

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

        while ( big_int_sub(x, copy_y)  >= 0)
            z[times - i] ++;
        //copy_y 左移一位   即是y的右移times - 1位
        for (j = 1; j < leny; j++)
            copy_y[j - 1] = copy_y[j];
        copy_y[--leny] = 0;

    }

    for (i = 0; i < MAX_LEN ; i++)
    {
        if (z[i] >= 10)
        {
            z[i + 1] += z[i] / 10;
            z[i]  =  z[i] % 10;
        }
    }

}

void big_int_print(const int z[])
{
    bool flag = 0;
    int i = 0;

    for (i = MAX_LEN; i >= 0; i--)
    {
        if (flag)
            printf("%d", z[i]);
        else if (z[i])
        {
            printf("%d", z[i]);
            flag = 1;
        }
    }

    if (!flag)
        printf("0");
    printf("\n");
}

int main( )
{
    int n;
    scanf("%d", &n);
    while (n--)
    {
        scanf("%s", a);
        scanf("%s", b);

        int len = 0;
        int lenx  = strlen(a);
        int leny  = strlen(b);

        len = lenx - leny;
        if (len < 0)
            printf("0\n");

        char_to_int(a, x);
        char_to_int(b, y);

        big_int_div(x, y, z);

        big_int_print(z);
    }

    return 0;

}
时间: 2024-10-02 20:11:49

高精度计算-大整数除法的相关文章

2737 大整数除法

题目来源:http://bailian.openjudge.cn/practice/2737/描述求两个大的正整数相除的商.输入第1行是被除数,第2行是除数.每个数均不超过100位.输出一行,相应的商的整数部分样例输入237624样例输出99题意描述:计算位数不超过200的两个大整数的商解题思路:总体用减法来模拟除法,当然为了让模拟更高效采用一定的方法. 先将被除数和除数分别存进一维字符数组str1和str2如果被除数的长度小于除数的,直接输出0逆置str1和str2存进数组a和b调用jiand

高精度计算-大整数加减法

问题描述 求两个不超过 200 位的非负整数的和. 输入数据 有两行,每行是一个不超过 200 位的非负整数,没有多余的前导 0. 输出要求 一行,即相加后的结果.结果里不能有多余的前导 0,即如果结果是 342,那么就不能 输出为 0342. 输入样例 22222222222222222222 33333333333333333333 输出样例 Output Sample: 55555555555555555555 解题思路 C/C++中的 int 类型能表示的范围是[?231,?231–1]

高精度计算-大整数乘法

大整数乘法 问题描述 求两个不超过 200 位的非负整数的积. 输入数据 有两行,每行是一个不超过 200 位的非负整数,没有多余的前导 0. 输出要求 一行,即相乘后的结果.结果里不能有多余的前导 0,即如果结果是 342,那么就不能 输出为 0342. 输入样例 12345678900 98765432100 输出样例 1219326311126352690000 解题思路 乘法规律,一个数的第i位和另一个数的第j位相乘,一定会累加到结果的第i+j位,结果的数组一个数组元素存2位数,最后对结

大整数除法,C语言基础语法实现

#include<stdio.h>#include<string.h>#define N 2004void change(char c[],int n[]);int Sub(int *a,int *b,int lena,int lenb);int main(){    char x[N],y[N];    int a[N]={0},b[N]={0};    scanf("%s %s",x,y);    change(x,a);    change(y,b);  

高精度_百炼_大整数除法 2737 (Python)

a=input() a=int(a) b=input() b=int(b) print(a//b) print("\n") 原文地址:https://www.cnblogs.com/MapReduce/p/8394534.html

题目:大整数乘法、除法,楼梯走法,数组中不同数字,超过一半数字(好)

大整数乘法,可以用单个数字想乘,跟踪进位信息来处理. 大整数除法,可以先把除数增大到跟被除数相同的量级,然后累计相减.比如 555 / 3,就先把3增大到300,555能够减1次,那么结果+100,被除数变成255,依次进行. 楼梯走法:一次走一级,或者走两级.没什么难度. 数组中不同数字:如果是2n+1数组找出不同的那个数字,用异或就可以. 如果是找出超出一般数目的数字,用遍历,看到不一样的,就一起删除,这样的方式. 上网搜了一下,找出了更好的方法: 用变量记录备选数字,一个计数器记录该数字剩

大整数的加减乘除

多项式的加减乘除能够利用多项式的加减乘除进行运算,所以下面程序採用了多项式的加减乘除.多项式运算已经在<算法导论>第30章有简要的介绍,详细的请參考数学书. 大整数加法:(利用书上公式轻松得出) //多项式加法-大数加法 #include <iostream> #include <time.h> using namespace std; #define m1 4 #define m2 5 //a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数

大整数运算模板总结

大整数运算模板总结. 大整数结构体表示 整型数组从低位到高位顺序存储每一位数字,另外需要存储数字的长度. struct bign { int d[1000]; int len; bign(){ memset(d, 0, sizeof(d)); len = 0; } }; 大整数输入 一般通过字符串输入. bign Change(string str)//输入字符串转大整数 { bign a; a.len = str.length(); for (int i = 0; i < a.len; i++

算法学习——大整数运算(高精度)C++

1.大整数加法 用数组来存储大整数的每一位,然后模拟人工运算,用for循环按位运算和处理,原理十分简单,直接上模板. #include<iostream> #include<vector> using namespace std; //大整数加法 vector<int> add(vector<int>& A,vector<int>& B){ vector<int> C; int t = 0; for(int i = 0