分解四则算式(例如:4+5-6)

ihrthk
博客专家认证
2012-04-22 07:57:15
请贴正则表达式,或可运行的代码。
...全文
242 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
4+5-6 这种表达式称为中缀表达式(运算符位于两个操作数的当中,故称为中缀表达式),
这种表达式适合人进行计算不适合计算机计算,因为其中有运算符的优先级别和改变优先级别的括
号。一般先将其转为后缀表达式(即运算符在操作数的后面)。

中缀表达式:4+5-6 转为后缀表达式为:4 5 + 6 -

得到这个后缀表达式后,使用空格将其拆成 String[]

1:初始化空栈;
2:从索引 0 开始遍历 String[]
3:如果为操作数,则将其压入栈中;
4:如果为运算符,将栈中的数弹出两次,后弹出的数与先弹出的数进行运算,将结果再压回栈中;
5:遍历完成;
6:这时栈中应该只有一个元素,将其弹出,这个元素就是计算结果。

原来写的代码,参考一下。仅支持括号、加、减、乘、除、冪、小数点、正负号,暂时还不能对表达式的正确性做出检查。

public class Test {

public static void main(String[] args) {
String expr = "+5+-5";
Calculator cal = new Calculator();
double d = cal.eval(expr);
System.out.println(d);
}
}


数学符号常量接口:MathSymbol.java

public interface MathSymbol {

/**
* 左括号
*/
public final static char LEFT_BRACKET = '(';

/**
* 右括号
*/
public final static char RIGHT_BRACKET = ')';

/**
* 中缀表达式中的空格,需要要忽略
*/
public final static char BLANK = ' ';

/**
* 小数点符号
*/
public final static char DECIMAL_POINT = '.';

/**
* 负号
*/
public final static char NEGATIVE_SIGN = '-';

/**
* 正号
*/
public final static char POSITIVE_SIGN = '+';

/**
* 后缀表达式的各段的分隔符
*/
public final static char SEPARATOR = ' ';
}


计算器:Calculator.java
import java.util.Stack;

public class Calculator implements MathSymbol {

/**
* 计算中缀表达式
* @param expression
* @return
*/
public double eval(String expression) {
String str = infix2Suffix(expression);
System.out.println(" Infix Expression: " + expression);
System.out.println("Suffix Expression: " + str);
if(str == null) {
throw new IllegalArgumentException("Expression is null!");
}
String[] strs = str.split("\\s+");
Stack<String> stack = new Stack<String>();
for(int i = 0; i < strs.length; i++) {
if(!Operator.isOperator(strs[i])) {
stack.push(strs[i]);
} else {
Operator op = Operator.getInstance(strs[i]);
double right = Double.parseDouble(stack.pop());
double left = Double.parseDouble(stack.pop());
double result = op.eval(left, right);
stack.push(String.valueOf(result));
}
}
return Double.parseDouble(stack.pop());
}

/**
* 将中缀表达式转换为后缀表达式
* @param expression
* @return
*/
public String infix2Suffix(String expression) {
if(expression == null) {
return null;
}
char[] chs = expression.toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder sb = new StringBuilder(chs.length);
boolean appendSeparator = false;
boolean sign = true;
for(int i = 0; i < chs.length; i++) {
char c = chs[i];
if(c == BLANK) {
continue;
}
// Next line is used output stack information.
// System.out.printf("%-20s %s%n", stack, sb.toString());
if(appendSeparator) {
sb.append(SEPARATOR);
appendSeparator = false;
}
if(isSign(c) && sign) {
sb.append(c);
continue;
}
if(isNumber(c)) {
sign = false;
sb.append(c);
continue;
}
if(isLeftBracket(c)) {
stack.push(c);
continue;
}
if(isRightBracket(c)) {
sign = false;
while(stack.peek() != LEFT_BRACKET) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
stack.pop();
continue;
}
appendSeparator = true;
if(Operator.isOperator(c)) {
sign = true;
if(stack.isEmpty() || stack.peek() == LEFT_BRACKET) {
stack.push(c);
continue;
}
int precedence = Operator.getPrority(c);
while(!stack.isEmpty() && Operator.getPrority(stack.peek()) >= precedence) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
stack.push(c);
}
}
while(!stack.isEmpty()) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
return sb.toString();
}

/**
* 判断某个字符是否是正号或者负号
* @param c
* @return
*/
private boolean isSign(char c) {
if(c == NEGATIVE_SIGN || c == POSITIVE_SIGN) {
return true;
}
return false;
}

/**
* 判断某个字符是否为数字或者小数点
* @param c
* @return
*/
private boolean isNumber(char c) {
if((c >= '0' && c <= '9') || c == DECIMAL_POINT) {
return true;
}
return false;
}

/**
* 判断某个字符是否为左括号
* @param c
* @return
*/
private boolean isLeftBracket(char c) {
return c == LEFT_BRACKET;
}

/**
* 判断某个字符是否为右括号
* @param c
* @return
*/
private boolean isRightBracket(char c) {
return c == RIGHT_BRACKET;
}
}


运算符类:Operator.java

import java.util.HashMap;
import java.util.Map;

