天天看點

POJ 1001

此題用最樸素的思路實作即可,需模拟加法器,乘法器,最煩人的地方是特殊情形,如末位是小數點(12.^2=144,取小數點),整數末位是0(100^2=10000),0次幂,測試用例可能超出題目中說的範圍,可能包含0次幂(100.0^0=0, 0.10^1=0.1)。代碼

#include <iostream>
#include <string>

using namespace std;

struct RLT {
    int unit; // 本位值
    int carryBit; // 進位值
};

RLT add(char ch1, char ch2, int carryBit);
RLT multiply(char ch1, char ch2, int carryBit);
string add(string op1, string op2, int x);
string multiply(string op1, char op2);
string multiply(string op1, string op2);
string remove(string str);

int main() {

    string number;
    int n;
    while (cin >> number >> n) {
        // 記錄小數點位置
        int punc = -1;
        int len = number.length();
        string multiplier = ""; // 乘數, 注意每次初始化置空
        for (int i = 0; i < len; i++) {
            if (number[i] == '.') {
                punc = len - i - 1;
                continue;
            }
            // 抽取出數字位
            multiplier += number[i];
        }

        string tmpRlt = multiplier;
        if(0==n) tmpRlt = "0";
        else {
            for(int j = 1; j < n; j++) { // 相乘次數
                tmpRlt = multiply(tmpRlt, multiplier);
            }

            // 計算小數點位置
            punc = punc*n;
            int tLen = tmpRlt.length();
            if(tLen!=punc && punc > 0) // 為整數時不必加小數點
                tmpRlt = tmpRlt.insert(tmpRlt.length()-punc, ".");

            // 注意處理末位為0的整數乘積情況
            tmpRlt = remove(tmpRlt);
        }

        cout << tmpRlt << endl;
    }

    return 1;
}

// 去除字元串前後無效零位
string remove(string str) {
    int start = -1;
    int end = -1;
    bool tag = false;
    bool tag2 = false;
    int index = -1;
    int len = str.length();
    for (int i=0; i<len; i++) {
        if (str[i]!='0' && !tag) {
            start = i;
            tag = true;
        }
        if (str[len-i-1]!='0' && !tag2) {
            end = len-i-1;
            tag2 = true;
        }
        if (str[i]=='.') index = i; // 查找小數點位置
    }
    if (index<0) { // 無小數點情況
    } else { // 處理帶小數點情況
        // 處理最後一位是小數點情況, 且前面位不是0
        if ('.' == str[end] && '.'!=str[start])
            str = str.substr(start, end-start);
        else if ('.'!=str[end]) // 處理最後一位不是小數點情況, 且前面位不是0
            str = str.substr(start, end-start+1);
        else
            str = "0";
    }

    return str;
}

// 一位加法器, 傳回進位值, carryBit, 上一位進位值
RLT add(char ch1, char ch2, int carryBit) {
    int sum = (ch1-48)+(ch2-48)+carryBit;
    int unit = sum%10;
    int carryBit2 = sum/10;
    RLT rlt;
    rlt.unit=unit;
    rlt.carryBit=carryBit2;

    return rlt;
}

// 一位乘法器, 傳回進位值
RLT multiply(char ch1, char ch2, int carryBit) {
    int product = (ch1-48)*(ch2-48)+carryBit;
    int unit = product%10;
    int carryBit2 = product/10;
    RLT rlt;
    rlt.unit=unit;
    rlt.carryBit=carryBit2;

    return rlt;
}

// 兩個數錯位相加
string add(string op1, string op2, int x) {
    string rlt = "";

    for (int i = 0; i < x; i++)
        op2 += '0';

    int len1 = op1.length();
    int len2 = op2.length();

    // 兩個數長度對齊
    if (len1<len2) {
        for (int i=0; i< len2-len1; i++)
            op1 = '0' + op1;
    } else {
        for (int i=0;i<len1-len2; i++)
            op2 = '0' + op2;
    }

    int carryBit = 0;
    int len = len1>len2?len1:len2;
    RLT tmp;
    for (int i=0; i<len; i++) {
        tmp = add(op1[len-i-1], op2[len-i-1], carryBit);
        carryBit = tmp.carryBit;
        rlt = char(tmp.unit+48)+rlt;
    }
    // 考慮最高位進位
    if (0!=tmp.carryBit) rlt = char(tmp.carryBit+48)+rlt;

    return rlt;
}

// 多位數乘一位數
string multiply(string op1, char op2) {
    string rlt= "";
    int unit = 0;
    int carryBit = 0; // 進位
    int len = op1.length();
    for (int k=len-1; k>=0; k--) {
        RLT tRlt = multiply(op1[k], op2, carryBit);
        unit = tRlt.unit; // 每一位乘積個位數字
        rlt = (char(unit+48)) + rlt;
        carryBit = tRlt.carryBit; // 每一位乘積十位數字
    }

    if(0!=carryBit)
        rlt = char(carryBit+48) + rlt;

    return rlt;
}

// 多位數相乘
string multiply(string op1, string op2) {
    string rlt = "0";
    int len2 = op2.length();
    for (int i=len2-1; i>-1; i--) {
        // 多位數與一位數相乘
        string tmp = multiply(op1, op2[i]);
        rlt = add(rlt, tmp, len2-i-1);
    }

    return rlt;
}
           

繼續閱讀