汇率换算自然语言理解功能JAVA DEMO
>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转载 <<<<<<<<<<<<<<<<<<<<<<<<
本文原地址:http://blog.csdn.net/happycxz/article/details/73223916
基础资源及工具
- eclipse + windowbuilder插件
- jdk 1.7
- 免费开放语义接口平台 olami.ai
- 参考开源代码 https://github.com/codingmonster/olami-nlu-samples-java.
实现功能
通过java客户端界面,输入汇率换算相关句子,可以查到汇率和货币相关的结果。
界面展示
APP内预置部分支持的说法,可点击“换一句”切换。点击“理解”即发送对应文本到olami开放语义服务器。
左下角是olami开放语义服务器返回的语义结构,右下角是我用对应拿到的语义,找了一个免费的汇率接口,获取到对应的数据展示出来。
资源下载
点击 github源码位置
点击 在CSDN免资源下载全部资料:源码、eclipse工程、可执行JAR包 。
点击 通过百度云下载此DEMO全部资料 。
源代码简介
CurrencyTable.java
汇率货币代码、名称、别名,对应国家或地区名称、别名管理。主要是对currencyTable.csv配置文件中的配置数据解析。
package exchangerate;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CurrencyTable {
private static Map<String, Currency> codeMap = new HashMap<String, Currency>();
private static Map<String, Currency> curMap = new HashMap<String, Currency>();
private static Map<String, Currency> cntMap = new HashMap<String, Currency>();
static {
try {
InputStream is = CurrencyTable.class.getResourceAsStream("/exchangerate/currencyTable.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "gbk"));
String line;
while ((line = reader.readLine()) != null) {
String lineTrim = line.trim();
if (lineTrim.startsWith("#") || lineTrim.isEmpty()) {
continue;
}
String[] splitTmp = lineTrim.split(",");
if (splitTmp.length != 3) {
Utils.p("WARN: currencyTable.csv has invalid line:" + line);
continue;
}
Currency cur = new Currency(splitTmp);
//Utils.p("Currency found from currencyTable.csv :" + cur.getCurrencyCode());
if (codeMap.containsKey(cur.getCurrencyCode())) {
//发现重复CODE,合并
codeMap.get(cur.getCurrencyCode()).mergeToThis(cur);
Utils.p("CODE重复(将合并): " + cur.getCurrencyCode());
} else {
codeMap.put(cur.getCurrencyCode(), cur);
}
//更新 cur
cur = codeMap.get(cur.getCurrencyCode());
for (String info : cur.getAliasCurrencyNames()) {
if (curMap.containsKey(info)) {
//Utils.p("--> CURRENCY重复:" + info);
} else {
curMap.put(info, cur);
}
}
for (String info : cur.getAliasCountryNames()) {
if (cntMap.containsKey(info)) {
//Utils.p("--> Country重复:" + info);
} else {
cntMap.put(info, cur);
}
}
}
reader.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
} finally {
}
}
/**
* 货币名查代码
* @param currency
* @return
*/
public static String currency2code(String currency) {
if (curMap.containsKey(currency) == false) {
return "";
}
return curMap.get(currency).getCurrencyCode();
}
/**
* xx国的货币名
* @param country
* @return
*/
public static String getCurrencyFromCountry(String country) {
if (cntMap.containsKey(country) == false) {
return "";
}
return cntMap.get(country).getPreferredCurrencyName();
}
/**
* xx是什么国家的货币
* @param currency
* @return
*/
public static String getCountryFromCurrency(String currency) {
if (curMap.containsKey(currency) == false) {
return "";
}
return curMap.get(currency).getPreferredCountryName();
}
public static void main(String[] args) {
Utils.p("done");
}
}
class Currency {
private String currencyCode = "";
private String preferredCurrencyName = "";
private Set<String> aliasCurrencyNames = new HashSet<String>();
private String preferredCountryName = "";
private Set<String> aliasCountryNames = new HashSet<String>();
public Currency(String[] info) {
if (info == null || info.length != 3) {
return;
}
String[] curArray = info[1].trim().split("\|");
String[] cntArray = info[2].trim().split("\|");
if (curArray == null || cntArray == null || curArray.length == 0 || cntArray.length == 0) {
return;
}
this.currencyCode = info[0].trim();
this.preferredCurrencyName = curArray[0];
this.aliasCurrencyNames = new HashSet<String>(Arrays.asList(curArray));
this.preferredCountryName = cntArray[0];
this.aliasCountryNames = new HashSet<String>(Arrays.asList(cntArray));
}
public void mergeToThis (Currency newCur) {
this.aliasCountryNames.addAll(newCur.getAliasCountryNames());
this.aliasCurrencyNames.addAll(newCur.getAliasCurrencyNames());
}
public String getPreferredCurrencyName() {
return preferredCurrencyName;
}
public Set<String> getAliasCurrencyNames() {
return aliasCurrencyNames;
}
public String getPreferredCountryName() {
return preferredCountryName;
}
public Set<String> getAliasCountryNames() {
return aliasCountryNames;
}
public String getCurrencyCode() {
return currencyCode;
}
}
ExHandler.java
处理语义和结果的类。
package exchangerate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ExHandler {
private String input = "";
private JSONObject nliResultJson = null;
private JSONObject resultJson = null;
//计算后的值,缓存用于界面显示
private float calculatedSrc = 0;
private float calculatedDst = 0;
private static final SimpleDateFormat yyyymmdd_sd = new SimpleDateFormat("yyyyMMdd");
protected DetailContext detailContext = new DetailContext(false);
public ExHandler(String input) {
this.input = input;
this.nliResultJson = this.getNliResult();
}
private JSONObject getNliResult() {
if (Utils.isEmpty(nliResultJson) == false) {
return nliResultJson;
}
return new NLI(this.input).getNliResult();
}
public String getNliResultForShow() {
JSONObject ret = getParsedSemantic();
if (Utils.isEmpty(ret)) {
ret = this.getNliResult();
}
return Utils.formatJson(ret);
}
public String getResultString() {
if (this.resultJson == null) {
this.resultJson = this.getResult();
}
if (false == "ok".equalsIgnoreCase(this.resultJson.optString("status"))) {
return "出错!" + this.resultJson.optString("info");
}
return this.resultJson.optString("info");
}
private JSONObject getParsedSemantic() {
return NLI.parseSemantic(this.getNliResult());
}
private JSONObject getResult() {
if (Utils.isEmpty(this.getParsedSemantic())) {
return errResult("获取语义失败!");
}
String modifier = getModifier();
String srcNumStr = getSlotValue("src_number");
String dstNumStr = getSlotValue("dst_number");
String srcMoney = getSlotValue("src_money");
String dstMoney = getSlotValue("dst_money");
String srcPlace = getSlotValue("src_place");
String dstPlace = getSlotValue("dst_place");
String time = getSlotValue("time");
// "100" to 100.0
float srcNum = str2float(srcNumStr);
float dstNum = str2float(dstNumStr);
// "人民币" to "CNY"
String srcMoneyCode = currency2code(srcMoney);
String dstMoneyCode = currency2code(dstMoney);
float rate = -1;
if ("can".equalsIgnoreCase(modifier) && (Utils.isEmpty(dstMoney) == false || Utils.isEmpty(srcMoney) == false)) {
//把 “你知道港元跟日元之间的汇率吗” 这种语义直接转成 “港元跟日元之间的汇率” 语义
modifier = "query";
}
switch (modifier) {
case "query" :
if (Utils.isEmpty(srcPlace) == false || Utils.isEmpty(dstPlace) == false) {
//查新加坡汇率
//我要去德国,帮我查一下汇率
String country = Utils.isEmpty(srcPlace) ? dstPlace : srcPlace;
String dstM = CurrencyTable.getCurrencyFromCountry(country);
String dstCode = currency2code(dstM);
if (Utils.isEmpty(dstCode)) {
return errResult("不支持【" + country + "】的货币汇率查询。");
}
if ("CNY".equalsIgnoreCase(dstCode)) {
//return okResult("不出境不需要兑外汇。");
dstCode = "USD";
dstM = "美元";
}
rate = getRate("CNY", dstCode);
detailContext = new DetailContext(true, 1, rate, "CNY", dstCode);
return okResult("1人民币可兑换【" + rate + dstM + "】");
}
if (Utils.isEmpty(srcMoneyCode) == false) {
String srcCode = srcMoneyCode;
String dstCode = dstMoneyCode;
String srcM = srcMoney;
String dstM = dstMoney;
if (Utils.isEmpty(dstMoneyCode) == false) {
//美元兑换成人民币
} else {
//美元的汇率是多少
if ("CNY".equalsIgnoreCase(srcCode)) {
dstCode = "USD";
dstM = "美元";
} else {
dstCode = "CNY";
dstM = "人民币";
}
}
rate = getRate(srcCode, dstCode);
detailContext = new DetailContext(true, 1, rate, srcCode, dstCode);
return okResult("1" + srcM + "可兑换【" + rate + dstM + "】");
}
if (Utils.isEmpty(time) == false) {
//今日汇率
rate = getDayRate("CNY", time);
detailContext = new DetailContext(true, 1, rate, "USD", "CNY");
return okResult("【" + time + "】美元兑人民币汇率【" + rate + "】");
}
rate = getRate("USD", "CNY");
detailContext = new DetailContext(true, 1, rate, "USD", "CNY");
return okResult("美元兑人民币汇率【" + rate + "】");
case "query_change" :
if (Utils.isEmpty(time) == false) {
//今天的汇率有什么变化
rate = getDa