无限大整数相加算法的C语言源代码

忙里偷闲,终于完成了无限大整数相加算法的C语言代码,无限大整数相加算法的算法分析在这里

500位的加法运行1000次,不打印结果的情况下耗时0.036秒,打印结果的情况下耗时16.285秒。

下面是源码:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <time.h>

#define MAXNUM 1000000000000000000
/*
存储数据用的结构
long int型指针(Number)指向一个long int 数组,索引值最底的位,
为10进制数的最低18位。依次类推。
int型数值(Length)为数组的长度。
因为数组长度受int型最大值的限制,所以这个算法也不能真正实现“无限”。
*/
struct BigInt{
    long long* Number;
    int Length;
};

void PrintBigInt(BigInt* bigNumber);

long long pow(int x, int y);

BigInt* MakeBigIntFromString(char* bigIntString);

void DeleteBigInt(BigInt* bigNumber);

BigInt* Add2BigInt(BigInt* n1, BigInt* n2);

void main(){

    char* numberStr = "99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999\0";
    char* numberStr2 = "99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999\0";
    BigInt* bn = MakeBigIntFromString(numberStr);
    BigInt* bn2 = MakeBigIntFromString(numberStr2);
    double tstart, tend, tcost;
    tstart = clock();
    PrintBigInt(bn);
    PrintBigInt(bn2);
    for (int i = 0; i < 1000; i++){
        BigInt* result = Add2BigInt(bn, bn2);
        //PrintBigInt(result);
        DeleteBigInt(result);
    }
    DeleteBigInt(bn);
    DeleteBigInt(bn2);
    tend = clock();
    tcost = (double)(tend - tstart) / CLOCKS_PER_SEC;
    printf("%lf\n", tcost);
}

BigInt* Add2BigInt(BigInt* n1, BigInt* n2){

    int maxLength = n1->Length;
    if (maxLength < n2->Length){
        maxLength = n2->Length;
    }

    /*
    加法只可能产生1位的进位,所以,只需要创建一个和最大长度相同的。
    */
    BigInt* nOut = (BigInt*)malloc(sizeof(BigInt));
    nOut->Length = maxLength;
    nOut->Number = (long long*)malloc(sizeof(long long)* nOut->Length);
    for (int i = 0; i < nOut->Length; i++){
        nOut->Number[i] = 0;
    }
    for (int i = 0; i < nOut->Length; i++){
        if (n1->Length > i){
            nOut->Number[i] += n1->Number[i];
        }
        if (n2->Length > i){
            nOut->Number[i] += n2->Number[i];
        }

        /*
        处理进位。最高位不需要处理。
        */
        if (i != (nOut->Length - 1)){
            if (nOut->Number[i] >= MAXNUM){
                nOut->Number[i] -= MAXNUM;
                nOut->Number[i + 1] = 1;
            }
        }
    }

    return nOut;

}

/*
从高到低显示数值
不考虑单个long long数据超出18位的情况。
*/
void PrintBigInt(BigInt* bigNumber){
    if (bigNumber == NULL){
        return;
    }
    if (bigNumber->Length < 1){
        return;
    }
    int length = bigNumber->Length - 1;
    for (int i = length; i >= 0; i--){
        if (i != length){
            if (bigNumber->Number[i] == 0){
                printf("000000000000000000");
            }
            else{
                printf("%018lld", bigNumber->Number[i]);
            }
        }
        else{
            if ((*bigNumber).Number[i] != 0){
                printf("%lld", bigNumber->Number[i]);
            }
        }
    }
    printf("\n");

}

/*
把字符串表示的数值格式化为BigInt型的结构
字符串结束位置用\0表示。
*/
BigInt* MakeBigIntFromString(char* bigIntString){
    /*获取字符串长度*/
    int cLength = strlen(bigIntString);
    BigInt* outBigInt = (BigInt*)malloc(sizeof(BigInt));
    if (cLength % 18 != 0){
        outBigInt->Length = cLength / 18 + 1;
    }
    else{
        outBigInt->Length = cLength / 18;
    }
    if (outBigInt->Length == 0){
        outBigInt->Length == 1;
        outBigInt->Number = (long long *)malloc(sizeof(long long));
        outBigInt->Number[0] = 0;

        return outBigInt;
    }
    outBigInt->Number = (long long *)malloc(sizeof(long long)* outBigInt->Length);
    for (int i = 0; i < outBigInt->Length; i++){
        outBigInt->Number[i] = 0;
    }

    int powNum = 0;
    int numPos = 0;
    for (int i = cLength - 1; i >= 0; i--){
        powNum = (cLength - 1 - i) % 18;
        numPos = (cLength - 1 - i) / 18;
        outBigInt->Number[numPos] += (bigIntString[i] - 48) * pow(10, powNum);
    }

    return outBigInt;
}

