您的位置:首页 > 编程语言 > C语言/C++

大整数类加减乘除的简单实现——C++

2016-01-30 14:47 609 查看


编程题#4:大整数的加减乘除

来源: POJ 
总时间限制: 1000ms 内存限制: 65536kB
描述

给出两个正整数以及四则运算操作符(+ - * /),求运算结果。

输入第一行:正整数a,长度不超过100

第二行:四则运算符o,o是“+”,“-”,“*”,“/”中的某一个

第三行:正整数b,长度不超过100

保证输入不含多余的空格或其它字符
输出一行:表达式“a o b”的值。

补充说明:

1. 减法结果有可能为负数

2. 除法结果向下取整

3. 输出符合日常书写习惯,不能有多余的0、空格或其它字符
样例输入
9876543210
+
9876543210


样例输出
19753086420


这次的大整数加减乘除的基本思想是用字符串构造一个类,记录十进制的数字。用竖式计算实现加和减。接下来要注意,对于乘法,因为只有+/- 可以调用,若要求求得a*b,仅仅用a次循环的+=b是极慢的。所以,要用递归来实现,若用res记录结果,第一次res=b,

第n次可使res=res+res;这样res的值以二次方增长,大大节省时间。除法也是如此。

</pre><pre name="code" class="cpp"><pre name="code" class="cpp">#include <iostream>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <sstream>
#include <stdio.h>
using namespace std;
void itoa1(int a, char* b, int c);
long long atoi1(const char s[])                            //atoi
{
long long temp = 0;
const char *ptr = s;
if (*s == '-' || *s == '+')
{
s++;
}
while (*s != 0)
{
if ((*s < '0') || (*s > '9'))
{
break;
}
temp = temp * 10LL + (long long)(*s - '0');
s++;
}
if (*ptr == '-') {
temp = -temp;
}

return temp;
}
class longint {
string a;

public:
longint(string);
longint();
longint(const char*);
string operator=(const char*);
string operator+(longint);
string operator-(longint);
string operator*(longint);
string operator/(longint);
};
void itoa1(int n, char *str, int c)                         //itoa
{
char buf[10] = "";
int i = 0;
int len = 0;
int temp = n < 0 ? -n : n;
if (n == 0) {
str[0] = '0';
str[1] = 0;
return;
}
if (str == NULL)
{
return;
}
while (temp)
{
buf[i++] = (temp % 10) + '0';
temp = temp / 10;
}

len = n < 0 ? ++i : i;  //如果n是负数,则多需要一位来存储负号
str[i] = 0;            //末尾是结束符0
while (1)
{
i--;
if (buf[len - i - 1] == 0)
{
break;
}
str[i] = buf[len - i - 1];  //把buf数组里的字符拷到字符串
}
if (i == 0)
{
str[i] = '-';          //如果是负数,添加一个负号
}
}
int cmpl(string f, string l);
int main() {

string k;
char o = 0; string kk;
cin >> k >> o >> kk;
longint a(k), b(kk);
switch (o)
{
case '+':cout << a + b << endl; break;
case '-':cout << a - b << endl; break;
case '*':cout << a * b << endl; break;
case '/':cout << a / b << endl; break;
default:
break;
}
/*
char tes[30] = {}; long long k = 0;
while (cin >> k) {

itoa1(k, tes, 10);
cout<<tes<< endl << endl;
}
*/
cin.get();
cin.get();
return 0;
}
int cmpl(string f, string l) {                                             //用于比较字符串大小
if (f.length() > l.length()) return 1;
else if (f.length() < l.length()) return -1;
else {
for (int i = 0; i < f.length(); i++) {
if (f[i] > l[i])return 1;
if (l[i] > f[i])return -1;
}
}return 0;
}
longint::longint(string b)
{
a = b;
}
longint::longint()
{

}
longint::longint(const char *b)
{
a = b;
}
string longint::operator=(const char * b)
{
a = b;
return a;
}
string longint::operator+(longint b)
{
int maxlen = 0;
string maxN;
string minN;
if (a.length() >= b.a.length()) {
maxlen = a.length();
maxN = "0";
maxN += a;
minN.resize(a.length() - b.a.length() + 1, '0');
minN += b.a;
}
else {
maxlen = b.a.length();
maxN = "0";
maxN += b.a;
minN.resize(b.a.length() - a.length() + 1, '0');
minN += a;
}
bool ad = 0;
string Sr; Sr.resize(maxlen + 1, '0');
for (int i = maxlen; i >= 0; i--) {
int res = 0;
if (ad) {
res += 1;
ad = 0;
}
char in1[2] = { maxN[i],'\0' };
char in2[2] = { minN[i],'\0' };
res += atoi1(in1) + atoi1(in2);

if (res > 9) {
ad = 1;
char temp[3] = {}; itoa1(res, temp, 10);
Sr[i] = temp[1];
}
else {
char temp[2] = {}; itoa1(res, temp, 10);
Sr[i] = temp[0];
}
}
if (Sr[0] == '0') {
Sr.erase(0, 1);
}

return Sr;
}
string longint::operator-(longint b)
{
int maxlen = 0; bool nag = 0;
string maxN;
string minN;
if (cmpl(a, b.a) == 1) {
maxlen = a.length();
maxN = "0";
maxN += a;
minN.resize(a.length() - b.a.length() + 1, '0');
minN += b.a;
}

else if (cmpl(a, b.a) == -1) {
nag = 1;
maxlen = b.a.length();
maxN = "0";
maxN += b.a;
minN.resize(b.a.length() - a.length() + 1, '0');
minN += a;
}
else return "0";
bool ad = 0;
string Sr; Sr.resize(1, '0'); Sr.re
4000
size(maxlen + 1, '0');
int res = 0;
for (int i = maxlen; i >= 0; i--) {
res = 0;
if (ad) {
res -= 1;
ad = 0;
}
char in1[2] = { maxN[i],'\0' };
char in2[2] = { minN[i],'\0' };
if (in1[0] + res< in2[0]) {
res += 10 + atoi1(in1) - atoi1(in2);
ad = 1;
}
else res += atoi1(in1) - atoi1(in2);

char temp[2] = {}; itoa1(res, temp, 10);
Sr[i] = temp[0];

}
while (Sr[0] == '0'&&Sr[1] == '0') {
Sr.erase(0, 1);

}
if (nag) {
Sr[0] = '-';
}
else {
Sr.erase(0, 1);
}
if (Sr[0] == 0) {
Sr.erase(0, 1);
}

return Sr;
}
string longint::operator*(longint b)
{
longint maxN;
longint minN;
if (a == "0" || b.a == "0")
return "0";
else if (cmpl(a, b.a) == 1) {
maxN = a;
minN = b.a;
}
else {
maxN = b.a;
minN = a;
}
longint times = minN;
longint Sr;
longint i = "1";
Sr = maxN;
/*for (; cmpl(i+i, times.a) != 1; i = i + i) {   // i<times
Sr = Sr + Sr;
}*/
for (; cmpl(i.a, times.a) ==-1;) {                              //类似递归的循环
longint k = "1";
longint Sr1 = maxN;
for (; cmpl(k+k, times - i) ==-1; k = k + k) {
Sr1 = Sr1 + Sr1;
}
i = k + i;
Sr = Sr + Sr1;
}
return Sr.a;
}
string  longint::operator/(longint b)
{
longint maxN = a;
longint minN = b.a;
longint i = "0";
longint k = "1";
longint Sr1 = minN;
for (; cmpl(((minN + minN)), (maxN.a.c_str())) != 1;) {

k = "1";
for (; cmpl((Sr1 + Sr1), maxN.a) != 1; k = k*"2") {
Sr1 = Sr1 + Sr1;
}
i = k + i;
maxN = maxN - Sr1;
Sr1 = minN;
k = "2";
}
for (; maxN.a[0] != '-'; i = i + "1") {                           <span style="font-family: Arial, Helvetica, sans-serif;">//类似递归的循环</span>

maxN = maxN - minN;
}i = i - "1";

return i.a;
}
/*
741269586512                               // 一些测试数据
*
984562478654

56765156165465786156467
/
54657815454782

48789151687984156
*
56487112346786

8465156478654165468421
-
15646878115487854312234567

48951487894146576543215646
+
5123123165784512313215686

87894123467984512789
/
5684

1.729826221447080406314848

2.2755958292703544831466745522616

3.1038555157

4.-15638412959009200146766146

5.54074611059931088856431332

6.15463427774100019
*/



另外,大整数也可以用链表、数组等来实现。

最后,提醒来找代码交作业的同学,不要直接拷贝啊!!!!这样没有任何好处!


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj c++ 大整数