#16182: C版本,參考


freedom501999@gmail.com (帥氣魔方生)

學校 : 不指定學校
編號 : 88611
來源 : [39.8.203.54]
最後登入時間 :
2019-05-30 22:56:25
a021. 大數運算 | From: [27.52.77.116] | 發表日期 : 2018-12-03 22:00

#include <stdio.h>
#include <string.h>
void bignum_Reverse(char a[])  /*倒轉儲存大數*/
{
   int len, i, temp;
   for(i=0; i<500 ; i++)
   {
      if(a[i]=='\0') break;
      a[i]=a[i]-'0';
   }
   len=i;
   a[len]=0;
   for(i=0; i<len ; i++)
   {
      if(i>= len/2) break;
      temp=a[i];
      a[i]=a[len-1-i];
      a[len-1-i]=temp;
   }
}

void bignum_print(int a[])  /*印大數*/
{
   int i, head;
   for(i=499;i>=0;i--)
      if(a[i]!=0) break;
   head=i;
   if(a[head]=='-')   /*小減大有負號*/
   {
      printf("-");
      head--;
   }
   if (head!= -1)   
   {
      for(i=head;i>=0;i--)
         printf("%d", a[i]);
   }
   else printf("0");   /* 相減或相除答案可能是0*/
}

void PLUS(char a[], char b[], int c[])
{
   int i, count=0;
   for(i=0;i<500;i++)
   {
      c[i]=a[i]+b[i]+count;
      if(c[i]>=10)
      {
         c[i]-= 10;
         count=1;
      }
      else count=0;
   }
}

int WhoIsBigger(char a[], char b[]) /* a 比 b 小,傳回 0 其餘傳回 1*/
{
   int i, lenA, lenB;
   for (i=499; i>=0 ;i--)
      if(a[i]!=0) break;
   lenA=i;
   for (i=499; i>=0 ;i--)
      if(b[i]!=0) break;
   lenB=i;
   if (lenA>lenB) return 1;
   else if (lenA<lenB) return 0;
   else
   {
      while (lenA>=0 && lenB>=0)
      {
         if(a[lenA]>b[lenB]) return 1;
         else if (a[lenA]<b[lenB]) return 0;
         else
         {
            lenA--;
            lenB--;
         }
      }
      return 1;
   }
}

void MINUS(char a[], char b[], int c[])
{
   int i, count=0;
   if (WhoIsBigger(a, b))
   {
      for(i=0;i<500;i++)
      {
         c[i]=a[i]-b[i]-count;
         if(c[i]<0)
         {
            c[i]+= 10;
            count=1;
         }
         else count=0;
      }
   }
   else
   {
      for(i=0;i<500;i++)
      {
         c[i]=b[i]-a[i]-count;
         if(c[i]<0)
         {
            c[i]+= 10;
            count=1;
         }
         else count=0;

      }
      for(i=499;i>=0;i--)
         if(c[i]!=0) break;
            c[i+1]='-';
   }
}

void MULTIP(char a[], char b[], int c[])
{
   int i, j;
   for(i=0;i<500;i++)
   {
      if(a[i]==0) continue;
      for(j=0;i+j<500;j++)
         c[i+j]+= a[i]*b[j];
   }
   for(i=0;i<500-1;i++)
   if(c[i]>=10)
   {
      c[i+1]+= c[i]/10;
      c[i]%=10;
   }
}
int div(char a[], char b[], int val)   /*算商用的,val 即為商*/
{
   int i, c[500]={0};
   if(WhoIsBigger(a,b))
   {
      MINUS(a,b,c);
      for(i=0;i<500;i++)
         a[i]=c[i];
      return div(a,b,val+1);
   }
   else return val;
}

void DIVIDE(char a[], char b[], int c[])
{
   int i, j, lenA, lenB, time10;
   if (!WhoIsBigger(a, b)) c[0]=0; /* a 小於 b 答案是 0*/
   else if (!strcmp(a,b)) c[0]=1; /* a 等於 b 答案是 1*/
   else
   {
      for (i=499; i>=0 ;i--)    /* 算長度 */
         if(a[i]!=0) break;
      lenA=i;
      for (i=499; i>=0 ;i--)
         if(b[i]!=0) break;
      lenB=i;
      j=0;
      time10=lenA-lenB;     /* 長度差做為乘以十的次數 */
      while (lenB-j>=0 && time10>0)   /*把除數變成與被除數相同長度*/
      {
         b[lenA-j]=b[lenB-j];
         b[lenB-j]=0;
         j++;
      }
      c[0]= div(a,b,0);      /*算第一個商*/
      j=1;
      while (time10>0)    /*之後除數每除以十算一次商*/
      {
         for(i=0;i<500-1;i++)
            b[i]=b[i+1];
         c[j]=div(a,b,0);
         j++;
         time10--;
      }

      for (i=499; i>=0 ;i--)   /*因為要符合大數儲存規則,字串要倒轉*/
         if(c[i]!=0) break;
      lenA=i;
      for(i=0;i<(lenA+1)/2;i++)
      {
         j=c[i];
         c[i]=c[lenA-i];
         c[lenA-i]=j;
      }
   }
}

