[算法]POJ-ACM exponentiation

 http://poj.org/problem?id=1001

Description

Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems. 

This problem requires that you write a program to compute the exact value of R n where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input

The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

Output

The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

Sample Input

95.123 12

0.4321 20

5.1234 15

6.7592  9

98.999 10

1.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721

.00000005148554641076956121994511276767154838481760200726351203835429763013462401

43992025569.928573701266488041146654993318703707511666295476720493953024

29448126.764121021618164430206909037173276672

90429072743629540498.107596019456651774561044010001

1.126825030131969720661201

解决方法,我的方法先把两个乘数变成整数,然后整数相乘,再把小数点添入适当位置。第一次使用string,觉得还是不错的。
#include <iostream>

#include <string>

#include <algorithm>

using namespace std;

void shift2right(string& str,unsigned int n)

{

    if (0 != n)

    {

        string temp = str;

        str.clear();

        while(0 != n)

        {

            str += '0';

            --n;

        }

        str += temp;

    }



}



void intAdd(const string& augend, const string& addend, string& sum)

{



    if(augend.length() >= addend.length())

    {

        unsigned int i = 0;

        unsigned int j = 0;

        unsigned int addLength = addend.length();

        unsigned int augLength = augend.length();

        unsigned int carry = 0;

        unsigned int temp;

        sum.clear();

        while(j < addLength)

        {

            temp = augend[i] -'0' + addend[j] - '0' + carry;

            sum += '0' + (temp % 10);

            carry = temp / 10;

            ++i;

            ++j;

        }

        while(i < augLength)

        {

            temp = augend[i] -'0' + carry;

            sum += temp % 10 + '0';

            carry = temp / 10;

            ++i;

        }

        if (0 != carry)

        {

            sum += carry + '0';

        }

    }

    else

    {

        intAdd(addend,augend,sum);

    }



}

void intMultiply(const string& multiplicand, const string& multiplier, string& product)

{

    if(multiplicand.length() >= multiplier.length())

    {

        unsigned int temp;

        unsigned int carry;

        product += '0';

        string tempProduct,sum;

        unsigned int i;

        unsigned int j;

        j = multiplier.length()-1;

        unsigned int n = 0;

        while (j != ~0)

        {

            i = multiplicand.length() - 1;

            tempProduct.clear();

            carry = 0;

            while(i != ~0)

            {



                temp = (multiplicand[i]-'0') * (multiplier[j]-'0') + carry;

                tempProduct += (temp % 10 + '0');

                carry = temp / 10;

                --i;

            }

            if (0 != carry)

            {

                tempProduct += carry + '0';

            }

            shift2right(tempProduct,n);    

            intAdd(product,tempProduct,sum);

            product = sum;

            ++n;

            --j;

        }

        reverse(product.begin(),product.end());

    }

    else

    {

        intMultiply(multiplier,multiplicand,product);

    }

}



void multiply(const string& Multiplicand,const string& Multiplier, string& product)

{

    string multiplicand = Multiplicand;

    string multiplier = Multiplier;

    unsigned int augDecLength = multiplicand.length() - multiplicand.find('.') -1;

    unsigned int addDecLength = multiplier.length() - multiplier.find('.') - 1;

    unsigned int decLength =  augDecLength + addDecLength;

    unsigned int augDotPos = multiplicand.find('.');

    unsigned int addDotPos = multiplier.find('.');

    multiplicand.erase(augDotPos,1);

    multiplier.erase(addDotPos,1);

    intMultiply(multiplicand,multiplier,product);

    string dot(".");

    product.insert(product.length() - decLength,dot,0,1);

}

void exponent(const string& base,unsigned int n,string& product)

{

    if (0 == n)

    {

        product +='0';

    }

    if(1 == n)

    {

        product = base;

    }

    else if(2 == n)

    {

        multiply(base,base,product);

    }

    else

    {

        string halfProduct, t;

        exponent(base,n/2,halfProduct);

        multiply(halfProduct,halfProduct,t);

        if(n&1)

        {

            multiply(base,t,product);

        }

        else

        {

            product = t;

        }

    }    

}

int main()

{

    string base,product;

    unsigned int n;

    while(cin>>base>>n)

    {

        exponent(base,n,product);

        unsigned int i = product.length()-1;

        if('0' == product[i])

        {

            while('0' == product[i])

            {

                --i;

            }

            ++i;

            product.erase(i);

        }

        if('.' == product[product.length()-1])

        {

            product.erase(product.length()-1);

        }

        if('0' == product[0])

        {

            product.erase(0,1);

        }

        cout<<product<<endl;

        base.clear();

        product.clear();

    }

    return 0;

} 

 


本文基于知识共享署名-非商业性使用 3.0 许可协议进行许可。欢迎转载、演绎,但是必须保留本文的署名林羽飞扬,若需咨询,请给我发信

你可能感兴趣的:(ACM)