之前在開發 機器人的語義系統的時候遇到這樣一個問題(機器人支持語音交互):
用戶說 :“我要取錢”。
機器人回答:“請問你要取多少?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