Codevs高精度入门(减法、加法和乘法)解题报告

题目:                                               

 

题目描述 Description

给出两个正整数AB,计算A-B的值。保证AB的位数不超过500位。 

输入描述 Input Description

读入两个用空格隔开的正整数

输出描述 Output Description

输出A-B的值

样例输入 Sample Input

3 12

样例输出 Sample Output

-9

 

题目分析                                                           

 

C++整数数据范围:

char                          -128 ~ +127                                        (1 Byte)
short                        -32767 ~ + 32768                       (2 Bytes)
unsigned short          0 ~ 65536                                        (2 Bytes)
int                              -2147483648 ~ +2147483647        (4 Bytes)
unsigned int             0 ~ 4294967295                           (4 Bytes)
long == int
long long          -9223372036854775808 ~ +9223372036854775807    (8 Bytes)
double              1.7 x 10^308                                              (8 Bytes)

 

long long范围最大,能表示19位。Test Case大于20位就会发生溢出的问题,无法计算。

所以题目的数据可以选择用string来储存。

如:string str = “123”//123 = 1 x 102 + 2 x 101 + 3 x 100

指数位    ———— 下标(数的高位与下标高位相反

系数位    ————

为了计算方便,将str转换为int[ ](我习惯用vector).然后用下标和值来进行加减法运算,先得到每一位的值,再进行处理(进位、借位)。

如:

vector<int> maxv = { 1, 0, 0, 9 }      // 1000

vector<int> maxv = { 2, 3 }         // 23

vector<int> sub, add;

计算后:sub = { 1, 0, -2, 6 };

add = { 1, 0, 2, 12 };

处理后 : sub = { 0, 8, 8, 6 }    // 小于0,借位

       add = { 1, 0, 3, 2 }    // 小于0,进位

输出:注意处理0

 

减法

n   计算:统一用大数减小数,如果输入被减数小于减数,交换它们,标记输出为负。按位相减即可,从低位高位皆可。

n   转换:高位借位-1,本位+10变为正,依次循环。

加法与减法类似。

乘法,用两个循环,依次相乘做和,更新每一位的值。

这个算式是从数值高位开始算的(直接从vector 0开始),当然也可以按普通乘法计算从低位开始。然后再进行进位转换,注意大于100和大于10的进位。

 

 

/*

高精度减法法题目:  http://codevs.cn/problem/3115/

2015.5.5 shaonian.ding

*/

#include<iostream>

#include<vector>

#include<string>

 

usingnamespace std;

//string convert to vector<int> function

void strToInts(string str, vector<int> &v){

    int len = str.size();

    for (int i = 0; i < len; i++)

    {

       int c = str[i] - '0';

       v.push_back(c);

    }

}

int main(){

 

    string maxStr, minStr;//被减数,减数string.

    /*test case*/

    //maxStr = "1000";

    //minStr = "10";

 

    /*Input Data*/

    cin >> maxStr>>minStr;

 

    /*code*/

    vector<int> maxv,minv;//max vectormin vector

    bool isPositive = true;//差正负标记,用来最后输出

 

    //如果减数小于被减数,交换位置他们。差标记为负数,isPositive = false;

    if (maxStr.size() <= minStr.size()){

       if (maxStr.size() == minStr.size()){

           for (int i = 0; i < maxStr.size(); i++)

           {

              if (maxStr[i] < minStr[i]){

                  swap(maxStr, minStr);

                  isPositive = false;

                  break;

              }

           }

       }

       else{

           swap(maxStr, minStr);

           isPositive = false;

       }

      

    };

 

    //string convert to ints

    strToInts(maxStr, maxv);

    strToInts(minStr, minv);

 

    //maxv = maxv - minv;高位开始减,得到序列max = {1,0,-1,0}

    for (int i = 0; i < minv.size(); i++)

    {

       int j = maxv.size() - minv.size()+i;

       if (i<minv.size()){

           maxv[j] = maxv[j] - minv[i];

       }

    }

 

    //将包含负数的序列按借位方法变为正。max = {0,9,9,0}

    for (int i = maxv.size()-1; i > 0; i--)

    {

       if (maxv[i] < 0){

           maxv[i] += 10;

           maxv[i - 1] -= 1;

       }

    }

 

    /*输出*/

    if (!isPositive){

       cout << "-";

    }

    if (maxv[0] != 0){

       cout << maxv[0];

    }

    for (int i = 1; i < maxv.size(); i++)

    {

       cout << maxv[i];

    }

    return 0;

}

 

 

 

加法:

/*

高精度加法题目:http://codevs.cn/problem/3116/

2015.5.5 shaonian.ding

*/

 

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

 

//string convert to vector<int> function

void strToInts(string str, vector<int> &v){

    int len = str.size();

    for (int i = 0; i < len; i++)

    {

       int c = str[i] - '0';

       v.push_back(c);

    }

}

int main(){

    string maxStr, minStr;

    /*test case*/

     //maxStr = "945";

     //minStr = "59";

   

    /*Input Data*/

    cin >> maxStr >> minStr;

 

    /*code*/

    vector<int> maxv, minv;//max vectormin vector

 

    if (maxStr.size() <= minStr.size()){

       swap(maxStr, minStr);

    };

 

    //string convert to ints

    strToInts(maxStr, maxv);

    strToInts(minStr, minv);

 

    //maxv = maxv - minv;高位开始加,得到序列max = {9,9,14}

    for (int i = 0; i < minv.size(); i++)

    {

       int j = maxv.size() - minv.size() + i;

       maxv[j] = maxv[j] + minv[i];

    }

 

    //max = {9,9,14}

    for (int i = maxv.size() - 1; i > 0; i--)

    {

       if (maxv[i] >= 10){//最多为19

           maxv[i] -= 10;

           maxv[i - 1] += 1;//i=1执行最后一次转换,maxv[0]可能等于10

       }

    }

 

    /*输出*/

    if (maxv[0] != 10){//跳过最高位为0

       cout << maxv[0];

    }

    else{

       cout << "1" << 10 - maxv[0];

    }

    for (int i = 1; i < maxv.size(); i++)

    {

       cout << maxv[i];

    }

    return 0;

}

 

乘法:

/*

高精度乘法题目:http://codevs.cn/problem/3117/

2015.5.5 shaonian.ding

*/

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

 

//string convert to vector<int> function

void strToInts(string str, vector<int> &v){

    int len = str.size();

    for (int i = 0; i < len; i++)

    {

       int c = str[i] - '0';

       v.push_back(c);

    }

}

int main(){

    string maxStr, minStr;

 

/*test case */

     //maxStr = "123";

     //minStr = "45";

 

     //maxStr = "99";

     //minStr = "99";

 

    /*Input Data*/

    cin >> maxStr >> minStr;

 

/*code*/

    vector<int> maxv, minv;//max vectormin vector

 

    //string convert to ints

    strToInts(maxStr, maxv);

    strToInts(minStr, minv);

 

    int n = maxv.size() + minv.size();//乘积的位数(不会大于两乘数位数之和)

    vector<int> mul(n, 0 );//保存乘积multiplication,用来输出。

 

    /*

    *tset1:mul ={ 0,4,13,22,15 }

    *tset2:mul ={ 0,81,162,81}

    */

    for (int i = 0; i < minv.size(); i++)// min i 外循环

    {

       for (int j = 0; j < maxv.size(); j++)//max j 内循环

       {

           mul[i + j+1] += maxv[j] * minv[i];//

       }

    }

   

    /*

    *test1:mul = { 0,5,5,3,5 }

    *test2:mul = { 9,8,0,1 }

    */

    for (int i = mul.size() - 1; i > 0; i--)

    {

       if (mul[i] >= 100){//最多为199

           mul[i - 1] += mul[i] / 10;//进位

           mul[i] -= mul[i] / 10 *10;

       }elseif (mul[i] >= 10){//最多为99

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

           mul[i] -= mul[i] / 10 * 10;

       }

    }

 

/*输出*/

    if (mul[0] != 0){//跳过最高位为0

       cout << mul[0];

    }

    for (int i = 1; i < mul.size(); i++)

    {

       cout << mul[i];

    }

    return 0;

}

原文地址:https://www.cnblogs.com/dingblog/p/4479571.html