[笔记]一道C语言面试题:大整数乘法

题目:输入两个数字字符串,如“1234567890”和“987654321”,返回二者相乘的结果字符串,如本例返回为“1219326311126352690”。

来源:某500强企业面试题目

思路:从尾部到头部,对两个字串的每个数字分别相乘,并放入结果字符串相应的位置。

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

char *BigNumMultiply(const char *n1, const char *n2)
{
    // quit if n1 or n2 is invalid
    if (!n1 || !n2) {
        return NULL;
    }

    // get length
    int Len1 = strlen(n1);
    int Len2 = strlen(n2);
    int Len = Len1 + Len2;

    // allocate result buffer
    char *ret = (char *)malloc(Len + 1);
    if (!ret) {
        return NULL;
    }
    memset(ret, 0, Len + 1);

    // multiply
    for (int i = Len1 - 1; i >= 0; --i) {
        for (int j = Len2 - 1; j >= 0; --j) {
            int k = i + j + 1;
            // multiply digit by digit
            ret[k] += (n1[i] - ‘0‘) * (n2[j] - ‘0‘);

            // add to upper position
            if (ret[k] >= 10){
                ret[k - 1] += ret[k] / 10;
                ret[k] = ret[k] % 10;
            }
        }
    }

    // handle first 0
    int d = ret[0] == 0 ? 1 : 0;
    for (int i = 0; i < Len - d; ++i) {
        ret[i] = ret[i + d] + ‘0‘;
    }
    ret[Len - d] = ‘\0‘;

    return ret;
}

int main(int argc, char* argv[])
{
    char n1[] = "1234567890";
    char n2[] = "987654321";
    char *ret = BigNumMultiply(n1, n2);
    printf("%s * %s = %s\n", n1, n2, ret);
    free(ret);
    ret = NULL;

    getchar();
    return 0;
}

从工程化角度考虑,有几点需要注意:

1、输入的字符串是否有效?
    上面的代码只判断了是否为空,实际上还有可能输入的字符串并非有效的数字字符串,如“12gh34”,这种也需要返回NULL。

2、前导0的处理
    a位数与b位数相乘,结果长度可能为a+b,如9*99=891;也可能a+b-1是如 10*100=1000。
    在代码的最后部分,对a+b-1的类型进行了移位处理,压缩掉了前导的0。

从编程角度考虑,有几点需要注意:

1、字符串下标从小到大,是从高位到低位。如n=“123”,最高位n[0]=1,最低位n[2]=3。

2、字符ASCII码与字符的转换,如n[3]=5这是纯数字,而+‘0‘后有n[3]=‘5‘这就是字符了。

3、数字交叉相乘的进位处理,通过 >=10来判断进位,此处注意不要写成>10;另外注意多次叠加,所以使用 +=

4、malloc()的返回值是(void *),为了让编译器happy,需要强制转为(char *),而且最后需要free来释放它申请的内存。

5、字符‘0‘和字符串“0”的区别

时间: 2024-10-12 01:02:41

[笔记]一道C语言面试题:大整数乘法的相关文章

[笔记]一道C语言面试题:IPv4字符串转为UInt整数

题目:输入一个IPv4字符串,如“1.2.3.4”,输出对应的无符号整数,如本例输出为 0x01020304. 来源:某500强企业面试题目 思路:从尾部扫描到头部,一旦发现无法转换,立即返回,减少无谓操作. #include "stdio.h" #include "stdlib.h" #include "string.h" bool ConvertIPv4ToUInt(const char *strIP, unsigned int *ip) {

C语言面试题大汇总

C语言面试题大汇总 1.局部变量能否和全局变量重名? 答:能,局部会屏蔽全局.要用全局变量,需要使用"::" ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量.对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内. 2.如何引用一个已经定义过的全局变量? 答: extern 可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引

python基础知识 05 python语言中的大整数

第五课 python语言中的大整数 java中的int 最大可以处理 2^31 -1(2147483647) 最小呢-2^31 (-2147483647)但是在Java中可以使用BigInteger 来处理无线大的数 print(2 ** 60) 结果为 1152921504606846976 print(2 ** 600) 41495155688809929585124078636911611510124462322424368999956573296906528114129081463997

POJ 1001 解题报告 高精度大整数乘法模版

题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于错误的判断还不够严厉. 对边界情况的讨论其实应该是思维严密的表现,当然这并不能表明我写的一点错误都没有,只是多多分析一下还是很有好处的. #include <iostream> #include <fstream> #include <string> #include &l

大整数乘法python3实现

由于python具有无限精度的int类型,所以用python实现大整数乘法是没意义的,但是思想是一样的.利用的规律是:第一个数的第i位和第二个数大第j位相乘,一定累加到结果的第i+j位上,这里是从0位置开始算的.代码如下: import sys def list2str(li): while li[0]==0: del li[0] res='' for i in li: res+=str(i) return res def multi(stra,strb): aa=list(stra) bb=l

分治法解大整数乘法

在某些情况下,需要处理很大的整数,它无法在计算机中精确的表述和处理.若要精确的表示大整数,就必须使用软件的方法来实现大整数的运算.最常用的解决大整数运算的方法是使用一个二重循环,其算法时间复杂度为O(m*n)(其中m,n分别为两个大整数的长度):而选用分治方法则可以将算法时间复杂度降到O(n^(log3))(两个大整数的长度同为n).但分治方法的算法实现较为复杂,针对这个问题,本文借助标准C++实现了分治方法求解大整数乘法的算法. 下面分别介绍两种算法原理,及其实现: 1.使用二重循环控制两个数

大整数乘法问题

数组可以实现的算法很多,典型应用就是大整数相乘问题.利用的思想非常巧妙,感觉和链表实现多项式运算有异曲同工,大整数相乘主要避免计算机存储精度不够的时候.按照基本的乘法运算实现即可! 主要注意返回指针类型,和关键点k=i的技巧. /*! * \file 算法之美--大整数乘法问题.cpp * * \author ranjiewen * \date 2016/12/04 15:58 * * */ #include <iostream> using namespace std; #define SI

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

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

使用快速傅里叶变换计算大整数乘法

我们知道,两个 N 位数字的整数的乘法,如果使用常规的算法,时间复杂度是 O(N2).然而,使用快速傅里叶变换,时间复杂度可以降低到 O(N logN loglogN). 假设我们要计算以下两个 N 位数字的乘积: a = (aN-1aN-2...a1a0)10 = aN-1x10N-1 + aN-2x10N-2 + ... + a1x101 + a0x100 b = (bN-1bN-2...b1b0)10 = bN-1x10N-1 + bN-2x10N-2 + ... + b1x101 + b