Android入門(mén)-計(jì)算器

1. 前言

這是我的第一個(gè)安卓app,從界面到算法都是自己寫(xiě)的,期間經(jīng)歷了各種各樣的bug凑队,也學(xué)到的各種各樣的知識(shí),加深了對(duì)Java的使用幔翰,也了解了如何寫(xiě)一個(gè)Android應(yīng)用漩氨。因?yàn)槲襃ava也才入門(mén),安卓更不用說(shuō)(第一行代碼第三章都沒(méi)看完)遗增,所以代碼寫(xiě)的肯定非常粗糙叫惊,望大家諒解。后期我會(huì)對(duì)其進(jìn)行改進(jìn)做修,也會(huì)上傳到此博客

2. 準(zhǔn)備

1. 編譯器:Android Studio

雖說(shuō)AndroidStudio有很多不如人意的地方(主要還是谷歌是一個(gè)404小公司)霍狰,特別是gradle。但是其作為現(xiàn)在谷歌力推的編譯器饰及,還是很值得信賴的蔗坯。基于Idea燎含,所以界面宾濒、插件等方面都不用說(shuō),而且從Idea過(guò)來(lái)簡(jiǎn)直就是秒適應(yīng)(畢竟他就相當(dāng)于一個(gè)加強(qiáng)版Idea)屏箍。所以我個(gè)人推薦AndroidStudio绘梦。

2. 所需知識(shí):

  1. 有一個(gè)簡(jiǎn)單的Java基礎(chǔ)橘忱。
    我也就學(xué)到異常和泛型這塊,IO卸奉、多線程都沒(méi)學(xué)
  2. 對(duì)Android開(kāi)發(fā)有一個(gè)簡(jiǎn)單的了解
    我是看第一行代碼看到第三章基礎(chǔ)空間以及布局就開(kāi)始寫(xiě)了
  3. 對(duì)計(jì)算器算法的大致了解
    中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式钝诚,后綴表達(dá)式的運(yùn)算

3. 學(xué)會(huì)使用百度谷歌等搜索引擎

很多東西書(shū)上沒(méi)講,你不知道怎么實(shí)現(xiàn)榄棵,就直接百度或者google敲长,找到別人的博客,然后好好看一遍秉继,就算你看不懂祈噪,但是一定要看一遍,對(duì)其有一個(gè)大致的了解

4. 會(huì)使用AndroidStudio

至少懂得如何使用快捷鍵尚辑,懂得編譯器界面上各個(gè)部分干嘛的

3. 實(shí)現(xiàn)效果辑鲤,截圖

1. 實(shí)現(xiàn)效果

  1. 能實(shí)現(xiàn)表達(dá)式的運(yùn)算(廢話,好歹是個(gè)計(jì)算器)
  2. 當(dāng)你表達(dá)式存在問(wèn)題時(shí)杠茬,不讓你輸入月褥,或者不讓你按下等號(hào),并且某些情況會(huì)提示你
  3. 能對(duì)負(fù)數(shù)進(jìn)行計(jì)算
  4. 有些簡(jiǎn)單的自動(dòng)補(bǔ)全功能
  5. 能拋出異常

2. 截圖

截圖.png

代碼部分

1. 界面

1. 使用百分比布局

我選擇的是百分比界面瓢喉,但是由于百分比布局是新增的布局宁赤,所以你得手動(dòng)添加其相應(yīng)的依賴

  • 打開(kāi) app/build.gradle 文件,在dependencies閉包中添加這樣一行代碼
dependencies {
    implementation 'com.android.support:percent:28.0.0-alpha3'
}
  • 添加完畢后栓票,編輯面板頂部會(huì)出現(xiàn)一行提示决左,點(diǎn)擊Sync now稍等片刻即可


    build提示.png

2. button周邊的邊框

因?yàn)锳ndroid對(duì)button不能通過(guò)設(shè)置屬性來(lái)達(dá)到顯示邊框的功能,所以我們只能創(chuàng)建一個(gè)圖片文件走贪,在圖片中設(shè)置背景色以及邊框的寬度和顏色佛猛,然后把button的background屬性設(shè)置為對(duì)應(yīng)圖片

  • 首先在app/src/main/res/drawable文件夾中新建一個(gè)Drawable resource file
  • 在彈出的窗口中設(shè)置文件名,文件名隨意坠狡,但是要簡(jiǎn)單易懂继找,而且編譯器不報(bào)錯(cuò),例如我設(shè)置的shape_blue_bg
  • 然后切換到text視圖逃沿,把代碼修改為
一定要把下面代碼中的注釋刪掉
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#f0ffff"/> //設(shè)置背景顏色婴渡,也就是你按鍵想要顯示的顏色
    <stroke
        android:width="0.01dp" //設(shè)置邊框的寬度
        android:color="#ccc0c0c0"/> //設(shè)置邊框的顏色
</shape>
  • 然后再在你的布局文件(例如app/src/main/res/layout/activity_main.xml)中,對(duì)需要顯示邊框的button中添加設(shè)置背景這行代碼
一定要把下面代碼中的注釋刪掉
<Button
        android:id="@+id/button0"
        android:background="@drawable/click_white" //設(shè)置button的背景
        />

3. 實(shí)現(xiàn)button點(diǎn)擊變色功能

