zoukankan      html  css  js  c++  java
  • 每日算法之三十四:Multiply Strings

    大数相乘,分别都是用字符串表示的两个大数。求相乘之后的结果表示。

    首先我们应该考虑一下測试用例会有哪些,先准备測试用例对防御性编程会有比較大的帮助。可以考虑一些极端情况。有以下几种用例:

    1)"0","0"  

    2)"0","879127346783" 当中一个是零

    3)"as234","123343"  存在非法字符

    4)"000000000000001234","2546"  存在零前缀。有冗余计算

    大概就这么多吧。

    要想实现大数乘法。必定先实现大数相加和一个大数和一个数字相乘。

    这样大数相乘就行切割迭代计算。

    以下是算法,自己写的。可能存在冗余。

    <span style="font-size:14px;">class Solution {
    public:
        string subTwoString(string num1,string num2)  //大数相加
    {
      string result = "";
      int i = num1.length()-1;
      int j = num2.length()-1;
      int plus = 0;//进位
      while(i>=0 && j>=0)
      {
        int temp = num1[i]-'0' + num2[j]-'0' + plus;//不能忘掉进位
        result =char(temp%10+'0')+ result;
        plus = temp/10;
        i--;j--;
      }
      if(i>=0)//一种一个没有加完。不全结果,当然还有进位
      {
        while(i>=0)
        {
          int temp = num1[i]-'0' + plus;
            result =char(temp%10+'0')+ result;
            plus = temp/10;
            i--;
        }
      }
      if(j>=0)
      {
        while(j>=0)
        {
          int temp = num2[j]-'0' + plus;
            result =char(temp%10+'0')+ result;
            plus = temp/10;
            j--;
        } 
      }
      if(plus != 0)//最后进位不为零是要在结果头部加上
        result = char(plus+'0')+result;
      return result;
    }
    string multi(string num1,int num)//大数和一位数字相乘
    {
      int len = num1.length()-1;
      int plus = 0;
      string result = "";
      while(len>=0)
      {
        int temp = (num1[len] - '0') * num + plus;//plus刚開始是忘掉的,也不能写在括号内,跟加法不同
        result = char(temp%10+'0') + result;
        plus = temp/10;
        len--;
      }
      if(plus != 0)
        result = char(plus+'0') + result;
      return result;}
    string multiply(string num1, string num2) {//大数相乘
    	if(num1.length() == 0 || num2.length() ==0)
    		return 0;
    	if(num1 == "0"|| num2 == "0")
    	    return "0";
    	string result = "";
    	int len1 = num1.length();
    	int len2 = num2.length();
    	for(int i = 0;i<len1;i++)
    		if(!isdigit(num1[i]))//是否存在数字
    			return 0;
    	for(int j = 0;j<len2;j++)
    		if(!isdigit(num2[j]))
    			return 0;
    	for(int k = len2-1;k>=0;k--)
    	{
    		string temp = multi(num1,num2[k]-'0');
    		for(int l = len2-k-1;l>0;l--)
    			temp = temp + "0";
    		result = subTwoString(result,temp);
    	}
    	return result;
        }
    };</span>

    以下是还有一种方法。不是依照手算乘法计算的,使用了辅助数组利用特点写的:

    思路:假设两个大数分别为m和n位,那么结果最多为m+n位,或者为m+n-1位(最后不存在进位)。比方123和23相乘。

    0 0 3 6 9
    0 2 4 6 0
    0 2 7 12 9
    0 2 8 2 9
    以下做一下解释,第一行是123和3相乘的结果,第二行是2和123相乘的结果。

    顺序前移了一位。第三行是把之前的计算结果相加。第四行是从后往前

    求进位,知道最開始。

    最后。再把他们转化成字符串就可以。

    <span style="font-size:14px;">string multiply(string num1, string num2) {
    		if(num1=="0" || num2=="0") return "0";
    		int l1 = num1.length(), l2 = num2.length();
    		int* n1 = new int[l1];
    		int* n2 = new int[l2];
    		int* res = new int[l1+l2];
    		memset(res,0,sizeof(int)*(l1+l2));
    		for(int i=0; i<l1; ++i)
    			n1[i] = num1[i] - '0';
    		for(int i=0; i<l2; ++i)
    			n2[i] = num2[i] - '0';
    		
    		for(int i=0; i<l1; ++i)
    			for (int j=0; j<l2; ++j)
    				res[i+j+1] += n1[i]*n2[j];
    
    		string ss = "";
    		for (int k=l1+l2-1; k>=0; --k){
    			if(k>0) res[k-1] += res[k]/10;
    			res[k] %= 10;
    			ss = char(res[k]+'0')+ss;
    		}
    		ss = ss[0]=='0'? ss.substr(1):ss;
    		//return ss.empty()?

    "0":ss; return ss; }</span>



查看全文
  • 相关阅读:
    vue.js生成纵向拓扑图
    vue.js生成横向拓扑图
    Vue.js中使用wangEditor富文本编辑器
    文件上传与下载,PDF与Excel的操作
    Element布局实现日历布局
    golang时间转换
    iView学习笔记(四):Form表单操作
    iView学习笔记(三):表格搜索,过滤及隐藏列操作
    iView学习笔记(二):Table行编辑操作
    iView学习笔记(一):Table基本操作(包含前后端示例代码)
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10466130.html
  • Copyright © 2011-2022 走看看