设为首页 加入收藏

TOP

C语言初学者代码中的常见错误与瑕疵(9)(一)
2014-11-23 21:27:31 来源: 作者: 【 】 浏览:25
Tags:语言 学者 代码 常见 错误 瑕疵
字母的个数
现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个。
输入:第一行输入一个正整数T(0
随后T行输入一个字符串s,s长度小于1010。
输出:每组数据输出占一行,输出出现次数最多的字符;
样例:
输入
3
abcd
bbaa
jsdhfjkshdfjksahdfjkhsajkf
输出:
a
a
j
原代码
#include
#include
int maxchar(char x[1010])
{
int i,j,temp,max;
int a[26]={0};
for (i = 0,temp =0;i
{
temp=x[i]-97;
a[temp]+=1;
}
for(i=1,max = a[0],j=0;i<26;i++)
{
if(max
{
j=i;
max = a[i];
}
}
return j+97;
}
int maxchar(char x[1010]);
int main()
{
char s[1010],c[26];
int T,i;
scanf("%d",&T);
for (i=0;i
{
scanf("%s",s);
c[i]=maxchar(s);
}
for (i=0;i
{
printf("%c\n",c[i]);
}
return 0;
}
评析:
总体:
  已经学会把函数类型声明写在函数定义外面了,但把其他函数定义写在main()之前,总体上还是有头重脚轻之感。
main():
char s[1010],c[26];
int T,i;
  s数组显然不应该定义在这里,因为这个数组只在第一个for语句内部用到。
  c数组不应该定义为26个元素,因为题目中说的是“0
scanf("%d",&T);
  这条语句无可指责,但输入后没考虑数据有效性。
for (i=0;i
{
scanf("%s",s);
c[i]=maxchar(s);
}
for (i=0;i
{
printf("%c\n",c[i]);
}
  原作者显然不了解这类ACM问题的套路(参见 C语言初学者代码中的常见错误与瑕疵(5) 11楼~13楼)。不过话说回来,ACM对这类问题的描述确实容易让外人误解,ACM是否应该自我检讨一下呢?
  除了不了解ACM的套路,这里的一个有欠考虑的地方是没有注意检查输入数据的有效性(当然,ACM对此是不管不顾的)。如果考虑输入数据的有效性应该不理会无效数据:
scanf("%d",&T);
if ( 0
{
//求解问题
}
或者“死等”
while ( scanf("%d",&T) , !( 0
{
//提示重新输入
}
  考虑的更周到些的话,可以
while ( scanf("%d",&T)!= 1 || !( 0
{
while ( getchar()!='\n')
;
//提示重新输入
}
  此外,这段代码中的
scanf("%s",s);
这句如果写成
scanf("%1009s",s);
就无可挑剔了。尽管ACM的测试数据不会出问题,但这是应该考虑到的一个问题。程序员最重要的品质应该是思虑周到。
maxchar()函数 :
int maxchar(char x[1010])
{
int i,j,temp,max;
int a[26]={0};
for (i = 0,temp =0;i
{
temp=x[i]-97;
a[temp]+=1;
}
for(i=1,max = a[0],j=0;i<26;i++)
{
if(max
{
j=i;
max = a[i];
}
}
return j+97;
}
int maxchar(char x[1010]);
  函数定义和函数类型声明都存在同一个问题,就是[]内的1010。这个是不应该写的,写了编译器也不“看”,写得毫无意义。
int a[26]={0};
  这个写成
int a['z'-'a'+1]={0};
为好。注意这里应该是假定使用ASCII码制,如果不是ASCII码,代码不能这样写。
for (i = 0,temp =0;i
{
temp=x[i]-97;
a[temp]+=1;
}
  这个槽点较多。首先temp明显多余,其次那个97太难看了,典型的谭浩强风格。应该写为'a'。
a[temp]+=1;
  可以直接写为
a[ x[i] - 'a']+=1;
  再有,i
#include
也完全是多余的。
  另外这条语句的功能与下一条for语句的功能相对各自独立,各抽象为一个独立的函数为好。
for(i=1,max = a[0],j=0;i<26;i++)
{
if(max
{
j=i;
max = a[i];
}
}
  这个地方写得有点笨,主要是变量太多。作者用max记录最大值元素,用j记录其下标,其实只要一个j就够了
for(i=1,j=0;i<26;i++)
{
if(a[j]
{
j=i;
}
}
  最后
return j+97;
这个也是谭浩强之流不入流的写法,非常难看。应该写为
return j+'a';
重构
/*
字母的个数
现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,
如果出现次数最多字母有多个那么输出最小的那个。
输入:第一行输入一个正整数T(0
随后T行输入一个字符串s,s长度小于1010。
输出:每组数据输出占一行,输出出现次数最多的字符;
样例:输入
3
abcd
bbaa
jsdhfjkshdfjksahdfjkhsajkf
输出:
a
a
j
作者:薛非
出处:http://www.cnblogs.com/pmer/ “C语言初学者代码中的常见错误与瑕疵”系列博文
*/
#include
#define S_LEN 1009
#define MAX_LEN (S_LEN + 1)
#define N(x
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇山东理工大学ACM平台题答案关于C.. 下一篇C运算符的优先级速记法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: