Android實現(xiàn)簡易計算器功能
本項目為大家分享了Android實現(xiàn)計算器功能的具體代碼,供大家參考,具體內(nèi)容如下
項目介紹
練手項目。能實現(xiàn)加減乘除及括號運算。
開發(fā)思路
界面布局
1.界面布局分三大塊:公式文本區(qū)、結(jié)果文本區(qū)、按鈕區(qū)。
2.通過點擊按鈕錄入數(shù)學(xué)公式,實時展示在公式文本區(qū)。
3.點擊等號,計算結(jié)果展示在結(jié)果文本區(qū)。
4.另外還有清空數(shù)據(jù)和刪除一個字符功能。
計算邏輯
1.將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式
2.計算后綴表達(dá)式得出結(jié)果
其他說明
棧數(shù)據(jù)結(jié)構(gòu)簡單說明:
1.棧數(shù)據(jù)結(jié)構(gòu)像彈夾一樣,先壓進去的子彈后打出來,后壓進去的子彈先打出來
2.入棧:將元素放進棧里,并改變棧頂指針
3.出棧:將元素從棧里拿出來,并改變棧頂指針
4.查看棧頂,取得棧頂元素,但不改變棧頂指針
中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式簡單說明
1.如果是數(shù)字,直接放進后綴表達(dá)式里。
2.如果是左括號,入棧。
3.如果是右括號,依次出棧(放到后綴表達(dá)式里),直到遇到左括號。
4.運算符號:
1).空?;驐m斒亲罄ㄌ?,入棧
2).棧頂符號優(yōu)先級比當(dāng)前符號小,入棧
3).棧頂符號優(yōu)先級大于等于當(dāng)前符號,依次出棧(放到后綴表達(dá)式里),直到遇到不滿足條件的元素或棧被掏空。
5.最后如果棧還有符號,依次出棧(放到后綴表達(dá)式里)
后綴表達(dá)式計算簡單說明
1.如果是數(shù)字,入棧
2.如果是運算符,將棧頂?shù)膬蓚€數(shù)字彈出并計算(先出棧的數(shù)字放在運算符后面進行計算),再將計算結(jié)果入棧。
代碼
界面代碼
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <TextView android:id="@+id/the_expression" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right" android:textSize="50dp" /> </LinearLayout> <View android:layout_width="wrap_content" android:layout_height="2dp" android:background="#000" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <TextView android:id="@+id/the_result" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right" android:textSize="50dp" /> </LinearLayout> <View android:layout_width="wrap_content" android:layout_height="2dp" android:background="#000" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/left_bracket" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="(" android:textSize="30sp" /> <Button android:id="@+id/right_bracket" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text=")" android:textSize="30sp" /> <Button android:id="@+id/clear" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="C" android:textSize="30sp" /> <Button android:id="@+id/delete" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="DEL" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/seven" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="7" android:textSize="30sp" /> <Button android:id="@+id/eight" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="8" android:textSize="30sp" /> <Button android:id="@+id/nine" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="9" android:textSize="30sp" /> <Button android:id="@+id/substraction" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="-" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/four" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="4" android:textSize="30sp" /> <Button android:id="@+id/five" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="5" android:textSize="30sp" /> <Button android:id="@+id/six" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="6" android:textSize="30sp" /> <Button android:id="@+id/add" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="+" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/one" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="1" android:textSize="30sp" /> <Button android:id="@+id/two" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="2" android:textSize="30sp" /> <Button android:id="@+id/three" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="3" android:textSize="30sp" /> <Button android:id="@+id/division" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="÷" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/zero" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="0" android:textSize="30sp" /> <Button android:id="@+id/point" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="." android:textSize="30sp" /> <Button android:id="@+id/equal" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="=" android:textSize="30sp" /> <Button android:id="@+id/mulitipliction" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="×" android:textSize="30sp" /> </LinearLayout> </LinearLayout>
后臺邏輯
package com.example.calc; import android.os.Bundle; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.calc.utils.Stack; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { static final String ADD_TEXT = "+"; static final String SUBSTRACTION_TEXT = "-"; static final String MULTIPLICATION_TEXT = "×"; static final String DIVISION_TEXT = "÷"; static final String LEFT_BRACKET_TEXT = "("; static final String RIGHT_BRACKET_TEXT = ")"; //符號集合 static final List<String> SYMBOLS = Arrays.asList(ADD_TEXT, SUBSTRACTION_TEXT, MULTIPLICATION_TEXT, DIVISION_TEXT, LEFT_BRACKET_TEXT, RIGHT_BRACKET_TEXT); //符號優(yōu)先級 static final Map<String, Integer> SYMBOL_PRIORITY_LEVEL = new HashMap<String, Integer>(4) {{ put(ADD_TEXT, 1); put(SUBSTRACTION_TEXT, 1); put(MULTIPLICATION_TEXT, 2); put(DIVISION_TEXT, 2); }}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { TextView expTextView = findViewById(R.id.the_expression); TextView resultTextView = findViewById(R.id.the_result); //數(shù)字與運算符按鈕 int[] ids = {R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.point, R.id.add, R.id.substraction, R.id.mulitipliction, R.id.division, R.id.left_bracket, R.id.right_bracket}; for (int id : ids) { findViewById(id).setOnClickListener((v) -> { String newText = expTextView.getText().toString() + ((Button) v).getText().toString(); expTextView.setText(newText); }); } //刪除一個字符 findViewById(R.id.delete).setOnClickListener((v) -> { CharSequence text = expTextView.getText(); if (text != null && text.length() > 0) { if (text.length() == 1) { expTextView.setText(null); } else { expTextView.setText(text.subSequence(0, text.length() - 1)); } } }); //清理 findViewById(R.id.clear).setOnClickListener((v) -> { expTextView.setText(null); resultTextView.setText(null); }); //等于 findViewById(R.id.equal).setOnClickListener((v) -> { List<String> infix = getInfix(expTextView.getText().toString()); List<String> suffix = infixToSuffix(infix); Double result1 = getResult(suffix); String result = String.valueOf(result1); if (result.contains(".") && result.split("\\.")[1].replace("0", "").length() == 0) { result = result.split("\\.")[0]; } resultTextView.setText(result); }); } //字符串轉(zhuǎn)中綴表達(dá)式 private List<String> getInfix(String exp) { List<String> texts = new ArrayList<>(); char[] chars = exp.toCharArray(); StringBuilder sText = new StringBuilder(); for (char c : chars) { String text = String.valueOf(c); if (SYMBOLS.contains(text)) { if (sText.length() > 0) { texts.add(sText.toString()); sText.delete(0, sText.length()); } texts.add(text); } else { sText.append(text); } } if (sText.length() > 0) { texts.add(sText.toString()); sText.delete(0, sText.length()); } return texts; } //中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式 private List<String> infixToSuffix(List<String> infix) { List<String> sufText = new ArrayList<>(); Stack<String> stack = new Stack<>(infix.size()); for (String text : infix) { if (!SYMBOLS.contains(text)) { //數(shù)值,直接放到后綴表達(dá)式 sufText.add(text); } else if (LEFT_BRACKET_TEXT.equals(text)) { //左括號,直接入棧 stack.push(text); } else if (RIGHT_BRACKET_TEXT.equals(text)) { //右括號,依次取出棧頂元素放到后綴表達(dá)式,直到遇到左括號 while (!stack.isEmpty()) { String pop = stack.pop(); if (!LEFT_BRACKET_TEXT.equals(pop)) { sufText.add(pop); } else { break; } } } else { //其他符號(+-*/) buildSuffix(text, sufText, stack); } } //取出剩余棧內(nèi)數(shù)據(jù)放到后綴表達(dá)式 while (!stack.isEmpty()) { sufText.add(stack.pop()); } return sufText; } //后綴表達(dá)式求結(jié)果 private Double getResult(List<String> suffix) { Stack<Double> stack = new Stack<>(suffix.size()); for (String text : suffix) { switch (text) { case SUBSTRACTION_TEXT: { Double pop1 = stack.pop(); Double pop2 = stack.pop(); stack.push(pop2 - pop1); break; } case ADD_TEXT: { Double pop1 = stack.pop(); Double pop2 = stack.pop(); stack.push(pop1 + pop2); break; } case DIVISION_TEXT: { Double pop1 = stack.pop(); Double pop2 = stack.pop(); stack.push(pop2 / pop1); break; } case MULTIPLICATION_TEXT: { Double pop1 = stack.pop(); Double pop2 = stack.pop(); stack.push(pop1 * pop2); break; } default: stack.push(Double.valueOf(text)); break; } } return stack.pop(); } private void buildSuffix(String symbol, List<String> suffix, Stack<String> stack) { if (stack.isEmpty()) { //是空棧符號直接入棧 stack.push(symbol); } else { //棧頂查看 String peek = stack.peek(); //棧頂是左括號符號或當(dāng)前符號優(yōu)先級大于棧頂符號直接入棧 if (LEFT_BRACKET_TEXT.equals(peek) || isGreaterThanLevel(symbol, peek)) { stack.push(symbol); } else { //棧頂不是左括號,依次取出比當(dāng)前符號優(yōu)先級小或優(yōu)先級相同的符號放到后綴表達(dá)式 while (!stack.isEmpty()) { if (isLessThanOrEquals(symbol, stack.peek())) { suffix.add(stack.pop()); } else { //遇到不符合條件的棧頂數(shù)據(jù),直接退出 break; } } //取完數(shù)據(jù)后,將當(dāng)前符號入棧 stack.push(symbol); } } } private boolean isGreaterThanLevel(String symbol, String peek) { Integer symbolLevel = SYMBOL_PRIORITY_LEVEL.get(symbol); Integer peekLevel = SYMBOL_PRIORITY_LEVEL.get(peek); return symbolLevel != null && peekLevel != null && symbolLevel > peekLevel; } private boolean isLessThanOrEquals(String symbol, String peek) { Integer symbolLevel = SYMBOL_PRIORITY_LEVEL.get(symbol); Integer peekLevel = SYMBOL_PRIORITY_LEVEL.get(peek); return symbolLevel != null && peekLevel != null && symbolLevel <= peekLevel; } }
棧數(shù)據(jù)結(jié)構(gòu)
package com.example.calc.utils; public class Stack<T> { private int size; private Object[] elements; private int top = -1; public Stack(int size) { this.size = size; elements = new Object[size]; } //壓棧 public void push(T element) { if (top != size - 1) { elements[top + 1] = element; top++; } else { throw new RuntimeException("stack is full!"); } } //彈棧 public T pop() { if (top > -1) { top--; return (T) elements[top + 1]; } else { throw new RuntimeException("stack is null!"); } } //查看棧頂 public T peek() { if (top > -1) { return (T) elements[top]; } else { return null; } } public boolean isEmpty(){ return top == -1; } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android時間對話框TimePickerDialog詳解
這篇文章主要為大家詳細(xì)介紹了Android時間對話框TimePickerDialog的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Android 獲取未安裝的APK圖標(biāo)、版本號、包名等信息方法
下面小編就為大家分享一篇Android 獲取未安裝的APK圖標(biāo)、版本號、包名等信息方法,具有很好的參考價值,希望對大家有所幫助。2018-01-01Ubuntu中為Android系統(tǒng)上實現(xiàn)內(nèi)置C可執(zhí)行程序測試Linux內(nèi)核驅(qū)動程序
本文主要介紹在Ubuntu上為Android系統(tǒng)內(nèi)置C可執(zhí)行程序測試Linux內(nèi)核驅(qū)動程序,這里對測試Linux 內(nèi)核驅(qū)動程序做了詳細(xì)介紹,并附有代碼示例,有興趣的小伙伴可以參考下2016-08-08Android自定義view實現(xiàn)電影票在線選座功能
這篇文章主要為大家詳細(xì)介紹了Android自定義view實現(xiàn)選座功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11Android啟動頁廣告(騰訊廣告聯(lián)盟)解決方法及源碼下載
這篇文章主要介紹了Android啟動頁廣告(騰訊廣告聯(lián)盟)解決方法的相關(guān)資料,啟動頁幾乎成為了每個app的標(biāo)配,有些商家在啟動頁中增加了開屏廣告以此帶來更多的收入,需要的朋友可以參考下2017-03-03Android中的SpannableString與SpannableStringBuilder詳解
這篇文章主要給大家介紹了關(guān)于Android中SpannableString與SpannableStringBuilder的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10Android 實現(xiàn)微信長按菜單 -FloatMenu
在日常開發(fā)中,長按某個view出現(xiàn)個菜單是很常見的需求,下面小編給大家?guī)砹薃ndroid 實現(xiàn)微信長按菜單 -FloatMenu的實現(xiàn)思路及具體實現(xiàn)代碼,感興趣的朋友跟隨腳本之家小編一起看看吧2018-07-07