點(diǎn)擊變色.png
  • 首先在app/src/main/res/drawable文件夾中新建一個(gè)Drawable resource file凯亮,隨意起名碉纺,例如我的click_blue
  • 把代碼修改為
一定要把下面代碼中的注釋刪掉
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_click_blue_bg" //設(shè)置背景尤蒿,就是上面的有邊框的文件馋评,你也可以就設(shè)置成顏色恨闪,或者其他圖片
        android:state_enabled="true"
        android:state_pressed="true"/> //當(dāng)button被點(diǎn)擊時(shí)
    <item android:drawable="@drawable/shape_white_bg"http://設(shè)置背景,就是上面的有邊框的文件置谦,你也可以就設(shè)置成顏色堂鲤,或者其他圖片
        android:state_enabled="true"
        android:state_pressed="false"/> //當(dāng)button未被點(diǎn)擊時(shí)
</selector>
  • 你可以看到他需要兩個(gè)drawable文件,一個(gè)是點(diǎn)擊時(shí)的顯示效果媒峡,一個(gè)是未點(diǎn)擊時(shí)的顯示效果瘟栖,而在設(shè)置邊框時(shí)還只創(chuàng)建了一個(gè)文件,也就是他不點(diǎn)擊時(shí)的文件谅阿,接下來(lái)半哟,我們還得創(chuàng)建一個(gè)跟他一樣的文件,只是顏色不同而已
  • 創(chuàng)建一個(gè)邊框背景文件签餐,隨意命名
  • 把代碼修改為如下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff"/>
    <stroke
        android:width="0.01dp"
        android:color="#ccc0c0c0"/>
</shape>
  • 然后再在你的布局文件(例如app/src/main/res/layout/activity_main.xml)中寓涨,對(duì)需要顯示邊框的button中添加設(shè)置背景這行代碼
一定要把下面代碼中的注釋刪掉
<Button
        android:id="@+id/button0"
        android:background="@drawable/click_blue" //設(shè)置button的背景,也就是你剛剛創(chuàng)建的那個(gè)起選擇按壓那個(gè)背景不按壓那個(gè)背景的文件
        />

4. 隱藏app默認(rèn)自帶標(biāo)題欄

  • 在代碼中氯檐,在onCreate()中戒良,在super.onCreate(savedInstanceState)之后setContentView(R.layout.activity_main)之前添加
// 隱藏標(biāo)題欄
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
    actionBar.hide();
}

5. 隱藏系統(tǒng)通知欄

  • 在上面一樣的地方,添加
// 隱藏通知欄
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

6. 修改app名稱(chēng)

  • app/src/java/res/values/strings.xml文件中將第二行(一般默認(rèn)是第二行冠摄,不是第二行的話就在其他地方找糯崎,反正編輯器一定會(huì)自動(dòng)創(chuàng)建這行代碼的)
<resources>
    <string name="app_name">小柯基的calculator</string> //“小柯基的calculator”就是我的app名稱(chēng),你可以換成任何自己想要的名字
</resources>

7. 修改app圖標(biāo)

因?yàn)槠捏w我就不再這說(shuō)了河泳,分享博客地址
https://blog.csdn.net/zhangkaidsy/article/details/74852470

8. 將默認(rèn)字體修改為非襯線字體

由于默認(rèn)字體我覺(jué)得有點(diǎn)粗了沃呢,而網(wǎng)上的使用極細(xì)字體的方法又太細(xì)了,所以我就想到了修改字體的方法拆挥,還是在layout設(shè)置布局的xml文件中薄霜,找到你要修改字體的組件,添加一行android:typeface="sans"

<Button
        android:id="@+id/button0"
        android:text="@string/num0"
        android:typeface="sans" //這行代碼就是修改
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

詳情見(jiàn)https://blog.csdn.net/l_lhc/article/details/51769245

9. 字體能適應(yīng)顯示框而改變大小

大家在很多app中都看到過(guò)一個(gè)功能纸兔,就是你輸入的文字黄锤,能隨著你輸入的文字的數(shù)量而快占滿顯示框的時(shí)候,自動(dòng)縮小字體以適應(yīng)顯示框


自動(dòng)適應(yīng).png
  • 同樣是在顯示布局的文件中食拜,在顯示組件中添加一行代碼
 <TextView
        android:id="@+id/text_view"
        app:autoSizeTextType="uniform" //開(kāi)啟字體自適應(yīng)功能
        app:layout_heightPercent="25%"
        app:layout_widthPercent="100%" />
  • 但是這種方法存在一個(gè)問(wèn)題鸵熟,就是它自動(dòng)適應(yīng)輸入框大小,就是說(shuō)负甸,你的輸入框有多大流强,他顯示的字體就有多大,所以我們得對(duì)他做個(gè)限制呻待。限制最大字體和最小字體以及每次變化的字體的大小
 <TextView
        android:id="@+id/text_view"
        app:autoSizeMaxTextSize="80sp" //最大字體
        app:autoSizeMinTextSize="20sp" //最小字體
        app:autoSizeStepGranularity="4sp" //每次變化的字體大小
        app:autoSizeTextType="uniform" //開(kāi)啟字體自適應(yīng)功能
        app:layout_heightPercent="25%"
        app:layout_widthPercent="100%" />

10. 關(guān)于組件之間配色問(wèn)題

自己百度(手動(dòng)doge)

