【问题标题】:Why is the answer submitted wrong为什么提交的答案错误
【发布时间】:2022-01-20 10:12:53
【问题描述】:
#include<stdio.h>
void f(char *s[],int n)
{
    int i=0;
    int j=0;
    int x=0;
    int k=i;
     
       for (x=0;x<n-1;x++)
        {
            for(j=0;j<n-1;j++)
                {
                if(*(*(s+j)+i)>*(*(s+j+1)+i))
                   {
                    char *temp;
                    temp=*(s+j);
                    *(s+j)=*(s+j+1);
                    *(s+j+1)=temp;
                     }
                else
                    if(*(*(s+j)+i)==*(*(s+j+1)+i))
                    {
                      for(k=1;k<n-1;k++)
                      {
                          if(*(*(s+j)+k)>*(*(s+j+1)+k))
                       {
                          {
                              char *temp;
                              temp=*(s+j);
                              *(s+j)=*(s+j+1);
                              *(s+j+1)=temp;
                              break;
                          }
                       }
                      }
                    }
                }
        }
}
int main()
{
    int n=0;
    char * str[100];
    char a[100][100];
    while(n<=100&&gets(a[n])!=NULL)
    {
        str[n]=a[n];
        n++;
     }
    f(str,n);
    int i=0;
     for(i=0;i<n;i++)
    {
        puts(str[i]);
    }
    return 0;
}

这就是这段代码的问题:向字符串数组输入多个英文单词,按字母顺序从小到大输出,不能使用strcmp。

样本输入: 一个
两个

四个

示例输出: 四
一个

两个

我的问题: 这段代码有什么问题

【问题讨论】:

  • 代码太糟糕了。
  • 输出似乎是正确的(按字母顺序)。
  • 请尝试使用更有意义的变量名,以便读者能够理解您的代码。另外,你的意思是按升序排列字符串,因为你问的问题有点不清楚吗?如果是这样,只需使用 strcmp 来获取字符串的顺序并使用任何正常的排序算法
  • 人们不喜欢这段代码的主要原因是无意义的重定向和指针运算。不要写像*(*(s+j)+i)这样不可读的东西,写s[i][j]。也不要使用gets,因为它已经过时了几十年,终于在十年前从 C 语言中删除了。
  • 编程不是一个智力难题,你试图让一个程序使用最少或最聪明的字符集工作,让编译器做你想让它做的事情。编程是通信,因此程序必须可读其他人。 (当然,它还必须让编译器执行您希望它执行的操作。)为什么将您的函数命名为f()sort() 会更清晰?既然s[j] 会更清晰,为什么还要写*(s+j) 这样的东西?

标签: c sorting c-strings bubble-sort function-definition


【解决方案1】:

首先,在使用它们的最小范围内声明变量。那是代替这段代码sn-p

int i=0;
int j=0;
int x=0;
int k=i;
 
   for (x=0;x<n-1;x++)
   //...

你可以写

   for ( int x=0;x<n-1;x++)

否则代码很难阅读。比如这个初始化

int k=i;

对于代码的读者来说什么也没说,因为变量 k 在这个 for 循环中被覆盖了

for(k=1;k<n-1;k++)

当第一个字符相等时,您不需要分开比较字符串的第一个字符和字符串的下一个字符。这种分离再次使代码的读者感到困惑。相反,您可以使用标准函数strcmp 来比较两个字符串。

这个for循环

                  for(k=1;k<n-1;k++)
                  {
                      if(*(*(s+j)+k)>*(*(s+j+1)+k))
                   {
                      {
                          char *temp;
                          temp=*(s+j);
                          *(s+j)=*(s+j+1);
                          *(s+j+1)=temp;
                          break;
                      }
                   }
                  }

可以调用未定义的行为,因为比较字符串的长度可能远小于表达式 n-1 的值。

用while循环代替for循环更好

  k = 1;
  while ( *(*(s+j)+k) != '\0' && !( *(*(s+j)+k) > *(*(s+j+1)+k) ) )
  {
      ++k;
  }


  if( *(*(s+j)+k) != '\0' )
  {
      char *temp;
      temp=*(s+j);
      *(s+j)=*(s+j+1);
      *(s+j+1)=temp;
  }

虽然使用下标运算符而不是取消引用运算符要好得多。

这个while循环

while(n<=100&&gets(a[n])!=NULL)

可以在 n 等于 100 时调用未定义的行为,因为数组的有效范围是 [0, 100 )

gets 函数不安全,不受 C 标准支持。最好使用例如 fgets。

【讨论】:

  • 我现在才学的,所以有些不懂。非常感谢您的回答。我会仔细研究的。
猜你喜欢
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多