您的位置:首页 > 其它

第一章作业题

2016-05-15 15:46 295 查看

题目大意

表达式求值,可以包含+ - * / ^运算,并按要求输出结果。

下面给出Java版代码,希望大家共同测试。

package com.mindto.other;

import java.util.Stack;

/**
* 解题思路:
* 1、获取字符串,得到不含有空格的表达式串,形如:1+2/3,记为 destStr
* 2、判断是否符合计算要求,符合则进行下一步,否则,输出错误,退出。
* 3、执行如下算法:
*  a,定义存储操作数的栈OVS,定义存储操作符的栈OPTR
*  b,自左向右扫描destStr,若是操作数,进栈OVS,若是操作符,则与OPTR栈顶的操作符比较:
*      。若当前操作符优先级大于OPTR栈顶操作符优先级,则进栈
*      。若当前操作符优先级小于或等于OPTR栈顶操作符优先级,则OPTR栈退栈一次,得到操作符x,OVS栈退栈2次,得到操作数a,b,进行x运算,结果入栈OVS
*  c,若是(,则获取第一个和它匹配的)中间的字符串进行扫描操作
* 4、对计算结果进行格式化,输出
* */
public class XTZX1 {
/*定义栈、表达式字符串及其他实例变量*/
private char[] destStr;
/*构造函数,进行初始化*/
XTZX1(String[] srcStr) {
//获取表达式字符串
StringBuffer buffer = new StringBuffer();
for (String str : srcStr) {
buffer.append(str);
}
destStr = buffer.toString().replace(" ", "").toCharArray();
//System.out.println("destStr`length = " + new String(destStr).length());
}
/*
* 解决问题
* target 当前处理的位置
* end 处理结束位置
* */
public void solve(int target, int end) {
//printChar();
//符合计算要求才进行计算
if (isLegal()) {
double r = calculate(target, end);
outputWithFormat(r);
}
}
private void outputWithFormat(double value) {
//System.out.println(value);
String temp = String.valueOf(value);
int dotIndex = temp.indexOf(".");
//System.out.println("indexof. = " + temp.indexOf("."));
int l = temp.substring(dotIndex).length();
if (l == 2) {//形如4.0这样的结果
System.out.println(temp.substring(0, temp.length() - 2));
}
if (l > 2 && l <=11) {
System.out.println(temp);
}
if (l > 11) {
//用来计算输出的数组
char[] result = temp.substring(0, dotIndex + 11).toCharArray();
//System.out.println(result);
char c = temp.charAt(dotIndex + 11);
//System.out.println("charAt(dotIndex + 11) = " + c);
if (c >= '5') {//四舍五入
int len = result.length;
//System.out.println("result.length = " + len);
int up = 1;
for (int i = len - 1; i >= 0 && up == 1; i --) {
if (result[i] == '.') {
continue;
}
int t = result[i] - '0' + up;
if (t >= 10) {
result[i] = (char) ('0' + (t % 10));
}else {
up = 0;
result[i] = (char) ('0' + t);
}
}
}
double before = Double.parseDouble(new String(result));//转换成数字
String bStr = String.valueOf(before);
if (bStr.substring(bStr.indexOf(".")).length() == 2) {
System.out.println(bStr.substring(0, bStr.length() - 2));
}else {
System.out.println(result);
}
}

}
/*
* 判断该表达式是否合法
* */
private boolean isLegal() {
String targetStr = new String(getDestStr());
//判断是否由数字,运算符以及 . ()组成
if (!targetStr.matches("^[0-9\\.\\(\\)\\+\\-\\*/]*$")) {
System.out.println("INPUT ERROR");
return false;
}
if (!isFromatOK()) {
System.out.println("FORMAT ERROR");
return false;
}
return true;
}
private boolean isFromatOK() {
int ovsNum = 0;
int optrNum = 0;
int left = 0;
int right = 0;
int begin = 0;
int end = getDestStr().length;
while (begin < end) {
char c = getDestStr()[begin];
if (c >= '0' && c <= '9') {
StringBuffer buffer = new StringBuffer();
while (begin < end) {
buffer.append(c);
begin ++;
if (begin >= end) {
break;
}
c = getDestStr()[begin];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
break;
}
}
ovsNum ++;
}
if (c == '+' || c == '-' || c == '*' || c == '/') {
optrNum ++;
}
if (c == '(') {
left ++;
}
if (c == ')') {
right ++;
}
begin ++;
}
if (ovsNum - 1 == optrNum && left == right) {
return true;
}
return false;
}
/*
* 计算从begin到end表达式的值
* */
private double calculate(int begin, int end) {
Stack<Double> ovs = new Stack<>();
Stack<Character> optr = new Stack<>();
//从begin开始扫描到end
while (begin < end) {
char c = getDestStr()[begin];
//是操作数(可能是小数),则取出操作数,入栈
if (c <= '9' && c >= '0') {
StringBuffer buffer = new StringBuffer();
while (begin < end) {
//System.out.print(c);
buffer.append(c);
begin ++;
if (begin >= end) {
break;
}
c = getDestStr()[begin];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
break;
}
}
//入栈
ovs.push(Double.parseDouble(buffer.toString()));
}
//是操作符
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
//操作符栈是否为空,空则直接入栈,否则进行比较
if (optr.isEmpty()) {
optr.push(c);
}else {
char topChar = optr.peek();
//当前运算符优先级大于栈顶运算符优先级,直接入栈
if (getLeave(c) > getLeave(topChar)) {
optr.push(c);
}else {
topChar = optr.pop();//运算符出栈
double a = ovs.pop();//运算数出栈
double b = ovs.pop();
ovs.push(calculateWithOption(topChar, b, a));
optr.push(c);
}
}
begin ++;
}
//左括号
if (c == '(') {
int subEnd = end;
while (c != ')') {
subEnd --;
c = getDestStr()[subEnd];
}//退出时subEnd是')'的下标值
double subResult = calculate(++begin, subEnd);
//计算结构入栈
ovs.push(subResult);
subEnd ++;
begin = subEnd;
}
}
while (!optr.isEmpty()) {
double a = ovs.pop();
double b = ovs.pop();
ovs.push(calculateWithOption(optr.pop(), b, a));
}
return ovs.peek();
}
/*
* 获取操作符优先级
* */
private int getLeave(char c) {
int leave = 0;
switch (c) {
case '+':
case '-':
leave = 1;
break;
case '*':
case '/':
leave = 2;
break;
case '^':
leave = 3;
break;
}
return leave;
}
/*
* 根据操作符进行运算
* */
private double calculateWithOption(char c, double a, double b) {
double result = 0;
switch (c) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
if (b == 0) {
System.out.println("VALUE ERROR");
System.exit(1);
}
result = a / b;
break;
case '^':
result = Math.pow(a, b);
break;
}
return result;
}
public char[] getDestStr() {
return destStr;
}
public void setDestStr(char[] destStr) {
this.destStr = destStr;
}
public void printChar() {
for (char c : getDestStr()) {
System.out.print(c);
}
System.out.println();
}
public static void main(String[] args) {
XTZX1 xtzx1 = new XTZX1(args);
xtzx1.solve(0, xtzx1.getDestStr().length);
}
}


注:我的作业无法提交,显示


估计是过了评定时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: