大数是指长度超过long long int(8字节)类型的自然数,该类型的自然数无法直接用整形数据来进行加减乘数四则运算,所以需要将该整形数据转换成int型的字符串,然后再通过对字符串逐位进行加减乘除运算,即可得出实际运算结果。
核心算法见solution.cpp文件。
/*********************************************************************/
main.cpp
/*********************************************************************/
#include <iostream>
#include <string.h>using namespace std;
char button;
// int dummy1[...];
char number[32 + 1];
// int dummy2[...];
char compare[32 + 1];
// int dummy3[...];
char display[32 + 1];
void Run(char button, char display[32 + 1]);
int main(void)
{
freopen("sample_input.txt", "r", stdin);
int testcase;
cin >> testcase;
for (int t = 1; t <= testcase; ++t)
{
int cnt;
cin >> cnt;
int ret = 0;
for (int i = 0; i < cnt; ++i)
{
cin >> button >> number;
if (button == 'N')
{
int len = strlen(number);
for (int j = 0; j < len; ++j)
{
compare[j] = number[j];
compare[j + 1] = 0;
Run(number[j], display);
if (strcmp(display, compare) == 0)
++ret;
}
}
else
{
Run(button, display);
if (strcmp(display, number) == 0)
++ret;
}
}
cout << "#" << t << " " << ret << endl;
}
return 0;
}
/*********************************************************************/
solution.cpp
/*********************************************************************/
#include <iostream>
#include <string.h>
#define MAX_LEN (32+1)
//#define DBG
typedef enum
{
FALSE,
TRUE
}STATUS_T;
typedef struct
{
int operate[MAX_LEN];//操作数,按照int型字符串存储
int len;//操作数的长度
}operate_t;
typedef struct
{
operate_t first_orig;//第一个操作数的原始数据
operate_t first_num;//第一个操作数的操作数据
char charact;//操作符
operate_t second_orig;//第二个操作数的原始数据
operate_t second_num;//第二个操作数的操作数据
operate_t dis_result;//操作结果
int flag;
}calculate_t;
calculate_t calculate;
static void init(void)
{
int i;
/*初始化,将所有操作符和操作数清空*/
for (i = 0; i<MAX_LEN; i++)
{
calculate.first_orig.operate[i] = 0;
calculate.first_num.operate[i] = 0;
calculate.second_orig.operate[i] = 0;
calculate.second_num.operate[i] = 0;
calculate.dis_result.operate[i] = 0;
}
calculate.first_orig.len = 0;
calculate.first_num.len = 0;
calculate.second_orig.len = 0;
calculate.second_num.len = 0;
calculate.flag = FALSE;
calculate.dis_result.len = 0;
calculate.charact = '\0';
}
static void debug(void)
{
#ifdef DBG
int i, j;
printf("first num len:%d \n", calculate.first_num.len);
for (i = 0; i<calculate.first_num.len; i++)
{
printf("%d ", calculate.first_num.operate[i]);
}
printf("\n");
printf("second num len:%d \n", calculate.second_num.len);
for (i = 0; i<calculate.second_num.len; i++)
{
printf("%d ", calculate.second_num.operate[i]);
}
printf("\n");
#endif
}
/*对操作数进行翻转,使之按顺序由低序到高序排列*/
static void rollover(void)
{
int i, j, len = 0;
int result[MAX_LEN];
calculate.first_num.len = calculate.first_orig.len;
for (i = 0; i<calculate.first_num.len; i++)
{
calculate.first_num.operate[calculate.first_num.len - i - 1] = calculate.first_orig.operate[i];
}
for (i = calculate.first_num.len; i<MAX_LEN; i++)
{
calculate.first_num.operate[i] = 0;
}
calculate.second_num.len = calculate.second_orig.len;
for (i = 0; i<calculate.second_num.len; i++)
{
calculate.second_num.operate[calculate.second_num.len - i - 1] = calculate.second_orig.operate[i];
}
for (i = calculate.second_num.len; i<MAX_LEN; i++)
{
calculate.second_num.operate[i] = 0;
}
for (i = 0; i<MAX_LEN; i++)
{
calculate.dis_result.operate[i] = 0;
}
calculate.dis_result.len = 0;
}
static void store_result(void)
{
int len = 0, i = MAX_LEN;
while (calculate.dis_result.operate[i] == '\0')
{
i--;
len++;
}
calculate.first_orig.len = MAX_LEN - len + 1;
if (calculate.first_orig.len <= 0)
{
calculate.first_orig.len = 1;
}
for (i = 0; i < calculate.first_orig.len; i++)
{
calculate.first_orig.operate[calculate.first_orig.len - i - 1] = calculate.dis_result.operate[i];
}
calculate.dis_result.len = calculate.first_orig.len;
for (i = 0; i< calculate.dis_result.len; i++)
{
calculate.dis_result.operate[i] = calculate.first_orig.operate[i];
}
calculate.flag = FALSE;
calculate.second_orig.len = 0;
}
static void add(void)
{
int i;
int len, len_first, len_second;
rollover();
debug();
len = (calculate.first_num.len>calculate.second_num.len) ? calculate.first_num.len : calculate.second_num.len;
len_first = calculate.first_num.len;
len_second = calculate.second_num.len;
for (i = 0; i<len; i++)//循环相加
{
calculate.dis_result.operate[i] += calculate.first_num.operate[i];
calculate.dis_result.operate[i] += calculate.second_num.operate[i];
calculate.dis_result.operate[i + 1] += calculate.dis_result.operate[i] / 10;
calculate.dis_result.operate[i] = calculate.dis_result.operate[i] % 10;
}
store_result();
}
static void minus(void)
{
int i, len;
rollover();
debug();
len = calculate.first_num.len;
for (i = 0; i<len; i++)
{
if (i< calculate.second_num.len)//如果长度小于第二个数的长度
{
if (calculate.first_num.operate[i] >= calculate.second_num.operate[i])//第一个数的当前位大于第二个数的当前位,直接减
{
calculate.dis_result.operate[i] = calculate.first_num.operate[i] - calculate.second_num.operate[i];
}
else//第一个数的当前位小于第二个数的当前位,向高位借位之后减
{
calculate.dis_result.operate[i] = calculate.first_num.operate[i] + 10 - calculate.second_num.operate[i];
calculate.first_num.operate[i + 1]--;
}
}
else
{
if (calculate.first_num.operate[i] < 0)//判断减数减完了之后高一位是否小于0
{
calculate.dis_result.operate[i] += 10;
calculate.first_num.operate[i + 1]--;
}
}
}
store_result();
}
static void mult(void)
{
int i, j, len = 0;
/*乘数为0或者被乘数为0, 结果也为0*/
if (((calculate.first_orig.len == 1) && (calculate.first_orig.operate[0] == 0)) || ((calculate.second_orig.len == 1) && (calculate.second_orig.operate[0] == 0)))
{
calculate.first_orig.len = 1;
calculate.first_orig.operate[0] = 0;
calculate.dis_result.len = 1;
calculate.dis_result.operate[0] = 0;
calculate.flag = FALSE;
calculate.second_orig.len = 0;
return;
}
rollover();
debug();
for (i = 0; i<calculate.first_num.len; i++)//从低位到高位循环相乘
{
for (j = 0; j<calculate.second_num.len; j++)
{
calculate.dis_result.operate[i + j] += (calculate.first_num.operate[i])*(calculate.second_num.operate[j]);
calculate.dis_result.operate[i + j + 1] += calculate.dis_result.operate[i + j] / 10;
calculate.dis_result.operate[i + j] = calculate.dis_result.operate[i + j] % 10;
}
}
store_result();
}
static int substract(int* num1, int* num2, int len1, int len2)
{
int i, j;
if (len1 < len2)//如果减数的长度小于被减数,直接退出
{
return -1;
}
if (len1 == len2)//如果减数和被减数相等
{
for (i = len1 - 1; i >= 0; i--)//判断减数是否大于被减数
{
if (num1[i] > num2[i])//大于则继续
{
break;
}
else if (num1[i] < num2[i])//小于则退出
{
return -1;
}
}
}
for (i = 0; i <= len1 - 1; i++)//从低位向高位循环递减
{
num1[i] -= num2[i];
if (num1[i] < 0)//向高位借位
{
num1[i] += 10;
num1[i + 1]--;
}
}
for (i = len1 - 1; i >= 0; i--)
{
if (num1[i])
{
return (i + 1);//返回减完之后结果的长度
}
}
return 0;
}
static void divis(void)
{
int i, j;
int result[MAX_LEN];
int len_first, len_second, len_dif;
int temp;
int* num1, *num2;
rollover();
debug();
len_first = calculate.first_num.len;
len_second = calculate.second_num.len;
if ((len_second == 1) && (calculate.second_num.operate[0] == 0))//如果被除数为0,直接退出
{
return;
}
if ((len_first == 1) && (calculate.first_num.operate[0] == 0))//如果除数为0,则结果为0
{
calculate.first_orig.len = 1;
calculate.first_orig.operate[0] = 0;
calculate.dis_result.len = 1;
calculate.dis_result.operate[0] = 0;
calculate.flag = FALSE;
calculate.second_orig.len = 0;
return;
}
num1 = calculate.first_num.operate;
num2 = calculate.second_num.operate;
if (len_first < len_second)//如果除数小于被除数,直接退出
{
return;
}
len_dif = len_first - len_second;//计算除数和被除数之间的长度差
for (i = len_first - 1; i >= 0; i--)//将被除数左移,使其和除数长度一样
{
if (i >= len_dif)
{
calculate.second_num.operate[i] = calculate.second_num.operate[i - len_dif];//将被除数左移
}
else
{
calculate.second_num.operate[i] = 0;//将剩余位补0
}
}
len_second = calculate.second_num.len = len_first;
for (i = 0; i <= len_dif; i++)//在0-len_dif范围内,对除数和被除数循环做减法运算
{
while ((temp = substract(num1, num2 + i, len_first, len_second - i)) >= 0)//如果做差之后剩余长度大于0
{
len_first = temp;//将该长度赋值给第一个数
calculate.dis_result.operate[len_dif - i]++;//结果的相应位+1
}
}
store_result();
}
void Run(char button, char display[32 + 1])
{
int i;
for (i = 0; i<MAX_LEN; i++)
{
display[i] = '\0';
}
if (button == 'C')
{
init();
display[0] = '0';
return;
}
if(calculate.charact == '\0')
{
if(button == '+' || button == '-' || button == '*' || button == '/' || button == '=')
{
calculate.charact = button;
}
else
{
calculate.first_orig.operate[calculate.first_orig.len++] = button - '0';
}
for (i = 0; i<calculate.first_orig.len; i++)
{
display[i] = calculate.first_orig.operate[i] + '0';
}
}
else //not first num
{
if ((calculate.flag == TRUE) && (button == '+' || button == '-' || button == '*' || button == '/' || button == '='))
{//have the first and second num
if (calculate.charact == '+')
{
add();
}
else if (calculate.charact == '-')
{
minus();
}
else if (calculate.charact == '*')
{
mult();
}
else if (calculate.charact == '/')
{
divis();
}
if (button != '=')
{
calculate.charact = button;
}
else
{
calculate.charact = '\0';
}
for (i = 0; i< calculate.dis_result.len; i++)
{
display[i] = calculate.dis_result.operate[i] + '0';
}
}
else //second num
{
calculate.flag = TRUE;
calculate.second_orig.operate[calculate.second_orig.len++] = button - '0';
for (i = 0; i<calculate.second_orig.len; i++)
{
display[i] = calculate.second_orig.operate[i] + '0';
}
}
}
}
/*********************************************************************/
sample_input.txt
/*********************************************************************/
618
C 0
N 178
/ 178
N 5
= 35
/ 35
N 5
= 7
+ 7
N 5
* 12
N 8
- 96
N 40
= 56
* 56
N 2
= 112
9
C 0
N 123456789
* 123456789
N 123456789123456789
* 15241578765432099750190521
N 987654
/ 15053406233994075046674668827734
N 483969384392948296938372859
= 31104
13
C 0
N 17698243644999381322284432307691
/ 17698243644999381322284432307691
N 238299204849929059530684839
* 74269
N 3920458102912849295
- 291168502845234404290355
N 124859209629582437568939
- 166309293215651966721416
N 69472849396839609384838
- 96836443818812357336578
N 96836443813386970438548
= 5425386898030
27
C 0
N 12345
* 12345
N 9197723418922634758233
* 113545895606599926090386385
N 134786
* 15304397085231177638018819288610
N 0
/ 0
N 3829859374838693945832858
+ 0
N 9991111111111111111111111111
+ 9991111111111111111111111111
N 8888888888888888888888888
+ 9999999999999999999999999999
N 9999999999999999999999
= 10000009999999999999999999998
+ 10000009999999999999999999998
N 9999999999999999999999
= 10000019999999999999999999997
+ 10000019999999999999999999997
N 939583949028693904595893945962
+ 949583969028693904595893945959
N 9949395028492956782934958385939
/ 10898978997521650687530852331898
N 39560386930286930498376983968375
= 0
15
C 0
N 28285828472854892754728478568323
- 28285828472854892754728478568323
N 28285828472854892754728478568323
= 0
+ 0
N 14362352580688212207152021252245
/ 14362352580688212207152021252245
N 492958729386930228493290587
= 29135
C 0
N 48289567434167997493876823785837
/ 48289567434167997493876823785837
N 4829439687385538294392834728
= 9999