界面
activity_main.xml
采用GridLayout<网格布局>,将网格设置为8行4列,第2行为显示数据的文本标签,第2行为清除数据的按钮,3~6行为数字键和运算符;
< ? xml version= "1.0" encoding= "utf-8" ? >
< GridLayout xmlns: android= "http://schemas.android.com/apk/res/android"
xmlns: app= "http://schemas.android.com/apk/res-auto"
xmlns: tools= "http://schemas.android.com/tools"
android: layout_width= "match_parent"
android: layout_height= "match_parent"
android: rowCount= "8"
android: columnCount= "4"
tools: context= ".MainActivity" >
< TextView
android: layout_width= "wrap_content"
android: layout_height= "wrap_content"
android: layout_columnSpan= "4"
android: layout_rowSpan= "4"
android: layout_marginLeft= "15sp"
android: gravity= "center_horizontal"
android: text = "0"
android: textSize= "70dip"
android: id= "@+id/tv"
/ >
< Button
android: layout_width= "match_parent"
android: layout_height= "wrap_content"
android: layout_columnSpan= "4"
android: text= "清除"
android: textSize= "45dip"
android: id= "@+id/bt_clear"
/ >
< Button android: text= "1" android: textSize= "40dip" android: id= "@+id/bt_1" / >
< Button android: text= "2" android: textSize= "40dip" android: id= "@+id/bt_2" / >
< Button android: text= "3" android: textSize= "40dip" android: id= "@+id/bt_3" / >
< Button android: text= "+" android: textSize= "40dip" android: id= "@+id/bt_plus" / >
< Button android: text= "4" android: textSize= "40dip" android: id= "@+id/bt_4" / >
< Button android: text= "5" android: textSize= "40dip" android: id= "@+id/bt_5" / >
< Button android: text= "6" android: textSize= "40dip" android: id= "@+id/bt_6" / >
< Button android: text= "-" android: textSize= "40dip" android: id= "@+id/bt_minus" / >
< Button android: text= "7" android: textSize= "40dip" android: id= "@+id/bt_7" / >
< Button android: text= "8" android: textSize= "40dip" android: id= "@+id/bt_8" / >
< Button android: text= "9" android: textSize= "40dip" android: id= "@+id/bt_9" / >
< Button android: text= "*" android: textSize= "40dip" android: id= "@+id/bt_multiply" / >
< Button android: text= "." android: textSize= "40dip" android: id= "@+id/bt_point" / >
< Button android: text= "0" android: textSize= "40dip" android: id= "@+id/bt_0" / >
< Button android: text= "=" android: textSize= "40dip" android: id= "@+id/bt_equal" / >
< Button android: text= "/" android: textSize= "40dip" android: id= "@+id/bt_divide" / >
< / GridLayout>
界面显示效果
计算逻辑
MainActivity.java
通过MainActivity直接实现 OnClickListener接口,方便按钮添加监听器;
按钮的功能相识,逐个添加监听器,会使重复代码过多,代码冗余;
简化代码的同时,要注意各部件功能差异,"±*/."不能重复输出,要设置判断方法,检测是否重复输入;
public class MainActivity extends AppCompatActivity implements OnClickListener {
Button bt_1;
Button bt_2;
Button bt_3;
.
.
.
private StringBuilder pending = new StringBuilder ( ) ;
protected void onCreate ( Bundle savedInstanceState) {
super . onCreate ( savedInstanceState) ;
setContentView ( R. layout. activity_main) ;
bt_0 = ( Button) findViewById ( R. id. bt_0) ;
bt_1 = ( Button) findViewById ( R. id. bt_1) ;
bt_2 = ( Button) findViewById ( R. id. bt_2) ;
.
.
.
tv_input = ( TextView) findViewById ( R. id. tv) ;
bt_0. setOnClickListener ( this ) ;
bt_1. setOnClickListener ( this ) ;
bt_2. setOnClickListener ( this ) ;
.
.
.
bt_point. setOnClickListener ( this ) ;
switch ( v. getId ( ) ) {
case R. id. bt_0:
pending = pending. append ( "0" ) ;
tv_input. setText ( pending) ;
break ;
case R. id. bt_1:
pending = pending. append ( "1" ) ;
tv_input. setText ( pending) ;
break ;
case R. id. bt_2:
pending = pending. append ( "2" ) ;
tv_input. setText ( pending) ;
break ;
case R. id. bt_3:
pending = pending. append ( "3" ) ;
tv_input. setText ( pending) ;
break ;
.
.
.
case R. id. bt_plus:
if ( ifReapet ( "+" ) ) {
pending = pending. append ( "+" ) ;
tv_input. setText ( pending) ;
}
break ;
case R. id. bt_minus:
if ( ifReapet ( "-" ) ) {
pending = pending. append ( "-" ) ;
tv_input. setText ( pending) ;
}
break ;
case R. id. bt_multiply: / / 乘
if ( ifReapet ( "*" ) ) {
pending = pending. append ( "*" ) ;
tv_input. setText ( pending) ;
}
break ;
case R. id. bt_divide:
if ( ifReapet ( "/" ) ) {
pending = pending. append ( "/" ) ;
tv_input. setText ( pending) ;
}
break ;
case R. id. bt_point:
if ( ifReapet ( "." ) ) {
pending = pending. append ( "." ) ;
tv_input. setText ( pending) ;
}
break ;
case R. id. bt_clear:
pending = pending. delete ( 0 , pending. length ( ) ) ;
tv_input. setText ( pending) ;
break ;
case R. id. bt_equal:
if ( ( pending. length ( ) > 1 ) ) {
InfixInToDuffix inf = new InfixInToDuffix ( ) ;
String jieguo;
try {
String a = inf. toSuffix ( pending) ;
jieguo = inf. dealEquation ( a) ;
} catch ( Exception ex) {
jieguo = "出错" ;
}
tv_input. setText ( pending + "=" + jieguo) ;
pending = pending. delete ( 0 , pending. length ( ) ) ;
if ( Character. isDigit ( jieguo. charAt ( 0 ) ) ) {
pending = pending. append ( jieguo) ;
}
}
break ;
default :
break ;
}
}
}
ifReapet(String a)
private boolean ifReapet(String a): 通过传入的字符参数,进行判断,返回boolean值;
实现过程: 创建整数数组 b[],存放获取对应字符的位置数,pending.lastIndexOf() 获取对应字符的位置,存放到b[],通过判断b[]的长度,b[]为空,则说明为pending不存在对应字符,字符未重复输入,返回true;
private boolean ifReapet ( String a) {
int [ ] b = new int [ a. length ( ) ] ;
int max;
for ( int i = 0 ; i < a. length ( ) ; i++ ) {
String c = "" + a. charAt ( i) ;
b[ i] = pending. lastIndexOf ( c) ;
}
Arrays. sort ( b) ;
if ( b[ a. length ( ) - 1 ] == - 1 ) {
max = 0 ;
} else {
max = b[ a. length ( ) - 1 ] ;
}
if ( pending. indexOf ( a, max) == - 1 ) {
return true ;
} else {
return false ;
}
}
计算优先级
import java. util. HashMap;
import java. util. List;
import java. util. Map;
import java. lang. *;
import java. util. ArrayList;
import java. util. *;
public class InfixInToDuffix {
private static final Map< Character, Integer> basic = new HashMap < Character, Integer> ( ) ;
static {
basic. put ( '-' , 1 ) ;
basic. put ( '+' , 1 ) ;
basic. put ( '*' , 2 ) ;
basic. put ( '/' , 2 ) ;
basic. put ( '(' , 0 ) ;
}
public String toSuffix ( StringBuilder infix) {
List< String> queue = new ArrayList < String> ( ) ;
List< Character> stack = new ArrayList < Character> ( ) ;
char [ ] charArr = infix. substring ( 0 , infix. length ( ) ) . trim ( ) . toCharArray ( ) ;
String standard = "*/+-()" ;
char ch = '&' ;
int len = 0 ;
for ( int i = 0 ; i < charArr. length; i++ ) {
ch = charArr[ i] ;
if ( Character. isDigit ( ch) ) {
len++ ;
} else if ( ch == '.' ) {
len++ ;
} else if ( standard. indexOf ( ch) != - 1 ) {
if ( len > 0 ) {
queue. add ( String. valueOf ( Arrays. copyOfRange ( charArr, i - len, i) ) ) ;
len = 0 ;
}
if ( ch == '(' ) {
stack. add ( ch) ;
continue ;
}
if ( ! stack. isEmpty ( ) ) {
int size = stack. size ( ) - 1 ;
boolean flag = false ;
while ( size >= 0 && ch == ')' && stack. get ( size) != '(' ) {
queue. add ( String. valueOf ( stack. remove ( size) ) ) ;
size-- ;
flag = true ;
}
if ( ch== ')' && stack. get ( size) == '(' ) {
flag = true ;
}
while ( size >= 0 && ! flag && basic. get ( stack. get ( size) ) >= basic. get ( ch) ) {
queue. add ( String. valueOf ( stack. remove ( size) ) ) ;
size-- ;
}
}
if ( ch != ')' ) {
stack. add ( ch) ;
} else {
stack. remove ( stack. size ( ) - 1 ) ;
}
}
if ( i == charArr. length - 1 ) {
if ( len > 0 ) {
queue. add ( String. valueOf ( Arrays. copyOfRange ( charArr, i - len+ 1 , i+ 1 ) ) ) ;
}
int size = stack. size ( ) - 1 ;
while ( size >= 0 ) {
queue. add ( String. valueOf ( stack. remove ( size) ) ) ;
size-- ;
}
}
}
String a = queue. toString ( ) ;
return a. substring ( 1 , a. length ( ) - 1 ) ;
}
public String dealEquation ( String equation) {
String [ ] arr = equation. split ( ", " ) ;
List< String> list = new ArrayList < String> ( ) ;
for ( int i = 0 ; i < arr. length; i++ ) {
int size = list. size ( ) ;
switch ( arr[ i] ) {
case "+" : double a = Double. parseDouble ( list. remove ( size- 2 ) ) + Double. parseDouble ( list. remove ( size- 2 ) ) ; list. add ( String. valueOf ( a) ) ; break ;
case "-" : double b = Double. parseDouble ( list. remove ( size- 2 ) ) - Double. parseDouble ( list. remove ( size- 2 ) ) ; list. add ( String. valueOf ( b) ) ; break ;
case "*" : double c = Double. parseDouble ( list. remove ( size- 2 ) ) * Double. parseDouble ( list. remove ( size- 2 ) ) ; list. add ( String. valueOf ( c) ) ; break ;
case "/" : double d = Double. parseDouble ( list. remove ( size- 2 ) ) / Double. parseDouble ( list. remove ( size- 2 ) ) ; list. add ( String. valueOf ( d) ) ; break ;
default : list. add ( arr[ i] ) ; break ;
}
}
return list. size ( )
== 1 ? list. get ( 0 ) : "运算失败" ;
}
}
功能实现测试