11. 代碼

layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/buttonC"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:background="@drawable/click_yellow"
        android:gravity="center"
        android:text="@string/C"
        android:textColor="#6f6f6f"
        android:textSize="30sp"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button0"
        android:layout_width="81dp"
        android:layout_height="81dp"
        android:layout_alignParentBottom="true"
        android:layout_toEndOf="@+id/buttonC"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num0"
        android:typeface="sans"
        android:textSize="30sp"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonDot"
        android:layout_alignParentBottom="true"
        android:layout_toEndOf="@id/button0"
        android:background="@drawable/click_yellow"
        android:gravity="center"
        android:text="@string/Dot"
        android:textSize="30sp"
        android:textColor="#6f6f6f"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonEqual"
        android:layout_alignParentBottom="true"
        android:layout_toEndOf="@id/buttonDot"
        android:background="#58a6e3 "
        android:gravity="center"
        android:text="@string/equal"
        android:textColor="#fff"
        android:textSize="40sp"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button1"
        android:layout_above="@id/buttonC"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num1"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        android:textSize="30sp"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button2"
        android:layout_above="@id/button0"
        android:layout_toEndOf="@id/button1"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num2"
        android:textSize="30sp"
        android:textColor="#6f6f6f"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button3"
        android:layout_above="@id/buttonDot"
        android:layout_toEndOf="@id/button2"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num3"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonAdd"
        android:layout_above="@id/buttonEqual"
        android:layout_toEndOf="@id/button3"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/add"
        android:textColor="#019eff"
        android:textSize="40sp"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button4"
        android:layout_above="@id/button1"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num4"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button5"
        android:layout_above="@id/button2"
        android:layout_toEndOf="@id/button4"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num5"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button6"
        android:layout_above="@id/button3"
        android:layout_toEndOf="@id/button5"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num6"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonDec"
        android:layout_above="@id/buttonAdd"
        android:layout_toEndOf="@id/button6"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/dec"
        android:textColor="#019eff"
        android:textSize="40sp"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button7"
        android:layout_width="wrap_content"
        android:layout_height="81dp"
        android:layout_above="@id/button4"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num7"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button8"
        android:layout_width="81dp"
        android:layout_height="81dp"
        android:layout_above="@id/button5"
        android:layout_marginStart="0dp"
        android:layout_toEndOf="@id/button7"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num8"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/button9"
        android:layout_above="@+id/button6"
        android:layout_toEndOf="@id/button8"
        android:background="@drawable/click_white"
        android:gravity="center"
        android:text="@string/num9"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#6f6f6f"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonMulti"
        android:layout_above="@id/buttonDec"
        android:layout_toEndOf="@id/button9"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/multi"
        android:textColor="#019eff"
        android:textSize="40sp"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonAC"
        android:layout_above="@+id/button7"
        android:layout_alignParentStart="true"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/AC"
        android:textSize="30sp"
        android:textColor="#e47c5e"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonBracketLeft"
        android:layout_above="@id/button8"
        android:layout_toEndOf="@id/buttonAC"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/BracketLeft"
        android:textSize="30sp"
        android:typeface="sans"
        android:textColor="#019eff"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonBracketRight"
        android:layout_above="@id/button9"
        android:layout_toEndOf="@id/buttonBracketLeft"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/BracketRight"
        android:textSize="30sp"
        android:textColor="#019eff"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />

    <Button
        android:id="@+id/buttonDiv"
        android:layout_above="@id/buttonMulti"
        android:layout_toEndOf="@id/buttonBracketRight"
        android:background="@drawable/click_blue_light"
        android:gravity="center"
        android:text="@string/div"
        android:textSize="30sp"
        android:textColor="#019eff"
        android:typeface="sans"
        app:layout_heightPercent="15%"
        app:layout_widthPercent="25%" />



    <TextView
        android:id="@+id/text_view"
        android:background="#FAFFF0"
        android:layout_alignParentTop="true"
        android:gravity="end|center_vertical"
        app:autoSizeMaxTextSize="80sp"
        app:autoSizeMinTextSize="20sp"
        app:autoSizeStepGranularity="4sp"
        app:autoSizeTextType="uniform"
        app:layout_heightPercent="25%"
        app:layout_widthPercent="100%" />

</android.support.percent.PercentRelativeLayout>
values/strings.xml
<resources>
    <string name="app_name">小柯基的calculator</string>
    <string name="AC">AC</string>
    <string name="AddDec">+/-</string>
    <string name="equal">=</string>
    <string name="add">+</string>
    <string name="dec">-</string>
    <string name="multi">*</string>
    <string name="div">/</string>
    <string name="Dot">.</string>
    <string name="num0">0</string>
    <string name="num1">1</string>
    <string name="num2">2</string>
    <string name="num3">3</string>
    <string name="num4">4</string>
    <string name="num5">5</string>
    <string name="num6">6</string>
    <string name="num7">7</string>
    <string name="num8">8</string>
    <string name="num9">9</string>
    <string name="BracketLeft">(</string>
    <string name="BracketRight">)</string>
    <string name="Mod">%</string>
    <string name="Delete">刪除</string>
    <string name="C">C</string>
</resources>
values/styles.xml
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="baseTextStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:fontFamily">sans-serif-light</item>
    </style>

