之前在开发 机器人的语义系统的时候遇到这样一个问题(机器人支持语音交互):
用户说 :“我要取钱”。
机器人回答:“请问你要取多少?5000以上还是5000以下”。
用户说:“我要取 三千4百元”。
那么问题来了,由于语音识别并没有那么的强大,并不能每次都把 客户表达的 “三千4百元”转成阿拉伯数值 “3400”,或许有时候翻译成了 “3千400元”、或许也是 “三千400元”等等。
问题已经出现,如果继续必须得把这些 不规范的 全部转成 阿拉伯整数值 “3400” 以供使用。
我们的算法工程师也给了一种思路并用python实现了,个人感觉比较复杂,我用递归的方式实现一种。
1.创建一个数组:顺序包含 : 亿、万、千与仟、百与佰、十与拾 // "千与仟"的意思是语音识别 可能的结果,例如 :四千 与四仟
public static boolean ExtractNumber(String content, RefInteger refInteger){
List<String> yiList = Arrays.asList("亿");
List<String> wanlList = Arrays.asList("万");
List<String> qianList = Arrays.asList("千","仟");
List<String> baiList = Arrays.asList("百","佰");
List<String> shilList = Arrays.asList("十","拾");
List<List<String>> unitList = new ArrayList<List<String>>();
unitList.add(yiList);
unitList.add(wanlList);
unitList.add(qianList);
unitList.add(baiList);
unitList.add(shilList);
return Extract(content, refInteger, unitList);//见下面
}
2.该函数使用了递归,遍历 unitList ,发现字符串中对应的值,转成 阿拉伯数值。然后 递归相加。
private static boolean Extract(String StringValue, RefInteger refInteger, List<List<String>> unitList){
if (isNumberic(StringValue, refInteger)) {
return true;
}
String newStringValueFont = null;
String unitString = "个";
for (List<String> list : unitList) {
for (String unit : list) {
if (StringValue.contains(unit)) {
unitString = unit;
Integer lastIndex = StringValue.lastIndexOf(unit);
if (lastIndex > 0) {
newStringValueFont = StringValue.substring(0, lastIndex);
}
StringValue = StringValue.substring(lastIndex+1);
break;
}
}
if (newStringValueFont == null || newStringValueFont.isEmpty()) {
continue;
}
RefInteger refInteger2 = new RefInteger();
if(Extract(newStringValueFont, refInteger2, unitList)){
refInteger.appendValue(refInteger2.getValue()*UnitEnum.getIndex(unitString));
}
newStringValueFont = null;
}
Integer value1 = 0;
RefInteger regfInteger4 = new RefInteger();
if (isNumberic(StringValue, regfInteger4)) {
//return true;
value1 = regfInteger4.getValue();
}
else {
value1 = UpperToNumber(StringValue);
}
refInteger.appendValue(value1);
return true;
}
/**
* 大写的汉子转成数字
* @param Upper : 必须为大写数字方能转换成功
* @return 0:转换失败
* */
private static Integer UpperToNumber(String Upper) {
return DigitalEnum.getIndex(Upper);
}
/**
* 判断字符串是否可以转成数字
* */
private static boolean isNumberic(String content,RefInteger refInteger){
try {
Integer value = Integer.parseInt(content);
refInteger.setValue(value);
return true;
} catch (Exception e) {
return false;
// TODO: handle exception
}
}
java源码 见 https://download.csdn.net/my