华为机考真题 -- 中文分词模拟器

题目描述:

给定一个连续不包含空格的字符串,该字符串仅包含英文小写字母及英文标点符号(逗号、分号、句号),同时给定词库,对该字符串进行精确分词。

说明:
1.精确分词: 字符串分词后,不会出现重叠。即“ilovechina” ,不同词库可分割为 “i,love,china” “ilove,china”,不能分割出现重叠的"i,ilove,china",i 重叠出现;
2.标点符号不成词,仅用于断句;
3.词库:根据外部知识库统计出来的常用词汇,例如:
dictionary=["i","love","china","lovechina","ilove"];
4.分词原则:采用分词顺序优先且最长匹配原则; 
例如:“ilovechina”,假设分词结果 [ i,ilove,lo,love,ch,china,lovechina ] 则
输出[ilove,china]
错误输出:[i,lovechina], 原因:"ilove ">优先于 "lovechina"成词
错误输出:[i,love,china] 原因:"ilove" >"i" 遵循最长匹配原则

输入描述:

第一行输入待分词语句 "ilovechina" ;
第二行输入中文词库 "i,love,china,ch,na,ve,lo,this,is,the,word" 

字符串长度限制:0<length<256;
词库长度限制: 1<length<100000;

输出描述:

按顺序输出分词结果 "i,love,china"

示例 1:

输入
ilovechina
i,love,china,ch,na,ve,lo,this,is,the,word

输出
i,love,china

示例 2:

输入
iat
i,love,china,ch,na,ve,lo,this,is,the,word,beauti,tiful,ful

输出
i,a,t

说明:单个字母,不在词库中且不成词则直接输出单个字母

示例 3:

输入
ilovechina,thewordisbeautiful
i,love,china,ch,na,ve,lo,this,is,the,word,beauti,tiful,ful

输出
i,love,china,the,word,is,beauti,ful

说明:标点符号为英文标点符号

C++源码:

#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <algorithm>
#include <vector>

using namespace std;

void findWord(string englishStr, set<string>& dic, int top) {
	vector<string> result;  // 用于存储分词结果
	int start = 0;           // 初始化当前处理的起始位置

	// 遍历整个字符串
	while (start < englishStr.length()) {
		// 跳过非小写字母的字符
		if (!islower(englishStr[start])) {
			start++;
			continue;
		}

		int end = start;      // end用于记录从位置start开始的最长匹配的终点位置
		string tmep = { englishStr[start] };  // 初始化当前正在构建的词

		// 从位置start+1开始尝试匹配最长的单词,直到达到词库中最长单词的长度
		for (int r = start + 1; r < min(start + top, static_cast<int>(englishStr.length())); ++r) {
			tmep += englishStr[r];
			// 如果当前构建的字符串在词库中,则更新p
			if (dic.find(tmep) != dic.end()) {
				end = r;
			}
		}

		// 将匹配到的最长单词加入结果列表
		tmep = tmep.substr(0, end - start + 1);
		dic.erase(tmep);  // 删除词库中的该单词
		result.push_back(tmep);
		start = end + 1;  // 更新start为最后匹配单词的下一个位置
	}

	// 输出所有分词结果,用逗号分隔
	for (int i = 0; i < result.size(); ++i) {
		cout << result[i];
		if (i < result.size() - 1) cout << ",";
	}
	cout << endl;
}

int main() {
	string str;
	getline(cin, str);  // 读取第一行输入的字符串
	set<string> dic;  // 创建一个集合用于存储词库
	int top = 0;      // 记录词库中最长单词的长度
	string word;
	// 读取第二行输入的词库,并分割成单个词汇,存入集合中
	string line;
	getline(cin, line);
	istringstream ss(line);

	while (getline(ss, word, ',')) {
		dic.insert(word);
		top = max(top, static_cast<int>(word.length()));  // 更新最长单词的长度
	}

	findWord(str,dic, top);

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值