[英]Can someone explain how this code works? (StringBuffer & StringTokenizer)
我正在寻找有关如何计算数学表达式的方法,这些数学表达式可以计算诸如sin(90)
和10E8
,直到我看到这些我无法完全理解其工作原理的代码。 我想以此为基础,因为我想改进我的MDAS计算器。
我很难理解这些代码。 我不熟悉StringBuffer
, StringTokenizer
, Math.ceil
, ans += mul();
, ( b.toString(), "\\t" );
,但我对三角函数和MDAS运算的工作原理有所了解。
更新:我了解什么是StringTokenizer
但它与StringBuffer
什么关系?
import java.util.*;
public class Expression {
String s, x;
double term() {
double ans = 0;
StringBuffer temp = new StringBuffer();
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
temp.append(Integer.parseInt("" + s.charAt(0)));
s = s.substring(1);
}
if (s.length() > 0 && s.charAt(0) == '.') {
temp.append('.');
s = s.substring(1);
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
temp.append(Integer.parseInt("" + s.charAt(0)));
s = s.substring(1);
}
}
if (s.length() > 0 && (s.charAt(0) == 'e' || s.charAt(0) == 'E')) {
temp.append('e');
s = s.substring(1);
temp.append(s.charAt(0));
s = s.substring(1);
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
temp.append(Integer.parseInt("" + s.charAt(0)));
s = s.substring(1);
}
}
ans = Double.valueOf(temp.toString()).doubleValue();
return ans;
}
double paren() {
double ans;
if (s.charAt(0) == '(') {
s = s.substring(1);
ans = add();
s = s.substring(1);
} else {
ans = term();
}
return ans;
}
double exp() {
boolean neg = false;
if (s.charAt(0) == '-') {
neg = true;
s = s.substring(1);
}
double ans = paren();
while (s.length() > 0) {
if (s.charAt(0) == '^') {
s = s.substring(1);
boolean expNeg = false;
if (s.charAt(0) == '-') {
expNeg = true;
s = s.substring(1);
}
double e = paren();
if (ans < 0) {
double x = 1;
if (Math.ceil(e) == e) {
if (expNeg)
e *= -1;
if (e == 0)
ans = 1;
else if (e > 0)
for (int i = 0; i < e; i++)
x *= ans;
else
for (int i = 0; i < -e; i++)
x /= ans;
ans = x;
} else {
ans = Math.log(-1);
}
} else if (expNeg)
ans = Math.exp(-e * Math.log(ans));
else
ans = Math.exp(e * Math.log(ans));
} else
break;
}
if (neg)
ans *= -1;
return ans;
}
double trig() {
double ans = 0;
boolean found = false;
if (s.indexOf("sin") == 0) {
s = s.substring(3);
ans = Math.sin((trig() * Math.PI) / 180);
found = true;
} else if (s.indexOf("cos") == 0) {
s = s.substring(3);
ans = Math.cos((trig() * Math.PI) / 180);
found = true;
} else if (s.indexOf("tan") == 0) {
s = s.substring(3);
ans = Math.tan((trig() * Math.PI) / 180);
found = true;
}
if (!found) {
ans = exp();
}
return ans;
}
double mul() {
double ans = trig();
if (s.length() > 0) {
while (s.length() > 0) {
if (s.charAt(0) == '*') {
s = s.substring(1);
ans *= trig();
} else if (s.charAt(0) == '/') {
s = s.substring(1);
ans /= trig();
} else
break;
}
}
return ans;
}
double add() {
double ans = mul();
while (s.length() > 0) {
if (s.charAt(0) == '+') {
s = s.substring(1);
ans += mul();
} else if (s.charAt(0) == '-') {
s = s.substring(1);
ans -= mul();
} else {
break;
}
}
return ans;
}
public double evaluate() {
s = x.intern();
double last = add();
return last;
}
public Expression(String s) {
StringBuffer b = new StringBuffer();
StringTokenizer t = new StringTokenizer(s, " ");
while (t.hasMoreElements())
b.append(t.nextToken());
t = new StringTokenizer(b.toString(), "\t");
b = new StringBuffer();
while (t.hasMoreElements())
b.append(t.nextToken());
x = b.toString();
}
public String toString() {
return x.intern();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter expression: ");
Expression e = new Expression(sc.nextLine());
System.out.println("\n" + e + " = " + e.evaluate() + "\n");
}
}
该程序通常读取数学表达式的字符串表示形式,并解释和执行该表达式。 至于Java元素,您很好奇:
StringBuffer
是处理String
对象的更有效的接口。
StringTokenizer(String, String)
是用于将字符串分解为令牌的类。 在此构造函数中,第一个参数是可拆分为令牌的字符串,第二个参数是用于创建这些令牌的定界符。
Math.ceil()
返回大于或等于自变量且等于数学整数的最小(最接近负无穷大)双精度值。
StringBuffer.toString()
写出一个代表缓冲区中数据的String
\\t
是标签
+=
和-=
是{add / subject}赋值运算符,它们将{add / subject}右操作数赋给左操作数,并将结果赋给左操作数。 例如
int x = 0;
x += 2; // x is now 2
请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html上有关StringBuffer的javadoc
有关StringTokenizer的信息,请参见javadoc, 网址为http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html
我将尝试评论所有明显的行号
import java.util.*;
public class Expression {
String s, x;
double term() {
double ans = 0;
StringBuffer temp = new StringBuffer(); //Efficient than simple String
while (s.length() > 0 && Character.isDigit(s.charAt(0))) { //Check if the first character is a digit
temp.append(Integer.parseInt("" + s.charAt(0))); //If true, add to temp String
s = s.substring(1);
}
if (s.length() > 0 && s.charAt(0) == '.') {
temp.append('.');
s = s.substring(1);
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
temp.append(Integer.parseInt("" + s.charAt(0)));
s = s.substring(1);
}
}
if (s.length() > 0 && (s.charAt(0) == 'e' || s.charAt(0) == 'E')) {
temp.append('e');
s = s.substring(1);
temp.append(s.charAt(0));
s = s.substring(1);
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
temp.append(Integer.parseInt("" + s.charAt(0)));
s = s.substring(1);
}
}
ans = Double.valueOf(temp.toString()).doubleValue();
return ans;
}
double paren() {
double ans;
if (s.charAt(0) == '(') {
s = s.substring(1);
ans = add();
s = s.substring(1);
} else {
ans = term();
}
return ans;
}
double exp() {
boolean neg = false;
if (s.charAt(0) == '-') {
neg = true;
s = s.substring(1);
}
double ans = paren();
while (s.length() > 0) {
if (s.charAt(0) == '^') {
s = s.substring(1);
boolean expNeg = false;
if (s.charAt(0) == '-') {
expNeg = true;
s = s.substring(1);
}
double e = paren();
if (ans < 0) {
double x = 1;
if (Math.ceil(e) == e) { //Check Math.ceil documentation at http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ceil(double)
if (expNeg)
e *= -1;
if (e == 0)
ans = 1;
else if (e > 0)
for (int i = 0; i < e; i++)
x *= ans;
else
for (int i = 0; i < -e; i++)
x /= ans;
ans = x;
} else {
ans = Math.log(-1); //http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#log(double)
}
} else if (expNeg)
ans = Math.exp(-e * Math.log(ans));
else
ans = Math.exp(e * Math.log(ans)); //http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#exp(double)
} else
break;
}
if (neg)
ans *= -1;
return ans;
}
double trig() {
double ans = 0;
boolean found = false;
if (s.indexOf("sin") == 0) {
s = s.substring(3);
ans = Math.sin((trig() * Math.PI) / 180);
found = true;
} else if (s.indexOf("cos") == 0) {
s = s.substring(3);
ans = Math.cos((trig() * Math.PI) / 180);
found = true;
} else if (s.indexOf("tan") == 0) {
s = s.substring(3);
ans = Math.tan((trig() * Math.PI) / 180);
found = true;
}
if (!found) {
ans = exp();
}
return ans;
}
double mul() {
double ans = trig();
if (s.length() > 0) {
while (s.length() > 0) {
if (s.charAt(0) == '*') {
s = s.substring(1);
ans *= trig();
} else if (s.charAt(0) == '/') {
s = s.substring(1);
ans /= trig();
} else
break;
}
}
return ans;
}
double add() {
double ans = mul();
while (s.length() > 0) {
if (s.charAt(0) == '+') {
s = s.substring(1);
ans += mul();
} else if (s.charAt(0) == '-') {
s = s.substring(1);
ans -= mul();
} else {
break;
}
}
return ans;
}
public double evaluate() {
s = x.intern();
double last = add();
return last;
}
public Expression(String s) {
StringBuffer b = new StringBuffer();
StringTokenizer t = new StringTokenizer(s, " "); //Creates a iterable t object so you can iterate over each "word" separate by space
while (t.hasMoreElements())
b.append(t.nextToken());
t = new StringTokenizer(b.toString(), "\t");
b = new StringBuffer();
while (t.hasMoreElements())
b.append(t.nextToken());
x = b.toString();
}
public String toString() {
return x.intern();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter expression: ");
Expression e = new Expression(sc.nextLine());
System.out.println("\n" + e + " = " + e.evaluate() + "\n");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.