2010年华为上机笔试二(高精度整数加法)
2012-10-05 09:59
369 查看
题目描述:高精度整数加法(计算机中整数的表示长度有限)
要求实现函数:
void add (const char *num1, const char *num2, char *result)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位'-'
【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。
注:
I、 当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
II、 输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
III、 要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
示例
输入:num1 = "580"
num2 = "-50"
输出:result = "530"
程序代码如下:
#include <iostream>
using namespace std;
//反转字符串,便于从低位开始运算
void reverse(char *num)
{
int len=strlen(num);
int mid=len/2;
for (int i=0; i<mid; i++)
{
num[i]^=num[len-i-1];
num[len-i-1]^=num[i];
num[i]^=num[len-i-1];
}
}
//两个正整数相加
void add_num(const char *num1, const char *num2, char *result)
{
int i;
int len1=strlen(num1);
int len2=strlen(num2);
int maxlen=(len1>len2?len1:len2);
char *num1_copy=(char*)malloc(maxlen+1);
char *num2_copy=(char*)malloc(maxlen+1);
strcpy(num1_copy,num1);
strcpy(num2_copy,num2);
reverse(num1_copy);
reverse(num2_copy);
for (i=len1; i<maxlen; i++)
{
num1_copy[i]='0';
}
num1_copy[maxlen]='\0';
for (i=len2; i<maxlen; i++)
{
num2_copy[i]='0';
}
num2_copy[maxlen]='\0';
result[0]=0; //标志是否有进位,没有为0.
for (i=0; i<maxlen; i++)
{
int addNum=result[i]+(num1_copy[i]-'0')+(num2_copy[i]-'0');
result[i]=addNum+'0';
result[i+1]=addNum/10; //进位
}
if (result[maxlen]!=0) //如果最后一位相加产生进位
{
result[maxlen]=result[maxlen]+'0';
result[maxlen+1]='\0';
}
else
{
result[maxlen]='\0';
}
reverse(result);
free(num1_copy);
free(num2_copy);
}
//计算两个正整数相减
void minus_num(const char *num1, const char *num2, char *result)
{
int i;
int len1=strlen(num1);
int len2=strlen(num2);
int maxlen=len1;
char *num1_copy=(char*)malloc(maxlen+1);
char *num2_copy=(char*)malloc(maxlen+1);
strcpy(num1_copy,num1);
strcpy(num2_copy,num2);
reverse(num1_copy);
reverse(num2_copy);
for (i=len2; i<maxlen; i++)
{
num2_copy[i]='0';
}
num2_copy[maxlen]='\0';
int borrow=0; //借位标识符
for (i=0; i<maxlen; i++)
{
int minusNum;
if (borrow) //如果有借位
{
if (num1_copy[i]=='0')
{
minusNum=9-(num2_copy[i]-'0');
result[i]=minusNum+'0';
borrow=1;
}
else
{
minusNum=(num1_copy[i]-'0')-1-(num2_copy[i]-'0');
if (minusNum<0)
{
result[i]=10+minusNum+'0';
borrow=1;
}
else
{
result[i]=minusNum+'0';
borrow=0;
}
}
}
else
{
minusNum=(num1_copy[i]-'0')-(num2_copy[i]-'0');
if (minusNum<0)
{
result[i]=10+minusNum+'0';
borrow=1;
}
else
{
result[i]=minusNum+'0';
borrow=0;
}
}
}
result[maxlen] = '\0';
i = maxlen - 1;
while (result[i] == '0') {
result[i] = '\0';
i--;
}
reverse(result);
free(num1_copy);
free(num2_copy);
}
//判断正数与负数的大小,并根据它们的大小关系确定相加结果的符号,以及调用减法函数。
void postive_add_negtive(const char *positive_num, const char *negtive_num, char *result, int *positive)
{
int len1=strlen(positive_num);
int len2=strlen(negtive_num);
if (len1>len2) //如果正数的长度大于负数的长度,则结果一定为正;调用函数,用正数减去负数的绝对值
{
minus_num(positive_num,negtive_num,result);
*positive=1;
}
else if(len1==len2) //如果两个数的长度相等
{
if (strcmp(positive_num,negtive_num)>0) //正数大于负数的绝对值
{
minus_num(positive_num,negtive_num,result);
*positive=1;
}else if (strcmp(positive_num,negtive_num)==0) //正数等于负数的绝对值
{
result[0]='0';
result[1]='\0';
*positive=1;
}else//正数小于负数的绝对值,这个时候要用负数的绝对值减去正数
{
minus_num(negtive_num,positive_num,result);
*positive=0;
}
}
else//负数的长度大于正数的长度
{
minus_num(negtive_num,positive_num,result);
*positive=0;
}
}
//两个整数(包括正整数和负整数)相加
void add(const char *num1, const char *num2, char *result)
{
int num1_len = strlen(num1);
int num2_len = strlen(num2);
int max_len = (num1_len >= num2_len ? num1_len : num2_len);
char *positive_result = (char *)malloc(max_len + 2);
int positive;
if (num1[0]!='-'&&num2[0]!='-') //如果都是正数
{
add_num(num1,num2,positive_result);
positive=1;
}else if (num1[0]!='-'&&num2[0]=='-') //一正一负
{
postive_add_negtive(num1,num2+1,positive_result,&positive);
}else if (num1[0]=='-'&&num2[0]!='-') //一正一负
{
postive_add_negtive(num2,num1+1,positive_result,&positive);
}else if (num1[0]=='-'&&num2[0]=='-') //都是负数
{
add(num1+1,num2+1,positive_result);
positive=0;
}
if (!positive) //如果是负数,在结果前加上‘-’号
sprintf(result, "-%s", positive_result);
else
sprintf(result, "%s", positive_result);
free(positive_result);
}
//经main函数测试,结果正确
int main()
{
char num1[]="123456789987654321";
char num2[]="-8765423198726514289367";
char result[40];
add(num1,num2,result);
cout<<result<<endl;
return 0;
}
要求实现函数:
void add (const char *num1, const char *num2, char *result)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位'-'
【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。
注:
I、 当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
II、 输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
III、 要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
示例
输入:num1 = "580"
num2 = "-50"
输出:result = "530"
程序代码如下:
#include <iostream>
using namespace std;
//反转字符串,便于从低位开始运算
void reverse(char *num)
{
int len=strlen(num);
int mid=len/2;
for (int i=0; i<mid; i++)
{
num[i]^=num[len-i-1];
num[len-i-1]^=num[i];
num[i]^=num[len-i-1];
}
}
//两个正整数相加
void add_num(const char *num1, const char *num2, char *result)
{
int i;
int len1=strlen(num1);
int len2=strlen(num2);
int maxlen=(len1>len2?len1:len2);
char *num1_copy=(char*)malloc(maxlen+1);
char *num2_copy=(char*)malloc(maxlen+1);
strcpy(num1_copy,num1);
strcpy(num2_copy,num2);
reverse(num1_copy);
reverse(num2_copy);
for (i=len1; i<maxlen; i++)
{
num1_copy[i]='0';
}
num1_copy[maxlen]='\0';
for (i=len2; i<maxlen; i++)
{
num2_copy[i]='0';
}
num2_copy[maxlen]='\0';
result[0]=0; //标志是否有进位,没有为0.
for (i=0; i<maxlen; i++)
{
int addNum=result[i]+(num1_copy[i]-'0')+(num2_copy[i]-'0');
result[i]=addNum+'0';
result[i+1]=addNum/10; //进位
}
if (result[maxlen]!=0) //如果最后一位相加产生进位
{
result[maxlen]=result[maxlen]+'0';
result[maxlen+1]='\0';
}
else
{
result[maxlen]='\0';
}
reverse(result);
free(num1_copy);
free(num2_copy);
}
//计算两个正整数相减
void minus_num(const char *num1, const char *num2, char *result)
{
int i;
int len1=strlen(num1);
int len2=strlen(num2);
int maxlen=len1;
char *num1_copy=(char*)malloc(maxlen+1);
char *num2_copy=(char*)malloc(maxlen+1);
strcpy(num1_copy,num1);
strcpy(num2_copy,num2);
reverse(num1_copy);
reverse(num2_copy);
for (i=len2; i<maxlen; i++)
{
num2_copy[i]='0';
}
num2_copy[maxlen]='\0';
int borrow=0; //借位标识符
for (i=0; i<maxlen; i++)
{
int minusNum;
if (borrow) //如果有借位
{
if (num1_copy[i]=='0')
{
minusNum=9-(num2_copy[i]-'0');
result[i]=minusNum+'0';
borrow=1;
}
else
{
minusNum=(num1_copy[i]-'0')-1-(num2_copy[i]-'0');
if (minusNum<0)
{
result[i]=10+minusNum+'0';
borrow=1;
}
else
{
result[i]=minusNum+'0';
borrow=0;
}
}
}
else
{
minusNum=(num1_copy[i]-'0')-(num2_copy[i]-'0');
if (minusNum<0)
{
result[i]=10+minusNum+'0';
borrow=1;
}
else
{
result[i]=minusNum+'0';
borrow=0;
}
}
}
result[maxlen] = '\0';
i = maxlen - 1;
while (result[i] == '0') {
result[i] = '\0';
i--;
}
reverse(result);
free(num1_copy);
free(num2_copy);
}
//判断正数与负数的大小,并根据它们的大小关系确定相加结果的符号,以及调用减法函数。
void postive_add_negtive(const char *positive_num, const char *negtive_num, char *result, int *positive)
{
int len1=strlen(positive_num);
int len2=strlen(negtive_num);
if (len1>len2) //如果正数的长度大于负数的长度,则结果一定为正;调用函数,用正数减去负数的绝对值
{
minus_num(positive_num,negtive_num,result);
*positive=1;
}
else if(len1==len2) //如果两个数的长度相等
{
if (strcmp(positive_num,negtive_num)>0) //正数大于负数的绝对值
{
minus_num(positive_num,negtive_num,result);
*positive=1;
}else if (strcmp(positive_num,negtive_num)==0) //正数等于负数的绝对值
{
result[0]='0';
result[1]='\0';
*positive=1;
}else//正数小于负数的绝对值,这个时候要用负数的绝对值减去正数
{
minus_num(negtive_num,positive_num,result);
*positive=0;
}
}
else//负数的长度大于正数的长度
{
minus_num(negtive_num,positive_num,result);
*positive=0;
}
}
//两个整数(包括正整数和负整数)相加
void add(const char *num1, const char *num2, char *result)
{
int num1_len = strlen(num1);
int num2_len = strlen(num2);
int max_len = (num1_len >= num2_len ? num1_len : num2_len);
char *positive_result = (char *)malloc(max_len + 2);
int positive;
if (num1[0]!='-'&&num2[0]!='-') //如果都是正数
{
add_num(num1,num2,positive_result);
positive=1;
}else if (num1[0]!='-'&&num2[0]=='-') //一正一负
{
postive_add_negtive(num1,num2+1,positive_result,&positive);
}else if (num1[0]=='-'&&num2[0]!='-') //一正一负
{
postive_add_negtive(num2,num1+1,positive_result,&positive);
}else if (num1[0]=='-'&&num2[0]=='-') //都是负数
{
add(num1+1,num2+1,positive_result);
positive=0;
}
if (!positive) //如果是负数,在结果前加上‘-’号
sprintf(result, "-%s", positive_result);
else
sprintf(result, "%s", positive_result);
free(positive_result);
}
//经main函数测试,结果正确
int main()
{
char num1[]="123456789987654321";
char num2[]="-8765423198726514289367";
char result[40];
add(num1,num2,result);
cout<<result<<endl;
return 0;
}
相关文章推荐
- 华为上机题:高精度整数加法
- 华为OJ(高精度整数加法)
- 华为机试在线训练-牛客网(27)无线OSS-高精度整数加法
- 【华为OJ】【039-无线OSS-高精度整数加法】
- 华为机试:无线OSS-高精度整数加法、矩阵乘法计算量估算
- 华为OJ------高精度整数加法
- 华为2013校园招聘上机笔试题-整数转换成字符串
- 华为上机-要求编程实现上述高精度的十进制加法。要求实现函数: void add (const char *num1, const char *num2, char *result)
- 华为OJ——无线OSS-高精度整数加法
- 【华为机试】无线OSS-高精度整数加法
- 华为OJ——无线OSS-高精度整数加法
- 华为2013校园招聘上机笔试题-计算整数二进制表达式中0的个数
- 2016华为校招上机笔试练习题1
- 高精度 大整数加法
- 2014 8月华为软件类上机笔试
- 华为2011上机笔试题1+参考程序
- 2014年实习生招聘之华为实习生招聘笔试题(上机完成)—2014/04/02
- 华为2011上机笔试题1+参考程序
- 高精度大整数加法
- 面团点评笔试:整数加法