首页
社区
课程
招聘
[原创]关于查找子串在父串中的位置的功能的实现
发表于: 2007-11-16 21:29 8065

[原创]关于查找子串在父串中的位置的功能的实现

2007-11-16 21:29
8065
////////////////////////////////////////////////////////////////////////
//TITLE:查找子串在父串中的位置的功能的实现(c/c++)
//AUTHOR:没有风
//DATE:2007/11/16
///////////////////////////////////////////////////////////////////////

#include <string.h>
#include <stdio.h>

char* strcasestr(const char *haystack,const char *needle);

main()
{
    char  str1[100];
    char  str2[50];
    char* str;

    do{
        flushall();
        system("cls");

        printf("请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):\n");
        
        scanf("%s%s",str1,str2);

        if(strlen(str1)>100||strlen(str2)>50){
            printf("\n对不起,你输入的字符串过长,请重新输入再来!");
            continue;
        }

      str=strcasestr((const char*)str1,(const char*)str2);

      if(!str){
            printf("父串中查找不到与子串匹配的串!\n按Q键退出,其它任意键继续!\n");
            continue;
        }

    printf("父串中第一个与子串匹配串的位置为:%d\n",str-str1+1);

    printf("按Q键退出,其它任意键继续!\n");

    }while(getch()!='q');
}

//////////////指针版的查找子串在源串中的位置的函数/////////////////
//加强错误处理之后的函数
//      2007/11/16
//1。当子串为空时进行了处理
//2。当子串比源串要长时
//3。每次比较完之后,父串的指针只向前移动一位
//4。现在可以进行勿略大小写的判断比较了(最新)
//5。修正了一个BUG,即不能进行字母A、a、Z、z的忽略大小写的判断
//6。对忽略大小写部分的判断进行了代码,代码明显少了些(最新)
//7。增加了在输入输出前对所有的缓冲区进行了清除操作的功能
////////////////////////////////////////////////////////////////////

/*
////////////////////////////

函数原型:char *strcasestr(const char *haystack,const char *needle)

函数功能:指向字符串haystack中第一次出现字符串needle的开始位置,
          字串匹配时忽略大小写,如果没有找到字符串,返回null.

///////////////////////////
*/

char* strcasestr(const char* haystack,const char* needle)
{
    int i=0;
    while(*haystack&&*needle){            
          while(*haystack==*needle||\
              *haystack==((*needle>='a'&&*needle<='z')?*needle-32:*needle)||\
              *haystack==((*needle>='A'&&*needle<='Z')?*needle+32:*needle)){
            if(!*(++needle))return  (char*)haystack-i;
            if(!*(++haystack))return 0;
            i++;
        }
        needle-=i;
        haystack-=(i-1);
        i=0;
    }
    return 0;
}
//////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////
//今日在群里偶然看到有个朋友发的请求:要求写一个查找子串第一次在父串出现的位置的函数,
//可是却要求返回那个位置所对应的字符的指针,我就按照他给的函数头及说明写了一个函数给他
//写程序只用了我五分钟,可是修改修改修改之后发现却花了我好几个小时,真是不写不知道,
//一写发现真的学到好多东西。就为了这个函数,我写了好几个样板,最后确定了要这个指针板的
//发上群里,高手一看就指出了好几个BUG,经过N次修改,经他们好意提醒,最终我把程序改成////了现在这个样子。
//可是程序还有不足的地方,那就是判断次数太多,有个朋友给我指出说将子串和父串里的字母
//全部转化为大写或者小写之后再比较就可以减少很多用于判断的时间,还有就是用一次比较4个字
//节的方法来提高运行效率,我都不太懂,也许我太菜了吧。有没有哪个朋友看了这个程序之后,
//发现有什么BUG或者可以提高运动效率的方法,麻烦告诉一下我。大家都是学生,交流交流嘛。
////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////字符串版本的比较函数(相较上面的指针版本的函数要简洁一点点:)

char* strcasestr(const char* haystack,const char* needle)
{
    int i=0,j=0;

    int haylen=strlen(haystack);
    int needlen=strlen(needle);

    for(i=0;i<haylen;){

        for(j=0;j<needlen;){

            if((haystack[i]==needle[j])\
                ||haystack[i]==((needle[j]>='a'&&needle[j]<'z')?needle[j]-32:needle[j])\
                ||haystack[i]==((needle[j]>='A'&&needle[j]<'Z')?needle[j]+32:needle[j])){
               
                if(!needle[++j])return &haystack[i-j+1];
               
                if(!haystack[++i])return 0;
            }
            else{
                 break;
            }

        }
        i=i-j+1;
    }
   
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//此函数为非指针版本的查找位置的函数,写这个程序感觉很费劲,因为当写好的时候发上群去,立即有人指出好几个BUG来。
//还好,现在经过我的努力,BUG总算减少了许多。所以,大家可以放心的使用本函数。如果发现有什么BUG的话,也请不忘提醒
//一下我。
//
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

运行结果(写入几个数据进行测试):

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
11122223333
122
父串中第一个与子串匹配串的位置为:3
按Q键退出,其它任意键继续!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
bcdef
DE
父串中第一个与子串匹配串的位置为:3
按Q键退出,其它任意键继续!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA FFFFFFFFFFF

对不起,你输入的字符串过长,请重新输入再来!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
-=\abcdef123
\ABCD
父串中第一个与子串匹配串的位置为:3
按Q键退出,其它任意键继续!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
SDF
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAA

对不起,你输入的字符串过长,请重新输入再来!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开)
d
aaa
父串中查找不到与子串匹配的串!
按Q键退出,其它任意键继续!

请分别输入长度不大于100和长度不大于50的两个字符串(用空格或者回车隔开):
a
a
父串中第一个与子串匹配串的位置为:1
按Q键退出,其它任意键继续!

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
2
搞这么复杂,咋一看没看懂
仔细一看还是O(n^2),还不如直接写2个for循环干净
btw:KMP是O(m+n)
2007-11-16 22:54
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
3
每次比较完之后,父串的指针只向前移动一位

看完这句之后我突然无欲了
2007-11-17 02:44
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
4
如果你要在软件中实现查找子串的功能,直接用strstr或者wcsstr即可,在string.h
2007-11-17 12:46
0
游客
登录 | 注册 方可回帖
返回
//