前言
最近開始學習Android,用Android寫了第一個小專案——計算器,用Android寫計算器首先是要從UI做起,再到每個Button的點擊事件,再到計算器的核心代碼部分,就是中綴運算式轉為后綴運算式,然后再用后綴運算式求值,最后就到改bug的時間了,
布局
從布局開始,我的計算器就算正式開始了,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include layout="@layout/button" />
<TextView
android:id="@+id/editText_1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:autoSizeTextType="uniform"
android:background="#00000000"
android:focusable="true"
android:gravity="end|bottom"
android:maxLines="2"
android:textSize="30dp"
android:autoSizeMinTextSize="40sp"
android:autoSizeMaxTextSize="100sp"
android:ellipsize="marquee"
/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="470dp"
android:layout_alignParentBottom="true"
>
<Button
android:id="@+id/button_1"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="10dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="290dp"
android:background="@drawable/back_button"
android:text="1"
android:textColor="#000000"
android:textSize="20dp" />
<Button
android:id="@+id/button_2"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="100dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="290dp"
android:background="@drawable/back_button"
android:text="2"
android:textColor="#000000"
android:textSize="20dp"/>
<Button
android:id="@+id/button_3"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="190dp"
android:layout_marginBottom="288dp"
android:background="@drawable/back_button"
android:text="3"
android:textColor="#000000"
android:textSize="20dp" />
<Button
android:id="@+id/button_4"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="4"
android:textColor="#000000"
android:layout_alignParentBottom="true"
android:background="@drawable/back_button"
android:layout_marginBottom="200dp"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_5"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="5"
android:textColor="#000000"
android:layout_alignParentBottom="true"
android:background="@drawable/back_button"
android:layout_marginBottom="200dp"
android:layout_marginLeft="100dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_6"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="6"
android:textColor="#000000"
android:layout_alignParentBottom="true"
android:background="@drawable/back_button"
android:layout_marginBottom="200dp"
android:layout_marginLeft="190dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_7"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="7"
android:textColor="#000"
android:layout_alignParentBottom="true"
android:background="@drawable/back_button"
android:layout_marginBottom="110dp"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_8"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="8"
android:textColor="#000"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_marginBottom="110dp"
android:layout_marginLeft="100dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_9"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="9"
android:textColor="#000"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_marginBottom="110dp"
android:layout_marginLeft="190dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_0"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="0"
android:textColor="#000"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="100dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_left"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="("
android:textColor="#000"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_right"
android:layout_width="70dp"
android:layout_height="70dp"
android:text=")"
android:textColor="#000"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="190dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_point"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="110dp"
android:background="@drawable/back_button"
android:text="·"
android:textSize="20dp"/>
<Button
android:id="@+id/button_equal"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="20dp"
android:background="@drawable/back_button2"
android:text="="
android:textColor="#fff"
android:textSize="20dp"/>
<Button
android:id="@+id/button_add"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="+"
android:layout_alignParentBottom="true"
android:textColor="#0066FF"
android:background="@drawable/back_button"
android:layout_marginBottom="380dp"
android:layout_marginLeft="100dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_subtraction"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="-"
android:layout_alignParentBottom="true"
android:textColor="#0066FF"
android:background="@drawable/back_button"
android:layout_marginBottom="380dp"
android:layout_marginLeft="190dp"/>
<Button
android:id="@+id/button_multiplication"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="X"
android:textColor="#0066FF"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@drawable/back_button"
android:layout_marginBottom="290dp"
android:layout_marginRight="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_division"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="/"
android:textColor="#0066FF"
android:background="@drawable/back_button"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="200dp"
android:layout_marginRight="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_clear"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:text="C"
android:textColor="#0066FF"
android:background="@drawable/back_button"
android:layout_marginBottom="380dp"
android:layout_marginLeft="10dp"
android:textSize="20dp"/>
<Button
android:id="@+id/button_delete"
android:layout_width="70dp"
android:layout_height="70dp"
android:text="Del"
android:textColor="#0066FF"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/back_button"
android:layout_marginBottom="380dp"
android:layout_marginRight="10dp"
android:textAllCaps="false"
android:textSize="20dp"/>
</RelativeLayout>
上面是我的布局代碼,我使用了RelativeLayout這種布局方式,這樣方便Button的放置,這樣就可以Button在螢屏上更好找到自己的位置,頁面設定也沒什么好說的,直接看下效果吧!