</resources>
drawable/click_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_click_blue_bg" android:state_enabled="true"
        android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_white_bg" android:state_enabled="true"
        android:state_pressed="false"/>
</selector>
drawable/click_blue_light.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_white_bg" android:state_enabled="true"
        android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_click_blue_bg" android:state_enabled="true"
        android:state_pressed="false"/>\

</selector>
drawable/click_white.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_click_blue_bg" android:state_enabled="true"
        android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_white_bg" android:state_enabled="true"
        android:state_pressed="false"/>\

</selector>
drawable/click_yellow.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_white_bg" android:state_enabled="true"
        android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_yellow_bg" android:state_enabled="true"
        android:state_pressed="false"/>\

</selector>
drawable/shape_click_blue_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#f0ffff"/>
    <stroke
        android:width="0.01dp"
        android:color="#ccc0c0c0"/>
</shape>
drawable/shape_white_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff"/>
    <stroke
        android:width="0.01dp"
        android:color="#ccc0c0c0"/>
</shape>
drawable/shape_yellow_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#c8fffaf0"/>
    <stroke
        android:width="0.01dp"
        android:color="#ccc0c0c0"/>
</shape>

活動(dòng)的代碼

1. 異常處理

  • 當(dāng)輸出的結(jié)果有問(wèn)題時(shí)打月,拋出異常,然后顯示Error
  • 當(dāng)左括號(hào)數(shù)目等于或者小于右括號(hào)時(shí)蚕捉,不然輸入右括號(hào)奏篙,而且按等號(hào)不會(huì)運(yùn)算,提示括號(hào)不匹配
  • 當(dāng)前面是符號(hào),然后輸入減號(hào)默認(rèn)添加'('當(dāng)負(fù)號(hào)處理
  • 實(shí)現(xiàn)輸入是'數(shù)字(數(shù)字'時(shí)秘通,當(dāng)乘法處理
    ···還有很多功能就不一一列舉了

2. 點(diǎn)擊時(shí)手機(jī)震動(dòng)

  • 首先在AndroidManifest.xml中添加震動(dòng)權(quán)限
<uses-permission android:name="android.permission.VIBRATE" />
  • 新建class文件为严,命名為Vibrate
    代碼如下
package com.example.calculator;

import android.content.Context;
import android.os.Vibrator;

/**
 * Created by littlecorgi_a1203991686 on 2018/08/02 15:56.
 */
public class Vibrate {
    private static Vibrator vibrator;
    /**
     * 簡(jiǎn)單震動(dòng)
     * @param context     調(diào)用震動(dòng)的Context
     * @param millisecond 震動(dòng)的時(shí)間,毫秒
     */
    @SuppressWarnings("static-access")
    public static void vSimple(Context context, int millisecond) {
        vibrator = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE);
        vibrator.vibrate(millisecond);
    }
    /**
     * 停止震動(dòng)
     */
    public static void stop() {
        if (vibrator != null) {
            vibrator.cancel();
        }
    }
}

3. MainActivity代碼

package com.example.calculator;

