| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 763 人关注过本帖
标题:代码BUG,找不出是哪里出错了。。求大神指教
取消只看楼主 加入收藏
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
结帖率:84.62%
收藏
已结贴  问题点数:10 回复次数:9 
代码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
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
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
嗯。。进位我已经考虑到了的。就是循环里面,进的位都加到a的下一个元素中了,在下一个循环赋值中就会到c中,在此基础上,你加的循环会有部分是多余的,所以时间复杂度就上来了,我想说的是我的代码应该有一个BUG,但是我找不出,虽然加了你的循环后是对的,但我还是有点不能理解,希望你能帮我找出这个BUG。
c[j] = '\0';  
不过我已经确定这句是多余的了。。
2012-08-17 08:45
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
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
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
所以为了降低时间复杂度,后面的while循环不能要了。。而是改在第二个循环中。。其实你应该早告诉我a[i]是在哪里开始溢出的,因为我找的就是这个溢出点。。不过,多谢啦。。这是我考虑太不全面了
2012-08-17 15:04
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
对了。。为了降低空间复杂度。。我们可以省去第二个循环。。就像你说的重新整理一遍会更好
2012-08-17 15:12
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
程序代码:
#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
               for(; i<LenA; i++)                   // 将多出的部分照抄,下面大体一样
                 c[i] = a[i];
               for(i = 0; c[i] != 0;i++)
                {
                    Ret = c[i]-'0';
                    if(Ret > 9)
                      {
                        c[i] = Ret%10 + '0';
                        c[i+1] += Ret/10;
                      }
                }
            }
         else if(LenA < LenB)
           {
             for(i=0; i<LenA; i++)           //  把b长度以前的数字相加
                 c[i] = a[i] + b[i]-'0';        // 相加后的数字赋给数组c
             for(; i<LenB; i++)                   // 将多出的部分照抄,下面大体一样
                 c[i] = b[i];
             for(i = 0; c[i] != 0;i++)
                {
                    Ret = c[i]-'0';
                    if(Ret > 9)
                      {
                        c[i] = Ret%10 + '0';
                        c[i+1] += Ret/10;
                      }
                }
           }
      else
        {
          for(i=0; i<LenB; i++) 
             c[i] = a[i] + b[i]-'0';
          for(i = 0; c[i] != 0;i++)
                {
                    Ret = c[i]-'0';
                    if(Ret > 9)
                      {
                        c[i] = Ret%10 + '0';
                        c[i+1] += Ret/10;
                      }
                }
        }
     strrev(c);
     printf("case %d:\n",N); 
     printf("%s + %s = %s",A,B,c);
     } 
   getch();
   return 0; 

 }    
现在有个怪问题。。就是只有第一次是错误的。。。同样的数据在第二次测试时N=2时就是对的。。这是什么BUG?
2012-08-17 15:33
chuanglan
Rank: 2
等 级:论坛游民
威 望:2
帖 子:91
专家分:29
注 册:2012-8-14
收藏
得分:0 
嗯。。。我觉得我的代码有点那个。。。因为只有第一次才出错。。如果有什么地方没有考虑完整。。那么第二次及以后都不会正确的。。事实却相反。。
那就看看你的代码为什么是全方面的吧。。
              int j=0;                                    //&&有进位的地方你没有考虑,直接全部赋值到c[]中然后统一考虑.
              while(c[j]!=0)               //因为我的全部成员的值是0,所以以此为终止循环的条件,
              {
                  if(c[j]-'0'>9)        // 这是c[j]需要处理的情况
                  {
                      c[j]=(c[j]-'0')%10 + '0';   //取个位
                      if(c[j+1]==0)      
             //这是当最高位进位的时候要赋值为'1',而不是我想当然的 +1,因为我的原本是0,加1便是笑脸, Soga问题在于这个if语句  ,终于全懂了
                          c[j+1]='1';
                      else
                        c[j+1]+=1;
                  }
                  j++;
              }
2012-08-18 08:55
快速回复:代码BUG,找不出是哪里出错了。。求大神指教
数据加载中...
 
   



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

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