上面這是真機的演示效果,由于手機螢屏的大小不同,可能效果也不同,以上布局是我根據我自己手機所制作的,可能因手機大小會有差異,
布局這塊非常的簡單,非常容易做出來,下來就是點擊事件的加入了,
Button的點擊事件
注冊點擊事件也很簡單;在前期的處理上,它是非常簡單的,但如果你前期處理時讓它過于簡單了,就會讓后面優化變得非常的讓人頭疼,我是用一個StringBuilder將所輸入的數字所記錄下來,這樣就比直接用字串節省許多的記憶體,并且在洗掉時也會特別的方便,不會讓字串反復的創建,節省了大量的記憶體,我是在這塊處理了很多的東西,好多不合法的內容就不會被輸入進去,所以在后面的計算方面就會變得非常的方便,但這樣做也有壞處,就是做了大量的判斷,代碼畢竟不會像我們人一樣會思考,所以只能用這樣的方法將一些不合法的輸入就杜絕了,
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_1:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(1);
editText.setText(stringBuilder.toString());
break;
case R.id.button_2:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(2);
editText.setText(stringBuilder.toString());
break;
case R.id.button_3:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(3);
editText.setText(stringBuilder.toString());
break;
case R.id.button_4:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(4);
editText.setText(stringBuilder.toString());
break;
case R.id.button_5:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(5);
editText.setText(stringBuilder.toString());
break;
case R.id.button_6:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(6);
editText.setText(stringBuilder.toString());
break;
case R.id.button_7:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(7);
editText.setText(stringBuilder.toString());
break;
case R.id.button_8:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(8);
editText.setText(stringBuilder.toString());
break;
case R.id.button_9:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (stringBuilder.length() != 0 && zero == false
&& stringBuilder.charAt(stringBuilder.length()-1) == '0') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
zero = true;
stringBuilder.append(9);
editText.setText(stringBuilder.toString());
break;
case R.id.button_0:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
}
if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
}
if (zero) {
stringBuilder.append(0);
editText.setText(stringBuilder.toString());
} else {
if (stringBuilder.length() != 0 &&
stringBuilder.charAt(stringBuilder.length()-1) == '0') {
editText.setText(stringBuilder.toString());
} else {
stringBuilder.append(0);
editText.setText(stringBuilder.toString());
}
}
break;
case R.id.button_equal:
try {
if (stringBuilder.length() == 0) {
editText.setText(stringBuilder.toString());
point = 0;
flag1 = 0;
break;
} else if (stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
point = 0;
flag1 = 0;
break;
}
String result = countResult(change2(change1()));
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append(result);
flag1 = 0;
/*for (int i = 0; i < stringBuilder.length(); i++) {
if (stringBuilder.charAt(i) == '.') {
point = 1;
break;
} else {
point = 0;
}
}*/
if (result.matches("^[-\\+]?[\\d+]$")) {
point = 0;
} else {
point = 1;
}
editText.setText(stringBuilder.toString());
if (stringBuilder.toString().equals("0")) {
zero = false;
} else {
zero = true;
}
} catch (Exception e) {
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append("Error");
editText.setText("Error");
point = 0;
flag1 = 0;
}
break;
case R.id.button_delete:
if (stringBuilder.length() == 2 && stringBuilder.charAt(0) == '-') {
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
break;
}
if (stringBuilder.length() > 2
&& stringBuilder.charAt(stringBuilder.length()-2) == '-'
&& (stringBuilder.charAt(stringBuilder.length()-3) == '*' ||
stringBuilder.charAt(stringBuilder.length()-3) == '/' ||
stringBuilder.charAt(stringBuilder.length()-3) == '(')) {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
stringBuilder.deleteCharAt(stringBuilder.length()-1);
editText.setText(stringBuilder.toString());
break;
}
if (stringBuilder.length() != 0) {
if (stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
break;
}
if (stringBuilder.charAt(stringBuilder.length()-1) == ')') {
flag1++;
} else if (stringBuilder.charAt(stringBuilder.length() - 1) == '.') {
point = 0;
} if (stringBuilder.charAt(stringBuilder.length()-1) == '(') {
flag1--;
}
stringBuilder.deleteCharAt(stringBuilder.length()-1);
editText.setText(stringBuilder.toString());
} else {
zero = false;
}
break;
case R.id.button_clear:
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
flag1 = 0;
point = 0;
zero = false;
break;
case R.id.button_add:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append("+");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
break;
}
String str3 = stringBuilder.toString();
if (str3.length() > 1 && "-".equals(str3.substring(str3.length()-1))
&& !"*".equals(str3.substring(str3.length()-2,str3.length()-1))
&& !"/".equals(str3.substring(str3.length()-2,str3.length()-1))
&& !"(".equals(str3.substring(str3.length()-2,str3.length()-1))) {
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append("+");
editText.setText(stringBuilder.toString());
break;
}
if (stringBuilder.length() != 0 &&
!"+".equals(str3.substring(str3.length()-1)) &&
!"*".equals(str3.substring(str3.length()-1)) &&
!"/".equals(str3.substring(str3.length()-1)) &&
!"-".equals(str3.substring(str3.length()-1)) ) {
if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
}
stringBuilder.append("+");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
}
break;
case R.id.button_subtraction:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append("-");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
break;
}
if (stringBuilder.length() == 0) {
stringBuilder.append("-");
editText.setText(stringBuilder.toString());
point = 0;
break;
}
String str4 = stringBuilder.toString();
if (stringBuilder.length() != 0 && "+".equals(str4.substring(str4.length()-1))) {
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append("-");
editText.setText(stringBuilder.toString());
break;
}
if (!"-".equals(str4.substring(str4.length()-1) ) &&
!"+".equals(str4.substring(str4.length()-1) )) {
if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
}
stringBuilder.append("-");
editText.setText(stringBuilder.toString());
point = 0;
}
break;
case R.id.button_multiplication:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
break;
}
if (stringBuilder.length() != 0) {
String str5 = stringBuilder.toString();
if (!"+".equals(str5.substring(str5.length()-1) ) &&
!"-".equals(str5.substring(str5.length()-1) ) &&
!"*".equals(str5.substring(str5.length()-1) ) &&
!"/".equals(str5.substring(str5.length()-1) )) {
if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
}
stringBuilder.append("*");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
}
}
break;
case R.id.button_division:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
break;
}
if (stringBuilder.length() != 0) {
String str6 = stringBuilder.toString();
if (!"+".equals(str6.substring(str6.length()-1) ) &&
!"-".equals(str6.substring(str6.length()-1) ) &&
!"*".equals(str6.substring(str6.length()-1) ) &&
!"/".equals(str6.substring(str6.length()-1) )) {
if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
}
stringBuilder.append("/");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
}
}
break;
case R.id.button_left:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
flag1++;
point = 0;
zero = false;
break;
}
if (stringBuilder.length() == 0) {
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
flag1++;
point = 0;
break;
} else {
String str7 = stringBuilder.toString();
if (".".equals(str7.substring(str7.length()-1))) {
stringBuilder.append(0);
stringBuilder.append("*");
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
point = 0;
zero = false;
flag1++;
} else if (stringBuilder.charAt(stringBuilder.length()-1) >= '0'
&& stringBuilder.charAt(stringBuilder.length()-1) <= '9') {
stringBuilder.append("*");
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
point = 0;
flag1++;
zero = false;
} else if (stringBuilder.charAt(stringBuilder.length()-1) == ')') {
stringBuilder.append("*");
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
flag1++;
point = 0;
zero = false;
} else {
stringBuilder.append("(");
editText.setText(stringBuilder.toString());
point = 0;
flag1++;
zero = false;
}
}
break;
case R.id.button_right:
String str1 = stringBuilder.toString();
if (flag1 > 0) {
if (!".".equals(str1.substring(str1.length()-1)) &&
!"(".equals(str1.substring(str1.length()-1)) &&
!"+".equals(str1.substring(str1.length()-1) ) &&
!"-".equals(str1.substring(str1.length()-1) ) &&
!"*".equals(str1.substring(str1.length()-1) ) &&
!"/".equals(str1.substring(str1.length()-1) )) {
stringBuilder.append(")");
point = 0;
editText.setText(stringBuilder.toString());
flag1--;
zero = false;
} else if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
stringBuilder.append(")");
point = 0;
editText.setText(stringBuilder.toString());
flag1--;
zero = false;
}
}
break;
case R.id.button_point:
if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
stringBuilder.delete(0, stringBuilder.length());
stringBuilder.append(0);
stringBuilder.append(".");
editText.setText(stringBuilder.toString());
point = 1;
zero = true;
break;
}
String str2 = stringBuilder.toString();
if (stringBuilder.length() != 0 &&
!"(".equals(str2.substring(str2.length()-1)) &&
!")".equals(str2.substring(str2.length()-1)) &&
!"+".equals(str2.substring(str2.length()-1)) &&
!"-".equals(str2.substring(str2.length()-1)) &&
!"*".equals(str2.substring(str2.length()-1)) &&
!"/".equals(str2.substring(str2.length()-1)) ) {
if (point == 0) {
stringBuilder.append(".");
editText.setText(stringBuilder.toString());
point = 1;
}
zero = true;
} else {
if (point == 0) {
stringBuilder.append(0);
stringBuilder.append(".");
editText.setText(stringBuilder.toString());
point = 1;
zero = true;
}
}
break;
default:
break;
}
}
上面代碼看著非常的多,做了許多的判斷,但這樣就保證了我的后面演算法就會變得非常的好進行運算,因為沒有了大多的非法輸入,也會是許多錯誤避免了,運算效率就提高了,這里面有許多的判斷,因為那些判斷是屬于優化程式的,所以后面再講他們的部分作用吧,
計算器的核心部分
計算器的核心部分就是計算出結果,前面做的全部都是準備作業,現在才開始計算其最為重要的部分,首先,我們要將其輸入的StringBuilder轉換為我們要進行計算的形式,所以就出現了我的change1()方法,我的這個方法是干什么的,就是將我的StringBuilder轉換為中綴運算式,為接下來的轉后綴運算式做準備,下面是我的change1()方法,
private ArrayList<String> change1() {
ArrayList<String> list = new ArrayList<>();
while (flag1 > 0) {
stringBuilder.append(")");
--flag1;
}
if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
stringBuilder.append(0);
}
String str = stringBuilder.toString();
String s = "";
for (int i = 0; i < str.length(); ) {
if (str.charAt(i) == '(') {
list.add(str.substring(i, i+1));
i++;
continue;
}
if (str.charAt(i) == '+') {
list.add(str.substring(i, i+1));
i++;
continue;
}
if (str.charAt(i) == '-') {
if (!(i != 0 && (str.charAt(i-1) == '*' || str.charAt(i-1) == '/'))) {
list.add(str.substring(i, i+1));
i++;
continue;
}
}
if (str.charAt(i) == '*') {
list.add(str.substring(i, i+1));
i++;
continue;
}
if (str.charAt(i) == '/') {
list.add(str.substring(i, i+1));
i++;
continue;
}
if (str.charAt(i) == ')') {
list.add(str.substring(i, i+1));
i++;
continue;
}
while (i < str.length() && ((str.charAt(i) <= '9' && str.charAt(i) >= '0') ||
str.charAt(i) == '.' ||
(str.charAt(i) == '-' && (str.charAt(i-1) == '*' || str.charAt(i-1) == '/')))) {
s = s + str.charAt(i);
i++;
}
list.add(s);
s = "";
}
return list;
}
在這個部分中,我也優化了當用戶輸入左括號時忘記輸入右括號所帶來的錯誤,我在這直接將右括號直接補上了,但是這樣就表示你忘記輸入的右括號就只能在最后了,我覺得開發者能做的只能是這些了,如果這樣導致和使用者所想的結果不同,我覺得這不是bug,這應該是使用者的粗心,因為開發者能想到的只能是將括號加在最后面,開發者不能知道使用者是如何去想的,
接下來就是中綴運算式轉后綴運算式了,我覺得這個是這個計算器中最難的一個部分了,先看代碼,
private ArrayList<String> change2(ArrayList<String> list1) {
ArrayList<String> list = new ArrayList<>();
Stack<String> myStack = new Stack<>();
String temp;
for (int i = 0;i < list1.size();i++) {
if (isNumber(list1.get(i))) {
list.add(list1.get(i));
} else if (list1.get(i).equals("(")) {
myStack.push(list1.get(i));
} else if (list1.get(i).equals("+") || list1.get(i).equals("-")) {
if (list1.get(i).equals("-") && (i == 0 || list1.get(i-1).equals("("))) {
list.add("0");
}
while (!myStack.isEmpty()) {
temp = myStack.pop();
if ("(".equals(temp)) {
myStack.push(temp);
break;
}
list.add(temp);
}
myStack.push(list1.get(i));
} else if (list1.get(i).equals("*") || list1.get(i).equals("/")) {
while (!myStack.isEmpty()) {
temp = myStack.pop();
if ("(".equals(temp) || "+".equals(temp) || "-".equals(temp)) {
myStack.push(temp);
break;
}
list.add(temp);
}
myStack.push(list1.get(i));
} else if (list1.get(i).equals(")")) {
while (!"(".equals(myStack.peek())) {
list.add(myStack.pop());
}
myStack.pop();
}
}
while (!myStack.isEmpty()) {
list.add(myStack.pop());
}
return list;
}
這是中綴表達轉后綴運算式,只要輸入的式子正確,我覺得應該都能轉換出來,這其實就是一個進堆疊出堆疊的程序,如果不會,建議繼續學習一下資料結構,
最后就是后綴運算式的求值問題,這也是資料結構那的知識,我就不細講了,我用的是BigDecimal來進行計算的,這樣就能夠保證數字不管是大數還是小數都能計算,最后還要處理小數點后面的0的問題,
private String countResult(ArrayList<String> list) {
Stack<BigDecimal> myStack = new Stack<>();
BigDecimal bigDecimal_1, bigDecimal_2;
for (String string : list) {
if (isNumber(string)) {
myStack.push(new BigDecimal(string));
} else {
bigDecimal_1 = myStack.pop();
bigDecimal_2 = myStack.pop();
switch (string) {
case "+" :
myStack.push(bigDecimal_1.add(bigDecimal_2));
break;
case "-" :
myStack.push(bigDecimal_2.subtract(bigDecimal_1));
break;
case "*" :
myStack.push(bigDecimal_1.multiply(bigDecimal_2));
break;
case "/" :
myStack.push(bigDecimal_2.divide(bigDecimal_1,5,BigDecimal.ROUND_HALF_UP));
break;
}
}
}
return deleteZero(myStack.peek().toString());
}
private String deleteZero(String string) {
if(string.indexOf(".") > 0){
string = string.replaceAll("0+?$", "");
string = string.replaceAll("[.]$", "");
}
return string;
}
優化
上面的計算器已經可以進行計算了,但是沒講如何進行優化的,接下來我簡單講一下我是如何進行優化的,在直接輸入一個小數點時,就可以在前面補上0,因為你已經輸入了小數點,單獨輸入小數點是沒有意義的,所以我就直接加上了0.在輸入小數點后沒有輸入任何數字時,輸入了運算子,就會在小數點后面添加一個0,這樣就不會出現運算錯誤了,
然后就是在輸入括號時,默認是輸入了一個括號,這也符合我們的使用習慣,
還優化了小數點,不能輸入多個小數點,不能連續輸入多個0.
還優化了一些細節,可能沒寫到,
這是我學習Android寫的第一個app,以后還會有很多的專案去做,希望自己能夠寫的越來越好!
這是Github原始碼地址:
GitHub原始碼地址
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/291673.html
標籤:其他
