2010年华为上机笔试二(高精度整数加法)

题目描述:高精度整数加法(计算机中整数的表示长度有限)


要求实现函数:
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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值