伪代码
public class MainTestwei
{
定义两个数组,List<Double> number和 List<Character>calculation分别用来装数字和 计算符
//与老师上课讲的入栈出栈差不多
public Count() {}方法初始化number和 calculation
public void init()方法清空数组
private boolean check()方法检查输入算式是否合法同时检查数字个数是否比计算符个数大1
private int findCount(String text, String regex, int len)方法返回输入的算式中匹配正则表达式得到元素的个数
private void setValue()给number和 calculation数组定初值(应用正则表达式)
private double sum()用case语句进行求值,注意*/在前+-在后
public String out(String text)判断是否合法,合法输出结果,不合法输出error
}
各个方法的依次实现
1.初始化number和 calculation
public Count() {
number = new ArrayList<>();
calculation = new ArrayList<>();
}
其中已经提前定义过
private List<Double> number;
private List<Character> calculation;
private String text;
即number是
2.private int findCount(String text, String regex, int len)方法返回输入的算式中匹配正则表达式得到元素的个数。代码如下
private int findCount(String text, String regex, int len) {
int count = 0;
Pattern compile = Pattern.compile(regex);
Matcher matcher = compile.matcher(text);
while (matcher.find()) {
count++;
if (len > 0) {//
System.out.println(matcher.group().length());
if (matcher.group().length() != len)//不理解matcher.group().length()
{
System.out.println(matcher.group().length());
return -1;
}
}
}
return count;
其中
matcher.group().length()
是关于正则表达式中含有括号的个数。如
regex1 = "[+\-*/]+"它的matcher.group().length()即为1.因为中。间没有()分割。
regex = "\d+"它的matcher.group().length()也为1.
matcher.group()即为一次匹配得到的所有,不考虑括号()问题,而matcher.group(i)即为匹配第i个括号中所得到的表达式。
其中
if (len > 0) {//为什么
System.out.println(matcher.group().length());
if (matcher.group().length() != len)//不理解matcher.group().length()
{
return -1;
}
是为了避免式子中出现括号。
3.private boolean check()方法检查输入算式是否合法同时检查数字个数是否比计算符个数大1。
代码如下
private boolean check() {
if (text == null || !text.matches("[0-9+\\-*/]+"))//正则表达式不太理解
return false;
String regex= "\\d+";
String regex1 = "[+\\-*/]+";
if (findCount(text, regex1, 1) == -1)
return false;
return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;
}
regex是匹配数字用的正则表达式,regex1是匹配+ -/的正则表达式,而-/ 都需要转义,故在前面加上//。
如果出现括号则error,否则如果数字个数比字符个数多1,则正确,返回true。
4.private void setValue()给number和 calculation数组定初值(应用正则表达式),代码如下:
private void setValue() {
Pattern compile = Pattern.compile("\\d+");
Matcher matcher = compile.matcher(text);
while (matcher.find()) {
number.add(Double.parseDouble(matcher.group()));
}
Pattern compile1 = Pattern.compile("[+-/*]");
Matcher matcher1 = compile1.matcher(text);
while (matcher1.find()) {
calculation.add(matcher1.group().charAt(0));
}
}
matcher.group()代表的就是匹配的内容,因为数字与字符交替排列,故每次add matcher.group()即可,转化为Double型。
5.private double sum()用case语句进行求值,注意*/在前+-在后。
代码如下:
private double sum() {
for (int i = 0; i < calculation.size(); i++) {
char c = calculation.get(i);
switch (c) {
case '*':
number.set(i, number.get(i) * number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;//为什么要加i=i-1;
break;
case '/':
number.set(i, (Double) number.get(i) / number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
}
}
for (int i = 0; i < calculation.size(); i++) {
char c = calculation.get(i);
switch (c) {
case '+':
number.set(i, number.get(i) + number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
case '-':
number.set(i, (Double) number.get(i) - number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
}
}
return number.get(0);
}
其中为什么需要i=i-1?
因为上面有 for (int i = 0; i < calculation.size(); i++)循环,当你执行 calculation.remove(i);之后,i所指向的已经是下一个符号或者是数字了,但因为for循环仍然需要i++,故要提前把i-1。
此处与栈的操作类型有几分相似之处,再MyDC.java中,经过
while (tokenizer.hasMoreTokens()) //进行遍历
{
token = tokenizer.nextToken();
//token是单字符的字符串
//如果是运算符,调用isOperator
if (isOperator(token)==true) {
op2=stack.pop();
op1=stack.pop();
//从栈中弹出操作数2
//从栈中弹出操作数1
result=evalSingleOp(token.charAt(0),op1,op2);
//根据运算符和两个操作数调用evalSingleOp计算result;
stack.push(result);
//计算result入栈;
}
else//如果是操作数
{
stack.push(Integer.parseInt(token));//需要转化为int型
}
//操作数入栈;
}
6.public String out(String text)判断是否合法,合法输出结果,不合法输出error
代码如下
public String out(String text) {
init();
if (getString(text)) {
return sum() +"";//sum()为double类型,需要转化为字符串类型,则加上“”即可
} else {
return "error";
}
}
其中init()用clear()方法即可。
最终代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainTest {
public static void main(String[] args) {
while (true) {
Scanner input = new Scanner(System.in);
String text = input.nextLine();
String string = new Count().out(text);
System.out.println(string);
}
}
}
class Count {
private List<Double> number;
private List<Character> calculation;
private String text;
public Count() {
number = new ArrayList<>();
calculation = new ArrayList<>();
}
public String out(String text) {
init();
if (getString(text)) {
return sum() +"";
} else {
return "error";
}
}
private double sum() {
for (int i = 0; i < calculation.size(); i++) {
char c = calculation.get(i);
switch (c) {
case '*':
number.set(i, number.get(i) * number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;//为什么要加i=i-1;
break;
case '/':
number.set(i, (Double) number.get(i) / number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
}
}
for (int i = 0; i < calculation.size(); i++) {
char c = calculation.get(i);
switch (c) {
case '+':
number.set(i, number.get(i) + number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
case '-':
number.set(i, (Double) number.get(i) - number.get(i + 1));
number.remove(i + 1);
calculation.remove(i);
i -= 1;
break;
}
}
return number.get(0);
}
public void init() {
number.clear();//清空数组
calculation.clear();
}
public boolean getString(String text) {
this.text = text;
if (check()) {
setValue();
return true;
}
return false;
}
private void setValue() {
Pattern compile = Pattern.compile("\\d+");
Matcher matcher = compile.matcher(text);
while (matcher.find()) {
number.add(Double.parseDouble(matcher.group()));
}
Pattern compile1 = Pattern.compile("[+-/*]");
Matcher matcher1 = compile1.matcher(text);
while (matcher1.find()) {
calculation.add(matcher1.group().charAt(0));
}
}
private boolean check() {
if (text == null || !text.matches("[0-9+\\-*/]+"))//正则表达式不太理解
return false;
String regex = "\\d+";
String regex1 = "[+\\-*/]+";
if (findCount(text, regex1, 1) == -1)
return false;
return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;
}
private int findCount(String text, String regex, int len) {
int count = 0;
Pattern compile = Pattern.compile(regex);
Matcher matcher = compile.matcher(text);
while (matcher.find()) {
count++;
if (len > 0) {//为什么
System.out.println(matcher.group().length());
if (matcher.group().length() != len)//不理解matcher.group().length()
{
return -1;
}
}
}
return count;
}
}