import android.annotation.SuppressLint;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private TextView textview;
    private StringBuilder sb = new StringBuilder();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 隱藏標(biāo)題欄
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null){
            actionBar.hide();
        }

        // 隱藏通知欄
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        // 定義控件
        Button button0 = findViewById(R.id.button0);
        Button button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        Button button3 = findViewById(R.id.button3);
        Button button4 = findViewById(R.id.button4);
        Button button5 = findViewById(R.id.button5);
        Button button6 = findViewById(R.id.button6);
        Button button7 = findViewById(R.id.button7);
        Button button8 = findViewById(R.id.button8);
        Button button9 = findViewById(R.id.button9);
        Button buttonC = findViewById(R.id.buttonC);
        Button buttonDot =  findViewById(R.id.buttonDot);
        Button buttonEqual =  findViewById(R.id.buttonEqual);
        Button buttonAdd =  findViewById(R.id.buttonAdd);
        Button buttonDec =  findViewById(R.id.buttonDec);
        Button buttonMulti =  findViewById(R.id.buttonMulti);
        Button buttonAC =  findViewById(R.id.buttonAC);
        Button buttonBracketLeft =  findViewById(R.id.buttonBracketLeft);
        Button buttonBracketRight =  findViewById(R.id.buttonBracketRight);
        Button buttonDiv =  findViewById(R.id.buttonDiv);
        textview = findViewById(R.id.text_view);

        button0.setOnClickListener(this);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
        button5.setOnClickListener(this);
        button6.setOnClickListener(this);
        button7.setOnClickListener(this);
        button8.setOnClickListener(this);
        button9.setOnClickListener(this);
        buttonAC.setOnClickListener(this);
        buttonAdd.setOnClickListener(this);
        buttonBracketLeft.setOnClickListener(this);
        buttonBracketRight.setOnClickListener(this);
        buttonC.setOnClickListener(this);
        buttonDec.setOnClickListener(this);
        buttonDiv.setOnClickListener(this);
        buttonDot.setOnClickListener(this);
        buttonEqual.setOnClickListener(this);
        buttonMulti.setOnClickListener(this);
    }

    private int count_negative = 0; //負(fù)數(shù)標(biāo)記
    private final int vibrate_time = 5; //震動(dòng)時(shí)長(zhǎng)
    private boolean equals = false;
    private int count_bracket_left = 0;
    private int count_bracket_right = 0;



    @SuppressLint("SetTextI18n")
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button0:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                sb = sb.append("0");
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button1:
                if (equals) { //當(dāng)equals為true肺稀,輸入數(shù)字第股,清空字符串,在把標(biāo)志變?yōu)閒alse
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*1");
                } else {
                    sb = sb.append("1");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button2:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*2");
                } else {
                    sb = sb.append("2");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button3:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*3");
                } else {
                    sb = sb.append("3");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button4:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*4");
                } else {
                    sb = sb.append("4");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button5:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*5");
                } else {
                    sb = sb.append("5");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button6:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*6");
                } else {
                    sb = sb.append("6");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button7:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*7");
                } else {
                    sb = sb.append("7");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button8:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*8");
                } else {
                    sb = sb.append("8");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.button9:
                if (equals) {
                    sb = sb.delete(0, sb.length());
                    equals = false;
                }
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ')') {
                    sb = sb.append("*9");
                } else {
                    sb = sb.append("9");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonC: //刪除
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    sb = sb.deleteCharAt(sb.length() - 1);
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonAC: //清空
                if (equals) {
                    equals = false;
                }
                sb = sb.delete(0, sb.length());
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonBracketLeft: //左括號(hào)
                if (equals) {
                    equals = false;
                }
                if (sb.length() > 0 && (sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9')) { //當(dāng)前面是數(shù)字是话原,自動(dòng)添加為'*('
                    sb = sb.append("*(");
                }
                if (sb.length() == 0) { //如果此時(shí)字符串是空的夕吻,也就是說(shuō)想在式子最前面添加括號(hào),就添加括號(hào)
                    sb = sb.append("(");
                }
                if (sb.length() > 0 && (sb.charAt(sb.length() - 1) == '*' || sb.charAt(sb.length() - 1) == '/' || sb.charAt(sb.length() - 1) == '+' || sb.charAt(sb.length() - 1) == '-')) { //如果當(dāng)括號(hào)前面是符號(hào)時(shí)添加括號(hào)
                    sb = sb.append("(");
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonBracketRight: //=右括號(hào)
                if (equals) {
                    equals = false;
                }
                int count_num = 0; //數(shù)字的數(shù)目
                count_bracket_left = count_bracket_right = 0;
                    if (sb.length() != 0) {
                        for (int i = sb.length() - 1; i >= 0; i--) { //對(duì)字符串進(jìn)行遍歷繁仁,如果存在左括號(hào)且括號(hào)中有數(shù)字涉馅,標(biāo)記轉(zhuǎn)為真,
                            if (count_bracket_left == 0 && (sb.charAt(i) >= '0' && sb.charAt(i) <= '9')) {
                                count_num++;
                            }
                            if (sb.charAt(i) == '(') {
                                count_bracket_left++;
                            }
                            if (sb.charAt(i) == ')') {
                                count_bracket_right++;
                            }
                        }
                        Log.d("count_bracket", String.valueOf(count_bracket_left+" "+count_bracket_right));
                        if ((count_bracket_left > count_bracket_right) && count_num > 0) { //當(dāng)標(biāo)記均為真,也就是存在左括號(hào)時(shí)且在左括號(hào)前面有數(shù)字黄虱,才讓添加括號(hào)
                            sb = sb.append(")");
                        }
                    }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonDiv: //除號(hào)
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') || sb.charAt(sb.length() - 1) == '.') {
                        if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9')) { //如果前一位是數(shù)字稚矿,就直接添加
                            // if (count_negative > 0){ //如果前面是負(fù)數(shù),就加上括號(hào)
                            //     sb = sb.append(")/");
                            //     count_negative = 0;
                            // } else {
                            sb = sb.append("/");
                            // }
                        }
                        if (sb.charAt(sb.length() - 1) == '.') { //如果前一位是'.',就先為前一位數(shù)字補(bǔ)0
                            sb = sb.append("0/");
                        }
                    }
                    if ((sb.charAt(sb.length() - 1) == ')')) { //如果前一位是')'也讓加上/
                        sb = sb.append("/");
                    }
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonMulti: //乘號(hào)
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') || sb.charAt(sb.length() - 1) == '.') {
                        if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9')) {//如果前一位是數(shù)字悬钳,就直接添加
                            sb = sb.append("*");
                        }
                        if (sb.charAt(sb.length() - 1) == '.') {//如果前一位是'.',就先為前一位數(shù)字補(bǔ)0
                            sb = sb.append("0*");
                        }
                    }
                    if ((sb.charAt(sb.length() - 1) == ')')) {
                        sb = sb.append("*");
                    }
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonDec: //減號(hào)
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') || sb.charAt(sb.length() - 1) == '.' ||
                            sb.charAt(sb.length() - 1) == '(') {
                        if (sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') {//如果前一位是數(shù)字盐捷,就直接添加
                            // if (count_negative > 0) { //如果前面是負(fù)數(shù),就加上括號(hào)
                            //     sb = sb.append(")-");
                            //     count_negative = 0;
                            // } else {
                            sb = sb.append("-");
                            // }
                        }
                        if (sb.charAt(sb.length() - 1) == '.') {//如果前一位是'.',就先為前一位數(shù)字補(bǔ)0
                            sb = sb.append("0-");
                        }
                        if (sb.charAt(sb.length() - 1) == '(') {
                            sb = sb.append("-");
                            count_negative++;
                        }

                    } else if ((sb.charAt(sb.length() - 1) == ')')) {
                        sb = sb.append("-");
                    } else {
                        sb = sb.append("(-");
                    }

                } else { //負(fù)號(hào)
                    sb = sb.append("(-");
                    count_negative++;
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonAdd: //加號(hào)
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') || sb.charAt(sb.length() - 1) == '.') {
                        if ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9')) {//如果前一位是數(shù)字默勾,就直接添加
                            // if (count_negative > 0) { //如果前面是負(fù)數(shù)碉渡,就加上括號(hào)
                            //     sb = sb.append(")+");
                            //     count_negative = 0;
                            // } else {
                            sb = sb.append("+");
                            // }
                        }
                        if (sb.charAt(sb.length() - 1) == '.') {//如果前一位是'.',就先為前一位數(shù)字補(bǔ)0
                            sb = sb.append("0+");
                        }
                    }
                    if ((sb.charAt(sb.length() - 1) == ')')) {
                        sb = sb.append("+");
                    }
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonDot: //小數(shù)點(diǎn)
                if (equals) {
                    equals = false;
                }
                if (sb.length() != 0) {
                    int count_dot = 0;
                    for (int i = sb.length() - 1; i >= 0; i--) {
                        if (sb.charAt(i) == '.') {
                            count_dot++;
                        }
                        if (!(sb.charAt(i) >= '0' && sb.charAt(i) <= '9')) {
                            break;
                        }
                    }
                    if (count_dot == 0) {
                        if (sb.charAt(sb.length() - 1) == '*' || sb.charAt(sb.length() - 1) == '/' || sb.charAt(sb.length() - 1) == '+' || sb.charAt(sb.length() - 1) == '-') {
                            // 如果最后一位是符號(hào)時(shí),直接輸小數(shù)點(diǎn)會(huì)自動(dòng)補(bǔ)'0'母剥,形成'0.'
                            sb = sb.append("0.");
                        } else {
                            sb = sb.append(".");
                        }
                    }
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                textview.setText(sb.toString());
                break;
            case R.id.buttonEqual: //等號(hào)
                if (equals) {
                    equals = false;
                }
                count_bracket_right = count_bracket_left = 0;
                if (sb.length() != 0) {
                    for (int i = 0; i < sb.length(); i++) {
                        if (sb.charAt(i) == '(')
                            count_bracket_left++;
                        if (sb.charAt(i) == ')')
                            count_bracket_right++;
                    }
                    if (count_bracket_left != count_bracket_right) {
                        Toast.makeText(MainActivity.this, "請(qǐng)注意括號(hào)匹配", Toast.LENGTH_SHORT).show();
                    }
                    if (count_bracket_left == count_bracket_right &&
                            ((sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') || sb.charAt(sb.length() - 1) == ')')) {
                        equals = true;
                        count_negative = 0;
                        try {
                            textview.setText(InfixToSufix.Cal(InfixToSufix.Suffix(sb)));
                            sb = sb.delete(0, sb.length());
                            sb.append(textview.getText().toString());
                        } catch (Exception e){
                            textview.setText("Error");
                            sb = sb.delete(0, sb.length());
                        }
                    }
                }
                Vibrate.vSimple(view.getContext(), vibrate_time);
                break;
            default:
                break;
        }
    }
}

