Android Calculator - Introduction
Author: Knight in Black
I. Preface
This is the first App I wrote, using the third chapter of Android First Line Code, some knowledge of UI controls. Then the overall structure synthesizes some works on CSDN blogs and short books. Similarly, in writing Android calculators, I have spent nearly a week studying some hierarchies, UI controls, and one. Some functional keywords and data structures that need to be used but are not available in the book. Then, when writing an Android calculator, Android studio will always make some unknown mistakes, and then check and modify them bit by bit. In addition, if the computer configuration is not high, the use of virtual machines will compile and run very slowly, so it is recommended that you use more real machine testing, especially fast. Next, I will share with you the basic steps of making a calculator.
II. Preparation
1. Compiler: Android Studio (there are many functions to be found)
2. Knowledge required by Android calculator:
1. Before that, there was a simple Java foundation to understand the use of some Java keywords.
2. Chapter 3 of "First Line of Code" (UI development in general, learn to use)
3. Master the algorithm of calculator calculation (infix expression to suffix expression, operation of suffix expression)
4. Suffix expressions need to be used Key word BigDecimal
3. Learn to use Baidu, Google and browse some necessary information.
Of course, you can also go to the CSDN official website to see some articles written by others, to learn, and then look at the code written by others, carefully study, you will gain a lot of knowledge.
4. Understand the basic functions of Android Studio
3. Implementing some distribution of controls and rendering
This is the result of a real machine side test and rendering.
Code section
** Here I use the percentage layout, but the percentage is the new layout, so I have to increase the corresponding dependencies by myself. Open the build.grade file of app in Android Studio and add such code in dependencies closure
Among them, 29.0.1 is based on its own version. For example, mine is:
Note: The icon for filling in the position is as follows:
After adding, a line of prompts appears at the top of the editing panel. Just click Sync now and wait a moment.
1. The peripheral of button
** Because Android can't change buttons by changing attributes, we need to modify them internally, create an image file, set the background color and the width and color of the border, and then set the button's background attribute to a picture.
- First create a Drawable resource file in the app/src/main/drawable folder in Android Studio
- Then pop-up window set file name, file name arbitrary, I set shape_white
- Because I created three colors, I created three files. The other two file names are shape_blue and shape_yellow.
- Below is the content of my document:
//However, the comments in the following code are best deleted <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#ffffff"/>//Set the background color (white) <stroke android:width="0.01dp"//Set the width of the border android:color="#ccc0c0c0"/>//Set the color of the border </shape>
The rest of the gray and blue just need to change the background color.
android:color="#f0ffff"/>//blue
android:color="#fff0f0f0"/>//Silver gray
android:color="#ff0fff"/>//Violet
Here I will not introduce the color attributes in turn.
after
In your layout file (such as app/src/main/res/layout/activity_main.xml), add the line setting the background to the button of the border that needs to be displayed.
<Button android:id="@+id/button0" android:background="@drawable/click_white"//Set button background color />
2. Implementing Button's Click-to-Color Function
In my calculator, when I click the button, it turns purple.
- First create a Drawable resource file in the Android Studio (app/src/main/res/drawable) folder, and then create the file name. My name is click_purple.
- Then change the code to:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/shape_purple_bg"//Set the color after clicking android:state_enabled="true" android:state_pressed="true"/>//When the button is clicked <item android:drawable="@drawable/shape_white_bg"//Set the background (color before clicking) android:state_enabled="true" android:state_pressed="false"/>//When not clicked </selector>
The meaning of this code is: from white to purple
Then I'll show you that this code needs two color files. We just created one, and then we can create another one.
For example, create a purple color file
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#ff0fff"/>//Violet <stroke android:width="0.01dp" android:color="#ccc0c0c0"/> </shape>
3. Adaptive font display box to change size
For example:
------------
Add a bunch of code
//Add a bunch of code as well <TextView android:"@+id/text_view" app:autoSizeTextType="uniform"//Font Adaptive Function app:layout_heightPercent="25%"//Adjusting the Height of Display Module with Percentage app:layout_widthPercent="100%"//Adjusting the Width of Display Module by Percentage />
- But there are also drawbacks in this approach, that is, the size of his input box and the font he displays, so we need to restrict him to the maximum font, the smallest font, and the font size of each change.
Here's the description of some controls. Next, let's take a look at the code of the control part.
activity_main.xml
<androidx.percentlayout.widget.PercentRelativeLayout//Percentage layout, we must see clearly, because there is also an androidx... with Percent in it. 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_width="0dp"//There is no specific effect, because using percentage layout, 0dp here is a specification android:layout_height="0dp" android:layout_alignParentLeft="true"//Control control position android:layout_alignParentBottom="true"//Control control position android:layout_gravity="bottom" android:text="C"//Name of control display android:textSize="40sp"//Control name font size app:layout_heightPercent="14%"//Control Height Percentage of Screen Height app:layout_widthPercent="25%"//Control width as a percentage of screen width android:background="@drawable/click_purple_blue"/>//Click on the color of the event (blue before clicking, purple after clicking) <Button android:id="@+id/button1" android:textSize="40sp" android:layout_width="0dp" android:layout_height="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:layout_above="@id/buttonc" android:text="1" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/buttond" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:text="=" android:textSize="40sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_blue"/> <Button android:id="@+id/button0" android:layout_width="0dp" android:layout_height="0dp" android:layout_toRightOf="@id/buttonc" android:layout_alignParentBottom="true" android:text="0" android:textSize="40sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/buttonDot" android:layout_width="0dp" android:layout_height="0dp" android:layout_toRightOf="@id/button0" android:layout_alignParentBottom="true" android:text="." android:textSize="40sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_blue"/> <Button android:id="@+id/button2" android:textSize="40sp" android:layout_width="0dp" android:layout_height="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:layout_toRightOf="@id/button1" android:layout_above="@id/button0" android:text="2" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button3" android:textSize="40sp" android:layout_width="0dp" android:layout_height="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:layout_toRightOf="@id/button2" android:layout_above="@id/buttonDot" android:text="3" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button4" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="4" android:textSize="40sp" android:layout_above="@id/button1" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button5" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="5" android:textSize="40sp" android:layout_above="@id/button2" android:layout_toRightOf="@id/button4" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button6" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="6" android:textSize="40sp" android:layout_above="@id/button3" android:layout_toRightOf="@id/button5" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/buttonj" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="+" android:textSize="40sp" android:layout_above="@id/buttonchenG" android:layout_toRightOf="@id/button6" android:background="@drawable/click_purple_yellow" /> <Button android:id="@+id/buttonchenG" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="*" android:textSize="40sp" android:layout_above="@id/buttond" android:layout_toRightOf="@id/button3" android:background="@drawable/click_purple_yellow" /> <Button android:id="@+id/button7" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="7" android:textSize="40sp" android:layout_above="@id/button4" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button8" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="8" android:textSize="40sp" android:layout_above="@id/button5" android:layout_toRightOf="@id/button7" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/button9" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="9" android:textSize="40sp" android:layout_above="@id/button6" android:layout_toRightOf="@id/button8" android:background="@drawable/click_purple_white"/> <Button android:id="@+id/buttonjian" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="-" android:textSize="40sp" android:layout_above="@id/buttonj" android:layout_toRightOf="@id/button9" android:background="@drawable/click_purple_yellow" /> <Button//Left parentheses android:id="@+id/buttonzuokuo" android:layout_height="0dp" android:layout_width="0dp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:text="(" android:textSize="40sp" android:layout_above="@id/button7" android:background="@drawable/click_purple_blue"/> <Button//Right parentheses android:id="@+id/buttonyoukuo" android:layout_width="0dp" android:layout_height="0dp" android:text=")" android:layout_toRightOf="@id/buttonc" android:layout_above="@id/button8" android:textSize="40sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_blue"/> <Button//Division sign android:id="@+id/buttonchufa" android:layout_width="0dp" android:layout_height="0dp" android:text="/" android:layout_toRightOf="@id/buttonyoukuo" android:layout_above="@id/button9" android:textSize="40sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_yellow"/> <Button//Delete key android:id="@+id/buttons" android:layout_width="0dp" android:layout_height="0dp" android:text="Del" android:layout_toRightOf="@id/buttonchufa" android:layout_above="@id/buttonjian" android:textSize="30sp" app:layout_heightPercent="14%" app:layout_widthPercent="25%" android:background="@drawable/click_purple_blue"/> <TextView//display android:id="@+id/text_view" android:background="#FAFFF0"//background color android:autoSizeTextType="uniform"//Font Adaptation app:autoSizeMaxTextSize="80sp"//Maximum font size app:autoSizeMinTextSize="20sp"//Minimum font size app:autoSizeStepGranularity="4sp"//The size of each font change android:layout_height="0dp"//Standard android:layout_width="0dp"//Standard android:textSize="40sp"//Initial font size app:layout_heightPercent="30%"//Percentage of height displayed app:layout_widthPercent="100%"/> </androidx.percentlayout.widget.PercentRelativeLayout>
4. Exception handling of active code
- 1. At the beginning of the input, when the "-" is input, it represents a minus sign. At this time, the screen should display "(-).
- 2. For the symbol ")", it is necessary to find out whether the left and right brackets are equal in operation, and if they are not equal, the error should be reported.
- 3. When there is a problem with the output, the error should be reported and the Error should be output.
- 4. If the minus sign is preceded by the plus, minus, multiply and divide sign, the minus sign system should be treated as a negative sign.
- 5. There are also some problems with decimal points, such as automatic zero-filling in front, and so on.
- 6. When deleting the negative sign, click on del and delete two.
Character, this needs to add a judgment, when adding judgment, pay attention to the problem of space allocation - 7. Of course, there are many more, not listed in turn.
MainActivity code
package com.example.calculation; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView textView; private StringBuffer sb=new StringBuffer(); private StringBuffer str=new StringBuffer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Define controls 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 buttonj=findViewById(R.id.buttonj); Button buttonjian=findViewById(R.id.buttonjian); Button buttonzuokuo=findViewById(R.id.buttonzuokuo); Button buttonyoukuo=findViewById(R.id.buttonyoukuo); Button buttonchenG=findViewById(R.id.buttonchenG); Button buttonc=findViewById(R.id.buttonc); Button buttond=findViewById(R.id.buttond); Button buttonDot=findViewById(R.id.buttonDot); Button buttons=findViewById(R.id.buttons); Button buttonchufa=findViewById(R.id.buttonchufa); 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); buttonc.setOnClickListener(this); buttonchufa.setOnClickListener(this); buttonchenG.setOnClickListener(this); buttonjian.setOnClickListener(this); buttonj.setOnClickListener(this); buttond.setOnClickListener(this); buttonDot.setOnClickListener(this); buttons.setOnClickListener(this); buttonzuokuo.setOnClickListener(this); buttonyoukuo.setOnClickListener(this); } private int count_negative=0; private boolean equals=false; private int count_bracket_left=0;//Number of left parentheses private int count_bracket_right=0;//Number of right parentheses private int a=0;//Delete as a pointer to a record @Override public void onClick(View view){ switch(view.getId()){ case R.id.button0: if(equals){ sb =sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("0"); }else{ if(sb.charAt(sb.length()-1)==')'){/// If the preceding bracket is the right bracket, add the multiplication sign before 0. sb.append("*0"); } else{ sb.append("0"); } } textView.setText(sb.toString()); break; case R.id.button1: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("1"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*1"); } else{ sb.append("1"); } } textView.setText(sb.toString()); break; case R.id.button2: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("2"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*2"); } else{ sb.append("2"); } } textView.setText(sb.toString()); break; case R.id.button3: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("3"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*3"); } else{ sb.append("3"); } } textView.setText(sb.toString()); break; case R.id.button4: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("4"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*4"); } else{ sb.append("4"); } } textView.setText(sb.toString()); break; case R.id.button5: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("5"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*5"); } else{ sb.append("5"); } } textView.setText(sb.toString()); break; case R.id.button6: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("6"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*6"); } else{ sb.append("6"); } } textView.setText(sb.toString()); break; case R.id.button7: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("7"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*7"); } else{ sb.append("7"); } } textView.setText(sb.toString()); break; case R.id.button8: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("8"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*8"); } else{ sb.append("8"); } } textView.setText(sb.toString()); break; case R.id.button9: if(equals){ sb=sb.delete(0,sb.length()); equals=false; } if(sb.length()==0){ sb.append("9"); }else{ if(sb.charAt(sb.length()-1)==')'){ sb.append("*9"); } else{ sb.append("9"); } } textView.setText(sb.toString()); break; case R.id.but if(equals){ equals=false; } if(sb.length()!=0&&a==0){ if(sb.charAt(sb.length()-1)=='-'&&sb.charAt(sb.length()-2)=='('||sb.charAt(sb.length()-1)=='.'&&sb.charAt(sb.length()-2)=='0'){ sb=sb.deleteCharAt(sb.length()-1); sb=sb.deleteCharAt(sb.length()-1); }else{ sb=sb.deleteCharAt(sb.length()-1); } } else if(sb.length()!=0&&a==1){ sb=sb.delete(0,sb.length()); } textView.setText(sb.toString()); a=0; break; case R.id.buttonc: if(equals){ equals=false; } sb=sb.delete(0,sb.length()); textView.setText(sb.toString()); break; case R.id.buttonzuokuo: if(equals){ equals=false; } if(sb.length()>0&&(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9')){ sb=sb.append("*("); } if(sb.length()==0){ 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)=='-')){ sb=sb.append("("); } textView.setText(sb.toString()); break; case R.id.buttonyoukuo: if(equals){ equals=false; } int count_num=0; int Sum=0; int num=0; count_bracket_left=count_bracket_right=0; if(sb.length()!=0){ for(int i=sb.length()-1;i>=0;i--){ 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++; } } if((count_bracket_left>count_bracket_right)&&count_num>0){ if(sb.charAt(sb.length()-1)!='-'&&sb.charAt(sb.length()-1)!='+'&&sb.charAt(sb.length()-1)!='*'&&sb.charAt(sb.length()-1)!='/'){ sb.append(")"); } } } textView.setText(sb.toString()); break; case R.id.buttonj: 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'){ sb.append("+"); } if(sb.charAt(sb.length()-1)=='.'){ sb.append("0+"); } } if(sb.charAt(sb.length()-1)==')'){ sb.append("+"); } } textView.setText(sb.toString()); break; case R.id.buttonjian: 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'){ sb.append("-"); } if(sb.charAt(sb.length()-1)=='.'){ sb.append("0-"); } } else if(sb.charAt(sb.length()-1)==')'){ sb.append("-"); } else if(sb.charAt(sb.length()-1)=='('){ sb.append("(-"); } else if(sb.charAt(sb.length()-1)=='+'||sb.charAt(sb.length()-1)=='-'||sb.charAt(sb.length()-1)=='*'||sb.charAt(sb.length()-1)=='/'){ sb.append("(-"); } } else{ sb.append("(-"); } textView.setText(sb.toString()); break; case R.id.buttonchenG: 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'){ sb.append("*"); } if(sb.charAt(sb.length()-1)=='.'){ sb.append("0*"); } } if(sb.charAt(sb.length()-1)==')'){ sb.append("*"); } } textView.setText(sb.toString()); break; case R.id.buttonchufa: 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'){ sb.append("/"); } if(sb.charAt(sb.length()-1)=='.'){ sb.append("0/"); } } if(sb.charAt(sb.length()-1)==')'){ sb.append("/"); } } textView.setText(sb.toString()); break; case R.id.buttonDot: int apps=0; if(equals){ equals=false; } if(sb.length()!=0){ if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){ for(int i=sb.length()-2;i>=0;i--){ if(sb.charAt(i)=='.'){ apps=1; break; } else if(sb.charAt(i)=='('||sb.charAt(i)=='+'||sb.charAt(i)=='-'||sb.charAt(i)=='*'||sb.charAt(i)=='/'){ break; } } if(apps==0){ sb.append("."); } } if(sb.charAt(sb.length()-1)=='('||sb.charAt(sb.length()-1)==')'){ if(sb.charAt(sb.length()-1)==')'){ sb.append("*0."); }else{ sb.append("0."); } } if(sb.charAt(sb.length()-1)=='*'||sb.charAt(sb.length()-1)=='/'||sb.charAt(sb.length()-1)=='+'||sb.charAt(sb.length()-1)=='-'){ sb.append("0."); } } else{ sb.append("0."); } textView.setText(sb.toString()); break; case R.id.buttond: int count_left=0; int count_right=0; if(equals){ equals=false; } if(sb.length()!=0){ for(int i=sb.length()-1;i>=0;i--){ if(sb.charAt(i)==')'){ count_right++; } if(sb.charAt(i)=='('){ count_left++; } } if(count_left!=count_right){ Toast.makeText(MainActivity.this, "Please pay attention to bracket matching!!!", Toast.LENGTH_SHORT).show(); } if(count_left==count_right&&(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9')||sb.charAt(sb.length()-1)==')'){ try{ textView.setText(InfixToSuffix.Cal(InfixToSuffix.Suffix(sb))); a=1; //Using class names to call static methods twice, the results of suffix expressions are output to the screen. sb=sb.delete(0,sb.length()); sb.append(textView.getText().toString()); }catch(Exception e){ textView.setText("Error!!!"); sb=sb.delete(0,sb.length()); } } } break; default: break; } } }//If the decimal point precedes the equal sign, add 0 after the decimal point.
5. Calculator algorithm
1.Infix expression to suffix expression
2.Suffix expression calculation
In addition, there are still some difficulties in the subsequent implementation of the code, which need to be slowly and carefully looked at.
6. Specific code for calculation
Create a class file named InfixToSuffix under the same package in MainActivity as a computational method
The code is as follows:
package com.example.calculation; 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; public class InfixToSuffix { //Converting infix expressions into suffix expressions public static ArrayList Suffix(StringBuffer str) { for (int i = 1; i < str.length(); i++) {//Add a "0" before the negative sign of the negative number if (str.charAt(i) == '-' && str.charAt(i - 1) == '(') {//Identify negative numbers str.insert(i, '0'); } } StringBuilder temp = new StringBuilder(); List<String> list = new ArrayList<>(); ArrayList<String> result = new ArrayList<>();//Store the transformed suffix expression in the result array for (int i = 0; i < str.length(); i++) {//Traversing the entire infix expression if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == '.') {//Detection of digits and decimal points if (str.charAt(i) == '.' && temp.length() == 0) { temp.append(0); temp.append(str.charAt(i)); } else { temp.append(str.charAt(i)); } if (i == str.length() - 1) {//The role of this step depends on the previous step in else, for example, assuming that the infix expression has no decimal point, then if the last digit is a number, first execute the command in else, and then input temp all into the list. list.add(temp.toString());//Add all of temp to the list } } else {//Symbols come in here. if (temp.length() != 0) list.add(temp.toString()); list.add(String.valueOf((str.charAt(i))));//Convert str.charAt(i) of StringBuffer type to String type and add it to list array temp.delete(0, temp.length());//temp emptying } }//The above step is to convert the StringBuffe type to String type with the infix expression unchanged. for (String aList : list) { System.out.println(aList + ""); } System.out.println(); Stack<String> stack = new Stack<>(); Map<Character, Integer> map = new HashMap<>(); //Character represents a character class, representing the operation of a single character, and its basic data type is char. //Integer is a complex data type and an encapsulated class of int with an initial value of null map.put('(', 2);//Define the priority of symbols map.put(')', 2); map.put('*', 1); map.put('/', 1); map.put('+', 0); map.put('-', 0); for (String s : list) { if (s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-") || s.equals("(") || s.equals(")")) { if (stack.size() == 0) { stack.push(s);//If there are no elements in the current stack, let the symbols go directly into the stack } else { if (s.equals(")")) { if (!stack.empty()) { while (!stack.peek().equals("(")) { result.add(stack.pop()); if (stack.empty()) { break; } } if (!stack.empty()) { if (stack.peek().equals("("))//View the stack top object without removing it stack.pop(); } } } else { if (stack.peek().charAt(0) != '(') { if (map.get(s.charAt(0)) > map.get(stack.peek().charAt(0))) { stack.push(s); } else { while ((map.get(s.charAt(0)) <= map.get(stack.peek().charAt(0))) && !stack.empty()) { result.add(stack.pop()); if (stack.empty()) { break; } if (stack.peek().equals("(")) { break; } } stack.push(s); } } else { stack.push(s); } } } } else { result.add(s); } } while (!stack.empty()) { result.add(stack.pop()); } return result; } //Operate the resulting suffix expression public static String Cal(ArrayList arrayList) { int length = arrayList.size(); String[] arr = new String[length]; for (int i = 0; i < arrayList.size(); i++) { arr[i] = (String) arrayList.get(i); } List<String> list = new ArrayList<>(); for (String anArr : arr) { int size = list.size(); switch (anArr) { case "+": BigDecimal a = new BigDecimal(list.remove(size - 2)).add(new BigDecimal(list.remove(size - 2))); list.add(a.stripTrailingZeros().toString());//Enter Strings into list with Scientific Counting Normal 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; } } if (list.size() == 1) { if (list.get(0).length() < 30) { BigDecimal bd = new BigDecimal(list.get(0)); return bd.toPlainString(); } else { double d = Double.valueOf(list.get(0)); return String.valueOf(d); } } else { return "Operational failure"; } } }