/*
简单的幂函数
x y 都必须为正整数
*/
long long pow(int x, int y){
    if (x == 0 || x < 0 || y < 0){
        return 0;
    }
    if (x == 1 || y == 0){
        return 1;
    }
    long long outNum = x;

    for (int i = 1; i < y; i++){
        outNum = outNum * x;
    }

    return outNum;
}

void DeleteBigInt(BigInt* bigNumber){
    if (bigNumber != NULL){
        if (bigNumber->Number != NULL){
            free(bigNumber->Number);
        }
        free(bigNumber);
    }
}
时间: 2024-11-02 02:46:43

无限大整数相加算法的C语言源代码的相关文章

算法---大整数相加

原文:算法---大整数相加 开通博客开始第一次写发表算法博客.深知一半算法考试都是用C,C++,由于大四开始到今年毕业工作到现在一直从事C#开发,C++用得很少了.链表,指针也只知道一个概念了.用得没以前熟练了.所以后续更新的算法题我都是基于C#语法的.算法主要体现的是解题思路.跟题目一样,本次算法主要实现大数据相加. 解题思路: 1. 将大数据存储到一个链表中,C#中用List<int>来存储,每个节点表示每一位的数字. {1,2,3,4,5} =>12345 和{9,6,5,9,5}

大整数相加 a+b 的c语言实现

终于来到我所期盼的高精度整数相加的题目了.这个题很经典,也算是一个很好的算法入门题吧. 如果是java的话,系统类库已经内置了BigInteger类,直接调用就可以很轻易地解决了.但是学习c的编写也是非常有意义的. 解题思路 1.首先用两个数组s1,s2临时存放输入的数据 2.输入以后将两个数组s1.s2以si[i]-'0'的方式把输入的字符串型数字转化为int型的数字. 注意转换的过程中,要倒过来存,以便相加的时候低位的对齐,从低位开始相加. 3.相加的过程:同位相加,相加的结果存放在num1

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

深入排序算法的多语言实现

深入浅出排序算法的多语言实现 作者:白宁超 2015年10月8日20:08:11 摘要:十一假期于实验室无趣,逐研究起数据结构之排序.起初觉得就那么几种排序,两三天就搞定了,后来随着研究的深入,发觉里面有不少东西.本文介绍常用的排序算法,主要从以下几个方面:算法的介绍.算法思想.算法步骤.算法优缺点.算法实现.运行结果.算法优化等.最后对本文进行总结.本文为作者原创,程序经测试无误.部分资料引用论文和网络材料以及博客,后续参见参考文献.(本文原创,转载注明出处) 1 排序的基本概念 排序: 所谓

SOJ 1002/1003/1004 大整数相加/相乘/相除

三个题目分别考察大整数相加相乘相除运算.如果按照传统算法是取一个长数组,之后进行模拟或者FFT来进行运算.但是相对繁琐. 后来昨天的青岛区域赛网赛1001,用到了JAVA的BigDecimal,于是反过来想到了这几个题目.用JAVA写了以后果然很简单. 1002:大数相加: AC代码: import java.util.*; import java.math.*; public class Main { public static void main(String[] args) { // TO

[Java]#从头学Java# Java大整数相加

重操旧业,再温Java,写了个大整数相乘先回顾回顾基本知识.算法.效率什么的都没怎么考虑,就纯粹实现功能而已. 先上代码: 1 package com.tacyeh.common; 2 3 public class MyMath { 4 5 public static String BigNumSum(String... n) { 6 int length = n.length; 7 StringBuilder result = new StringBuilder(); 8 //这里判断其实不需

更快的求整数幂算法

相信整数幂运算作为一个算法演变的例子是再合适不过的了为了节省访客们宝贵的学习时间省去介绍递归等可能涉及到的初级概念的定义.同时如果发现文中有错误的地方请敞开衣服指正. 因为在测试性能时合适的测试数据是必要的,所以本文用C++的大数类进行演示. 点击获取C++大数类源码 这里我们先列一下会提到的算法分析技术: 动态规划 减治法 测试平台: Linux g++ 4.7 原始递归方法 这就不花时间赘述什么了. BigInteger pow(BigInteger x, int N) { if (N ==

华为测试 超长整数相加

请设计一个算法完成两个超长正整数的加法. 输入两个字符串数字 输出相加后的结果,string型 样例输入:99999999999999999999999999999999999999999999999999 1 样例输出:100000000000000000000000000000000000000000000000000 #include<iostream> #include<string> using namespace std; string add(string num1,

iOS中计算两个大数相加算法(OC实现)

我们知道计算机的数据类型不同,所能表示的数据量级也不相同,比如: unsigned int : 0-4294967295   int : -2147483648-2147483647 unsigned long : 0-4294967295long :  -2147483648-2147483647long long : -9223372036854775808 ~ 9223372036854775807unsigned long long : 0 ~ 18446744073709551615