算法

1. 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

http://www.nowamagic.net/librarys/veda/detail/2307

2. 后綴表達(dá)式的計(jì)算

http://www.nowamagic.net/librarys/veda/detail/2306

3. 具體代碼

在MainActivity同一個(gè)包下新建class文件滞诺,命名為InfixToSuffix
代碼如下

package com.example.calculator;

import android.util.Log;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Created by littlecorgi_a1203991686 on 2018/08/02 15:56.
 */
public class InfixToSuffix {
    /**
     * 中綴轉(zhuǎn)后綴
     * @param str 從鍵盤(pán)讀入的String類(lèi)型的對(duì)象,也就是要求的表達(dá)式
     * @return 返回一個(gè)ArrayList類(lèi)型的對(duì)象环疼,也就是一個(gè)集合习霹,也即是后綴表達(dá)式,讓cal方法接收炫隶,
     */
    public static ArrayList Suffix(StringBuilder str){
        /*
         * Stack() 構(gòu)造方法
         * void add(int index, Object element) 在此向量的指定位置插入指定的元素
         * boolean empty() 測(cè)試堆棧是否為空
         * Object pop( ) 移除堆棧頂部的對(duì)象淋叶,并作為此函數(shù)的值返回該對(duì)象
         * Object push(Object element) 把項(xiàng)壓入堆棧頂部
         */

        for (int i = 1; i < str.length(); i++){ //識(shí)別到'(-'自動(dòng)補(bǔ)0
            if (str.charAt(i) == '-' && str.charAt(i - 1) == '('){
                str.insert(i, '0');
            }
        }

        StringBuilder temp = new StringBuilder(); // 當(dāng)做中間字符串,臨時(shí)存放數(shù)字伪阶,方便往list中添加

        List<String> list = new ArrayList<>(); // 用于存儲(chǔ)分割后的數(shù)字和符號(hào)

        ArrayList<String> result = new ArrayList<>(); //作為結(jié)果集合煞檩,后綴表達(dá)式保存在其中

        for (int i = 0; i < str.length(); i++){
            // if ( i != str.length() - 1 ){ //對(duì)不是最后一位數(shù)字的
            if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == '.'){ // 判斷是不是數(shù)字
                if (str.charAt(i) == '.' && temp.length() == 0){ //如果此位為'.',且這個(gè)時(shí)候中間字符串為空栅贴,自動(dòng)補(bǔ)0
                    temp.append(0); // 添加0斟湃,在添加'.'
                    temp.append(str.charAt(i));
                } else {
                    temp.append(str.charAt(i)); // 是數(shù)字,就往中間字符串添加
                }
                if (i == str.length() - 1){ //對(duì)最后一位進(jìn)行單獨(dú)判斷檐薯,如果是字符串最后一位凝赛,直接進(jìn)行添加到list操作
                    list.add(temp.toString());
                }
            } else  { // 不是數(shù)字
                if (temp.length() != 0)
                    list.add(temp.toString()); // 判斷中間字符串長(zhǎng)度是不是0,不是0就往list中添加
                list.add(String.valueOf(str.charAt(i))); // 將符號(hào)往list中添加
                temp.delete(0, temp.length()); // 清空中間字符串
            }
            // } else { //單獨(dú)把最后一個(gè)字符拿出來(lái)進(jìn)行判斷
            //     if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == '.'){ // 下面代碼注釋參考上面
            //         temp.append(str.charAt(i));
            //
            //     } else  {
            //         if (temp.length() != 0)
            //             list.add(temp.toString()); // 判斷中間字符串長(zhǎng)度是不是0,不是0就往list中添加
            //         list.add(String.valueOf(str.charAt(i)));
            //         temp.delete(0, temp.length());
            //     }
            // }
        }

