这个作业属于哪个课程 | 软件工程 (福州大学至诚学院 - 计算机工程系) |
---|---|
这个作业要求在哪里 | 第一次个人编程作业 |
这个作业的目标 | 实现功能、熟练使用git和GitHub |
作业正文 | 如下 |
其他参考文献 | 如下 |
GitHub仓库地址:learn-programming
看到题目零碎的想法
- 木兰
- 留学生的文言文编程语言
- C语言的宏定义
零碎的想法对问题的解决并没有什么帮助,所以开始搜相关案例
搜索
搜索关键字“中文编程”,意外看到了一个Github项目
中文编程的历史, 现状和展望
Java采用Unicode字符集,所以变量、方法名、类名等都可以定义为中文,所以有一种实现“中文编程”的方式就是把类名、变量名都定义为中文,但是这种方式还是不能脱离Java的关键字,所以这种方方式不符合这次的要求
开心一下-实现基于Java一个中文编程语言
没有找到相关案例,最后就从语义的角度开始分析:可以通过截取字符串来获取关键词、变量和常量,再进行逻辑操作
分析
需求分析
- 整数变量定义、赋值
- 加减运算
- 输出变量或字符串
- 三目运算:如果 则 否则
需要解决的问题
- 字符串截取
- 字符串语义判断
- 异常处理
- 负数,多位数
遇到的一些坑
- 字符串split的时候左右边的空格会被加入到split返回的数组
完整代码
主函数
public class DemoMain {
public static void main(String[] args) {
Map map = new HashMap();
Scanner sc = new Scanner(System.in);
while (true) {
Utils.callFunction(sc.nextLine().trim(), map);
}
}
}
Utils类
public class Utils {
public static String numWords = "零一二三四五六七八九十";
/**
* 调用方法
* @param str
* @param map
*/
public static void callFunction(String str, Map map) {
String[] split = str.trim().split(" ");
String keyword = split[0];
if (map.get(keyword) != null) {
Utils.manipulateNum(str, map);
} else {
switch (keyword) {
case "整数":
// System.out.println(map.get("钱包"));// 不存在返回null
int num = Utils.assignInt(split);
map.put(split[1], num);
break;
case "看看":
Utils.printOut(split, map);
break;
case "如果":
Utils.ternaryOperator(str, map);
break;
default:
throw new IllegalArgumentException("judgeOperator 没有对应的判断符号请输入(整数、看看、如果): " + keyword);
}
}
}
@Test
public void testCall() {
Map map = new HashMap();
callFunction("整数 气温 等于 十", map);
callFunction("气温 减少 三", map);
callFunction("气温 增加 二", map);
callFunction("看看 气温", map);
callFunction("如果 气温 大于 八 则 看看 “你好,世界” 否则 看看 “冻死我了”", map);
//
callFunction("整数 钱包 等于 零", map);
callFunction("钱包 增加 四", map);
callFunction("钱包 减少 一", map);
callFunction("看看 钱包 ", map);
callFunction("看看 “字符串”", map);
callFunction("如果 钱包 大于 二 则 看看 “钱太多了” 否则 看看 “我穷死了”", map);
}
/**
* 赋值整数变量
* @param array
* @return
*/
public static int assignInt(String[] array) {
// 先考虑一位情况
return toNum(array[3]);
}
/**
* 输出字符串或者变量
* @param array
* @param map
*/
public static void printOut(String[] array, Map map) {
String printStr = array[1];
if (printStr.contains("“") && printStr.contains("”")) {
System.out.println(printStr.replace("“", "").replace("”", ""));
} else {
System.out.println(toChStr(map.get(printStr)));
}
}
@Test
public void testPrintOut() {
Map map = new HashMap();
map.put("钱包", 10);
Utils.printOut("看看 钱包 ".split(" "), map);
Utils.printOut("看看 “字符串” ".split(" "), null);
}
/**
* 三目运算
* @param str
* @param map
*/
public static void ternaryOperator(String str, Map map) {
// 如果 钱包 大于 十 则 看看 “钱太多了” 否则 看看 “我穷死了”
// 先不考虑三目嵌套三目的情况
String statement1 = str.substring(0, str.indexOf("则")).replace("如果", "");
String statement2 = str.substring(str.indexOf("则"), str.indexOf("否则")).replace("则", "");
String statement3 = str.substring(str.indexOf("否则")).replace("否则", "");
boolean judge = judgeOperator(statement1, map);
// System.out.println(judge);
if( judge) {
callFunction(statement2, map);
}else {
callFunction(statement3, map);
}
}
@Test
public void testTernary() {
Map map = new HashMap();
map.put("钱包", 10);
ternaryOperator("如果 钱包 等于 十 则 看看 “钱太多了” 否则 看看 “我穷死了”", map);
}
/**
* 判断语句,传入如果语句 例如:零 等于 零
* @param str
* @param map
* @return
*/
public static boolean judgeOperator(String str, Map map) {
String[] strArray = str.trim().split(" ");// 不去除左右空格,空格会被加入到分割数组
String leftStr = strArray[0];
String rightStr = strArray[2];
String middle = strArray[1];
int leftInt = 0;
int rightInt = 0;
if (map.get(leftStr) != null) {
leftInt = map.get(leftStr);
} else {
leftInt = toNum(leftStr);
}
if (map.get(rightStr) != null) {
rightInt = map.get(rightStr);
} else {
rightInt = toNum(rightStr);
}
switch (middle) {
case "等于":
return leftInt == rightInt;
case "大于":
return leftInt > rightInt;
case "小于":
return leftInt < rightInt;
default:
throw new IllegalArgumentException("judgeOperator没有对应的判断符号请输入(大于、等于、小于): " + middle);
}
}
@Test
public void testJudge() {
Map map = new HashMap();
map.put("钱包", 10);
System.out.println(judgeOperator("零 等于 零", map));
}
/**
* 汉字转化为数字
* @return
*/
public static int toNum(String str) {
return numWords.indexOf(str);// -1不存在
}
/**
* 数字转化为汉字
* @param num
* @return
*/
public static String toChStr(int num) {
return numWords.substring(num,num+1);
}
/**
* 运算操作
* @param str
* @param map
*/
public static void manipulateNum(String str, Map map) {
String[] strArray = str.trim().split(" ");
String varStr = strArray[0];
String operator = strArray[1];
String numStr = strArray[2];
int num = 0;
if (map.get(varStr) != null) {
num = map.get(varStr);
} else {
throw new DemoException("变量:" + varStr + " 未定义");
}
switch (operator) {
case "减少":
num -= toNum(numStr);
map.put(varStr, num);
break;
case "增加":
num += toNum(numStr);
map.put(varStr, num);
break;
default:
throw new IllegalArgumentException("manipulateNum没有对应的判断符号请输入(增加、减少): " + operator);
}
}
@Test
public void testManipulate() {
Map map = new HashMap();
map.put("钱包", 10);
manipulateNum("钱包 减少 四", map);
System.out.println(map.get("钱包"));
}
}
Exception类
public class DemoException extends RuntimeException {
public DemoException() {
super();
}
public DemoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public DemoException(String message, Throwable cause) {
super(message, cause);
}
public DemoException(String message) {
super(message);
}
public DemoException(Throwable cause) {
super(cause);
}
}
数据测试
编程记录
第一次提交的代码行数(包括文档注释和单元测试):260+
查资料+需求分析时间:2小时左右
第一次完成编码时间:4小时左右
思路
代码有三个类
- DemoMain 存放主函数(处理传入的字符串,分割成行)
- Utils 字符处理的工具类
- DemoException (Demo的异常处理)
Utils类
- callFunction 传入一行字符串,判断逻辑逻辑关键字并调用对应的方法
- assignInt 整数赋值
- printOut 输出字符串或者整数
- ternaryOperator 三目操作
- judgeOperator 判断语句(举例:零 等于 零)
- toNum 把中文数字转化为数字
- toChStr 把数字转化为中文数字
- manipulateNum 增减运算
主要是根据功能的不同来分类,对于一些会被其他类经常用到的就单独抽取出来类如:toNum()和toChStr()和judgeOperator()
把toNum()和toChStr()划分出来有利于代码的迭代更新,目前仅实现了一位数字的运算,通过修改这两个方法就可以实现负数和多位数字的运算
public static String numWords = "零一二三四五六七八九十";
public static int toNum(String str) {
return numWords.indexOf(str);
}
public static String toChStr(int num) {
return numWords.substring(num,num+1);
}
代办
- 负数和多位数字的运算
- 完善异常处理