| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 763 人关注过本帖
标题:代码BUG,找不出是哪里出错了。。求大神指教
只看楼主 加入收藏
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
结帖率:84.62%
收藏
已结贴  问题点数:10 回复次数:14 
代码BUG,找不出是哪里出错了。。求大神指教
程序代码:
#include<stdio.h>
#include<string.h>
int main()

 {
   char a[50]={'\0'},b[50]={'\0'},c[50]={'\0'};    // 为了避免使用元素时没有初值,所以全部赋为0
   char A[50],B[50];
   int i,j,Ret,T,N,LenA,LenB;
   scanf("%d",&T);
      for(N = 1; N <= T; N++)       //    多次测试,总共T次?
        {
           scanf("%s%s",a,b);        //  输入两个数据。、,以字符串的形式
           strcpy(A,a);
           strcpy(B,b);
           strrev(a);
           strrev(b);               //  将两个字符创倒置,方便计算
           printf("%-20s\n",a);
           printf("%-20s\n",b);
           LenA = strlen(a);
           LenB = strlen(b);         // 求出a,b的长度
           if(LenA > LenB)              //   如果a比b长
             {
               for(i=0; i<LenB; i++)           //  把b长度以前的数字相加
                 {
                   c[i] = a[i] + b[i]-'0';        // 相加后的数字赋给数组c
                   Ret = c[i]-'0';
                   if(Ret >= 10)                  //看c[i]是否超过10
                     {
                       c[i] = (c[i]-'0')%10 + '0';  //   将c[i]取个位数字
                       a[i+1] = a[i+1] + Ret/10;    //    将超过十的数字加到后面高位上
                     }
                  }
              for(; i<LenA; i++)                   // 将多出的部分照抄,下面大体一样
                c[i] = a[i];
              c[i] = '\0';
            }
         else if(LenA < LenB)
           {
             for(i=0; i<LenA; i++)
               {
                 c[i] = a[i] + b[i]-'0';
                 Ret = c[i]-'0';
                 if(Ret >= 10)
                  {
                    c[i] = (c[i]-'0')%10+'0';
                    b[i+1] += Ret/10;
                  }
               }
            for(; i<LenB; i++)
               c[i] = b[i];
            c[i] = '\0';     
          }
      else
        {
          for(i=0; i<LenB; i++) 
           {
             c[i] = a[i] + b[i]-'0';
             Ret = c[i]-'0';
             if(Ret >= 10)
              {
                c[i] = (c[i]-'0')%10+'0';
                b[i+1] += Ret/10;
              }  
           }
         if(Ret>=10)
           c[i] = b[i];
         c[i+1] = '\0';
        }  
     strrev(c);
     printf("case %d:\n",N); 
     printf("%s + %s = %s",A,B,c);
     } 
   return 0; 

 }    
问题是,9900加100得不到10000,而是出现  :000,这是OJ  http://acm.hdu.
2012-08-16 11:24
obstratiker
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:198
专家分:758
注 册:2011-5-5
收藏
得分:10 
你还有进位的情况没有考虑,a[]+1的时候可能会>9,由此赋值到c[]时,就是乱码了,给你改了lenA>lenB的情况,剩下的都一样。
程序代码:
#include<stdio.h>
#include<string.h>
int main()
{
   char a[50]={'\0'},b[50]={'\0'},c[50]={'\0'};    // 为了避免使用元素时没有初值,所以全部赋为0
   char A[50],B[50];
   int i,j,Ret,T,N,LenA,LenB;
   scanf("%d",&T);
      for(N = 1; N <= T; N++)       //    多次测试,总共T次?
        {
           scanf("%s%s",a,b);        //  输入两个数据。、,以字符串的形式
           strcpy(A,a);
           strcpy(B,b);
           strrev(a);
           strrev(b);               //  将两个字符创倒置,方便计算
           printf("%-20s\n",a);
           printf("%-20s\n",b);
           LenA = strlen(a);
           LenB = strlen(b);         // 求出a,b的长度
           if(LenA > LenB)              //   如果a比b长
             {
               for(i=0; i<LenB; i++)           //  把b长度以前的数字相加
                 {
                   c[i] = a[i] + b[i]-'0';        // 相加后的数字赋给数组c
                   Ret = c[i]-'0';
                   if(Ret >= 10)                  //看c[i]是否超过10
                     {
                       c[i] = (c[i]-'0')%10 + '0';  //   将c[i]取个位数字
                       a[i+1] = a[i+1] + Ret/10;    //    将超过十的数字加到后面高位上
                   }
                 }
              for(; i<LenA; i++)                   // 将多出的部分照抄,下面大体一样
                c[i] = a[i];
              int j=0;                                    //&&有进位的地方你没有考虑,直接全部赋值到c[]中然后统一考虑.
              while(c[j]!=0)
              {
                  if(c[j]-'0'>9)
                  {
                      c[j]=(c[j]-'0')%10 + '0';
                      if(c[j+1]==0)
                          c[j+1]='1';
                      else
                        c[j+1]+=1;
                  }
                  j++;
              }
              c[j] = '\0';                                //&&
           }
         else if(LenA < LenB)
           {
             for(i=0; i<LenA; i++)
               {
                 c[i] = a[i] + b[i]-'0';
                 Ret = c[i]-'0';
                 if(Ret >= 10)
                  {
                    c[i] = (c[i]-'0')%10+'0';
                    b[i+1] += Ret/10;
                  }
               }
            for(; i<LenB; i++)
               c[i] = b[i];
            c[i] = '\0';    
          }
      else
        {
          for(i=0; i<LenB; i++)
           {
             c[i] = a[i] + b[i]-'0';
             Ret = c[i]-'0';
             if(Ret >= 10)
              {
                c[i] = (c[i]-'0')%10+'0';
                b[i+1] += Ret/10;
              } 
           }
         if(Ret>=10)
           c[i] = b[i];
         c[i+1] = '\0';
        } 
     strrev(c);
     printf("case %d:\n",N);
     printf("%s + %s = %s",A,B,c);
     }
   return 0;
}   

 
2012-08-16 13:22
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
嗯。。又学到一招。。谢谢
2012-08-16 17:57
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
回复 2楼 obstratiker
不过我有点不懂诶。。。为什么我前面有进位的部分,但是没起作用,这是什么原因,你只是在后面补上了这段进位的代码。。却对了。。而且这样的话,时间复杂度就要高许多了。。能加扣扣细聊吗?994564686
2012-08-16 21:05
obstratiker
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:198
专家分:758
注 册:2011-5-5
收藏
得分:0 
回复 4楼 chuanglan
是这里,
程序代码:
                   Ret = c[i]-'0';
                   if(Ret >= 10)                  //看c[i]是否超过10
                     {
                       c[i] = (c[i]-'0')%10 + '0';  //   将c[i]取个位数字
                       a[i+1] = a[i+1] + Ret/10;    //    将超过十的数字加到后面高位上
                     }
