A-B


Boj上的A-B题目:

首先,看到这个题,应该觉察到是一个大数运算的问题,如果是实际开发,对性能没什么要求,无需自己写,因为java等语言里已经能够支持大数运算。

其次,据说十年前的大牛的补码解决方案就已经完美解决了这个问题。但我还是只能按照普通的逻辑来做,需要注意的有以下几点:

1.用无符号字符数组存储大数。

2.对输入判断做加法还是做减法。

3. 加法,对应位置字符直接减字符0转换为整数后相加,全部相加后,循环将大于10的-10,其前面的数加一(即进位),最后一个数不用检查,直接输出即可。

4. 减法,一种是借一位(即上一位——大于零——够借,则直接本位字符加上char(10),上一位减去char(1)。若不够借——等于零——则加上char(9)继续向上借,直到借到,将哪一位减去 char(1)。

               测试用例:

-1 , 100; 

1 , 1100; 

0 ,0;

-999,-999

9999999999999,-999999999999999999999999

个人代码留作以后修改。

#include <stdio.h>

int compare(char * , char *);
void print(int *, int);
void rectify(char *);
int*  minus(char * , char * );
int * add(char * , char *);
int main()
{
  unsigned char a[105];
  unsigned char b[105];
  int  *result;

  
  char calSign =  '-';
  char resSign = '+';
  scanf("%s%s",a ,b);
  //a 为负,b为正
  if( a[0] == '-' && b[0] != '-' )
  {
    int i = 0;
    for( i = 0; i < strlen(a);i++ )
    {
      a[i] = a[i+1];
    }
    calSign = '+';
    resSign = '-';
  }
  //a为正b为负
  if( a[0] != '-' && b[0] == '-')
  {
    int i = 0;
    for( i = 0; i < strlen(b); i++ )
    {
      b[i] = b[i+1];
    }
    calSign = '+';
    resSign = '+';
  }
  //a为负b为负
  if( a[0] == '-' && b[0] == '-')
  {
    int i = 0;
    for( i = 0; i < strlen(a); i++ )
    {
      a[i] = a[i+1];
    }
    for( i = 0; i < strlen(b);i++ )
      b[i] = b[i+1];
    
    calSign = '-';
    resSign = '-';
  }
  rectify(a);
  rectify(b);
  if( calSign == '+' )
  {
    //int res = 0;
    if( strlen(a) > strlen(b) )
    {
       
      result = add(a ,b );
      if( resSign == '-' )
	printf("%c", resSign);
      int n;
      for(n = 0;n< strlen(a);n++)
      {
	printf("%d",result[n]);
      }
    }
    else
    {
      result =  add(b , a);
      if( resSign == '-' )
	printf("%c", resSign);
      int n ;
      for(n=0 ;n< strlen(b);n++)
      {
	printf("%d",result[n]);
      }
    }  
    // printf("\n");
  }
  else if( calSign == '-')
  {
    int com = compare(a ,b);
    if( com > 0 )
    {
      result =  minus(a , b);
      int i = 0;
      if( resSign == '-' )
	printf("%c" , resSign);
      print(result, strlen(a));
    }
    else if( com == 0 )
    {
      printf("%d", 0 );
    }
    else if( com < 0 )
    {
       result =  minus(b,a);
       int i = 0;
       if( resSign == '-' )
	 resSign = '+';
       else
	 resSign = '-';
       if( resSign == '-')
	 printf("%c",resSign);
       print(result, strlen(b));
    }
  }
  printf("\n");
  // printf("%d\n", a);
  // printf("%s\t%s\n",a,b);
  // printf("%d\n",strlen(a));
  // printf("%d\n",sizeof(a));
  return 0;
}

void rectify(char * rec)
{
  int sign = 0;
  int i;
  for(i = 0; i < strlen(rec);i++)
  {
    if( rec[i] == '0' )
      sign++;
    else
      break;
  }
  //printf("%d",sign);
  if( sign != 0 )
  {
    if( sign == strlen(rec) )
    {
      rec[1]='\0';
    }
    else 
    {
      for( i = 0;(i+sign) <= strlen(rec);i++ )
      {
	rec[i] = rec[i + sign];
      }
      // rec[strlen(rec)-sign]= '\0';
    }
  }
}
void print(int * result ,int n)
{
      int yes = 0;
      int i;
      for(i = 0 ; i < n; i++ )
      {
	if( yes == 0 )
	{
	  if( result[i] == 0 )
	    continue;
	  else
	  {
	    yes = 1;
	    printf("%d", result[i]);
          }
	}
	else
	  printf("%d",result[i]);
      }
}
int compare(char * x, char * y)
{
  if( strlen(x) != strlen(y))
    return strlen(x) > strlen(y)?1:-1;
  return strcmp( x , y );
}



int * minus(char * big, char *small)
{
  int * result = malloc(sizeof(int)* (strlen(big)+1)) ;
  int i = strlen(big)-1;
  int j = strlen(small)-1;
  for( ;i >=0;i-- )
  {
    if( big[i] >= small[j])
    {
      // printf("%c",big[i]);
      result[i] = big[i]-small[j];
    }
    else
    {
      
      big[i] = big[i]+ (char)10;
      int k = i-1;
      for(; k >=0;k--)
      {
	if( big[k] < '1' )
	{
	  big[k] += (char)9;
	}
	else
	{
	  big[k] -=(char)1;
	  break;
	}
      }
      result[i] = big[i]-small[j];
    }
    j--;
    if( j < 0 && i > 0 )
    {
      int k = i-1;
      for( ;k >=0; k-- )
      {
	result[k]= (int)(big[k] - '0'); 
      }
      break;
    }
  }
  return result;
}

int*  add(char* a, char *b )
{
  int i = strlen(a) - 1;
  int j = strlen(b) - 1;
  int * result = malloc(sizeof(int) * (strlen(a)+ 1));
  for( ; i >= 0; i-- )
  {
    result[i] = (int)( (int)(a[i]- '0') + (int)( b[j] - '0' ));
    // printf("%d",result[i]);
    j--;
    if( j < 0 && i > 0 )
    {
      int k = i-1;
      for( ;k>= 0; k-- )
	result[k]= (int)(a[k] - '0');
      break;
    }
  }
  
  int x = strlen(a) - 1;
  int temp = 1;
  int res = 0;
  for( ;x >0; x-- )
  {
    if( result[x] >= 10 )
    {
      result[x] -= 10;
      result[x-1] += 1;
    }
  }
  return result;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值