栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C程序设计语言(K&R 第二版):练习4-1

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C程序设计语言(K&R 第二版):练习4-1

题目:

编写函数strrindex(s,t),它返回字符串t在s中最右边出现的位置。如果s中不包含t,则返回-1.

自我解答:

先看4.1中和第一章中的两个getline函数:

第1章中的getline函数如下:

#define MAXLINE     1000

int getline(char s[], int lim)
{
    int c, i;
    
    for(i = 0; i < lim -1 && (c = getchar()) != EOF && c != 'n'; ++i)
        s[i] = c;
    if(c == 'n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '';
    return i;
}

4.1中的getline函数如下:

#define MAXLINE     1000

int getline(char s[], int lim)
{
    int c, i;
    
    i = 0;
    while(--lim && (c = getchar()) != EOF && c != 'n')
        s[i++] = c;
    if(c == 'n')
        s[i++] = c;
    s[i] = '';
    return i;
}

两者之间的区别主要在于循环的实现方式,第一章中使用的是for循环,4.1中实现的是while循环. 而while循环中直接使用了--lim作为一个判断条件,显得更加简洁。

再回到本题目,自我解答如下:

int strrindex(char s[], char t[])
{
    int i, j ,k;
    int catchFlag = false, pos;
    
    
    for(i = 0; s[i] != ''; i++)
    {
        k = i;
        
        for(j = 0; t[j] != '' && (t[j] == s[k++]); j++);  
        if(t[j] == '') 
        {
            catchFlag = true;
            pos = i;
        }
    }
    if(catchFlag)
        return pos;
    else
        return -1;
}

实现的思想是把目标字符串t[]当成一个window不断在源字符串s[]中滑动,直到s结尾。第一层for循环负责窗在s中的滑动;第二层for循环负责判断t[]是否和s[]匹配,在判断匹配的过程中,如果t中有一个字符和目前s窗的字符中不匹配就会终止本次循环,对s进行滑动之后继续判断。

上述程序存在的一个小问题是,在第二层循环中访问字符串s中的元素时可能会出现数组越界的情况,但这并不影响程序的运行结果。

另一种思路是把s和t翻转,然后在s中寻找第一个和t匹配的字符串。

参考答案

int strrindex(char s[], char t[])
{
    int i, j ,k, pos;
    
    pos = -1;
    for(i = 0; s[i] != ''; i++)
    {
        for(j = i, k = 0; t[k] != '' && (s[j] == t[k]); j++, k++);  
        if(k > 0 && t[k] == '') 
            pos = i;
    }
        return pos;
}

strrindex函数与strindex函数(见教材第59页)很相似。两者的区别是strindex函数只要找到字符串t在字符串s中第一次(最左边)出现的位置就结束了;而strrindex函数在找到字符串t在字符串s中的匹配之后只记录其位置,然后继续搜索,因为它必须返回字符串t在字符串s中最后一次(最右边)出现的位置。

if(k > 0 && t[k] == '') 
            pos = i;

下面是本题的另一种解决方法:

int strrindex(char s[], char t[])
{
    int i, j ,k;
    
    for(i = strlen(s) - strlen(t); i >= 0; i--)
    {
        for(j = i, k = 0; t[k] != '' && (s[j] == t[k]); j++, k++); 
        if(k > 0 && t[k] == '') 
            return i;
    }
    return -1;
}

就本题而言,第二种方法比前一种方法的执行效率更高。它从字符串s的尾部(最右边)再向串首推进字符串t的长度个字符的位置开始寻找字符串t。如果没有匹配,strrindex函数将(从右向左)后退一个位置并在此进行比较。这样,当strrindex函数在字符串s中找到字符串t时,它将立刻返回变量i,因为变量i此时的取值就是字符串t在字符串s中最右边出现的位置。

总结:

对比参考答案的第一种写法和自我解答中,有两点不同。一点是自我解答中的catchFlag不是必须的,可以按照参考答案中的办法进行删减。另一点是参考答案中在赋值pos时增加了一个k>0的条件。这个主要是为了处理t是空字符串的情况,如果t是空字符串,参考程序会返回-1,而自我解答中会返回s字符串中最后字符的位置。

本书中第二种解法就是自我解答中第二种思路,但是书中说执行效率更高,这个有疑问,因为这种解法中需要提前获得字符串的长度,strlen函数也需要时间开销。也许从统计角度来看,第二种的效率更高效

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/589792.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号