界面
activity_main.xml
- 采用GridLayout<网格布局>,将网格设置为8行4列,第2行为显示数据的文本标签,第2行为清除数据的按钮,3~6行为数字键和运算符;
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="8"
android:columnCount="4"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:layout_rowSpan="4"
android:layout_marginLeft="15sp"
android:gravity="center_horizontal"
android:text = "0"
android:textSize="70dip"
android:id="@+id/tv"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text= "清除"
android:textSize="45dip"
android:id="@+id/bt_clear"
/>
<Button android:text="1" android:textSize="40dip" android:id="@+id/bt_1"/>
<Button android:text="2" android:textSize="40dip" android:id="@+id/bt_2"/>
<Button android:text="3" android:textSize="40dip" android:id="@+id/bt_3" />
<Button android:text="+" android:textSize="40dip" android:id="@+id/bt_plus"/>
<Button android:text="4" android:textSize="40dip" android:id="@+id/bt_4"/>
<Button android:text="5" android:textSize="40dip" android:id="@+id/bt_5"/>
<Button android:text="6" android:textSize="40dip" android:id="@+id/bt_6"/>
<Button android:text="-" android:textSize="40dip" android:id="@+id/bt_minus" />
<Button android:text="7" android:textSize="40dip" android:id="@+id/bt_7"/>
<Button android:text="8" android:textSize="40dip" android:id="@+id/bt_8"/>
<Button android:text="9" android:textSize="40dip" android:id="@+id/bt_9"/>
<Button android:text="*" android:textSize="40dip" android:id="@+id/bt_multiply"/>
<Button android:text="." android:textSize="40dip" android:id="@+id/bt_point"/>
<Button android:text="0" android:textSize="40dip" android:id="@+id/bt_0"/>
<Button android:text="=" android:textSize="40dip" android:id="@+id/bt_equal"/>
<Button android:text="/" android:textSize="40dip" android:id="@+id/bt_divide"/>
</GridLayout>
- 界面显示效果
计算逻辑
MainActivity.java
- 通过MainActivity直接实现 OnClickListener接口,方便按钮添加监听器;
- 按钮的功能相识,逐个添加监听器,会使重复代码过多,代码冗余;
- 简化代码的同时,要注意各部件功能差异,"±*/."不能重复输出,要设置判断方法,检测是否重复输入;
public class MainActivity extends AppCompatActivity implements OnClickListener{
Button bt_1;
Button bt_2;
Button bt_3;
.
.
.
private StringBuilder pending = new StringBuilder();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_0 = (Button) findViewById(R.id.bt_0);
bt_1 = (Button)findViewById(R.id.bt_1);
bt_2 = (Button)findViewById(R.id.bt_2);
.
.
.
tv_input = (TextView) findViewById(R.id.tv);
bt_0.setOnClickListener(this);
bt_1.setOnClickListener(this);
bt_2.setOnClickListener(this);
.
.
.
bt_point.setOnClickListener(this);
switch (v.getId()) {
case R.id.bt_0:
pending = pending.append("0");
tv_input.setText(pending);
break;
case R.id.bt_1:
pending = pending.append("1");
tv_input.setText(pending);
break;
case R.id.bt_2:
pending = pending.append("2");
tv_input.setText(pending);
break;
case R.id.bt_3:
pending = pending.append("3");
tv_input.setText(pending);
break;
.
.
.
case R.id.bt_plus:
if (ifReapet("+")) {
pending = pending.append("+");
tv_input.setText(pending);
}
break;
case R.id.bt_minus:
if (ifReapet("-")) {
pending = pending.append("-");
tv_input.setText(pending);
}
break;
case R.id.bt_multiply:// 乘
if (ifReapet("*")) {
pending = pending.append("*");
tv_input.setText(pending);
}
break;
case R.id.bt_divide:
if (ifReapet("/")) {
pending = pending.append("/");
tv_input.setText(pending);
}
break;
case R.id.bt_point:
if (ifReapet(".")) {
pending = pending.append(".");
tv_input.setText(pending);
}
break;
case R.id.bt_clear:
pending = pending.delete(0, pending.length());
tv_input.setText(pending);
break;
case R.id.bt_equal:
if ((pending.length() > 1)) {
InfixInToDuffix inf = new InfixInToDuffix();
String jieguo;
try {
String a = inf.toSuffix(pending);
jieguo = inf.dealEquation(a);
} catch (Exception ex) {
jieguo = "出错";
}
tv_input.setText(pending + "=" + jieguo);
pending = pending.delete(0, pending.length());
if (Character.isDigit(jieguo.charAt(0))) {
pending = pending.append(jieguo);
}
}
break;
default:
break;
}
}
}
ifReapet(String a)
- private boolean ifReapet(String a): 通过传入的字符参数,进行判断,返回boolean值;
- 实现过程: 创建整数数组 b[],存放获取对应字符的位置数,pending.lastIndexOf() 获取对应字符的位置,存放到b[],通过判断b[]的长度,b[]为空,则说明为pending不存在对应字符,字符未重复输入,返回true;
private boolean ifReapet(String a) {
int[] b = new int[a.length()];
int max;
for (int i = 0; i < a.length(); i++) {
String c = "" + a.charAt(i);
b[i] = pending.lastIndexOf(c);
}
Arrays.sort(b);
if (b[a.length() - 1] == -1) {
max = 0;
} else {
max = b[a.length() - 1];
}
if (pending.indexOf(a, max) == -1) {
return true;
} else {
return false;
}
}
计算优先级
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.lang.*;
import java.util.ArrayList;
import java.util.*;
public class InfixInToDuffix {
private static final Map<Character,Integer>basic =new HashMap<Character, Integer>();
static {
basic.put('-',1);
basic.put('+', 1);
basic.put('*', 2);
basic.put('/', 2);
basic.put('(', 0);
}
public String toSuffix(StringBuilder infix){
List<String> queue = new ArrayList<String>();
List<Character> stack = new ArrayList<Character>();
char[] charArr = infix.substring(0,infix.length()).trim().toCharArray();
String standard = "*/+-()";
char ch = '&';
int len = 0;
for (int i = 0; i < charArr.length; i++) {
ch = charArr[i];
if(Character.isDigit(ch)) {
len++;
}else if(ch == '.'){
len++;
}else if(standard.indexOf(ch) != -1) {
if(len > 0) {
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));
len = 0;
}
if(ch == '(') {
stack.add(ch);
continue;
}
if (!stack.isEmpty()) {
int size = stack.size() - 1;
boolean flag = false;
while (size >= 0 && ch == ')' && stack.get(size) != '(') {
queue.add(String.valueOf(stack.remove(size)));
size--;
flag = true;
}
if(ch==')'&&stack.get(size) == '('){
flag = true;
}
while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
if(ch != ')') {
stack.add(ch);
} else {
stack.remove(stack.size() - 1);
}
}
if(i == charArr.length - 1) {
if(len > 0) {
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
}
int size = stack.size() - 1;
while (size >= 0) {
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
}
String a = queue.toString();
return a.substring(1,a.length()-1);
}
public String dealEquation(String equation){
String [] arr = equation.split(", ");
List<String> list = new ArrayList<String>();
for (int i = 0; i < arr.length; i++) {
int size = list.size();
switch (arr[i]) {
case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(a)); break;
case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(b)); break;
case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(c)); break;
case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(d)); break;
default: list.add(arr[i]); break;
}
}
return list.size()
== 1 ? list.get(0) : "运算失败" ;
}
}
功能实现测试