        // 遍歷輸出
        for (String aList : list) {
            System.out.print(aList + " ");
        }
        System.out.println();

        // 定義棧
        Stack<String> stack = new Stack<>();

        // 定義符號(hào)的優(yōu)先級(jí)
        Map<Character, Integer> map = new HashMap<>();
        map.put('(', 0);
        map.put(')', 0);
        map.put('*', 1);
        map.put('/', 1);
        map.put('+', 2);
        map.put('-', 2);

        for ( String s : list ) {
            // System.out.println("s=" + s);
            if ( s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-") || s.equals("(") || s.equals(")") ){ //不為數(shù)字
                if (stack.size() == 0){ //如果當(dāng)前棧里面沒(méi)有元素墓猎,不管是啥捆昏,直接進(jìn)棧
                    stack.push(s);
                } else { //如果棧中有元素
                    if (s.equals(")")) { //如果當(dāng)前是),那就的往前找(與其對(duì)應(yīng)輸出
                        if (!stack.empty()){ //容錯(cuò),不然會(huì)有EmptyStackException陶衅,下面的類(lèi)似的表達(dá)式同理
                            while (!stack.peek().equals("(")){ //循環(huán)屡立,從棧頂開(kāi)始循環(huán)直晨,一直到棧頂為(搀军,退出循環(huán)
                                // System.out.print(stack.pop() + " "); //輸出并且把棧頂元素移除
                                result.add(stack.pop()); //保存到結(jié)果集合中,并且把棧頂元素移除
                                if (stack.empty()){//容錯(cuò)勇皇,不然會(huì)有EmptyStackException,見(jiàn)上面
                                    break;
                                }
                            }
                            if (!stack.empty()){
                                if (stack.peek().equals("("))//如果此時(shí)棧頂元素為(,就將他移除罩句,原因是后綴表達(dá)式不用(,而在之前我們將他壓入了棧中,具體見(jiàn)下面第5行
                                    stack.pop();
                            }
                        }
                    } else{
                        if (s.equals("(")){ //如果是'('將其入棧
                            stack.push(s);
                        } else {
                            if (stack.peek().charAt(0) != '('){
                                if ( map.get(s.charAt(0)) < map.get(stack.peek().charAt(0)) ){ //棧頂符號(hào)的優(yōu)先級(jí)高于元素優(yōu)先級(jí)敛摘,也就是數(shù)字小门烂,進(jìn)棧
                                    stack.push(s);
                                } else { //棧頂符號(hào)優(yōu)先級(jí)低于元素優(yōu)先級(jí),輸出并循環(huán)
                                    while ((map.get(s.charAt(0)) >= map.get(stack.peek().charAt(0))) && !stack.empty()){
                                        // System.out.print(stack.pop() + " ");
                                        result.add(stack.pop());
                                        if (stack.empty()){
                                            break;
                                        }
                                        if (stack.peek().equals("(")){
                                            break;
                                        }
                                    }
                                    stack.push(s);
                                }
                            } else {
                                stack.push(s);
                            }
                        }
                    }
                }
            } else { //是數(shù)字
                result.add(s);
            }
        }

