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; }
我看了你的算法,有一个想法,我们可以建立一个非常简单的哈希表就能满足要求。由于字符(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;
}
谢谢解答。估计是我没看明白,觉得有几个地方好像有点问题。总体思路大致是,建立个哈希表,然后依次遍历其中的关键字,然后使得出现的次数加一。但这个算法中是不是没有匹配关键字这一步?
while(*(pHashKey) != '\0')
hashTable[*(pHashKey+8)]++;
这两条语句可以起到这个作用吗?可以详细解答吗?谢谢了。
我说下我上面写的那个函数的思路。
while(pos >= 0) { pos = str.find("新闻", pos + 8); a[0] = count++; }
利用string类的find函数可以定位到第一次出现“新闻”这个关键字的位置,如果找到,使计数加一,然后跳过这个关键字,接着查找,如此循环。
您上面写的哈希表只是8个字节的往后循环吗?但是整个页面源码不小,所以,这样会不会欠妥?或者是我没看懂。。
@东子同学:上面的代码是有问题,其实我的想法就是把如“新闻”当作Key,数量当作Value,进行一次统计,页面源码无论你怎么样,不管你用什么方法,是一定至少遍历一次的,如果你想好看些,比如你说的find,在C#里面用linq更加好统计,但也需要去考虑find,是怎么找到你的关键字的,目前用哈希表是我想到的相对好点的,其他好方法我也不会了
@稳稳的河: 嗯,谢谢。受教了。
其实使用正则式是个不错的选择,能够直接匹配出你要查询的数量
额。。正则表达式该怎么写?我在网上搜了一下只知道[\u4E00-\u9FA5]这个表达式能匹配到汉字,但是不明白怎么对这个几个指定的汉字进行查找,请老师赐教,谢谢。
@东子同学: 直接匹配你要的“汉字”就好了,
正则表达式没用,还是会每个关键词一次遍历,没有减少复杂度
@稳稳的河: 嗯,那有没有其他可参考的方案?
@东子同学: 你的语言是c++吗?
@稳稳的河: 是的。c++。
@东子同学: 在后面回复了一个思路