最近写了一个大数相乘和相加的程序,结果看起来是对的。不过期间的效率可能不是最好的,有些地方也是临时为了解决问题而直接写出来的。

可以大概说一下相乘和相加的解决思路(当然,大数操作基本就是两个字符串的操作了):

一、思路:

在操作大数前,一定会有一些异常判断,比如输入的字符串是否合法(是否是纯数字?是否为空?等等),然后才是具体的操作实现:

1、大数相加(大体思路:将大数相加问题,转换成十以内的两数相加):

①申请合适的空间,一般可以认定,两个数字相加时,长度至多是最长的数的长度或最长的数的长度加1;

②从个位(字符串中就是从最后一位)开始,进行逐位相加;

③每位相加后,立即判断是否有进位,再将本次计算的个位数字记录到result字符串中;

④当短字符串过完后,按照同样的方式,过完长字符串的剩余数字;

⑤长字符串过完后,判断是否存在进位,如果有,则最后再赋值到result字符串中,如果没有,则最后将0(也就是结束符)赋值到result字符串中;

⑥由于操作的result字符串是倒置操作的,最后再把字符串逆置,返回即为两数相加结果;

2、大数相乘(大体思路:将大数相乘问题,转换成十以内的两数相乘):

①按照一般的两数相乘的思路,运算过程中,会产生一个二维数组样式的中间结果(准确点是一个字符串数组),数组的行数是第二个数字的个数;

②每次得出这个字符串数组的一行的结果,具体为:

a、针对这个字符串数组,每次运算前,申请合适的空间,一般可以认定,一个数和一个十以内的数字相乘时,长度至多是该数的长度或该数长度加1;但是还有一点需要考虑到,从十位开始,数字相乘后,默认是在最后加0的,规律为十位对应1个0,百位对应2个0,以此类推。因此需要申请的空间除了该数的长度加1外,还需要加上本次操作需要额外增加的0的个数;

b、在数字真正相乘前,需要将对应的0进行补齐(即个位数相乘时增加0个0,十位数相乘时增加1个0 ... ... )

c、每次取出第二个数的一个数字,取出顺序为倒序(从个位开始),然后与第一个数字进行逐位相乘;

d、相乘结果判断进位,并且保存,此次乘出来的结果保留个位数字,放入到本行的字符串结果中;

e、过完第一个数字的长度后,判断是否有进位,有的话则直接将进位赋值到本行字符串结果中,没有的话则将0赋值到本行字符串结果中;

f、然后循环进行,直到将第二个数字过完后,就会产出一个二维数组(或称之为字符串数组);

③最后把这个字符串数组的每一行相加(用到上面的大数相加函数来做),就是最终的相乘结果;

二、代码:

1、大数相加:

char *BigNumSum(char *bignum1, char *bignum2)
{
        char *result, *big, *small;
        int bignum1_length = strlen(bignum1);
        int bignum2_length = strlen(bignum2);
        int bigger, smaller;

        if(bignum1_length >= bignum2_length)
        {
                bigger = bignum1_length;
                smaller = bignum2_length;
                big = bignum1;
                small = bignum2;
        }
        else
        {
                bigger = bignum2_length;
                smaller = bignum1_length;
                big = bignum2;
                small = bignum1;
        }

        int tmp, tmp_gewei, tmp_jinwei = 0, num = 0;
        result = (char *)malloc(sizeof(char) * (bigger + 1));
        for(int i = smaller - 1, j = bigger - 1; i >= 0 && j >= 0; i--, j--)
        {
                char *tmp_big = ctocs(big[j]);
                char *tmp_small = ctocs(small[i]);
                tmp = atoi(tmp_big) + atoi(tmp_small) + tmp_jinwei;
                tmp_gewei = tmp % 10;
                tmp_jinwei = tmp / 10;
                result[num++] = tmp_gewei + ASICNUM;
        }
        for(int i = bigger - smaller - 1; i >= 0; i--)
        {
                char *tmp_big = ctocs(big[i]);
                tmp = atoi(tmp_big) + tmp_jinwei;
                tmp_gewei = tmp % 10;
                tmp_jinwei = tmp / 10;
                result[num++] = tmp_gewei + ASICNUM;
        }
        if(tmp_jinwei > 0)
        {
                result[num] = tmp_jinwei + ASICNUM;
        }
        else
        {
                result[num] = 0;
        }
        recover(result);
        return result;
}

