【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274

Description

输入a,b

输出a*b的竖式乘法,格式见样例。

Sample Input1

11
9

Sample Output1

11
 9
--
99

Sample Input2

10
10

Sample Output2

    10
    10
   ---
   100

Sample Input3

101
101

Sample Output3

        101
        101
      -----
        101
      101
      -----
      10201

Sample Input4

10086
2

Sample Output4

        2
    10086
    -----
       12
      16
    2
    -----
    20172

Sample Input5

12340012384
12039847102934

Sample Output5

              12340012384
           12039847102934
 ------------------------
              49360049536
             37020037152
           111060111456
           24680024768
         12340012384
        86380086688
       49360049536
      98720099072
    111060111456
   37020037152
  24680024768
 12340012384
 ------------------------
 148571862351672082734656


此题虽然没什么算法难度,但是给人的一个启发就是要把样例研究透彻,比如这些案例里隐含了几个条件。
1.如果一个数为1位数,另外一个数的位数>=3则,把短的放在上面,如果是2或1 则不必处理
2.如果结果中只有一行则直接输出
3.如果结果中的某一行全是0则不输出

代码如下
#include <iostream>
#include <cstring>

using namespace std;


char a_input[120]={0};
char b_input[120]={0};
char res[120][120]={0};//存储每次乘法的计算结果
int final_res[300]={0};
inline void printBlank(int n,char flag = ' '){
    for (int i = 0; i < n; ++i)
    {
        cout<<flag;
    }
    return;
}

void cal(char a[],char b[],int a_len,int b_len){
    int final_res_len = 0;
    for (int i = b_len-1; i >=0; --i)//b[i]是下边的一位数
    {
        int remain = 0;//存储要进位的数
        int index = b_len-1 - i;//这次乘法的计算结果存储到res[index]中
        //逆序存储
        int cur = 0;
        for (int j = a_len -1 ; j >=0; --j)
        {
            int tmp_res = (a[j]-'0') * (b[i]-'0') + remain;
            res[index][cur] = (tmp_res) % 10 + '0';
            remain = tmp_res / 10;
            cur++;
        }
        if(remain>0)//最后还要进一位
            res[index][cur] = remain  + '0';
    }
    //计算最终结果
    for (int i = 0; i < b_len; ++i)
    {
        int remain = 0; //要进位的数
        for (int j = 0; j < strlen(res[i]); ++j)//最低的i位保持不变
        {
            //final_res的第j位 和 j-i-1位对齐
            int temp_res = final_res[j+i] + (res[i][j]-'0') +remain;
            final_res[j+i] = temp_res % 10;
            remain = temp_res / 10;
        }
        if(remain>0)//最后还要进位
        {
            final_res[strlen(res[i])+i] = remain;
            if(i==b_len-1)
                final_res_len = strlen(res[i])+i+1;
        }else{
            if(i==b_len-1)
                final_res_len = strlen(res[i])+i;
        }
    }
    
    
    printBlank(final_res_len - a_len);    cout<<a<<endl;
    printBlank(final_res_len - b_len);     cout<<b<<endl;
    printBlank(final_res_len,'-');        cout<<endl;
    
    bool toOutput = false; int cot = 0;
    for (int i = 0; i < b_len; ++i) if(b[b_len-1-i]!='0')
        cot++;
    toOutput = cot>1;
    if(toOutput){
        for (int i = 0; i < b_len; ++i) if(b[b_len-1-i]!='0')
        {
            printBlank(final_res_len - strlen(res[i])-i);
            for (int j = strlen(res[i])-1; j>=0 ; --j)
                cout<<res[i][j];
            cout<<endl;
            //cout<<strlen(res[i])<<":"<<res[i]<<endl;
        }
        printBlank(final_res_len,'-');      cout<<endl;
    }

    for (int i = final_res_len-1; i >=0 ; --i)
    {
        cout<<final_res[i];
    }cout<<endl;
}
int main(int argc, char const *argv[])
{
    char a[120]={0};
    char b[120]={0};
    cin>>a_input;
    cin>>b_input;
    int a_len = 0;
    int b_len = 0;
    //去除前置0
    bool began = false;
    for (int i = 0; i < strlen(a_input); ++i) {
        if(!began and a_input[i]!='0')
            began = true;
        if (began)
            a[a_len++] = a_input[i];
    }
    
    began = false;
    for (int i = 0; i < strlen(b_input); ++i) {
        if(!began and b_input[i]!='0')
            began = true;
        if (began)
            b[b_len++] = b_input[i];
    }
    
    //以上是初始化 
    if(a_len>=3 and b_len == 1)
        cal(b,a,b_len,a_len);
    else
        cal(a,b,a_len,b_len);
    return 0;
}

/*
 
 
              12340012384
           12039847102934
 ------------------------
              49360049536
             37020037152
           111060111456
           24680024768
         12340012384
        86380086688
       49360049536
      98720099072
    111060111456
   37020037152
  24680024768
 12340012384
 ------------------------
 148571862351672082734656
 
 */
View Code

 

posted @ 2015-04-29 18:32  雨尘之林  阅读(530)  评论(0编辑  收藏  举报