int main(void)
{
   char sym;
   char BIGa[500]={0}, BIGb[500]={0};
   int bigAnswer[500]={0};
   while(scanf("%s %c %s", BIGa, &sym, BIGb)!=EOF)
   {
      memset(bigAnswer,0,sizeof(int)*500);
      bignum_Reverse(BIGa);
      bignum_Reverse(BIGb);
      switch(sym)
      {
         case '+':
               PLUS(BIGa, BIGb, bigAnswer);
               break;
         case '-':
               MINUS(BIGa, BIGb, bigAnswer);
               break;
         case '*':
               MULTIP(BIGa, BIGb, bigAnswer);
               break;
         case '/':
               DIVIDE(BIGa, BIGb, bigAnswer);
               break;
      }
      bignum_print(bigAnswer);
      printf("\n");
      memset(BIGa,0,500);
      memset(BIGb,0,500);
   }
   return 0;
}

 
#16445: Re:C版本,參考


freedom501999@gmail.com (帥氣魔方生)

學校 : 不指定學校
編號 : 88611
來源 : [39.8.203.54]
最後登入時間 :
2019-05-30 22:56:25
a021. 大數運算 | From: [27.52.77.116] | 發表日期 : 2019-01-02 00:04

 

void DIVIDE(char a[], char b[], int c[])
{
   int i, j, lenA, lenB, time10;
   if (!WhoIsBigger(a, b)) c[0]=0; /* a 小於 b 答案是 0*/
   else if (!strcmp(a,b)) c[0]=1; /* a 等於 b 答案是 1*/
   else
   {
      for (i=499; i>=0 ;i--)    /* 算長度 */
         if(a[i]!=0) break;
      lenA=i;
      for (i=499; i>=0 ;i--)
         if(b[i]!=0) break;
      lenB=i;
      j=0;
      time10=lenA-lenB;     /* 長度差做為乘以十的次數 */
      while (lenB-j>=0 && time10>0)   /*把除數變成與被除數相同長度*/
      {
         b[lenA-j]=b[lenB-j];
         b[lenB-j]=0;
         j++;
      }
      c[0]= div(a,b,0);      /*算第一個商*/
      j=1;
      while (time10>0)    /*之後除數每除以十算一次商*/
      {
         for(i=0;i<500-1;i++)
            b[i]=b[i+1];
         c[j]=div(a,b,0);
         j++;
         time10--;
      }
      /*因為要符合大數儲存規則,字串要倒轉*/
      for (i=499; i>=0 ;i--) 
         if(c[i]!=0) break;
      lenA=j-1;
      for(i=0;i<(lenA+1)/2;i++)
      {
         j=c[i];
         c[i]=c[lenA-i];
         c[lenA-i]=j;
      }
   }
}

更正部分程式碼,刪除線為要刪除的部分,粗底為修正部分

 
#22165: Re:C版本,參考


407473377 (MilkyCat)

學校 : 桃園市私立新興高級中學
編號 : 120334
來源 : [140.113.89.197]
最後登入時間 :
2023-12-19 14:29:34
a021. 大數運算 | From: [220.133.27.13] | 發表日期 : 2020-08-13 20:52

 

void DIVIDE(char a[], char b[], int c[])
{
   int i, j, lenA, lenB, time10;
   if (!WhoIsBigger(a, b)) c[0]=0; /* a 小於 b 答案是 0*/
   else if (!strcmp(a,b)) c[0]=1; /* a 等於 b 答案是 1*/
   else
   {
      for (i=499; i>=0 ;i--)    /* 算長度 */
         if(a[i]!=0) break;
      lenA=i;
      for (i=499; i>=0 ;i--)
         if(b[i]!=0) break;
      lenB=i;
      j=0;
      time10=lenA-lenB;     /* 長度差做為乘以十的次數 */
      while (lenB-j>=0 && time10>0)   /*把除數變成與被除數相同長度*/
      {
         b[lenA-j]=b[lenB-j];
         b[lenB-j]=0;
         j++;
      }
      c[0]= div(a,b,0);      /*算第一個商*/
      j=1;
      while (time10>0)    /*之後除數每除以十算一次商*/
      {
         for(i=0;i<500-1;i++)
            b[i]=b[i+1];
         c[j]=div(a,b,0);
         j++;
         time10--;
      }
      /*因為要符合大數儲存規則,字串要倒轉*/
      for (i=499; i>=0 ;i--) 
         if(c[i]!=0) break;
      lenA=j-1;
      for(i=0;i<(lenA+1)/2;i++)
      {
         j=c[i];
         c[i]=c[lenA-i];
         c[lenA-i]=j;
      }
   }
}

更正部分程式碼,刪除線為要刪除的部分,粗底為修正部分

這裡用這個會怪(兩個字串被動過了
 else if (!strcmp(a,b)) c[0]=1; /* a 等於 b 答案是 1*/ 

刪掉似乎就不影響

 
ZeroJudge Forum