public abstract class Operator {

/**
* 运算符
*/
private char operator;

/**
* 运算符的优先级别,数字越大,优先级别越高
*/
private int priority;

private static Map<Character, Operator> operators = new HashMap<Character, Operator>();

private Operator(char operator, int priority) {
setOperator(operator);
setPriority(priority);
register(this);
}

private void register(Operator operator) {
operators.put(operator.getOperator(), operator);
}

/**
* 加法运算
*/
public final static Operator ADITION = new Operator('+', 100) {
public double eval(double left, double right) {
return left + right;
}
};

/**
* 减法运算
*/
public final static Operator SUBTRATION = new Operator('-', 100) {
public double eval(double left, double right) {
return left - right;
}
};

/**
* 乘法运算
*/
public final static Operator MULTIPLICATION = new Operator('*', 200) {
public double eval(double left, double right) {
return left * right;
}
};

/**
* 除法运算
*/
public final static Operator DIVITION = new Operator('/', 200) {
public double eval(double left, double right) {
return left / right;
}
};

/**
* 冪运算
*/
public final static Operator EXPONENT = new Operator('^', 300) {
public double eval(double left, double right) {
return Math.pow(left, right);
}
};

public char getOperator() {
return operator;
}
private void setOperator(char operator) {
this.operator = operator;
}
public int getPriority() {
return priority;
}
private void setPriority(int priority) {
this.priority = priority;
}

/**
* 根据某个运算符获得该运算符的优先级别
* @param c
* @return 运算符的优先级别
*/
public static int getPrority(char c) {
Operator op = operators.get(c);
if(op != null) {
return op.getPriority();
}
return 0;
}

/**
* 工具方法,判断某个字符是否是运算符
* @param c
* @return 是运算符返回 true,否则返回 false
*/
public static boolean isOperator(char c) {
return getInstance(c) != null;
}
public static boolean isOperator(String str) {
if(str.length() > 1) {
return false;
}
return isOperator(str.charAt(0));
}

/**
* 根据运算符获得 Operator 实例
* @param c
* @return 从注册中的 Operator 返回实例,尚未注册返回 null
*/
public static Operator getInstance(char c) {
return operators.get(c);
}
public static Operator getInstance(String str) {
if(str.length() > 1) {
return null;
}
return getInstance(str.charAt(0));
}

/**
* 根据操作数进行计算
* @param left 左操作数
* @param right 右操作数
* @return 计算结果
*/
public abstract double eval(double left, double right);
}

  • 打赏
  • 举报
回复
你把正则表达式当作什么了?

这是语法分析、词法分析的工作!
sdojqy1122 2012-04-22
  • 打赏
  • 举报
回复
我只是为了得到+-*/然后计算,把数字和操作符分开。
ihrthk 2012-04-22
  • 打赏
  • 举报
回复
String op = str.replaceAll("\\d+","");
请教这行代码是什么是意思,重点"\\d+"是什么意思,\\我知道是转义的意思,d是0-9的数字,+是一次或多次。我的理解就是字符串所有的d字母,转换为空。
请教正确的理解方式,谢谢。
sdojqy1122 2012-04-22
  • 打赏
  • 举报
回复
手写犯错误了。

public class SleepTest {
public static void main(String[] args) throws InterruptedException {
String str="34+5-6";
String numbers[] =str.split("[\\+-/\\*]");
String op = str.replaceAll("\\d+","");
char opp[] =op.toCharArray();
for(int i=0;i<numbers.length-1;i++){
switch(opp[i]){
case '+':
numbers[i+1] = String.valueOf(Integer.parseInt(numbers[i]) + Integer.parseInt(numbers[i+1]));
break;
case '-':
numbers[i+1] = String.valueOf(Integer.parseInt(numbers[i])-Integer.parseInt(numbers[i+1]));
break;
}
}
System.out.print("the answer is:"+numbers[numbers.length-1]);
}
}
ihrthk 2012-04-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
String str="4+5-6";
String numbers[] =str.split("[\\+-/\\*]");
String op = str.replaceAll("[\\+-/\\*]","");
char opp[] =op.toCharArray();
for(int i=0;i<numbers.length-1;i++){
switch(opp[i]){
cas……
[/Quote]
String numbers[] =str.split("[\\+-/\\*]");
如下写可以不?
String numbers[] =str.split("[\\+-\\*/]");
你这里,还有一个很重要的问题没有处理:操作数可能是两位数哦,比如:34+5-6
sdojqy1122 2012-04-22
  • 打赏
  • 举报
回复
刚才本来写了乘除,想到不能用Integer处理,要用double,为了简化过程,就写+-了,如果有括号,这种题目用栈好处理。
sdojqy1122 2012-04-22
  • 打赏
  • 举报
回复
String str="4+5-6";
String numbers[] =str.split("[\\+-/\\*]");
String op = str.replaceAll("[\\+-/\\*]","");
char opp[] =op.toCharArray();
for(int i=0;i<numbers.length-1;i++){
switch(opp[i]){
cash '+':numbers[i+1] =String.valueOf(Integer.parseInt(numbers[i])+Integer.parInt(numbers[i+1]));
break;
cash '-':numbers[i+1] =String.valueOf(Integer.parseInt(numbers[i])-Integer.parInt(numbers[i+1]));
break;
}
}
System.out.print("the answer is:"+numbers[numbers.length-1]);
ihrthk 2012-04-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
怎么算分解?
[/Quote]
不好意思,
String str="4+5-6";
int n=4+5-6;
求出n
sdojqy1122 2012-04-22
  • 打赏
  • 举报
回复
怎么算分解?

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