2、大数相乘:

char *BigNumMultip(char *bignum1, char *bignum2)
{
        char *result;
        int bignum1_length = strlen(bignum1);
        int bignum2_length = strlen(bignum2);

        char *tmp[bignum2_length];
        int i;
        for(i = bignum2_length - 1; i >= 0; i--)
        {
                int t;
                int j;
                tmp[i] = (char *)malloc(sizeof(char) * (bignum1_length + 1 + (bignum2_length -1 - i)));
                for(t = 0; t < bignum2_length -1 - i; t++)
                        tmp[i][t] = 0 + ASICNUM;
                int tmp_jinwei = 0;
                for(j = bignum1_length - 1; j >= 0; j--)
                {
                        char *tmp_bignum1 = ctocs(bignum1[j]);
                        char *tmp_bignum2 = ctocs(bignum2[i]);
                        int tmp_multip = atoi(tmp_bignum1) * atoi(tmp_bignum2) + tmp_jinwei;
                        int tmp_gewei = tmp_multip % 10;
                        tmp_jinwei = tmp_multip / 10;
                        tmp[i][t++] = tmp_gewei + ASICNUM;
                }
                if(tmp_jinwei > 0)
                {
                        tmp[i][t] = tmp_jinwei + ASICNUM;
                }
                else
                {
                        tmp[i][t] = 0;
                }
                recover(tmp[i]);
//              puts(tmp[i]);
        }
        result = (char *)malloc(sizeof(char) * (strlen(tmp[i+1]) + 1));
        memset(result, '0', strlen(result));
        for(int i = 0; i < bignum2_length; i++)
        {
                result = BigNumSum(tmp[i], result);
        }

        return result;
}

3、其他:

①字符串逆置:

void recover(char *string)
{
        int length = strlen(string);
        int tmp;
        for(int i = 0; i < length / 2; i++)
        {
                tmp = string[i];
                string[i] = string[length - i - 1];
                string[length - i - 1] = tmp;
        }
}

②判断是否是数字字符串:

bool isDigital(char *string)
{
        bool ret = true;
        int length = strlen(string);

        for(int i = 0; i < length; i++)
        {
                if(string[i] < '0' || string[i] > '9')
                {
                        ret = false;
                        break;
                }
        }
        return ret;
}

③字符转换为字符串:

char *ctocs(char ch)
{
        char *a;
        a = (char *)malloc(sizeof(char) * 2);
        a[0] = ch;
        a[1] = 0;

        return a;
}

④main函数调用:

int main(int argc, char **argv)
{
        if(3 != argc)
        {
                printf("error\n");
                return 1;
        }
        char *bignum1 = argv[1];
        char *bignum2 = argv[2];

        bool ret1 = isDigital(bignum1);
        bool ret2 = isDigital(bignum2);

        if(false == ret1 || false == ret2)
        {
                printf("input not number\n");
                return 2;
        }
        char *multip_result = BigNumMultip(bignum1, bignum2);
        char *sum_result = BigNumSum(bignum1, bignum2);

        printf("数字 1:%s\n数字 2:%s\n两数积:%s\n两数和:%s\n", bignum1, bignum2, multip_result, sum_result);
        return 0;
}

这段代码也就是按照一个最基本的思路进行简单的实现,基本如上,没有太多注释,目前可以预见到的问题就是:①执行效率、②内存消耗;后面有空会再进行优化的~

目前测试了一些数字,是可以正确返回的(当然,太大的数字也就是验证的后面或前面的几位的数字)。如果大家有发现不对有有问题的地方,求指点~