        while (!stack.empty()){ //最后遍歷棧兄淫,把結(jié)果保存到result中屯远,直到棧被清空
            result.add(stack.pop());
        }
        return result;
    }

    /**
     * 用于計(jì)算后綴表達(dá)式的結(jié)果
     * @param arrayList 從Suffix傳出來(lái)的后綴表達(dá)式
     * @return 返回String類(lèi)型對(duì)象,也就是最后的結(jié)果
     */

    public static String Cal(ArrayList arrayList){
        int length = arrayList.size();
        String[] arr = new String[length]; //轉(zhuǎn)為字符串?dāng)?shù)組,方便模擬棧

        for (int i = 0; i < arrayList.size(); i++){
            arr[i] = (String)arrayList.get(i);
        }
        Log.d("asdfg", arrayList.toString());

        List<String> list = new ArrayList<>();
        for (String anArr : arr) { //此處就是上面說(shuō)的運(yùn)算過(guò)程捕虽,因?yàn)閘ist.remove的緣故慨丐,所以取出最后一個(gè)數(shù)個(gè)最后兩個(gè)數(shù)  都是size-2
            int size = list.size();
            switch (anArr) {
                case "+":
                    BigDecimal a = new BigDecimal(list.remove(size - 2)).add(new BigDecimal(list.remove(size - 2)));
                    // list.add(String.valueOf(a.stripTrailingZeros().toPlainString()));
                    list.add(a.stripTrailingZeros().toString()); //去掉結(jié)果最后的0
                    break;
                case "-":
                    BigDecimal b = new BigDecimal(list.remove(size - 2)).subtract(new BigDecimal(list.remove(size - 2)));
                    list.add(b.stripTrailingZeros().toString());
                    break;
                case "*":
                    BigDecimal c = new BigDecimal(list.remove(size - 2)).multiply(new BigDecimal(list.remove(size - 2)));
                    list.add(c.stripTrailingZeros().toString());
                    break;
                case "/":
                    BigDecimal d = new BigDecimal(list.remove(size - 2)).divide(new BigDecimal(list.remove(size - 2)), 10, BigDecimal.ROUND_HALF_UP);
                    list.add(d.stripTrailingZeros().toString());
                    break;
                default:
                    list.add(anArr);
                    break;//如果是數(shù)字  直接放進(jìn)list中
            }
        }

        if (list.size() == 1){
            if (list.get(0).length() < 30){ //當(dāng)結(jié)果長(zhǎng)度不長(zhǎng)時(shí),就直接輸出
                BigDecimal bd = new BigDecimal(list.get(0));
                return bd.toPlainString(); //BigDecimal默認(rèn)直接輸出
            } else { //當(dāng)結(jié)果過(guò)長(zhǎng)時(shí)泄私,就用科學(xué)計(jì)數(shù)法輸出
                double d = Double.valueOf(list.get(0));
                return String.valueOf(d); //Double會(huì)使用科學(xué)計(jì)數(shù)法輸出
            }
        } else {
            return "運(yùn)算失敗";
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末房揭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子晌端,更是在濱河造成了極大的恐慌捅暴,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咧纠,死亡現(xiàn)場(chǎng)離奇詭異蓬痒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)漆羔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)梧奢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人钧椰,你說(shuō)我怎么就攤上這事粹断。” “怎么了嫡霞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵瓶埋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)养筒,這世上最難降的妖魔是什么曾撤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮晕粪,結(jié)果婚禮上挤悉,老公的妹妹穿的比我還像新娘。我一直安慰自己巫湘,他們只是感情好装悲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著尚氛,像睡著了一般诀诊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阅嘶,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天属瓣,我揣著相機(jī)與錄音,去河邊找鬼讯柔。 笑死抡蛙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魂迄。 我是一名探鬼主播粗截,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼极祸!你這毒婦竟也來(lái)了慈格?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤遥金,失蹤者是張志新(化名)和其女友劉穎浴捆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體稿械,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡选泻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了美莫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片页眯。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖厢呵,靈堂內(nèi)的尸體忽然破棺而出窝撵,到底是詐尸還是另有隱情,我是刑警寧澤襟铭,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布碌奉,位于F島的核電站短曾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赐劣。R本人自食惡果不足惜嫉拐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望魁兼。 院中可真熱鬧婉徘,春花似錦、人聲如沸咐汞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碉考。三九已至塌计,卻和暖如春挺身,著一層夾襖步出監(jiān)牢的瞬間侯谁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工章钾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留墙贱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓贱傀,卻偏偏與公主長(zhǎng)得像惨撇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子府寒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,146評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程魁衙,因...
    小菜c閱讀 6,423評(píng)論 0 17
  • 上點(diǎn)兒年紀(jì)的人多多少少都會(huì)有些俄羅斯情結(jié),實(shí)在是從小時(shí)的教育株搔,聽(tīng)的歌剖淀,看的電影,讀的小說(shuō)纤房,學(xué)的歷史纵隔,處處有蘇聯(lián)老大...
    暢游0321閱讀 393評(píng)論 0 2
  • 秋愷老師說(shuō):“大冬天泡溫泉很舒服,特別是在冰天雪地之中炮姨,那真是一種極致的享受! 但是大家去泡溫泉的時(shí)候是怎樣...
    Maya姐閱讀 200評(píng)論 0 0
  • 一 今天在這里我要重點(diǎn)推薦訊飛語(yǔ)音輸入法捌刮,經(jīng)過(guò)一斷時(shí)間的使用,感覺(jué)非常方便舒岸。 語(yǔ)音輸入的新可能 在我們?nèi)粘I钪校?..
    haoooozi閱讀 1,735評(píng)論 1 0