大数相乘

来源:互联网 发布: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
原创粉丝点击