关键字过滤

        前段时间由于项目需要,要写个屏蔽敏感词的功能。就研究了一下。这个东西不难,简单的实现就可以很快的写出,比如基本的strstr,或者KMP算法。这类基本的方法都需要关键词的逐个比较。效率比较低,这里选用基于关键字hash的方法来加快查找的效率。

        先建立关键字hash树,对每个关键字建立一个hash映射,加快查找速度。对hash相同的建立数结构,比如ab,aab,bc,建立的结果就是:

      key : a                                                                       key: b

  

         数据结构如下:

typedef struct _Node{
	char value;
	_Node* parent;
	_Node* childs;
	_Node* siblings;
	_Node() {parent= childs = siblings = NULL;};
}Node, *NodePtr;

        这里的关键字key是取的单个字节的char值。对于包含汉字的utf关键字,当然可以转换成ansi,定下字节数(汉字占2字节)然后以2字节做key。如此就可以建立一个字典树。建立的过程如下:

          

	for (i = 0; i < m_str.size(); i ++){
		// 首字key做hash
		int key = m_str[i][0];
		m_it = m_map.find(key);
		if (m_it == m_map.end()){
			NodePtr pNode = new Node;
			pNode->value = key;
			pNode->parent = NULL;
			pNode->childs = NULL;
			pNode->siblings = NULL;
			m_map[key] = pNode;
		}

		NodePtr pNode = m_map[key];
		int j = 1, count = m_str[i].size() - 1;
		while (count -- > 0){
			key = m_str[i][j++];
			NodePtr pChild = pNode->childs;
			if (!pChild){	// first child
				pChild = new Node;
				pChild->value = key;
				pChild->parent = pNode;
				pNode->childs = pChild;
				pNode = pChild;// new root
			} else {		// second child
				while (pChild->siblings){
					if (pChild->siblings->value == key) break;
					pChild = pChild->siblings;
				}
				if (pChild->siblings){	// found
					pNode = pChild->siblings;	// new root
				} else {
					pChild->siblings = new Node;
					pChild->siblings->value = key;
					pChild->siblings->parent = pNode;
					pNode = pChild->siblings;	// new root
				}
			}
		}
	}


        对于一个给定的字符串,来判断是否包含关键字。这个过程就是一个查找的过程,和建立词典数是类似的方法:

       

bool KeyWordFilter::checkWord(const char* str)
{
	int i,length = strlen(str);
	std::stack<NodePtr> toTmp, toCheck;
	std::stack<NodePtr> *pTmp, *pToCheck;
	pTmp = &toTmp;
	pToCheck = &toCheck;
	for (i = 0; i < length; i ++){
		int key = str[i];
		while (!pToCheck->empty()){
			// test each one
			NodePtr pNode = pToCheck->top();
			pToCheck->pop();
			if (pNode->childs){
				if (pNode->childs->value == key){
					// found
					if (pNode->childs->childs)
						pTmp->push(pNode->childs);
					else {
						//dump(pNode->childs);
						return true;
					}
				} else {
					NodePtr pChild = pNode->childs;
					while(pChild->siblings){
						if (pChild->siblings->value == key) break;
						pChild = pChild->siblings;
					}
					if (pChild->siblings){
						// found
						if (pChild->siblings->childs)
							pTmp->push(pChild->siblings);
						else {
							//dump(pChild->siblings);
							return true;
						}
					}
				}
			}
		}

		// 新的单词开始
		m_it = m_map.find(key);
		if (m_it != m_map.end()){
			pTmp->push(m_it->second);
		}
		// switch
		std::stack<NodePtr> *tmp;
		tmp = pToCheck;
		pToCheck = pTmp;
		pTmp = tmp;
	}

	return false;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js是一种流行的JavaScript框架,用于构建用户界面。关键字过滤是Vue.js中的一个常见功能,用于在列表或表格中根据用户输入的关键字过滤数据。 在Vue.js中实现关键字过滤可以通过以下步骤: 1. 在Vue实例的data属性中定义一个用于存储原始数据的数组,例如`items`。 2. 在Vue实例的data属性中定义一个用于存储过滤后数据的数组,例如`filteredItems`。 3. 在Vue实例的methods属性中定义一个方法,例如`filterItems`,用于根据关键字过滤数据。 4. 在模板中使用`v-model`指令将用户输入的关键字绑定到Vue实例的一个属性上,例如`keyword`。 5. 使用计算属性或侦听器来监听关键字的变化,并在变化时调用`filterItems`方法进行数据过滤。 6. 在模板中使用`v-for`指令遍历`filteredItems`数组,并展示过滤后的数据。 下面是一个简单的示例代码: ```html <template> <div> <input type="text" v-model="keyword" placeholder="请输入关键字"> <ul> <li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li> </ul> </div> </template> <script> export default { data() { return { keyword: '', items: [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 3, name: 'Orange' } ], filteredItems: [] }; }, methods: { filterItems() { this.filteredItems = this.items.filter(item => { return item.name.toLowerCase().includes(this.keyword.toLowerCase()); }); } }, watch: { keyword() { this.filterItems(); } } }; </script> ``` 在上述示例中,用户输入的关键字会触发`keyword`属性的变化,然后通过计算属性或侦听器调用`filterItems`方法进行数据过滤,最终展示过滤后的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值