问题要求:
1. 实现一个web版本的计算器
a) 无任何输入(初始状态)时,显示框中显示0,有输入内容后显示正确的输入内容
b) 数字和运算符可通过点击按钮输入,也可以使用键盘输入,使用js验证输入是否符合要求(5分)
c) 点“=”之前,需要显示之前输入的公式,
d) 界面风格(字体、背景、边框、宽高、位置),按下图要求(5分)
e) 点击“=”号后,清除所有显示,只显示正确的计算结果,计算结果不允许js中获得,需要使用ajax技术调用后台servlet执行运算并将当前计算的公式、计算的时间、计算的结果存放在数据库中,实现所有的加减乘除、清除、撤销 运算功能(20分)
(1)界面代码不值得一提,js部分如下:
<script>
var flag;
$(document).ready(function(){
document.getElementById("txt1").value = "0";
flag= 1;
<%--此处做的事键盘响应--%>
$('body').on('keydown',function (event){
var myKey = event.which;
if(flag == 1){
document.getElementById("txt1").value = "";
flag = 0;
}
var tempp;
if(myKey>=48&&myKey<=57){
tempp = myKey-48;
document.getElementById("txt1").value += tempp;
}
else if(myKey==187||myKey==61){
tempp = "+";
document.getElementById("txt1").value += tempp;
}
else if(myKey==189||myKey==173){
tempp = "-";
document.getElementById("txt1").value += tempp;
}
else if(myKey==190){
tempp = ".";
document.getElementById("txt1").value += tempp;
}
else if(myKey==80){
tempp = "*";
document.getElementById("txt1").value += tempp;
}
else if(myKey==191){
tempp = "/";
document.getElementById("txt1").value += tempp;
}
else if(myKey==37){
var ss = document.getElementById("txt1").value;
var ll = ss.length-1;
document.getElementById("txt1").value=ss.substring(0, ll);
}
else if(myKey==13){
flag=1;
var obj=document.getElementById("txt1").value;//在此仍是字符串
try{
eval("var ret ="+obj);
if (ret!=Infinity) {
}else {
document.getElementById("txt1").value="输入错误";
return;
}
} catch(e){
document.getElementById("txt1").value="输入错误";
return 0;
}
var rule = obj.replace(/\+/g,"%2B");
$.ajax({
type: "POST",
url: "/WebCalcular/Gink/Calculate_makeCalculateResult",
data: "calculateOrder="+rule+"&Gink==",
success: function(msg){
document.getElementById("txt1").value=msg.result;
}
});
}
else{
}
});
});
<%--此处做的是当点击按键的时候就将点击的按钮内容添加到input里面去--%>
function add(obj)
{
if(flag == 1){
<%--这个if语句在很多地方都会出现,原因是符合“无任何输入(初始状态)时,显示框中显示0,有输入内容后显示正确的输入内容”这个要求--%>
document.getElementById("txt1").value = "";
flag = 0;
}
var temp=obj.value;//目的是在进行过一次运算后在下次点击之前保留数值,防治出现摁两次情形
document.getElementById("txt1").value+=obj.value;
var obf=document.getElementById("txt1").value;
if(obf.indexOf("=")>0)//当input里面已经有过一次运算的痕迹之后进行清空
{
clears();
document.getElementById("txt1").value=temp;//将缓存起来的值吐出来
}
}
function results(objj)
{
flag=1;
var obj=document.getElementById("txt1").value;//在此仍是字符串
try{
<%--这个try目的是检测输入是否合法,如果不合法就崩了--%>
eval("var ret ="+obj);
if (ret!=Infinity) {
}else {
document.getElementById("txt1").value="输入错误";
return 0;
}
} catch(e){
document.getElementById("txt1").value="输入错误";
return 0;
}
<%-- if(obj.indexOf("=")==-1) --%>
<%-- document.getElementById("txt1").value+="="+eval(obj);//eval函数可以经字符串转换成运算结果--%>
var rule = obj.replace(/\+/g,"%2B");
var hand = objj.value=='%'?"percent":objj.value;
<%--很奇怪,ajax不支持“+”还有百分号的传输,故不得以进行一次转换--%>
$.ajax({
type: "POST",
url: "/WebCalcular/Gink/Calculate_makeCalculateResult",
data: "calculateOrder="+rule+"&Gink="+hand,
success: function(msg){
document.getElementById("txt1").value=msg.result;
}
});
}
function clears()
{
document.getElementById("txt1").value="0";
flag=1;
}
function back()
{
var ss = document.getElementById("txt1").value;
var ll = ss.length-1;
document.getElementById("txt1").value=ss.substring(0, ll);
}
function negative(obj)
{
document.getElementById("txt1").value="正负功能尚未实现,请点击C";
flag=1;
}
</script>
(2)Services层代码如下:
package com.gink.service;
import java.sql.SQLException;
import java.util.Stack;
import com.gink.dao.CalculatorDao;
import com.gink.model.Calculator;
public class CalculateService {
static CalculatorDao calculatorDao = new CalculatorDao();
public static String countExpressionByEquals(String str) {
// TODO Auto-generated method stub
String temp = countExpression(str);
if (temp.isEmpty()) {
return "计算错误!";
} else if (temp.equals("Infinity")) {
return "除数为零能做么?";
} else {
if (temp.substring(temp.indexOf(".") + 1, temp.length())
.equals("0")) {
temp = temp.substring(0, temp.indexOf("."));// 这个else
// if的用途就是当是整数运算的时候将末尾小数点省掉,即当1+1=2.0时显示2
}
StringBuilder stringBuilder = new StringBuilder(str);
stringBuilder.append("=");
save(stringBuilder.toString(), temp);
}
return temp;
}
public String countExpressionByPercent(String str) {
// TODO Auto-generated method stub
String temp = countExpression(str);
if (temp.isEmpty()) {
return "计算错误!";
} else if (temp.equals("Infinity")) {
return "除数为零能做么?";
} else {
Double dTemp = Double.parseDouble(temp) / 100;
temp = dTemp.toString();
StringBuilder stringBuilder = new StringBuilder("(");
stringBuilder.append(str);
stringBuilder.append(")%=");
save(stringBuilder.toString(), temp);
}
return temp;
}
public String countExpressionByRadical(String str) {
// TODO Auto-generated method stub
String temp = countExpression(str);
if (temp.isEmpty()) {
return "计算错误!";
} else if (temp.equals("Infinity")) {
return "除数为零能做么?";
} else if (temp.substring(temp.indexOf(".") + 1, temp.length()).equals(
"0")) {
Double dTemp = Double.parseDouble(temp);
dTemp = Math.sqrt(dTemp);
temp = dTemp.toString();
StringBuilder stringBuilder = new StringBuilder("√(");
stringBuilder.append(str);
stringBuilder.append(")=");
save(stringBuilder.toString(), temp);
}
return temp;
}
public String countExpressionByBackCount(String str) {
// TODO Auto-generated method stub
String temp = countExpression(str);
if (temp.isEmpty()) {
return "计算错误!";
} else if (temp.equals("Infinity")) {
return "除数为零能做么?";
} else if (temp.substring(temp.indexOf(".") + 1, temp.length()).equals(
"0")) {
Double dTemp = 1 / Double.parseDouble(temp);
temp = dTemp.toString();
System.out.println(dTemp);
StringBuilder stringBuilder = new StringBuilder("1/(");
stringBuilder.append(str);
stringBuilder.append(")=");
save(stringBuilder.toString(), temp);
}
return temp;
}
public static String countExpression(String str) {
Stack countStack1 = new Stack();
Stack countStack2 = new Stack();
String[] operater = new String[20];
String[] number = new String[20];
double result = 0;
number = str.split("\\/|\\*|\\+|\\-");
createOperater(str, operater);
for (int i = 0; i < number.length; i++) {
countStack1.push(number[i]);
if (i != number.length - 1) {
countStack1.push(operater[i + 1]);// 这句是将运算符数组中下一个数组压入压入栈中,但是目前这样就有一个bug,如果开始时输入的就是负数,那么该程序就挂了
}
}
// 当上面那个for循环循环完毕,第一个栈中就储存了三个量
while (!countStack1.isEmpty())
countStack2.push(countStack1.pop());// 当值栈不空的时候压入另外一个栈,注意比如10+3这个式子,第一次压入的是3,第二次是+,第三次是10
String op;
while (!countStack2.isEmpty()) {
// 当的的确确从第二个值栈压出
result = 0;
op = countStack2.pop().toString();
if (op.equals("*")) {
result = Double.parseDouble(countStack1.pop().toString())
* Double.parseDouble(countStack2.pop().toString());
countStack1.push(result);
continue;
}
if (op.equals("/")) {
result = Double.parseDouble(countStack1.pop().toString())
/ Double.parseDouble(countStack2.pop().toString());
countStack1.push(result);
continue;
}
countStack1.push(op);
}
while (!countStack1.isEmpty())
countStack2.push(countStack1.pop());
while (!countStack2.isEmpty()) {
result = 0;
op = countStack2.pop().toString();
if (op.equals("+")) {
result = Double.parseDouble(countStack1.pop().toString())
+ Double.parseDouble(countStack2.pop().toString());
countStack1.push(result);
continue;
}
if (op.equals("-")) {
result = Double.parseDouble(countStack1.pop().toString())
- Double.parseDouble(countStack2.pop().toString());
countStack1.push(result);
continue;
}
countStack1.push(op);
}
return countStack1.pop().toString();
}
private static void createOperater(String str, String[] operater) {
char[] cs = str.toCharArray();
operater[0] = " ";
int j = 0;
for (int i = 0; i < cs.length; i++) {
if (cs[i] == '+' || cs[i] == '-' || cs[i] == '*' || cs[i] == '/') {
j++;
operater[j] = String.valueOf(cs[i]);
}
}
}
public static String save(String str, String temp) {
Calculator calculator = new Calculator();
int msg = 0;
try {
calculator.setId(calculatorDao.getSqlCount() + 1);
calculator.setCountResult(temp);
calculator.setCountRule(str);
msg = calculatorDao.insert(calculator);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (msg == 0) ? "插入失败" : "插入成功";
}
}