Linux C/C++ 编程练手 --- 大数相加和大数相乘的更多相关文章

  1. 好记性不如烂笔头--linux学习笔记9练手写个shell脚本

    #!/bin/bash #auto make install httpd #by authors baker95935 #httpd define path variable H_FILES=http ...

  2. HDU 1316 (斐波那契数列,大数相加,大数比较大小)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1316 Recall the definition of the Fibonacci numbers: ...

  3. Java 大数相乘、大数相加、大数相减

    思路来源:: https://blog.csdn.net/lichong_87/article/details/6860329 /** * @date 2018/6/22 * @description ...

  4. JAVA大数类练手

    今天突然看到了OJ上的大数类题目,由于学习了一点大数类的知识.果断水了6道题......都是非常基础的.就当的练手的吧. 学到的只是一些大数类的基本操作.以后多做点这样的题,争取熟练运用水大数题... ...

  5. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  6. 10个有趣的Python教程,附视频讲解+练手项目。

    从前的日色变得慢,车.马.邮件都慢 一生只够爱一门编程语言 从前的教程也好看,画面精美有样子 你看了,立马就懂了 Python最性感的地方,就在于它的趣味性和前沿性,学习Python,你总能像科技节的 ...

  7. 【Python精华】100个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同 ...

  8. web前端学习部落22群分享给需要前端练手项目

    前端学习还是很有趣的,可以较快的上手然后自己开发一些好玩的项目来练手,网上也可以一抓一大把关于前端开发的小项目,可是还是有新手在学习的时候不知道可以做什么,以及怎么做,因此,就整理了一些前端项目教程, ...

  9. POJ 1503 Integer Inquiry(大数相加,java)

    题目 我要开始练习一些java的简单编程了^v^ import java.io.*; import java.util.*; import java.math.*; public class Main ...

随机推荐

  1. php curl 多线程方法

    <?php /** * curl 多线程 * @param array $array 并行网址 * @param int $timeout 超时时间 * @return array */ fun ...

  2. DiscuzX程序升级教程_不知道关闭论坛的看过来

    DiscuzX程序升级教程,不知道关闭论坛的朋友看过来,适用于  1.0, 1.5 2.0 , 2.5Beta, 2.5RC,2.5, 3.0 1)关闭论坛:后台- 全局- 站点信息- 是否关闭 :是 ...

  3. android studio 真机调试

    1.使用usb连接电脑,打开开发者选项,打开usb调试. 2.不能使用仅充电,修改为媒体设备(MTP) 3.如果无法连接可以使用豌豆荚或者金山手机助手连接. 4.运行android程序即可. 5.如果 ...

  4. Android SDK下载技巧

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/android-sdk-download-tips/ 说明 想必在国内的你,是不是经常在下载Android S ...

  5. 基于HTML5的SLG游戏开发( 三):认识PureMVC

    在游戏开发中,对于一般网络游戏,由于需要多人协同开发,每个人负责不同的模块开发,为了减少耦合,需要用来一些MVC框架,减少模块之间的耦合.我们现在使用的mvc框架是pureMVC.pureMVC的官网 ...

  6. PL/SQL 编程(二)游标、存储过程、函数

    游标--数据的缓存区 游标:类似集合,可以让用户像操作数组一样操作查询出来的数据集,实质上,它提供了一种从集合性质的结果中提取单条记录的手段. 可以将游标形象的看成一个变动的光标,他实质上是一个指针, ...

  7. 利用ffmpeg将H264流 解码为RGB

    利用H264解码分为几个步骤: 注意一点在添加头文件的时候要添加extern "C",不然会出现错误 [cpp] view plaincopy extern "C&quo ...

  8. Neural Network Programming - Deep Learning with PyTorch with deeplizard.

    PyTorch Prerequisites - Syllabus for Neural Network Programming Series PyTorch先决条件 - 神经网络编程系列教学大纲 每个 ...

  9. springboot第一个项目【创建】

    1.new project,不勾选create from archetype,直接选择 2.next下一步 在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个属性构成的,分别是groupId ...

  10. java框架之Spring(1)-入门

    介绍 概述 Spring 是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring 是于 2003 年兴起的一个轻量级的 J ...