POJ-1001 高精度指数运算

解这道题,主要是几个要点:
1. 大数可表示为:
2. 可利用数组存储,数组索引n上的元素a,代表值:a * 10^n
3. 大数相乘,可表示为:
其他则是一些边界情况处理(比如头尾去0,小数点位置等),这方面主要依靠测试数据集,我使用的测试数据附在文末。下面是算法代码:

#include <stdio.h>
#include <string.h>
#include <math.h>

#define INIT_LEN 6
#define MAX_LEN 150
#define LINE_SZ 100

int input[MAX_LEN];
int mid[MAX_LEN];
int result[MAX_LEN];

//get the number length
int get_number_length(int *array, int max_len) {
    int i;

    for (i = max_len-1; i >=0; i--) {
        if (array[i] != 0) {
            break;
        }
    }

    return i+1;
}
/*
 * @exp: exponential number
 */
int exponential(int exp) {
    int i = 0;
    int k = 0;
    int m = 0;
    int init_len = get_number_length(input, MAX_LEN);

    //init mid with input
    memset(mid, 0, MAX_LEN * sizeof(int));
    for (i = 0; i < init_len; i++) {
        mid[i] = input[i];
    }
    if (exp < 2) {
        for(i=0; i < init_len; i++) {
            result[i] = input[i];
        }
        return 0;
    }
    //start multiply: input ^2...exp
    for (k = 2; k <= exp; k++) {
        int mid_len = get_number_length(mid, MAX_LEN);
        int j;

        memset(result, 0, MAX_LEN * sizeof(int));
        for (i = 0; i < init_len; i++ ) {
            for (j = 0; j < mid_len; j++) {
                result[i + j] += input[i]  * mid[j];

                //发生进位
                for (m = i + j; m < MAX_LEN; m++) {
                    if (result[m] >= 10) {
                        result[m + 1] += result[m] / 10;
                        result[m] = result[m] % 10;
                    } else
                        break;
                }
            }
        }
        //copy result back to mid
        memset(mid, 0, MAX_LEN * sizeof(int));
        for (i = 0; i < get_number_length(result, MAX_LEN); i++) {
            mid[i] = result[i];
        }
    }
    return 0;
}

int read_args(char *line, int *exp, int *npoint) {
    char *p =  line;
    char c;
    int max_index = 0;
    int i = 0;
    int point_num = 0;

    while(*p != ' ' && *p != '\n') {
        c = *p;
        point_num++;
        if (c == '.') {
            point_num = 0;
            p++;
            continue;
        }
        if (max_index + 1 > INIT_LEN -1)
            return 0;
        for (i = max_index+1;i>0; i--) {
            input[i] = input[i-1];
        }
        input[0] = c - 48;
        max_index++;
        p++;
    }
    sscanf(p, " %d", exp);
    *npoint = point_num;
    return 1;
}

int main(int argc, char **argv) {
    while (1) {
        int exp;
        int i, j;
        int npoint;
        int len, integer_len;
        char line[LINE_SZ];

        memset(input, 0, 6 * sizeof(int));
        memset(mid, 0, MAX_LEN * sizeof(int));
        memset(result, 0, MAX_LEN * sizeof(int));

        if (fgets(line, LINE_SZ, stdin) && read_args(line, &exp, &npoint)) {
            exponential(exp);
        } else {
            break;
        }
        npoint  = npoint * exp;
        len = get_number_length(result, MAX_LEN);
        //浮点部分省略0
        for (i=0; i < npoint; i++) {
            if (result[i] != 0)
                break;
        }
        //处理移动
        if (i > 0) {
            for (j=0;  j + i < len; j++) {
                result[j] = result[i+j];
                result[i+j] = 0;
            }
        }
        //小数位不够,补充0
        if (len <= npoint) {
            printf(".");
            for (i=npoint - len; i >0; i--) {
                printf("0");
            }
            for (i = len-1; i >= 0; i--) {
                printf("%d", result[i]);
            }
        } else {
            j = get_number_length(result, MAX_LEN);
            for(i= j-1; i >=0; i--) {
                if (j - 1 - i == len - npoint) {
                    printf(".");
                }
                printf("%d", result[i]);
            }
        }
        printf("\n");
    }
    return 0;
}

这里是我网上找的测试数据:

5.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12
.00001  1
.12345  1
0001.1  1
1.1000  1
10.000  1
000.10  1
000000  1
000.00  1
.00000  0
000010  1
000.10  1
0000.1  1
00.111  1

猜你喜欢

转载自blog.csdn.net/lovelylichqq/article/details/81708858