Android實(shí)現(xiàn)簡易計(jì)算器功能
本項(xiàng)目為大家分享了Android實(shí)現(xiàn)計(jì)算器功能的具體代碼,供大家參考,具體內(nèi)容如下
項(xiàng)目介紹
練手項(xiàng)目。能實(shí)現(xiàn)加減乘除及括號運(yùn)算。
開發(fā)思路
界面布局
1.界面布局分三大塊:公式文本區(qū)、結(jié)果文本區(qū)、按鈕區(qū)。
2.通過點(diǎn)擊按鈕錄入數(shù)學(xué)公式,實(shí)時(shí)展示在公式文本區(qū)。
3.點(diǎn)擊等號,計(jì)算結(jié)果展示在結(jié)果文本區(qū)。
4.另外還有清空數(shù)據(jù)和刪除一個(gè)字符功能。
計(jì)算邏輯
1.將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式
2.計(jì)算后綴表達(dá)式得出結(jié)果
其他說明
棧數(shù)據(jù)結(jié)構(gòu)簡單說明:
1.棧數(shù)據(jù)結(jié)構(gòu)像彈夾一樣,先壓進(jìn)去的子彈后打出來,后壓進(jìn)去的子彈先打出來
2.入棧:將元素放進(jìn)棧里,并改變棧頂指針
3.出棧:將元素從棧里拿出來,并改變棧頂指針
4.查看棧頂,取得棧頂元素,但不改變棧頂指針
中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式簡單說明
1.如果是數(shù)字,直接放進(jìn)后綴表達(dá)式里。
2.如果是左括號,入棧。
3.如果是右括號,依次出棧(放到后綴表達(dá)式里),直到遇到左括號。
4.運(yùn)算符號:
1).空?;驐m斒亲罄ㄌ枺霔?br />
2).棧頂符號優(yōu)先級比當(dāng)前符號小,入棧
3).棧頂符號優(yōu)先級大于等于當(dāng)前符號,依次出棧(放到后綴表達(dá)式里),直到遇到不滿足條件的元素或棧被掏空。
5.最后如果棧還有符號,依次出棧(放到后綴表達(dá)式里)
后綴表達(dá)式計(jì)算簡單說明
1.如果是數(shù)字,入棧
2.如果是運(yùn)算符,將棧頂?shù)膬蓚€(gè)數(shù)字彈出并計(jì)算(先出棧的數(shù)字放在運(yùn)算符后面進(jìn)行計(jì)算),再將計(jì)算結(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>
后臺(tái)邏輯
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ù)字與運(yùn)算符按鈕
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);
});
}
//刪除一個(gè)字符
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í)有所幫助,也希望大家多多支持腳本之家。
- 從零開始學(xué)android實(shí)現(xiàn)計(jì)算器功能示例分享(計(jì)算器源碼)
- Android開發(fā)實(shí)現(xiàn)的簡單計(jì)算器功能【附完整demo源碼下載】
- android計(jì)算器簡單實(shí)現(xiàn)代碼
- Android計(jì)算器編寫代碼
- android計(jì)時(shí)器,時(shí)間計(jì)算器的實(shí)現(xiàn)方法
- Android Studio實(shí)現(xiàn)簡易計(jì)算器
- Android實(shí)現(xiàn)簡易計(jì)算器小程序
- Android中使用GridLayout網(wǎng)格布局來制作簡單的計(jì)算器App
- android studio實(shí)現(xiàn)計(jì)算器
- Android studio設(shè)計(jì)簡易計(jì)算器
相關(guān)文章
Android列表組件ListView使用詳解之動(dòng)態(tài)加載或修改列表數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于Android列表組件ListView使用詳解之動(dòng)態(tài)加載或修改列表數(shù)據(jù),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03
Android 線程之自定義帶消息循環(huán)Looper的實(shí)例
這篇文章主要介紹了Android 線程之自定義帶消息循環(huán)Looper的實(shí)例的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10
Android實(shí)現(xiàn)ListView控件的多選和全選功能實(shí)例
這篇文章主要介紹了Android實(shí)現(xiàn)ListView控件的多選和全選功能,結(jié)合實(shí)例形式分析了ListView控件多選及全選功能的布局與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-07-07
用Android Location獲取當(dāng)前地理位置的方法
本篇文章小編為大家介紹,用Android Location獲取當(dāng)前地理位置的方法。需要的朋友參考下2013-04-04
Android viewpager無限輪播獲取網(wǎng)絡(luò)圖片功能
這篇文章主要為大家詳細(xì)介紹了Android viewpager無限輪播獲取網(wǎng)絡(luò)圖片功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
android使用FlipAnimation實(shí)現(xiàn)3D垂直翻轉(zhuǎn)動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了android使用FlipAnimation實(shí)現(xiàn)3D垂直翻轉(zhuǎn)動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Java語言讀取配置文件config.properties的方法講解
今天小編就為大家分享一篇關(guān)于Java語言讀取配置文件config.properties的方法講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03
Android之高德地圖定位SDK集成及地圖功能實(shí)現(xiàn)
本文主要介紹了Android中高德地圖定位SDK集成及地圖功能的實(shí)現(xiàn)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04
android 添加按(power鍵)電源鍵結(jié)束通話(掛斷電話)
首先我們發(fā)現(xiàn)現(xiàn)在我們所用的android智能手機(jī)大部分都有當(dāng)你在打電話時(shí)按power鍵來掛斷電話,一般都是在設(shè)置中2013-01-01

