一个字符串里面包含运算符,如何转成正常运算的运算符?

suan2046 2008-10-30 02:01:50
现在有一个字符串 ,比如 String s="40944.0501-3.2*100"

要转换成 可运算的加减乘除。

用java 方法来解析,怎么解析(貌似用到什么编译原理的状态机,但不是很清楚)
...全文
1911 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
chen_yunxing2011 2011-08-30
  • 打赏
  • 举报
回复
感谢,解决问题!!!!!
xcm881026 2011-07-21
  • 打赏
  • 举报
回复
我也是,你写出来了没啊?
gbybywj 2011-03-25
  • 打赏
  • 举报
回复
我有一个想法:
将没有括号时的表达式按照火龙果前辈的方法来做,一遇到括号时,便用递归的方式再次调用,并最终将括号内的结果算出来赋以一个值,拿到括号外面参与运算。由于是递归调用,原则上不必考虑有多少重括号吧。(弱弱的讲?)只是一个想法,不知可行与否。
chendabian 2008-12-21
  • 打赏
  • 举报
回复
研究 研究
zfl110 2008-11-04
  • 打赏
  • 举报
回复
学习
yyh84yangtaohui 2008-11-02
  • 打赏
  • 举报
回复
学习了,不错啊
suan2046 2008-10-31
  • 打赏
  • 举报
回复
实在太感谢了,注释说明又清楚!!
多谢多谢
suan2046 2008-10-31
  • 打赏
  • 举报
回复
实在太感谢了,注释说明又清楚!!
多谢多谢
Strafer_Y 2008-10-30
  • 打赏
  • 举报
回复
这个问题我也想知道一个比较好的解决办法,如果只是简单的+-*/那if是够了,如果有()呢?或是其它的一些符号
  • 打赏
  • 举报
回复
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 final static Operator MOD = new Operator('%', 200) {
public double eval(double left, double right) {
return 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);
}


  • 打赏
  • 举报
回复
原来写的一个,采用中缀转为后缀表达式方式进行计算,现在仅支持正负号、加减乘除、次方和模运算,仅供参考:

public class Test {

public static void main(String[] args) {
String str = "40944.0501-3.2*100";
Calculator cal = new Calculator();
double d = cal.eval(str);
System.out.println(d);
}
}

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 = ' ';
}

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;
}
}
wzchong007 2008-10-30
  • 打赏
  • 举报
回复
如果字符串中的数字是定长就直接取出计算.不是定长就正常取,到有'+''-''*'时(可以用IF判断)停,取出其前面的作为一个变量,后面的同理取出.
meadking 2008-10-30
  • 打赏
  • 举报
回复
看看java计算器的代码是怎么写的,下一个,呵呵
简单的计算就够了!

如果是负责的,要语法分析器的,呵呵

81,095

社区成员

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

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