搜狗输入法的分词算法
搜狗输入法最近的用户输入中出现了一种新的输入模式,形如 “0k1234567”,搜狗的工程师发现这一模式后了解到,这是一种新被提出的对于十五进制数字的标记模式,其中 “0k” 是标记进制为15的前缀标记,之后的部分 “1234567” 是实际的十五进制的数字串。
在发现这一标记模式后,搜狗的工程师开始尝试在已有的分词算法上进一步加入对于十五进制数字串的处理,把网页上的这种形式的 15 进制数正确地提取出来。我们知道,标记十五进制的 “0k” 中 k 必须是小写,数字 0 到 14 在这套标记模式下会被依次表示为:0k0, 0k1, ..., 0k9, 0kA, 0kB, 0kC, 0kD, 0kE。也就是说 15 进制数字中只会出现 0-9、k 和 A-E。
值得注意的是,数字表示中不能有多余的 0,比如 0k05 是不能被当做一个十五进制数字的。另外,作为一种约定,当出现 “0k90k8” 时,只有 0k90 是符合期望的十五进制数字,即总是从左至右依次提取出最长的十五进制数字。如果希望表达 0k9 和 0k8 这两个数字的连写情况时,则会被写成 “0k9'0k8” 这一的形式(单引号代表其他任意非数字字符)。
搜狗的工程师希望将用户输入中符合上述要求的所有十五进制数依次输出。你能帮他实现么?
输入格式
输入一行字符串 str (1 ≤ |str| ≤ 106),表示搜狗工程师得到的用户输入。用户输入中的字符一定是数字 (0 - 9) 或大小写英文字母 (a - z, A - Z)。
输出格式
输出包括若干行,每行输出一个提取出的十五进制数(形式如同:0k1234),分别对应输入字符串中含有的若干个符合标记模式的十五进制数字;输出时,请以数字在原字符串中的顺序依次输出。
输入:
sjfjfhua0kA0000lmNhdhahdfhGgdJG90K10k110k120kF
输出:
0kA0000 0k110
解题思路:
1.如果0k后面不满足要求的话,就不输出。
2.如果0k后面的字符为'0',则直接输出"0k0"。
3.如果0k后面的字符不是0,在所要求的范围内,那就输出这个字符,直到不满足所要求字符break。
AC代码:
#include <bits/stdc++.h>
using namespace std;
char str[1000005];
bool check(char c){
if(isdigit(c) || (c >= 'A' && c <= 'E'))
return true;
return false;
}
int main(){
while(~scanf("%s",str)){
int len = strlen(str);
for(int i = 0; i < len-2; ++i){
if(str[i] == '0' && str[i+1] == 'k' && check(str[i+2])){
printf("%c%c%c",str[i],str[i+1],str[i+2]);
int flag = 1;
if(str[i+2] != '0'){
i += 3;
flag = 0;
for(; i < len && check(str[i]); ++i)
printf("%c",str[i]);
--i;
}
if(flag)
i += 2;
printf("\n");
}
}
}
return 0;
}