2、大数相加减
以前写过一篇日志,不过写的不是很全。
http://blog.163.com/zhoumhan_0351/blog/static/399542272010328112344940/
今天重写一下,如下:
// JSON.cpp : 定义控制台应用程序的入口点。
//
#include "iostream"
using namespace std;
const int M = 1000; //先将定最大是位,如果要更大值,可以更改这个值
int num1[M] = {0}, num2[M] = {0}, num3[M] = {0}; //存放两个数及生成结果
int n1 = 0, n2 = 0, n3 = 0; //相加的两个数和位数,及结果位数
char cn1[M] = "", cn2[M] = ""; //输入的存放两个数的字符串
int flag1 = 0, flag2 = 0, flag3 = 0; //0表示是正数,表示是负数
char *p1 = NULL, *p2 = NULL; //实际做运算的两个字符串
int tmpflag = 0; //来记录是应当加,还是减运算,0表示相加,表示相减
bool reverseIt = false; //来标志是否需要反转,false表示不需要,true表示需要
/*
void calculateMulti()
{ //大数相乘算法
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
{
int temp = num1[i] * num2[j];
num3[i + j] = num3[i + j] + temp; //处理当前位
int temp1 = num3[i + j];
num3[i + j] = temp1 % 10;
num3[i + j + 1] += (temp1 / 10); //处理高位
int temp2 = num3[i + j + 1];
num3[i + j + 1] = temp2 % 10;
num3[i + j + 2] += temp2 / 10; //处理次高位
int k = 2;
//while (num3[i + j + k] > 10 && (i + j + k) < (n1 + n2 -1))
// {
// int tempme = num3[i + j + k];
// num3[i + j + k] = tempme % 10;
// num3[i + j + k + 1] += tempme / 10; //依此处理次高位,直到最后。
// k++;
// }
}
if (0 == num3[n1+n2-1])
n3 = n1 + n2 -2;
else
n3 = n1 + n2 -1;
for (int i = n3; i >= 0; i--)
cout << num3[i];
cout << endl;
}
*/
void calculateAdd()
{
n3 = n1 > n2 ? n1 : n2;
for (int i = 0; i < n3; i++)
{
int temp = num1[i] + num2[i];
num3[i] = num3[i] + temp; //处理当前位
int temp1 = num3[i];
num3[i] = temp1 % 10;
num3[i + 1] += (temp1 / 10); //处理高位
}
if (0 == num3[n3]) //决定和是几位
n3 = n3 - 1;
else
n3 = n3;
if (1 == flag3)
cout << "-";
for (int i = n3; i >= 0; i--)
cout << num3[i];
cout << endl;
}
void calculateSubA(int num1[], int num2[])
{
n3 = n1 > n2 ? n1 : n2;
for (int i = 0; i < n3; i++)
{
///*
int temp = num1[i] - num2[i];
num3[i] = num3[i] + temp; //处理当前位
int temp1 = num3[i];
if ((temp1 < 0) && ((i + 1) < n3))
{
num3[i + 1] -= 1;
num3[i] = (temp1 + 10) % 10;
}
}
}
void convert(char cn1[], char cn2[], int n1, int n2)
{
int count = 0;
for (int i = n1-1; i >= 0; i--)
num1[count++] = p1[i] - '0';
count = 0;
for (int i = n2-1; i >= 0; i--)
num2[count++] = p2[i] - '0';
}
int doifalpha()
{
for (int i =0; i < n1; i++)
if (isdigit(cn1[i]) || ('-' == cn1[0]) || ('+' == cn1[0]))
continue;
else
{
cout << "you input include no digit alpha, please input again." << endl;
return -1;
}
for (int i =0; i < n2; i++)
if (isdigit(cn2[i]) || ('-' == cn2[0]) || ('+' == cn2[0]))
continue;
else
{
cout << "you input include no digit alpha, please input again." << endl;
return -1;
}
return 0;
}
void calculateSub(int num1[], int num2[])
{
calculateSubA(num1, num2);
if (flag3 == 1)
cout << '-';
for (int i = n3-1; i >= 0;i--)
cout << num3[i];
cout <<endl;
}
void PreDeal(char cn1[], char cn2[], int &n1, int &n2)
{ //前期处理
p1 = cn1;
p2 = cn2;
if (cn1[0] == '-') //第一个数是负数
{
flag1 = 1;
n1--;
p1++;
}
else if (cn1[0] == '+') //第一个数是正数
{
flag1 = 0;
n1--;
p1++;
}
else
{
flag1 = 0; //正数
}
if (cn2[0] == '-') //第二个数是负数
{
flag2 = 1;
n2--;
p2++;
}
else if (cn2[0] == '+') //第二个数是正数
{
flag2 = 0;
n2--;
p2++;
}
else
{
flag2 = 0; //正数
}
}
void DecideZF()
{ //来决定结果是正或负
int tempflag3 = strcmp(p1, p2);
//两个数都是负数,我们执行相加运算
if ((1 == flag1) && (1 == flag2))
{
tmpflag = 0; //相加运算
flag3 = 1; //结果是负的
}
//两个都是正的,招待相加运算
if ((0 == flag1) && (0 == flag2))
{
tmpflag = 0;
flag3 = 0;
}
//第一个是正的,第二个是负的
if ((0 == flag1) && (1 == flag2))
{
tmpflag = 1;//执行减运算
if ((n1 > n2) || ((n1 == n2) && (tempflag3 > 0)))
{
flag3 = 0; //正数
reverseIt = false;//第一个数大,不需要反转
}
else
{
flag3 = 1;
reverseIt = true;//需要反转
}
}
//第一个是负的,第二个是正的
if ((1 == flag1) && (0 == flag2))
{
tmpflag = 1;//执行减运算
if ((n1 > n2) || ((n1 == n2) && (tempflag3 > 0)))
{
flag3 = 1; //负数
reverseIt = false;//第一个数大,不需要反转
}
else
{
flag3 = 0;
reverseIt = true;//需要反转
}
}
}
void DoTheOperation()
{
if (tmpflag == 1) //减运算
{
if (true == reverseIt) //要反转
calculateSub(num2, num1); //这是相减算法
else
calculateSub(num1, num2); //这是相减算法
}
else
{
//加运算
calculateAdd();
}
}
int main(int argc, char* argv[])
{
while(1)
{
memset(num3, 0, M);
memset(num1, 0, M);
memset(num2, 0, M);
memset(cn1, ' ', M);
memset(cn2, ' ', M);
cout << "Input two num:" << endl;
cin >> cn1 >> cn2;
n1 = (int)strlen(cn1);
n2 = (int)strlen(cn2);
int ret = doifalpha(); //是否输入非法
if (ret == -1) return ret;
PreDeal(cn1, cn2, n1, n2);
DecideZF();
convert(cn1, cn2, n1, n2);
//calculateMulti(); //这是相乘算法
//calculateAdd();
DoTheOperation(); //进行运算
}
return 0;
}
感兴趣可以到CSDN论坛上讨论一下:
http://topic.csdn.net/u/20100827/17/5817b294-d1ad-4da1-af7c-f1fe0187639f.html