码迷,mamicode.com
首页 > 其他好文 > 详细

高精度计算-大整数除法

时间:2015-05-05 12:42:37      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:大整数除法

问题描述

求两个大的正整数相除的商
输入数据
第 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;



}

高精度计算-大整数除法

标签:大整数除法

原文地址:http://blog.csdn.net/zwhlxl/article/details/45499537

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!