如果a[i+1]原来就是'9'的话,你再a[i+1] = a[i+1] + Ret/10;就“爆”了
你必须考虑a[]中的进位,所以我在后面补了一段。
时间复杂度还行吧,就是原来时间 + O(len(max(A,B)))咯
2012-08-16 22:13
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
嗯。。进位我已经考虑到了的。就是循环里面,进的位都加到a的下一个元素中了,在下一个循环赋值中就会到c中,在此基础上,你加的循环会有部分是多余的,所以时间复杂度就上来了,我想说的是我的代码应该有一个BUG,但是我找不出,虽然加了你的循环后是对的,但我还是有点不能理解,希望你能帮我找出这个BUG。
c[j] = '\0';  
不过我已经确定这句是多余的了。。
2012-08-17 08:45
obstratiker
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:198
专家分:758
注 册:2011-5-5
收藏
得分:0 
回复 6楼 chuanglan
你的bug就是“如果a[i+1]原来就是'9'的话,你再a[i+1] = a[i+1] + Ret/10;a[i+1]中的值就溢出了啊”。
嗯,c[j]确实是多余的。
我加的循环在有些情况下会多余,有些情况下不是,比如你输入 9999 111
从第一次进位开始,a[1]之后的值都溢出了,b[]却没有加完,所以并不是b[]全部加完了之后才用整理溢出,你不知道a[]中哪些值会溢出,溢出多少
所以直接从头整理一次比较好,位数也不多,哪怕是100位的数字,从头过一遍不就和 f(i=0;i<100;i++)的循环在一个数量级么
2012-08-17 10:25
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
“如果a[i+1]原来就是'9'的话,你再a[i+1] = a[i+1] + Ret/10;a[i+1]中的值就溢出了啊”。
这句我不理解。。溢出指什么?我是这样处理的,如果a[i+1]原来等于'9',那么a[i+1] = a[i+1] + Ret/10后就会增加ASC码值Ret/10,即进的位值,也就是说a[i+1]不在数字字符区了。。但是这并不影响c[i] = a[i] + b[i]-'0';这个过程,因为我进的位已经加到a[i+1]中了,所以如果Ret为14,那么a[i+1]的ASC码值就会加1,相当于进一位,所以不必再用循环来处理c[i]了。。但是就是不行,所以我卡在这个地方了。。想不明白
2012-08-17 13:23
obstratiker
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:198
专家分:758
注 册:2011-5-5
收藏
得分:0 
回复 8楼 chuanglan
我指的就是不在0-9的字符区,你看看 999+11 的例子
第一位加进去后,c[0]是0,但是进位a[1]就是'9'+1了,然后c[1]还要再加上1,就是'9'+2,不是一个数字的字符码
之后由于你的进位设置,a[1]和c[1]之后的值都会超出数字的字符区。
所以你必须从头整理一遍。
……调试一下你就知道啦
2012-08-17 14:08
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
抱歉,还是没懂,其实问题出在这个循环
程序代码:
for(i=0; i<LenB; i++)           //  把b长度以前的数字相加,这句暂且不是重点
   {
      c[i] = a[i] + b[i]-'0';       // 原本是这样的 c[i] = a[i]-'0' + b[i]-'0'+ '0';就是求得c[i]比'0'多出的ASC值
                                    //  这里先假设a[i]='9', b[i]='9',则c[i] = '0' + 18; 
      Ret = c[i]-'0';           //这里只是判断c[i]是否在数字字符区,Ret = 18
   if(Ret >= 10)                  // 如果超出数字区      
      {
         c[i] = (c[i]-'0')%10 + '0';  //   将c[i]重新赋值为 '0' + 8 ,让它取超过的个位数字
         a[i+1] = a[i+1] + Ret/10;    //    将要进的位值加到下一次c[i]的计算中,即a[i+1]在原来的基础上要进一位   
      }
   }
所以假设现在是999 + 11
999
11
c[0] = '0',a[1] = '0' + 10,
c[1] = '1',a[2] = '0' + 10,
此时第一轮循环结束了
然后第二个循环开始
   哦!!!终于发现了。BUG出现在第二轮循环,因为之后的a[i]值如果是'9'的话我原本的代买没有执行进位了,所一只有b长度前的执行了进位,功夫不负有心人
2012-08-17 15:02
快速回复:代码BUG,找不出是哪里出错了。。求大神指教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.046171 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved