我有一个使用Java的家庭自动化系统,我想添加简单的数学功能,如加法,减法,乘法,除法,根和幂。
在系统当前状态下,它可以将短语转换为标记,如以下示例所示:
示例:
Phrase: "what is one hundred twenty two to the power of seven"
Tagged: {QUESTION/math} {NUMBER/122} {MATH/pwr} {NUMBER/7}
示例:
Phrase: "twenty seven plus pi 3 squared"
Tagged: {NUMBER/27} {MATH/add} {NUMBER/3.14159} {MATH/multiply} {MATH/pwr} {NUMBER/2}
这个例子可以很容易地转换成这样的东西:
27 + 3.14159 * 3^2
每个标记都是一个可以查询其值的对象。
编辑:具体问题:
所以现在我需要一种方法来将该组标签作为方程式读取,并返回数值结果。作为最后的手段,我可以使用google或wolfram alpha,但这会更慢,我正在努力保持自动化系统完全自包含。
如果您想查看整个来源,here it is in github. 请注意,我没有提交最后几个更改,所以我给出的一些数学相关的东西不起作用。
答案 0 :(得分:3)
经过一些更多的googleing(我最初不知道我在做什么的名字)我找到了一个已经做过类似事情的人:
答案 1 :(得分:1)
pop(), pop(), evaluate(), push();
。这要求你检查个别令牌一个调查运算符和操作数交集的表。这不是你能快速或轻松地做的事情。
答案 2 :(得分:1)
你需要的是一个解析方法,它将构建一个方程并从你的文本中返回一个答案。我将采取一条线,并通过制作这样一种方法,然后你需要自己解决。请注意,这只是一个普遍的想法,除了Java之外的某些语言可能更适合这种操作。
{QUESTION / math} {NUMBER / 122} {MATH / pwr} {NUMBER / 7}
//let's assume that the preprocessor reduces the input to an array that is something like this:
// [122, pwr, 7] (this is a very common construction in a language like LISP).
public static int math(string[] question){
while(i < question.length){
if(question[i] == "pwr"){
return pow(Integer.parseInt(question[i-1]), Integer.parseInt(question[i+1]);
}
i++;
}
return 0;
}
基本上你需要的是一个很好的方法,从中缀到前缀表示法,带一点字符串到任何转换。
这样做的结构可能比我上面制作的更好,但是这样的事情可以让你前进。
答案 3 :(得分:0)
我编写的代码依赖于标签的给定顺序是“NUMBER”“MATH”“NUMBER”“MATH”“NUMBER”并且 完全忽略数学中的操作规则 。它只是只是你可以做什么的概述,所以你可能需要修改它以做你想做的事情。
由于时间不够,我没有测试过这个文件,所以必要时进行调试!
import net.sprakle.homeAutomation.interpretation.tagger.tags.*;
import java.util.List;
import java.util.Arrays;
public class Math {
private Tag[] tags; //Stores the converted tags as a "MathTag"
//Requires an array of tags
public Math(Tag[] inputTags) {
tags = new MathTag[inputTags.length]; //create a new MathTag array
System.arraycopy(inputTags, 0, tags, 0, tags.length); //Convert Tag array to MathTag array
}
//returns a value based on the tags
//TODO: ADD MATHEMATICAL ORDER OF OPERATIONS!!!
public double performMath() {
double value = 0;//initial value to return
for (int i = 0; i < tags.length; i++) { //perform initial check of the phrase given
if (tags[i].getType() = TagType.NUMBER && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i].getValue()), tags[i+1].getType());
} else if (tags[i].getType() = TagType.MATH && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i + 1].getValue()), tag.getType()); //I'm not positive if this would not cause issues
}
}
}
//Perform individual operations given the index of the operation, value1, value2, and the operation type
//The order of the array "operations" must match the order of the operations in the switch statement.
public double peformOperation(int i, double value1, double value2, String operation) {
String[] operations = {"add", "subtract", "multiply", "divide", "pwr", "root"}; //Array of operations
List list = Arrays.asList(operations); //Not exactly effecient, used to check what operation to perform
switch (list.indexOf(operation)) { //Perform a task based on the operation
case 0: //Addition
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 + value2;
case 1: //Subtraction
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 - value2;
case 2: //Multiplication
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value2;
case 3: //Division
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 / value2;
case 4: //Power
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value1;
case 5: //Square Root
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return Math.sqrt(value1);
}
return error(); //Non-valid operation found
}
//Need some way to detect an error
public double error() {
return 0;
}
//Need some way to check if a tag was looked at before
class MathTag extends Tag {
protected static boolean wasChecked = false;
public void setChecked(boolean checked) {
wasChecked = true;
}
public boolean getWasChecked() {
return wasChecked;
}
}
}