回 帖 发 新 帖 刷新版面

主题:算法问题

这是网叶地址:http://www.programfan.com/club/newpost.asp?bbsid=5&topicid=0


网址主叶是:www.programfan.com,

怎么样编一个算法,可以网叶地址中把网址主叶找出来?

回复列表 (共9个回复)

沙发

指导思想是模式匹配,要想想你要提取的这部分字符串是什么特征

板凳

夹在第一个"//"和第一个"/"中间的就是主网址
先STRSTR再STRCPY

3 楼

"雪光风剑" 宏观解释,"强强"是微观解释;
非常感谢~~~~~~~~

各加30分

4 楼


         char URL[256] = "http://www.programfan.com/club/newpost.asp?bbsid=5&topicid=0

";
         char *pTemp;
    if (URL[0] == 'h' && URL[1] == 't' && URL[2] == 't' && URL[3] == 'p')
        pTemp = URL + 7;
    else
        pTemp = URL;

    char Host[128]; char *pHost;
    for(pHost = Host; *pTemp != 0 && *pTemp != '/' && *pTemp != ':';)
        *pHost++ = *pTemp++;
    *pHost = 0;

5 楼

ls的代码风格个人认为不好,前四个字符里可能混有大写,这点没有纳入考虑

6 楼

字符串匹配

7 楼

正则表达式,是解决这类问题的良方。
传统的C++标准中并没有正则表达式的功能(这也是C++多年的痛脚),好在现在TR1里面有这样的东西了(也就是regex,源自boost库),它即将成为标准。GCC、Visual Studio 2008(SP1)、Visual Studio 2010等工具都对它提供了支持。
不过,杀鸡不用牛刀。C语言的scanf系列函数其实已经具备了简单的正则表达式功能。虽然scanf系列函数并不完全支持正则表达式,但用在这里也足够了。

闲话说完,看代码:
[code=c]#include <cstdio>

static const int BUFFER_SIZE = 512;

int main() {
    char buf[BUFFER_SIZE] = {0};
    const char* input = "http://www.programfan.com/club/newpost.asp?bbsid=5&topicid=0";
    int result = sscanf(input, "%*[^/]//%[^/]/", buf);

    if (result == 1) {
        printf("%s\n", buf);
    }

    return 0;
}[/code]

输出为:
www.programfan.com

解释:
1. scanf系列函数有一个较少用到的用法,那就是%[]。一般的%s,读取时遇到空格就会停止。但如果用%[]代替%s,则可以在中括号内部指定字符(而且可以指定多个字符,比如“%[,.]”)。在读取时,遇到中括号内的字符就读取,否则就停止。而如果中括号里面第一个字符是^,则反过来,遇到中括号内的字符就停止,否则就读取。例如,“%[^/]”就表示:一直读取,直到遇到“/”这个字符才停止。
2. 还有一个用法,就是“*”符号。比如%*d,就表示“虽然读取了一个整数,但是把读取的值丢弃掉,不要保存到任何变量中”。
3. 另外,scanf系列函数对于所有不是%开头的内容,全部按照原样读取。

有了这三点,就可以看那个古怪的字符串“%*[^/]//%[^/]/”了。首先是“%*[^/]”,因为有“*”号,所以读取的内容会被丢掉,不会保存到变量。这一段会一直读取,直到遇到“/”才停止。所以实际上我们读取到了“http:”这样的内容(不过被丢弃了,没有保存)。然后是“//”,这里是原样读取,如果输入的数据没有“//”,则读取失败,函数将返回零,程序不会输出。至此,我们一共读取到了“http://”这样的内容,但是都丢弃了。
接下来是重头戏,“%[^/]”,这表示一直读取,直到遇到“/”才停止。而且读取的内容会保存到buf中。(提示:如果一直不会遇到“/”就到了结束,那buf中也保存了一些数据。比如输入“http://abc.com”,则最后会输出“abc.com”)
最后的那个“/”可要可不要,已经关系不大了。

可见,程序的复杂性完全集中在“%*[^/]//%[^/]/”这个字符串上面。而不是像咖喱炒饭同学在4楼的代码那样分散。如果发现规则有变,则只要修改这个字符串即可,不需要到处修改。像“URL[0] == 'h'”、“pTemp = URL + 7;”这样的代码,如果反复修改的话,会让人头痛,但“%*[^/]//%[^/]/”这样的内容,看似复杂,但修改的时候反而容易一些。

不仅仅是编程,正则表达式还可以用在其它地方。比如现在很多编辑器都是支持正则表达式的(UltraEdit、EditPlus、Visual Studio等),可以进行复杂搜索(比如,找出文章中所有的url)。有兴趣可以在网上搜索一下相关的介绍。

当然,正则表达式也并非万能。比如,它就无法判断一个表达式的括号是否配对。

8 楼

好!!!

9 楼

牛...学习了..

我来回复

您尚未登录,请登录后再回复。点此登录或注册