画圆的沙滩

亦简亦美

大数计算

继续贴一点。大数计算的简单实现,很可惜除法写得很笨拙,用来应付online judge的多数题目应该够了。用string作为存储。

string toBigInt(int i) {
    string r;
    if (i) {
        while (i > 0) {
            r.push_back(i%10 + '0');
            i /= 10;
        }
    }
    else {
        r = "0";
    }
    return r;
}
 
void normalize(string& num) {
    size_t i = num.length();
    for (; i > 1 && num[i-1] == '0'; --i);
    num.resize((i ? i: 1), '0');
}

bool lessThan(const string& lv, const string& rv) {
    if (lv.length() < rv.length()) return true;
    else if (lv.length() > rv.length()) return false;

    for (size_t i = lv.length(); i > 0; --i) {
        if (lv[i-1] < rv[i-1]) return true;
        else if (lv[i-1] > rv[i-1]) return false;
    }
    return false;
}
void add(string& lvalue, string rvalue) {
    if (lvalue.length() < rvalue.length())
        lvalue.resize(rvalue.length(), '0');
    else if (lvalue.length() > rvalue.length())
        rvalue.resize(lvalue.length(), '0');

    int c = 0;
    for (size_t i = 0; i < lvalue.length(); ++i) {
        int d = lvalue[i] - '0' + rvalue[i] - '0' + c;
        lvalue[i] = d%10 + '0';
        c = d/10;
    }
    if (c) lvalue.push_back(c + '0');
}

void multiple(string& lvalue, char rvalue) {
    if (rvalue == '0') {
        lvalue = "0";
        return;
    }

    int c = 0;
    for (size_t i = 0; i < lvalue.length(); ++i) {
        int d = (lvalue[i] - '0')*(rvalue - '0') + c;
        lvalue[i] = d%10 + '0';
        c = d/10;
    }
    if (c) lvalue.push_back(c + '0');
}

void multiple(string& lvalue, string rvalue) {
    if (lvalue.length() < rvalue.length()) swap(lvalue, rvalue);

    string r("0");
    for (size_t i = 0; i < rvalue.length(); ++i) {
        string t(lvalue);
        multiple(t, rvalue[i]);
        t.insert(t.begin(), i, '0');
        add(r, t);
    }
    lvalue = r;
}

void exp(string& lvalue, unsigned int rvalue) {
    if (rvalue == 0) {
        lvalue = "1";
    }
    else if (rvalue != 1) {
        string t = lvalue;
        exp(t, rvalue/2);
        multiple(t, t);
        if (rvalue%2) multiple(t, lvalue);
        lvalue = t;
    }
}
void subtract(string& lvalue, string rvalue) {
    if (lessThan(lvalue, rvalue)) return;

    int c = 0;
    for (size_t i = 0; i < lvalue.length(); ++i) {
        int d = lvalue[i] - (i < rvalue.length() ? rvalue[i]: '0') - c;
        c = (d < 0);
        d = (d + 10)%10;
        lvalue[i] = d + '0';
    }
    normalize(lvalue);
}

string divide(string& lvalue, const string& rvalue) {
    if (lessThan(lvalue, rvalue)) return string("0");

    string r, q;

    for (size_t i = lvalue.length() - rvalue.length() + 1; i > 0; --i) {
        int n = 0;
        q = lvalue.substr(i-1);
        normalize(q);
        for (; !lessThan(q, rvalue); ++n)
            subtract(q, rvalue);
        r.push_back(n + '0');

        if (n) {
            lvalue.resize(i-1);
            lvalue += q;
        }
    }

    reverse(r.begin(), r.end());
    normalize(r);
    normalize(lvalue);

    return r;
}
 
int main() {
    string lv, rv, q;
    char op;
    while(cin>>lv>>op>>rv) {
        reverse(lv.begin(), lv.end());
        reverse(rv.begin(), rv.end());
        normalize(lv);
        normalize(rv);

        q = divide(lv, rv);

        if (op == '/') {
            reverse(q.begin(), q.end());
            cout<<q<<'\n';
        }
        else {
            reverse(lv.begin(), lv.end());
            cout<<lv<<'\n';
        }
    }

    return 0;
}

posted on 2011-03-11 16:21  acmaru  阅读(156)  评论(0编辑  收藏  举报

导航