大数相乘
来源:互联网 发布:ue编辑器 mac版 编辑:程序博客网 时间:2024/06/11 09:01
大数乘法主要有模拟手工计算的普通大数乘法,分治算法和FFT算法。普通大数乘法算法,主要有逐位相乘处理进位法、移位进位法。
逐位相乘处理进位法
思路如下:
逐位相乘处理进位法就是模拟小学学的竖式乘法计算,模拟手工计算方法。有大数a[i]、b[j]相乘
- 【1】反转字符串
- 【2】转为数字相乘并把结果存入resul[i+j]
- 【3】进位处理
- 【4】转回字符串
- 【5】反转回正确顺序
举个例子:
a=16,b=15,
计算a*b过程原理如下。
- 【1】反转字符串 a->(6,1) b->(5,1)
【2】转为数字相乘并把结果存入resul[i+j]
axb= (6x5,6x1+1x5, 1x1)=(30,11,1)
【3】进位处理
(30,11,1)= (0,4,2)
- 【4】转回字符串
【5】反转回正确顺序
->(2,4,0)
代码
//实现相乘过程 char* multiply(char* s1,char* s2) { int len1 = get_len(s1); int len2 = get_len(s2); int len3 = len1*len2+1; //结果可能的最大长度 char* result = (char*)malloc(sizeof(char)*len3); int *res = (int*)malloc(sizeof(int)*len3); int i,j; //初始化数组 for (i=0; i<len3; i++) { res[i] = 0; } //【1】反转字符串 revers(s1); revers(s2); //【2】转为数字逐位相乘并存入res[i+j] for (i=0; i<len1; i++) for(j=0; j<len2; j++) { res[i+j] += char_to_num(s1[i])*char_to_num(s2[j]); } //【3】进位处理 for (i=0; i<len3; i++) { if (res[i]>9)//符合进位条件 { res[i+1] += res[i]/10; res[i] = res[i]%10; } } //【4】转为字符存入result for (i=0; i<len3; i++) { result[i] = char(res[i]+48); } result[len3] = '\0'; //【5】反转回正确顺序 revers(result); free(res); return result; }
完整测试代码【纯c版】
/两个任意长度的大数字相乘【纯c版】*/ #include "stdafx.h" #include<stdio.h> #include<malloc.h> int revers(char *s);//反转字符串,返回字符串长度 int get_len(char* s);//获取长度 void print(char* s);//打印 int char_to_num(char s);//字符转数字 char *multiply(char* s1,char* s2);//相乘 int main(int argc, char* argv[]) { char s1[6] = {'1','2','3','4','0'}; char s2[6] = {'1','2','3','4','5'}; char* s3 = multiply(s1, s2); print(s3); return 0; } //实现相乘过程 char* multiply(char* s1,char* s2) { int len1 = get_len(s1); int len2 = get_len(s2); int len3 = len1*len2+1; //结果可能的最大长度 char* result = (char*)malloc(sizeof(char)*len3); int *res = (int*)malloc(sizeof(int)*len3); int i,j; //初始化数组 for (i=0; i<len3; i++) { res[i] = 0; } //【1】反转字符串 revers(s1); revers(s2); //【2】转为数字逐位相乘并存入res[i+j] for (i=0; i<len1; i++) for(j=0; j<len2; j++) { res[i+j] += char_to_num(s1[i])*char_to_num(s2[j]); } //【3】进位处理 for (i=0; i<len3; i++) { if (res[i]>9)//符合进位条件 { res[i+1] += res[i]/10; res[i] = res[i]%10; } } //【4】转为字符存入result for (i=0; i<len3; i++) { result[i] = char(res[i]+48); } result[len3] = '\0'; //【5】反转回正确顺序 revers(result); free(res); return result; } //字符转数字 int char_to_num(char s) { return s-'0'; } //获取长度 int get_len(char* s) { int i = 0; while(s[i] != '\0') { i++; } return i; } //反转字符串,返回字符串长度 int revers(char *s) { int len = get_len(s)-1; for (unsigned int i=0; i!=(len)/2; i++) { char c; c = s[i]; s[i] = s[len-i]; s[len-i] = c; } s[len+1] = '\0'; return len; } //打印 void print(char* s) { int i = 0; while(s[i] == '0') i++;//除去开头为零 while( s[i] != '\0') { printf("%c",s[i]); i++; } printf("\n"); }
完整测试代码【c++版】
//大数相乘【c++版】 #include "stdafx.h" #include <iostream> #include <string> #include <vector> #include <stdlib.h> using namespace std; struct bigcheng { vector<int> a; vector<int> b; string result_str; }; void chartonum(string a,string b,bigcheng &tempcheng);//字符串转为数字并且反转,存入temp void multiply(bigcheng &tempchengh,vector<int> &result_num);//诸位相乘,进位处理,结果存入n_result void numtochar(bigcheng &tempcheng,vector<int> &result_num);//将计算结果转换为字符串并反转,存入temp //【1】字符转为数字并且反转 void chartonum(string a,string b,bigcheng &tempcheng) { int size_a=a.size(); int size_b=b.size(); for (int i=size_a-1;i>=0;i--) { tempcheng.a.push_back(a[i]-'0');//从尾部添加数据 } for (int i=size_b-1;i>=0;i--) { tempcheng.b.push_back(b[i]-'0'); } } void multiply(bigcheng &tempcheng,vector<int> &result_num) { //【2】诸位相乘 for (unsigned int i=0;i<tempcheng.a.size();i++) { for (unsigned int j=0;j<tempcheng.b.size();j++) { result_num[i+j]+=(tempcheng.a[i])*(tempcheng.b[j]); } } for (int i=result_num.size()-1;i>=0;i--) { if (result_num[i]!=0) { break; } else result_num.pop_back(); } //【3】处理进位 int c=0; for (unsigned int i=0;i<result_num.size();i++) { result_num[i]+=c; c=result_num[i]/10; result_num[i]=result_num[i]%10; } if (c!=0) { result_num.push_back(c); } } //【4】数字转字符并且反转 void numtochar(bigcheng &tempcheng,vector<int> &result_num) { int size=result_num.size(); for (unsigned int i=0;i<result_num.size();i++) { tempcheng.result_str.push_back(char(result_num[size-1-i]+'0')); } } int main() { bigcheng tempcheng; string a,b; cin>>a>>b; chartonum(a,b,tempcheng); vector<int> resultnum(a.size()+b.size(),0); multiply(tempcheng,resultnum); numtochar(tempcheng,resultnum); cout<<tempcheng.result_str<<endl; system("pause"); return 0; }
1 0
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- 大数相乘
- centos 安装
- re.sub 使用方法
- codeforces 754A(思维题)
- 多线程的实现方式
- 深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP
- 大数相乘
- springMVC的一个controller方法怎么处理多个请求地址
- Tomcat的简单配置
- 13 QT的QProcess与进程间的通信
- cron表达式轮询操作
- 导航条实例(哔哩哔哩部分)
- DHTML技术演示---动态设置表格行间隔显示、表格排序、鼠标悬停样式改变
- 复习
- 线程池的好处