c语言:大神最近写了一个关于匹配最长单词的程序。有点问题求指导

#include<stdio.h>voidmatch_lgest_word(chara[],charb[]){charc[20];//一个单词不会超过20个字母吧inti... #include <stdio.h>
void match_lgest_word(char a[],char b[])
{
char c[20]; //一个单词不会超过20个字母吧
int i=0,j,m,n,maxlen=0,from;
for(;a[i]!='\0';)
{
for(j=0;a[i]!=' ';i++,j++) //将a中单词放到c中
{
c[j]=a[i];
}
c[j]='\0'; //c加上结束标识
for(m=0;b[m]!='\0';m++) //这个部分验证c是否为b的子串
{
for(n=0;b[m]==c[n]&&c[n]!='\0';m++,n++)
{
;
}
if(c[n]=='\0'&&maxlen<j-1)
{
maxlen=j-1;
from=i-j+1;
break;
}
}
for(;a[i]=' ';i++) //去掉单词之间一个或多个空格,继续循环
{
;
}
}
for(;a[from]!=' '&&a[from]!='\0';from++)
printf("%c",a[from]);
}

void main()
{
char str1[]="This is C programming text";
char str2[]="This is a text for C programming";
printf("两个字符串公共最长英文单词是:");
match_lgest_word(str1,str2);
}
具体问题时这段代码变异没问题,运行不起来,直接死掉。
展开
 我来答
冰火梦幻
2013-12-26 · TA获得超过2308个赞
知道小有建树答主
回答量:1095
采纳率:57%
帮助的人:430万
展开全部

有两个主要修改点:

【修改点1】

尝试获取a中单词保存到c中时,注意最后一个单词可能不是空格结尾而是'\0'结尾。

【修改点2】

“去掉单词之间一个或多个空格,继续循环”这句话里的for中间

a[i]=' '改成a[i] == ' '。

另外为了预防,这类情况建议写成' ' == a[i],因为少写一个等号变成' ' = a[i]时编译器会帮你检测出来。

其他修改点见注释“修改点”。

#include <stdio.h>
void match_lgest_word(char a[],char b[])
{
    char c[20];  //一个单词不会超过20个字母吧
    int i=0,j,m,n,maxlen=0,from;
    for(;a[i]!='\0';)
    {
        for(j=0;a[i]!=' ' && a[i] != '\0';i++,j++)   //将a中单词放到c中 修改点:最后一个单词后面可能没有空格。
        {
            c[j]=a[i];
        }
        c[j]='\0';    //c加上结束标识
        for(m=0;b[m]!='\0';m++)    //这个部分验证c是否为b的子串
        {
            for(n=0;b[m]==c[n]&&c[n]!='\0';m++,n++)
            {
                ;
            }
            if(c[n]=='\0'&&maxlen<j) // 修改点:j已经是单词长度,不用-1了
            {
                maxlen=j; // 修改点:j已经是单词长度,不用-1了
                from=i-j; // 修改点:从下标角度考虑,由于j不-1,所以from也不用+1
                break;
            }
        }
        for(; ' ' == a[i];i++)   //去掉单词之间一个或多个空格,继续循环 修改点:“=”改成“==”,颠倒比较顺序
        {
            ;
        }
    }
    for(;a[from]!=' '&&a[from]!='\0';from++)
        printf("%c",a[from]);
}

void main()
{
    char str1[]="This is C programming text";
    char str2[]="This is a text for C programming";
    printf("两个字符串公共最长英文单词是:");
    match_lgest_word(str1,str2);
}
追问
感谢!感谢!思虑不周啊!另外请问两个问题
1、代码还能优化么
2、你们回答的这种专门的代码block怎么调出来的啊
追答
  1. 代码还能优化。比如“将a中单词放到c中”之后,由于a的单词长度已定(就是j),那么直接就能让j和maxlen比较。如果j小于maxlen,后面就不用比较了,反正肯定不会是“最长相同单词”。

    再比如“这个部分验证c是否为b的子串”的地方,不一定要循环到b[m]是'\0'的地步,如果b后面只剩下3个字母,而c的长度(也就是当前的a中单词长度)是4,那么肯定匹配不到了。你可以在整个函数match_lgest_word的一开头先求出a和b的长度,对于每个单词,先求出c的长度,然后在这个地方的for的边界就改成m + “c的长度” > “a的长度”。


2.关于block,你在发帖时,右上方有个“代码语言”的下拉列表,点一下然后选择“C/C++”,就会看到灰色的底色,在那里输入的都会被视为代码。

plmday
2013-12-26 · TA获得超过474个赞
知道小有建树答主
回答量:143
采纳率:0%
帮助的人:244万
展开全部

你没有意识到应该先测试字符数组的结尾再测试该字符是否为空格。修改后的代码如下。


void match_lgest_word(char a[], char b[])
{
  char c[20];  
  int i = 0, j, m, n, maxlen = 0, from;
  for (; a[i] != '\0';) {
    for (j = 0; a[i] != '\0' && a[i] != ' '; i++, j++) {  // 这里不测试a[i]非零的话会出界
      c[j] = a[i];
    }
    c[j] = '\0';
    for (m = 0; b[m] != '\0'; m++) {
      for (n = 0; c[n] != '\0' && b[m] == c[n]; m++, n++) {  // 这里不先测试c[n]非零的话也会出界
        ;
      }
      if (c[n] == '\0' && maxlen < j) {  // 之前这里字符串长度计算有误
        maxlen = j;
        from = i-j;  // 尤其是这里
        break;
      }
    }
    for(; a[i] == ' '; i++) {
      ;
    }
  }
  for(; a[from] != '\0' && a[from] != ' '; from++)  // 这里类似
    printf("%c", a[from]);
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式