题目描述:
给定一个连续不包含空格的字符串,该字符串仅包含英文小写字母及英文标点符号(逗号、分号、句号),同时给定词库,对该字符串进行精确分词。
说明:
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;
}

2227

被折叠的 条评论
为什么被折叠?



