首页 新闻 会员 周边 捐助

如何对页面源码进行多个关键字查找?

0
悬赏园豆:30 [已解决问题] 解决于 2015-08-03 16:26

RT。我抓取了一个页面的源码,想对里面的内容进行关键字匹配分类并统计有多少个。如:匹配“新闻”有几个,“游戏”有几个,“购物”有几个,“新闻”有几个等等。这个该怎么做。目前我用了一种较笨的方法就是,对源码进行find查找,依次对这几个关键字进行while循环匹配。但这样效率实在是太低了。要是有很多个关键字,查找起来很费时间,请问该怎么做?

问题补充:

这个就是写的小函数,只是粘贴了一部分。写这个函数的思路就是,定义一个数组用于存放关键字的次数,然后分别对里面的关键字进行查找,并使得引用计数加1。最后再再数组中查找一个最大的元素,返回出去。但这样做效率很低,请问该怎么优化?谢谢各位了。

int DownHtml::Judge(const std::string &str) //待优化
{
    int pos = 0;
    int count = 0;
    int a[12] = {0};
    while(pos >= 0)
    {
        pos = str.find("新闻", pos + 8);
        a[0] = count++;
    }
    pos = 0;
    count = 0;
    while(pos >= 0)
    {
        pos = str.find("购物", pos + 8);
        a[1] = count++;
    }
    pos = 0;
    count = 0;
    while(pos >= 0)
    {
        pos = str.find("银行", pos + 8);
        a[2] = count++;
    }
    pos = 0;
    count = 0;
    while(pos >= 0)
    {
        pos = str.find("集团", pos + 8);
        a[3] = count++;
    }
        int k = 0;
    int max = a[0];
    for (int i = 0; i < 12; i++)
    {
        if (a[i] > max)
        {
            max = a[i];
            k = i;
        }
    }
    return k;
}
东子同学的主页 东子同学 | 初学一级 | 园豆:64
提问于:2015-08-03 11:27
< >
分享
最佳答案
1

我看了你的算法,有一个想法,我们可以建立一个非常简单的哈希表就能满足要求。由于字符(char)是一个长度为8的数据类型,我们可以和你一样建立一个长度12的数组,而数组中存储的是每组关键字的对应的次数。这样我们就创建了一个以关键字位码的哈希表,我们就扫描一次数组,就统计了所以的关键字个数,用C写的,c++语法全忘记了,这样

空间复杂度:O(1)        

          时间复杂度:O(n)

还有一些没写了,如果可以就采纳

char KeywordChar(char* pString) 

{
//输入不合法
if(!pString)
return 0;

//创建一个哈希表,并初始化
const int tableSize = 12;
int hashTable[tableSize];
for(int i = 0; i < tableSize; i++)
hashTable[i] = 0;

//确定字符串中每个字符出现的次数
char* pHashKey = pString;
while(*(pHashKey) != '\0')
hashTable[*(pHashKey+8)]++;

//如果这个字符串为空,或者字符串中的每个字符都至少出现两次
return 0;

}

收获园豆:30
稳稳的河 | 老鸟四级 |园豆:4216 | 2015-08-03 15:37

谢谢解答。估计是我没看明白,觉得有几个地方好像有点问题。总体思路大致是,建立个哈希表,然后依次遍历其中的关键字,然后使得出现的次数加一。但这个算法中是不是没有匹配关键字这一步?
while(*(pHashKey) != '\0')
hashTable[*(pHashKey+8)]++;

这两条语句可以起到这个作用吗?可以详细解答吗?谢谢了。

东子同学 | 园豆:64 (初学一级) | 2015-08-03 16:03

我说下我上面写的那个函数的思路。

while(pos >= 0) { pos = str.find("新闻", pos + 8); a[0] = count++; }

利用string类的find函数可以定位到第一次出现“新闻”这个关键字的位置,如果找到,使计数加一,然后跳过这个关键字,接着查找,如此循环。

您上面写的哈希表只是8个字节的往后循环吗?但是整个页面源码不小,所以,这样会不会欠妥?或者是我没看懂。。

东子同学 | 园豆:64 (初学一级) | 2015-08-03 16:12

@东子同学:上面的代码是有问题,其实我的想法就是把如“新闻”当作Key,数量当作Value,进行一次统计,页面源码无论你怎么样,不管你用什么方法,是一定至少遍历一次的,如果你想好看些,比如你说的find,在C#里面用linq更加好统计,但也需要去考虑find,是怎么找到你的关键字的,目前用哈希表是我想到的相对好点的,其他好方法我也不会了

稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-03 16:23

@稳稳的河: 嗯,谢谢。受教了。

东子同学 | 园豆:64 (初学一级) | 2015-08-03 16:25
其他回答(1)
0

其实使用正则式是个不错的选择,能够直接匹配出你要查询的数量

刘宏玺 | 园豆:14020 (专家六级) | 2015-08-03 11:55

额。。正则表达式该怎么写?我在网上搜了一下只知道[\u4E00-\u9FA5]这个表达式能匹配到汉字,但是不明白怎么对这个几个指定的汉字进行查找,请老师赐教,谢谢。

支持(0) 反对(0) 东子同学 | 园豆:64 (初学一级) | 2015-08-03 11:58

@东子同学: 直接匹配你要的“汉字”就好了,

支持(0) 反对(0) 刘宏玺 | 园豆:14020 (专家六级) | 2015-08-03 12:02

正则表达式没用,还是会每个关键词一次遍历,没有减少复杂度

支持(0) 反对(0) 稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-03 12:06

@稳稳的河: 嗯,那有没有其他可参考的方案?

支持(0) 反对(0) 东子同学 | 园豆:64 (初学一级) | 2015-08-03 13:25

@东子同学: 你的语言是c++吗?

支持(0) 反对(0) 稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-03 14:57

@稳稳的河: 是的。c++。

支持(0) 反对(0) 东子同学 | 园豆:64 (初学一级) | 2015-08-03 14:58

@东子同学: 在后面回复了一个思路

支持(0) 反对(0) 稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-03 15:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册