第一次写博客嘿嘿嘿,很激动,记录一下Android开发课第一次试验——简易计算器。
P.S.刚接触Android Studio,纯探索式完成,代码以及内容有些粗糙QAQ
好啦,进入正题
首先是布局activity_main.xml文件,先上代码:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/msg"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:autofillHints="" tools:targetApi="o">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/clc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/clc"></Button>
<Button
android:id="@+id/mod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/per"></Button>
<Button
android:id="@+id/div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/div"></Button>
<Button
android:id="@+id/mul"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/mul"></Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/seven"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/seven"></Button>
<Button
android:id="@+id/eight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/eight"></Button>
<Button
android:id="@+id/nine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/nine"></Button>
<Button
android:id="@+id/sub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/sub"></Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/four"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/four"></Button>
<Button
android:id="@+id/five"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/five"></Button>
<Button
android:id="@+id/six"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/six"></Button>
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/add"></Button>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false">
<LinearLayout android:orientation="vertical"
android:layout_weight="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/one"></Button>
<Button
android:id="@+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/two"></Button>
<Button
android:id="@+id/three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/three"></Button>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/zero"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="2"
style="?android:attr/borderlessButtonStyle"
android:text="@string/zero"></Button>
<Button
android:id="@+id/dot"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/dot"></Button>
</LinearLayout>
</LinearLayout>
<LinearLayout android:orientation="vertical"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<Button
android:id="@+id/equ"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/borderlessButtonStyle"
android:text="@string/equ"></Button>
</LinearLayout>
</LinearLayout>
下面是MainActivity.java文件,主要分为四种键分开处理:C键(单个字符清除键),=键(EditText获取所有表达式字符处理键),数字键以及操作符键:
首选是数字键(0~9),其主要实现把本身的value(activity中设置)传给EditText显示出来,由于代码基本一致,就先放一个例子:
zero.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(zero.getText().toString());
}
});
其次是操作符键(+-*/.),其实现思路原本和数字键一样,但是不知道为什么append方法不适用于这些操作符,有大佬知道原因的话,烦请告知啊QAQ,于是:
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"+");
}
});
之后是C(单个字符清除键),其思路是假设EditText中有n个字符,先取出n-1个字符,再把第n位用“ ”代替,代码如下:
clc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count=0;//记录覆盖的空格的个数,由于空格也计入字符串长度中,对下面的每次删去的个数有影响,所以记录并在下面减去
String s = msg.getText().toString();
for(int i=0;i<s.length();i++)
if((s.substring(i,i+1)==""))
count++;
//考虑边界情况
if(count>=s.length()-1)
count = s.length()-1;
s = (String) s.subSequence(0,s.length()-1-count);
s = s.concat("");
msg.setText(s);
}
});
最后是=键(表达式处理得出结果键),其思路是把中缀表达式转化成后缀表达式,在通过后缀表达式计算,代码如下(代码十分粗糙,由于只会C,不大会java,很多方法都是先查的QAQ):
equ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = 0, j = 0, k = 0,count=1;//count 记录小数点后面有几位
char b;
String str=msg.getText().toString();
double data[] = new double[100];//模拟数字栈
String strr = "";//模拟操作符栈
//入栈
for (i = 0; i < str.length(); i++) {
count=1;
data[j]=0;
//首先判断是都是数字,注意多位数的情况
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
}
j++;
//考虑操作数是小数的情况
if((i < str.length()) &&(str.substring(i,i+1).equals(".")))
{
i++;
j--;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
count=count*10;
}
data[j]=data[j]*1.0/count;
j++;
System.out.println(data[j]);
}
if (i >= str.length()) break;
if ((k == 0)||(i<str.length())&&(pric(str.charAt(i)) >= pric(strr.charAt(k - 1)))) {
strr = strr.concat(str.substring(i, i + 1));
//System.out.println("strr:"+strr);
k++;
}
else {
//还要考虑一直大于的情况,一直字符串出栈
while (k >= 1 && (pric(str.charAt(i)) < pric(strr.charAt(k - 1)))) {
j--;
k--;
b = strr.charAt(k);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
}
strr = (String) strr.subSequence(0, k);
strr = strr.concat(str.substring(i, i + 1));
k++;
}
}
k--;
//出栈
while (k >= 0 && j >= 0) {
j--;
b = strr.charAt(k);
System.out.println("b:" + b);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
k--;
}
msg.setText(Double.toString(data[0]));
}
@org.jetbrains.annotations.Contract(pure = true)
private double add(double a, double b)
{
return a+b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double sub(double a, double b)
{
return a-b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double mul(double a, double b)
{
return a*b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double div(double a, double b)
{
return a*1.0/b;
}
@org.jetbrains.annotations.Contract(pure = true)
private int pric(char a)
{
if(a=='+')return 1;
else if(a=='-')return 2;
else if(a=='*')return 3;
else if(a=='/')return 4;
return 0;
}
});
然后放一下MainActivity.java所有代码:
private EditText msg;
private Button zero;
private Button one;
private Button two;
private Button three;
private Button four;
private Button five;
private Button six;
private Button seven;
private Button eight;
private Button nine;
private Button add;
private Button sub;
private Button mul;
private Button div;
private Button mod;
private Button dot;
private Button clc;
private Button equ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.msg = findViewById(R.id.msg);
this.zero = findViewById(R.id.zero);
this.one = findViewById(R.id.one);
this.two = findViewById(R.id.two);
this.three = findViewById(R.id.three);
this.four = findViewById(R.id.four);
this.five = findViewById(R.id.five);
this.six = findViewById(R.id.six);
this.seven = findViewById(R.id.seven);
this.eight = findViewById(R.id.eight);
this.nine = findViewById(R.id.nine);
this.add = findViewById(R.id.add);
this.sub = findViewById(R.id.sub);
this.mul = findViewById(R.id.mul);
this.div = findViewById(R.id.div);
this.equ = findViewById(R.id.equ);
this.clc = findViewById(R.id.clc);
this.dot = findViewById(R.id.dot);
zero.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(zero.getText().toString());
}
});
one.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(one.getText().toString());
}
});
two.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(two.getText().toString());
}
});
three.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(three.getText().toString());
}
});
four.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(four.getText().toString());
}
});
five.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(five.getText().toString());
}
});
six.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(six.getText().toString());
}
});
seven.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(seven.getText().toString());
}
});
eight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(eight.getText().toString());
}
});
nine.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(nine.getText().toString());
}
});
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"+");
}
});
sub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"-");
}
});
mul.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"*");
}
});
div.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"/");
}
});
dot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+".");
}
});
clc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count=0;//记录覆盖的空格的个数
String s = msg.getText().toString();
for(int i=0;i<s.length();i++)
if((s.substring(i,i+1)==""))
count++;
if(count>=s.length()-1)
count = s.length()-1;
s = (String) s.subSequence(0,s.length()-1-count);
s = s.concat("");
msg.setText(s);
}
});
equ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = 0, j = 0, k = 0,count=1;//count 记录小数点后面有几位
char b;
String str=msg.getText().toString();
double data[] = new double[100];//模拟数字栈
String strr = "";//模拟字符栈
//入栈
for (i = 0; i < str.length(); i++) {
count=1;
data[j]=0;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
}//取数字保存在data中
j++;
if((i < str.length()) &&(str.substring(i,i+1).equals(".")))
{
i++;
j--;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
count=count*10;
}//取数字保存在data中
data[j]=data[j]*1.0/count;
j++;
System.out.println(data[j]);
}
if (i >= str.length()) break;
if ((k == 0)||(i<str.length())&&(pric(str.charAt(i)) >= pric(strr.charAt(k - 1)))) {
strr = strr.concat(str.substring(i, i + 1));
k++;
}
else {//还要考虑一直大于的情况,一直字符串出栈
while (k >= 1 && (pric(str.charAt(i)) < pric(strr.charAt(k - 1)))) {
j--;
k--;
b = strr.charAt(k);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
}
strr = (String) strr.subSequence(0, k);
strr = strr.concat(str.substring(i, i + 1));
k++;
}
}
k--;
//出栈
while (k >= 0 && j >= 0) {
j--;
b = strr.charAt(k);
System.out.println("b:" + b);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
k--;
}
System.out.println(data[0]);
msg.setText(Double.toString(data[0]));
}
@org.jetbrains.annotations.Contract(pure = true)
private double add(double a, double b)
{
return a+b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double sub(double a, double b)
{
return a-b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double mul(double a, double b)
{
return a*b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double div(double a, double b)
{
return a*1.0/b;
}
@org.jetbrains.annotations.Contract(pure = true)
private int pric(char a)
{
if(a=='+')return 1;
else if(a=='-')return 2;
else if(a=='*')return 3;
else if(a=='/')return 4;
return 0;
}
});
}
然后说一下这个计算器的BUG:
1.中缀转后缀表达式的中间无法解决出现负数的情况,负数入栈还不知道怎么考虑
2.%虽然设计在上面也没有考虑
其他暂时还未发现什么bug,有发现的同学告知一下哈!
好啦,结束啦!