输入为字符串,输出为整数,运算符合运算优先级法则,如图,第二行中间有个空格。
可以参考文章 https://blog.csdn.net/leinminna/article/details/100180546
大概如下,看着调整
public static void main(String[] args) throws ScriptException {
Scanner.sc = new Scanner(System.in);
System.out.println(“请输入一行字符串”);
String expression = sc.next();
double result = Calculator.conversion(expression);
System.out.println(expression + " = " + result);
System.out.println();
}
public class Calculator {
private Stack<String> postfixStack = new Stack<String>();// 后缀式栈
private Stack<Character> opStack = new Stack<Character>();// 运算符栈
private int[] operatPriority = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };// 运用运算符ASCII码-40做索引的运算符优先级
public static double conversion(String expression) {
double result = 0;
Calculator cal = new Calculator();
try {
expression = transform(expression);
result = cal.calculate(expression);
} catch (Exception e) {
// e.printStackTrace();
// 运算错误返回NaN
return 0.0 / 0.0;
}
// return new String().valueOf(result);
return result;
}
/**
* 将表达式中负数的符号更改
*
* @param expression
* 例如-2+-1*(-3E-2)-(-1) 被转为 ~2+~1*(~3E~2)-(~1)
* @return
*/
private static String transform(String expression) {
char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '-') {
if (i == 0) {
arr[i] = '~';
} else {
char c = arr[i - 1];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
arr[i] = '~';
}
}
}
}
if(arr[0]=='~'||arr[1]=='('){
arr[0]='-';
return "0"+new String(arr);
}else{
return new String(arr);
}
}
/**
* 按照给定的表达式计算
*
* @param expression
* 要计算的表达式例如:5+12*(3+5)/7
* @return
*/
public double calculate(String expression) {
Stack<String> resultStack = new Stack<String>();
prepare(expression);
Collections.reverse(postfixStack);// 将后缀式栈反转
String firstValue, secondValue, currentValue;// 参与计算的第一个值,第二个值和算术运算符
while (!postfixStack.isEmpty()) {
currentValue = postfixStack.pop();
if (!isOperator(currentValue.charAt(0))) {// 如果不是运算符则存入操作数栈中
currentValue = currentValue.replace("~", "-");
resultStack.push(currentValue);
} else {// 如果是运算符则从操作数栈中取两个值和该数值一起参与运算
secondValue = resultStack.pop();
firstValue = resultStack.pop();
// 将负数标记符改为负号
firstValue = firstValue.replace("~", "-");
secondValue = secondValue.replace("~", "-");
String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
resultStack.push(tempResult);
}
}
return Double.valueOf(resultStack.pop());
}
/**
* 数据准备阶段将表达式转换成为后缀式栈
*
* @param expression
*/
private void prepare(String expression) {
opStack.push(',');// 运算符放入栈底元素逗号,此符号优先级最低
char[] arr = expression.toCharArray();
int currentIndex = 0;// 当前字符的位置
int count = 0;// 上次算术运算符到本次算术运算符的字符的长度便于或者之间的数值
char currentOp, peekOp;// 当前操作符和栈顶操作符
for (int i = 0; i < arr.length; i++) {
currentOp = arr[i];
if (isOperator(currentOp)) {// 如果当前字符是运算符
if (count > 0) {
postfixStack.push(new String(arr, currentIndex, count));// 取两个运算符之间的数字
}
peekOp = opStack.peek();
if (currentOp == ')') {// 遇到反括号则将运算符栈中的元素移除到后缀式栈中直到遇到左括号
while (opStack.peek() != '(') {
postfixStack.push(String.valueOf(opStack.pop()));
}
opStack.pop();
} else {
while (currentOp != '(' && peekOp != ',' && compare(currentOp, peekOp)) {
postfixStack.push(String.valueOf(opStack.pop()));
peekOp = opStack.peek();
}
opStack.push(currentOp);
}
count = 0;
currentIndex = i + 1;
} else {
count++;
}
}
if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {// 最后一个字符不是括号或者其他运算符的则加入后缀式栈中
postfixStack.push(new String(arr, currentIndex, count));
}
while (opStack.peek() != ',') {
postfixStack.push(String.valueOf(opStack.pop()));// 将操作符栈中的剩余的元素添加到后缀式栈中
}
}
/**
* 判断是否为算术符号
*
* @param c
* @return
*/
private boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}
/**
* 利用ASCII码-40做下标去算术符号优先级
*
* @param cur
* @param peek
* @return
*/
public boolean compare(char cur, char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低
boolean result = false;
if (operatPriority[(peek) - 40] >= operatPriority[(cur) - 40]) {
result = true;
}
return result;
}
/**
* 按照给定的算术运算符做计算
*
* @param firstValue
* @param secondValue
* @param currentOp
* @return
*/
private String calculate(String firstValue, String secondValue, char currentOp) {
String result = "";
switch (currentOp) {
case '+':
result = String.valueOf(ArithHelper.add(firstValue, secondValue));
break;
case '-':
result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
break;
case '*':
result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
break;
case '/':
result = String.valueOf(ArithHelper.div(firstValue, secondValue));
break;
}
return result;
}
}
package com.liuzhen.string_1;
import java.util.Scanner;
public class StringToInt {
public static int Max_INT = Integer.MAX_VALUE;
public static int Min_INT = Integer.MIN_VALUE;
public int getStringToInt(String A){
char[] arrayA = A.toCharArray();
int n = 0;
if(A.equals("") || A.equals(null)) //判断输入是否为空
return 0;
int i = 0;
while(arrayA[i] == ' ') //处理字符串首位的空格
i++;
int sign = 1; //用于判定输入字符串数字的正负,初始化为1表示为正数
if(arrayA[i] == '+' || arrayA[i] == '-'){
if(arrayA[i] == '-')
sign = -1;
i++;
}
while(i < arrayA.length && Character.isDigit(arrayA[i])){ //确定是数字0~9才执行循环
int c = arrayA[i] - '0';
//当输入字符串表示数为正数,且大于Max_INT
if(sign > 0 && (n > Max_INT/10 || (n == Max_INT/10 && c > Max_INT%10))){
n = Max_INT;
break;
}
//当输入字符串表示数为负数,且小于Min_INT
if(sign < 0 && (n + Min_INT/10 > 0 || (n + Min_INT/10 == 0 && c + Min_INT%10 > 0))){
n = Min_INT;
break;
}
//把之前得到的数字乘以10,再加上 当前字符表示的数字
n = n*10 + c;
i++;
}
return sign > 0 ? n : -n;
}
public static void main(String[] args){
StringToInt test = new StringToInt();
Scanner in = new Scanner(System.in);
System.out.println("请输入一个由数字组成的字符串:");
String A = in.nextLine();
int result = test.getStringToInt(A);
System.out.println("整数result = "+result);
}
}