前段时间,刚刚看完了刘汝佳的算法入门经典的重载运算符,刚开始不是很懂那是什么鬼,不过,现在学完了C++的运算符重载之后,就感觉So easy!~
实现大数的运算,主要还是字符串的模拟。程序实现大数的运算,说白了,就是我们笔算的过程,而我们需要做的是如何控制程序以我们笔算的过程来运算。
class Operator
{
public:
Operator(){} //构造函数
~Operator(){} //析构函数
friend istream& operator >> (istream &, Operator &); //重载流提取运算符
friend ostream& operator << (ostream &, Operator &); //重载流插入运算符
friend Operator operator + (Operator, Operator); //重载 +
friend Operator operator - (Operator, Operator); //重载 -
friend Operator operator * (Operator, Operator); //重载 *
friend Operator operator / (Operator, int); //重载 /
private:
char str[1000];
};
这是我定义的类,相信大家应该看到了,除法的那个友元函数,目前的我,还不会大数除以大数,所以只能用大数除以一个小的数来实现了。而大数除以大数,也是我们笔算的过程来实现,有机会再尝试一下,再来给大家分享。
重载 + 号实现大数加法,相对比较简单,不多说
Operator operator + (Operator s1, Operator s2)
{
Operator s;
int length1, length2, i, j, k;
int a[1000];
length1 = strlen(s1.str);
length2 = strlen(s2.str);
k = 0;
i = length1 - 1;
j = length2 - 1;
for ( ; i >= 0 && j >= 0; )
{
a[k++] = (s1.str[i--] - '0') + (s2.str[j--] - '0');
}
while (i >= 0) //s1中没有加完
{
a[k++] = s1.str[i--] - '0';
}
while (j >= 0) //s2中没有加完
{
a[k++] = s2.str[j--] - '0';
}
for (i = 0; i < k; i++) //进位
{
if (a[i] >= 10 && i != k - 1)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
}
if (a[k - 1] >= 10)
{
a[k] = a[k - 1] / 10;
a[k - 1] = a[k - 1] % 10;
k++;
}
j = 0;
for (i = k - 1; i >= 0; i--) //因为我是逆序存放的结果,所以这里要反过来,才能得到结果
{
s.str[j++] = a[i] + '0';
}
s.str[j] = '\0';
return s;
}
重载 - 号,相对比较麻烦,需要考虑减数和被减数的大小。主要是考虑两个数的大小,是否需要加上“-”号,我的函数中,比较长,因为有很多地方是重复的。
Operator operator - (Operator s1, Operator s2)
{
Operator s;
int length1, length2;
length1 = strlen(s1.str);
length2 = strlen(s2.str);
if (strcmp(s1.str, s2.str) == 0) //两个数相等的情况
{
s.str[0] = '0';
s.str[1] = '\0';
return s;
}
else
{
int a[1000], i, j, k = 0;
i = length1 - 1;
j = length2 - 1;
if (length1 > length2) //减数大的情况
{
for (; j >= 0;)
{
if (s1.str[i] < s2.str[j]) //向下一位借1
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i--] - '0') - (s2.str[j--] - '0');
}
while (i >= 0) //减完了,剩余的位数补上
{
if (s1.str[i] < '0') //0被借1之后的情况,需要再向前借
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i--] - '0');
}
}
else if (length1 < length2) //被减数大的情况
{
for (; i >= 0;)
{
if (s2.str[j] < s1.str[i]) //借位
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0') - (s1.str[i--] - '0');
}
while (j >= 0) //减完,补位
{
if (s2.str[j] < '0') //0被借位的情况,同上
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0');
}
a[k++] = '-'; //最后补上负号
}
else //两个数长度相同但不相等的情况,不需考虑借位遗留的问题
{
int flag = 0, b = 0;
while (1) //判断哪个数比较大
{
if (s1.str[b] > s2.str[b])
{
break;
}
else if (s1.str[b] < s2.str[b])
{
flag = 1;
break;
}
else
b++;
}
if (flag == 0) //减数大的情况
{
for (; j >= 0;)
{
if (s1.str[i] < s2.str[j])
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i] - '0') - (s2.str[j] - '0');
}
}
else //被减数大的情况
{
for (; i >= 0;)
{
if (s2.str[j] < s1.str[i])
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0') - (s1.str[i--] - '0');
}
a[k++] = '-'; //添加负号
}
}
j = 0;
if (a[k - 1] == '-') //有负号,先添加
{
s.str[j++] = '-';
k--;
}
while (a[k - 1] == 0) //去掉因为借位和相减结果为0的前置的0
{
k--;
}
for (i = k - 1; i >= 0; i--) //逆序返回结果。
{
s.str[j++] = a[i] + '0';
}
s.str[j] = '\0';
}
return s;
}
重载 * 号,比较简单,不多说
Operator operator * (Operator s1, Operator s2)
{
Operator s;
int a[2000], length1, length2;
length1 = strlen(s1.str);
length2 = strlen(s2.str);
for (int i = 0; i < 2000; i++)
a[i] = 0;
for (int i = 0; i < length1; i++) //乘法运算
{
for (int j = 0; j < length2; j++)
{
a[i + j + 1] += (s1.str[i] - '0') * (s2.str[j] - '0');
}
}
for (int i = length1 + length2 - 1; i >= 0; i--) //进位
{
if (a[i] >= 10)
{
a[i - 1] += a[i] / 10;
a[i] %= 10;
}
}
int i = 0, j;
while (!a[i]) //去掉前置的0
i++;
for (j = 0; i < length1 + length2; j++, i++) //返回结果
s.str[j] = a[i] + '0';
s.str[j] = '\0';
return s;
}
Operator operator / (Operator s1, int s2)
{
Operator s;
int div = 0, length, i, j, k = 0;
int a[1000];
length = strlen(s1.str);
for (i = 0; i < length; i++)
{
div = div * 10 + (s1.str[i] - '0');
a[k++] = div / s2;
div = div % s2;
}
j = i = 0;
while (!a[j]) //去掉前置的0
j++;
for (; j < k; j++)
s.str[i++] = a[j] + '0';
s.str[i] = '\0';
return s;
}
下面是整的代码:
# include
# include
using namespace std;
class Operator
{
public:
Operator(){} //构造函数
~Operator(){} //析构函数
friend istream& operator >> (istream &, Operator &); //重载流提取运算符
friend ostream& operator << (ostream &, Operator &); //重载流插入运算符
friend Operator operator + (Operator, Operator); //重载 +
friend Operator operator - (Operator, Operator); //重载 -
friend Operator operator * (Operator, Operator); //重载 *
friend Operator operator / (Operator, int); //重载 /
private:
char str[1000];
};
istream& operator >> (istream &input, Operator &s)
{
input >> s.str;
return input;
}
ostream& operator << (ostream &output, Operator &s)
{
output << s.str;
return output;
}
Operator operator + (Operator s1, Operator s2)
{
Operator s;
int length1, length2, i, j, k;
int a[1000];
length1 = strlen(s1.str);
length2 = strlen(s2.str);
k = 0;
i = length1 - 1;
j = length2 - 1;
for (; i >= 0 && j >= 0;)
{
a[k++] = (s1.str[i--] - '0') + (s2.str[j--] - '0');
}
while (i >= 0) //s1中没有加完
{
a[k++] = s1.str[i--] - '0';
}
while (j >= 0) //s2中没有加完
{
a[k++] = s2.str[j--] - '0';
}
for (i = 0; i < k; i++) //进位
{
if (a[i] >= 10 && i != k - 1)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
}
if (a[k - 1] >= 10)
{
a[k] = a[k - 1] / 10;
a[k - 1] = a[k - 1] % 10;
k++;
}
j = 0;
for (i = k - 1; i >= 0; i--) //因为我是逆序存放的结果,所以这里要反过来,才能得到结果
{
s.str[j++] = a[i] + '0';
}
s.str[j] = '\0';
return s;
}
Operator operator - (Operator s1, Operator s2)
{
Operator s;
int length1, length2;
length1 = strlen(s1.str);
length2 = strlen(s2.str);
if (strcmp(s1.str, s2.str) == 0) //两个数相等的情况
{
s.str[0] = '0';
s.str[1] = '\0';
return s;
}
else
{
int a[1000], i, j, k = 0;
i = length1 - 1;
j = length2 - 1;
if (length1 > length2) //减数大的情况
{
for (; j >= 0;)
{
if (s1.str[i] < s2.str[j]) //向下一位借1
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i--] - '0') - (s2.str[j--] - '0');
}
while (i >= 0) //减完了,剩余的位数补上
{
if (s1.str[i] < '0') //0被借1之后的情况,需要再向前借
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i--] - '0');
}
}
else if (length1 < length2) //被减数大的情况
{
for (; i >= 0;)
{
if (s2.str[j] < s1.str[i]) //借位
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0') - (s1.str[i--] - '0');
}
while (j >= 0) //减完,补位
{
if (s2.str[j] < '0') //0被借位的情况,同上
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0');
}
a[k++] = '-'; //最后补上负号
}
else //两个数长度相同但不相等的情况,不需考虑借位遗留的问题
{
int flag = 0, b = 0;
while (1) //判断哪个数比较大
{
if (s1.str[b] > s2.str[b])
{
break;
}
else if (s1.str[b] < s2.str[b])
{
flag = 1;
break;
}
else
b++;
}
if (flag == 0) //减数大的情况
{
for (; j >= 0;)
{
if (s1.str[i] < s2.str[j])
{
s1.str[i - 1] -= 1;
s1.str[i] += 10;
}
a[k++] = (s1.str[i] - '0') - (s2.str[j] - '0');
}
}
else //被减数大的情况
{
for (; i >= 0;)
{
if (s2.str[j] < s1.str[i])
{
s2.str[j - 1] -= 1;
s2.str[j] += 10;
}
a[k++] = (s2.str[j--] - '0') - (s1.str[i--] - '0');
}
a[k++] = '-'; //添加负号
}
}
j = 0;
if (a[k - 1] == '-') //有负号,先添加
{
s.str[j++] = '-';
k--;
}
while (a[k - 1] == 0) //去掉因为借位和相减结果为0的前置的0
{
k--;
}
for (i = k - 1; i >= 0; i--) //逆序返回结果。
{
s.str[j++] = a[i] + '0';
}
s.str[j] = '\0';
}
return s;
}
Operator operator * (Operator s1, Operator s2)
{
Operator s;
int a[2000], length1, length2;
length1 = strlen(s1.str);
length2 = strlen(s2.str);
for (int i = 0; i < 2000; i++)
a[i] = 0;
for (int i = 0; i < length1; i++) //乘法运算
{
for (int j = 0; j < length2; j++)
{
a[i + j + 1] += (s1.str[i] - '0') * (s2.str[j] - '0');
}
}
for (int i = length1 + length2 - 1; i >= 0; i--) //进位
{
if (a[i] >= 10)
{
a[i - 1] += a[i] / 10;
a[i] %= 10;
}
}
int i = 0, j;
while (!a[i]) //去掉前置的0
i++;
for (j = 0; i < length1 + length2; j++, i++) //返回结果
s.str[j] = a[i] + '0';
s.str[j] = '\0';
return s;
}
Operator operator / (Operator s1, int s2)
{
Operator s;
int div = 0, length, i, j, k = 0;
int a[1000];
length = strlen(s1.str);
for (i = 0; i < length; i++)
{
div = div * 10 + (s1.str[i] - '0');
a[k++] = div / s2;
div = div % s2;
}
j = i = 0;
while (!a[j]) //去掉前置的0
j++;
for (; j < k; j++)
s.str[i++] = a[j] + '0';
s.str[i] = '\0';
return s;
}
int main()
{
Operator a, b, c;
cin >> a >> b;
c = a + b;
cout << a << '+' << b << '=' << c << endl;
c = a - b;
cout << a << '-' << b << '=' << c << endl;
c = a * b;
cout << a << '*' << b << '=' << c << endl;
c = a / 111;
cout << a << '/' << "111" << '=' << c << endl;
return 0;
}
如果大家发现有什么错误的话,欢迎跟我说,我会纠正的!~~