理解两个大数相乘过程


1,明确程序是一个通用法则。这个实现过程既可以满足一位数字相乘,也可以满足两位数字相乘。既然能够满足一位数字,两位数字,那么自然也能够满足多位数字相乘。



2,最开始自己面对这一道面试题,第一反应就是,我无法使用任何编程语言的基本数据类型去表示这样一个大数,自然也不能够满足这个数的乘积了。这也是这个面试题的难点。



3,我的想法就是抛开一切数学中的理论概念。用编程语言的字符组成字符串的方式进行思考。



4,思考了很久。也按照自己的想法分析这个大数的一些特征,比如大数的个数是明确的。我可以任意按照自己的想法去取。去拼接最后的一个结果。但是都没有想到一个解决思路。当然问题肯定能够解决的,只是会显得特别复杂,这样程序的易读性也就没有了。


5,网上搜寻资料。得到一个解决问题的思想。

思想:将输入的字符串,转成char数组,转成int数组。采用分治思想,每一位的相乘。

公式:AB*CD  =  AC (BC+ AD) BD,然后   从后到前满十进位。


举个例子


套用公式

67*89 = 6*8(7*8 + 6*9)7*9  

67*89 = 48(110)63


从后到前满十进位

63进6剩余3,

110变成116,满十进位,进行11,剩余6,

48变成59。所以: 5963


6,实现过程

publicString multiply(String num1, String num2) {  

     //把字符串转成char数组

     charchars1[] = num1.toCharArray();

     charchars2[] = num2.toCharArray();

    

     //声明存放结果和两个乘积的容器

     intresult[] = newint[chars1.length + chars2.length];

     int n1[]= newint[chars1.length];

     int n2[]= newint[chars2.length];

    

     //char转换成int数组。

     for (int i =0; i < chars1.length; i++){

        n1[i] = chars1[i] - '0';

     }

 

     for (int j =0; j < chars2.length; j++){

        n2[j] = chars2[j] - '0';

     }

    

     //逐个相乘

     for (int i = 0; i < chars1.length; i++){

        for (int j = 0; j < chars2.length; j++) {

          result[i+j] += n1[i]  *  n2[j];

        }

     }

    

     //从后往前满十进位

     for (int i = result.length -1; i > 0; i--) {

        result[i-1] += result[i] / 10;

        result[i] = result[i] % 10;

     }

    

     //转成string并返回

     String resultStr = "";

     for (int i = 0; i < result.length - 1; i++) {

        resultStr += "" +result[i];

     }

     returnresultStr;

   }

7,关键点

        a,一个数乘以一个数的结果长度必定小于或者等于这个两个数长度之和。

 

        b,把char字符转成int型,需要这个字符减去字符0.

        字符和数字在内存里都是以ASCII形式存储的。'0'字符的ASCII是30。

 

        c,逐个相乘。(其实也是数组中根据index的对应位上进行相加累积)

算法是根据数据结构的。而我们的数据是放入数组中进行操作的。我怎样才能操作两个数据结构(数组)的每一位呢?刚接触编程的时候,通常会学习冒泡排序和选择排序,通过两层循环去遍历这个数据结构中的每一个数字(一般来说都是多位的)。并且这种基本算法思想,在实现业务逻辑过程中也是需要的,可见对基本知识的一个理解深度是很重要的。

 

        d,从后往前满十进位。一个操作。

        关键

                哪个位是进位并且作相加累积。

                哪个位是保存余下的数字。


图解循环过程



从后往前满十进位


                        21,进2,剩下1;

                        32+2为34,进3,剩下4;

                        34+3为37,进行3,剩下7;

                        28+3为31,进3,剩下1;

                        13+3为16,进1,剩下6;

                        4+1为5。所以:561741。














  • 24
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是一个基于链表的 C 语言代码,用于计算两个大数的乘积。 ```c #include <stdio.h> #include <stdlib.h> struct node { int data; struct node *next; }; typedef struct node Node; Node *create_node(int num) { Node *new_node = (Node *) malloc(sizeof(Node)); new_node->data = num; new_node->next = NULL; return new_node; } Node *insert_at_end(Node *head, int num) { Node *new_node = create_node(num); if (head == NULL) { head = new_node; return head; } Node *temp = head; while (temp->next != NULL) { temp = temp->next; } temp->next = new_node; return head; } Node *reverse_list(Node *head) { Node *prev = NULL, *current = head, *next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } return prev; } Node *multiply_lists(Node *head1, Node *head2) { Node *result = NULL; Node *temp1 = head1, *temp2; int carry = 0, sum; while (temp1 != NULL) { temp2 = head2; Node *new_node = NULL; carry = 0; while (temp2 != NULL) { sum = (temp1->data * temp2->data) + carry; carry = sum / 10; new_node = insert_at_end(new_node, sum % 10); temp2 = temp2->next; } if (carry > 0) { new_node = insert_at_end(new_node, carry); } new_node = reverse_list(new_node); for (int i = 0; i < temp1->data; i++) { new_node = insert_at_end(new_node, 0); } result = add_lists(result, new_node); temp1 = temp1->next; } return result; } Node *add_lists(Node *head1, Node *head2) { Node *result = NULL; Node *temp1 = head1, *temp2 = head2; int carry = 0, sum; while (temp1 != NULL || temp2 != NULL) { sum = carry + (temp1 != NULL ? temp1->data : 0) + (temp2 != NULL ? temp2->data : 0); carry = sum / 10; result = insert_at_end(result, sum % 10); if (temp1 != NULL) { temp1 = temp1->next; } if (temp2 != NULL) { temp2 = temp2->next; } } if (carry > 0) { result = insert_at_end(result, carry); } return result; } void display_list(Node *head) { Node *temp = head; while (temp != NULL) { printf("%d", temp->data); temp = temp->next; } printf("\n"); } int main() { Node *num1 = NULL, *num2 = NULL, *result = NULL; char c; int num; printf("Enter first number:\n"); while ((c = getchar()) != '\n') { num = c - '0'; num1 = insert_at_end(num1, num); } printf("Enter second number:\n"); while ((c = getchar()) != '\n') { num = c - '0'; num2 = insert_at_end(num2, num); } num1 = reverse_list(num1); num2 = reverse_list(num2); result = multiply_lists(num1, num2); printf("Result:\n"); display_list(result); return 0; } ``` 该代码将两个大数存储为链表,并使用一个辅助函数来反转链表。然后,它将两个链表相乘,产生一个新的链表,该链表包含结果。最后,它将结果链表打印到控制台上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值