还剩22页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言程序设计实训C报告书班级惠普测试142__________________学号14学090213________________姓名闫伟明____________指导教师庞志永getResult;}else if label,equals/ZDELZZ{int end=sbBuilder.length;sbBuilder=sbBuilder.deleteCharAtend-1;textbox.setText sbBuilder.toStringO;}else iflabel,equals〃C〃{int end=sbBuilder.length;sbBuilder=sbBuilder.delete0,end;textbox.setText sbBuilder.toString;oldtextbox.setTextCLEAR;else{sbBuilder.append label;textbox.setText sbBuilder.toStringO;public MainFrameString titlethrows HeadlessExceptionsupertitle;//调用父类构造方法setupFrame;//调整窗体属性setupControls;//创建控件private voidsetupControls{setupDisplayPanel;//创建文本面板setupButtonsPanel;//创建按钮面板//创建按钮面板并添加按钮private voidsetupButtonsPanel{JPanel panel=new JPanel;panel.setBorderborder;panel.setLayoutnew GridLayout4,5,3,3;createButtons panel,new String口〃7〃,〃8〃,〃9〃,〃+〃,〃DEL〃,〃4〃,〃5〃,〃6〃,〃-〃,〃C〃,〃1〃,〃2〃,”〃,〃*〃,〃〃,//空字符串表示这个位置没有按钮〃八〃〃〃〃〃〃/〃〃\〃l\0,・,=,/,};this,add panel,BorderLayout.SOUTH;*在指定的面板上创建按钮*@param panel*要创建按钮的面板*@param labels*按钮文字private voidcreateButtonsJPanel panel,String[]labels{for String label:labels{//如果label为空,则表示创建一个空面板否则创建一个按钮if label,equals C{panel,add new JPanel;}else{JButton b=new JButtonlabel;b.setFont newFont〃微软雅黑〃,Font.PLAIN,20;b.addActionListener listener;//为按钮添加侦听器panel,addb;//设置显示面板,用一个文本框来作为计算器的显示部分private voidsetupDisplayPanel{JPanel panel=new JPanel;JPanel panel1=newJPanel;panel.setLayoutnew BorderLayout;panel.setBorder border;panel
1.setLayoutnew BorderLayout;panell.setBorder border;setupTextbox;panell.addqz textbox,BorderLayout.CENTER;panel.addoldtextbox,BorderLayout.NORTH;panel,add textbox,BorderLayout.CENTER;this,addpanell,BorderLayout.NORTH;this,add panel,BorderLayout.CENTER;//调整文本框private voidsetupTextbox{qz_textbox.setHorizontalAlignmentJTextField.RIGHT;//文本右对齐qz_textbox.setEditablefalse;textbox.setHorizontalAlignment JTextField.RIGHT;//文本右对齐textbox.setEditable true;//文本框只读〃按下ENTER键得到结果textbox.addKeyListenernew KeyAdapter{©Overridepublic voidkeyReleasedKeyEvent e{if e.getKeyCode==KeyEvent.VK ENTER{getResult;textbox.setBackgroundColor,white;//文本框背景色为白色qz_textbox.setBackgroundColor,white;//文本框背景色为白色oldtextbox.setHorizontalAlignment JTextField.RIGHT;//文本右对齐oldtextbox.setEditablefalse;//文本框只读oldtextbox.setBackgroundColor,white;//文本框背景色为白色oldtextbox.setBorder BorderFactory.createEmptyBorder5,5,0,5;textbox.setBorder BorderFactory.createEmptyBorder5,5,5,qz_textbox.setBorderBorderFactory.createEmptyBorder5,5,5,5;textbox.setFont newFont〃微软雅黑〃,Font.BOLD,20;oldtextbox.setFontnew Font〃微软雅黑〃,Font.PLAIN,16;//TODO让文本框一进入程序就能获得输入焦点//调整窗体private voidsetupFrame{this.setDefaultCloseOperationEXIT_0N_CL0SE;//当窗体关闭时程序结束this.setLocation100,50;//设置窗体显示在桌面上的位置this.setSize400,300;//设置窗体大小this.setResizablefalse;//窗体大小固定//程序入口public staticvoid mainString[]args throwsException{UIManager.setLookAndFeelUIManager.getSystemLookAndFeelClass Name;MainFrame frame=new MainFrame〃支持表达式求值的计算器的设计与实现〃;frame.setVisibletrue;//在桌面上显示窗体Calculator,java import java.util.Stack;*利用栈实现中缀表达式计算*©authorpublic classCalculator{*转换成前缀表达式并计算.br/*将中缀表达式转换为前缀表达式br/〉*遵循以下步骤br/*1初始化两个栈运算符栈S1和储存中间结果的栈S2;br/*2从右至左扫描中缀表达式;br/*3遇到操作数时,将其压入S2;br/*4遇到运算符时,比较其与S1栈顶运算符的优先级br/*4-1如果S1为空,或栈顶运算符为右括号“”,则直接将此运算符入栈;br/〉*4-2否则,若优先级比栈顶运算符的较高或相等,也将运算符压入SI;br/*4-3否则,将S1栈顶的运算符弹出并压入到S2中,再次转到4-1与S1中新的栈顶运算符相比较;br/*5遇到括号时br/*5-1如果是右括号“”,则直接压入SI;br/*5-2如果是左括号“”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;br/*6重复步骤⑵至5,直到表达式的最左边;br/*7将S1中剩余的运算符依次弹出并压入S2;br/*8依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式br/〉*©param表达式字符串*©return计算结果Object
[2]
[0]:Double result
[1]:String expression*©throws IllegalArgumentException*©throws NumberFormatExceptionpublicstatic String[]toPolishNotationString inputthrowsIllegalArgumentException,NumberFormatException]//string:1+3*2-1int len=input.lengthO;//len:9char c,tempChar;StackCharacter si=new Stack〈Character;〃操作运算符StackDouble s2=new Stack〈Double;〃中间结果StackObject expression=new Stack〈Object;〃前缀表达式double number;int lastindex=-1;for inti=len-1;i=0;--i{//8-0c=input.charAti;//i:8c:if Character.isDigitc{//i7c:1自右向左找到input中最后一个数的最后一位数字的下标lastindex=readDoubleRe verseinput,i;//lastindex input中最后一个数的第一位数字的下标:7number=Double.parseDoub]edn^put.substring lastindex,i+1;//找到input中最后一个数numbers
2.push number;〃遇到操作数时,将其压入S2;i=lastindex;〃将前缀表达式压入expression栈if intnumber==number expression,pushint number;elseexpression,push number;}else if{isOperator^c{//遇到运算符时,比较其与si栈顶运算符的优先级*peek:*Looks at the object atthe top of this*stack withoutremoving itfrom thestack.*Return theobjectatthetopofthisstack*the lastitem ofthe Vectorobject.while!sl.isEmptysi.peek!=priorityComparec,si.peek0{expression,push si.peek;〃乘法和除法优先级较高,先从S1弹出并计算s
2.push
372.pop,s
2.pop,si.pop;C CS〃如果SI为空,或栈顶运算符为右括号“”,则直接将此运算符入栈〃若优先级比栈顶运算符的较高或相等,也将运算符压入S1;si.pushc;//}else if c=={//遇到括号时括号优先级最高将括号内算式压入S2最先计算
51.pushc;〃如果是右括号“”,则直接压入S1;}else ifc=={while tempChar=si.pop!={//如果是左括号“”,则依次弹出SI栈顶的运算符,并压入expression,直到遇到右括号为止,此时将这一对括号丢弃;expression,pushtempChar;〃这里转化为中缀表达式的同时对s2栈顶元素进行了计算〃遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算栈顶元素op次顶元素,并将结果入栈;
52.push ca7cs
2.pop,s
2.pop,tempChar;if si.isEmpty{throw newIllegalArgumentException〃\n栈si:缺少右括号‘’.〃;}else ifc=={//ignore}else{throw newHlegalArgunientException〃错误字符〃+c//前缀表达式的计算机求值//从右至左扫描表达式,//遇到数字时,将数字压入堆栈,//遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算栈顶元素op次顶元素,并将结果入栈;//重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果//例如前缀表达式“-X+3456”//1从右至左扫描,将
6.
5.
4.3压入堆栈;//2遇到+运算符,因此弹出3和43为栈顶元素,4为次顶元素,计算出3+4的值,得7,再将7入栈;//3接下来是X运算符,因此弹出7和5,计算出7X5=35,将35入栈;//4最后是-运算符,计算出35-6的值,即29,由此得出最终结实训项目名称支持表达式求值的计算器的设计与实现
1.实训目的所设计的计算器可以进行简单的表达式求值,并支持括号运算通过该课程设计,了解数组的使用,学会用函数实现栈等操作
2.实训要求1应用所学知识,完成实训目标2程序能够正常运行,运算结果正确,满足设计要求
3.功能描述要求程序具有输入界面,该输入界面至少有一个文本框和一个按钮用户在文本输入框内输入需要计算的表达式,并单击按钮后,程序可以计算出该表达式的值用户输入的表达式可能是符合数学规则的表达式,也可能是不符合数学规则的表达式如果输入的表达式正确,则计算器能够给出正确结果,否则,程序输出错误信息,并尽可能指出错误的位置与错误的类型
4.总体设计果while!sl.isEmpty{〃将SI中剩余的运算符依次弹出并压入expression;〃同时对S2栈顶元素进行计算tempChar=si.pop;expression,pushtempChar;s
2.push ca7cs
2.pop,s
2.pop,tempChar;//System,out.printin〃中缀表达式〃+input;//System,out.print〃前缀表达式〃;StringBuilder qianzhui_expression=new StringBuilder〃前缀表达式〃;while!expression.isEmpty{//System,out.print expression,pop+〃〃;qianzhui expression.append expression.pop+〃〃;double result=s
2.pop;〃最后结果if!s
2.isEmptythrow newII legalArgumentException z,input isa wrong・〃\expression.;if int result==resultreturn newString口intresult+/z//,qianzhui_expression.toString};elsereturn newString[]{result+//z/,qianzhui_expression.toStringO;*计算参数1op参数2的值.*如是运算符*@param numl*@param num2*@param op*©return*©throws IllegalArgumentExceptionpublicstatic doublecalc double numl,doublenum2,throwschar op11legalArgumentException{switch op{case+:return numl+num2;case-:return numl-num2;case*:return numl*num2;case/:if num2==0throw newIllegalArgumentException/zdivisor cant be
0.〃);return numl/num2;default:return0;//will nevercatch uphere*比较两个运算符的优先级.*@param opl*@param op2*©returnstatic intpriorityComparechar opl,char op2{switch opl{case+:case-:return op2==*||op2==/~1:0;case*:case/:return op2==+||op2=-1:0;return1;*读取下一个数reverse*自右向左找到input中最后一个数的第一位数字的下标*©param input*©param start*©return*©throws IIlegalArgumentExceptionpublicstatic intreadDoubleReverseString input,int startthrowsI1legalArgumentException{int dotindex=-1;char c;for inti=start;i=0;--i{//7-0c=input.charAt i;ifc={if dotindex!=-1throw newIllegalArgumentException“there havemore than1dots inthe number./z;elsedotindex=i;}else if!Character.isDigitc{return i+1;}else ifi==0{return0;throw newIllegalArgumentException/znot anumber./z;*如果字符C是操作符则返回true.*©param c*©returnpublic staticboolean isOperatorcharc{,,c==-return c==+C=,*,I Ic=,/,;
5.程序实现与相关描述前缀表达式前缀记法、波兰式前缀表达式的运算符位于操作数之前前缀表达式的计算机求值从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算栈顶元素op次顶元素,并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果例如前缀表达式“-X+3456”1从右至左扫描,将
6、
5、
4.3压入堆栈;2遇到+运算符,因此弹出3和43为栈顶元素,4为次顶元素,注意与后缀表达式做比较,计算出3+4的值,得7,再将7入栈;3接下来是X运算符,因此弹出7和5,计算出7X5=35,将35入栈;4最后是-运算符,计算出35-6的值,即29,由此得出最终结果可以看出,用计算机计算前缀表达式的值是很容易的将中缀表达式转换为前缀表达式遵循以下步骤br/*1初始化两个栈运算符栈S1和储存中间结果的栈S2;br/〉*2从右至左扫描中缀表达式;br/*3遇到操作数时,将其压入S2;br/*4遇到运算符时,比较其与S1栈顶运算符的优先级br/*4-1如果S1为空,或栈顶运算符为右括号“”,则直接将此运算符入栈;*4-2否则,若优先级比栈顶运算符的较高或相等,也将运算符压入SI;br/*4-3否则,将S1栈顶的运算符弹出并压入到S2中,再次转到4-1与S1中新的栈顶运算符相比较;br/*5遇到括号时br/*5-1如果是右括号“”,则直接压入SI;br/*5-2如果是左括号“”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;〈br/*6重复步骤⑵至5,直到表达式的最左边;〈br/*7将S1中剩余的运算符依次弹出并压入S2;〈br/*8依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式〈br/〉例如,将中缀表达式“1+2+3S2栈底-S1栈底说明X4-5”转换为前缀表达式的过栈顶-栈顶程如下扫描到的元素55空数字,直接入栈5S1为空,运算—一符直接入栈右括号直接入5_栈454一)数字直接入栈X54-X S1栈顶是右括号,直接入栈右括号直接入54-X栈3543-X数字+543S1栈顶是右括-X+号,直接入栈25432数字-X+5432+-X左括号,弹出运算符直至遇到右括号5432+同上—X+5432+优先级与-相一+X同,入栈-+15432+数字X1到达最左端5432+空S1中剩余的运X1+-算符运行截图:
6.本实训中遇到的关键问题与其解决方法:中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间中缀表达式是人们常用的算术表示方法虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值对计算机来说,计算前缀或后缀表达式的值非常简单
7.实训总结:通过一个简单的计算器程序,让我对java编程与栈的操作有了进一步的认识认识到需要培养团队合作能力
8.附录:程序实现代码:MainFrame.javaimport javax.swing.*;import javax.swing,border.Border;import java.awt.*;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;import java.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;*我的计算器MainFrame继承于JFrame,是计算器的界面public classMainFrame extendsJFrame{private staticfinal longserialVersionUID=IL;private Borderborder=BorderFactory.createEmptyBorder5,5,5,5;private JTextFieldtextbox=new JTextField〃O〃;private JTextFieldoldtextbox=new JTextField〃0〃;private JTextFieldqz_textbox=new JTextField〃0〃;StringBuilder sbBuilder=new StringBuilder〃〃;〃输入缓存〃按下二或回车得到结果void getResult{if!sbBuilder.toStringO.equals textbox.getText{int end=sbBuilder.length;sbBuilder=sbBuilder.delete0,end;sbBuilder.append textbox.getText;String string=null;String[]results=null;try{string=sbBuilder.toStringO;if string,matches〃・*[=\\一*/]〃{throw newException〃运算符格式不正确!〃;}else ifstring,matches〃[+\\-*/]*〃{string=sbBuilder.insert0,O・toStringO;results=Calculator.toPolishNotationstring;}catch Exceptione{string=〃0〃;sbBuilder=new StringBuilder〃0〃;results=new String[]{〃0〃,〃0〃};JOptionPane.showMessageDialogthis,〃表达式格式错误〃+e.getMessage;String oResult=results
[0];//oldtextbox.setTextstring;qz_textbox.setText results
[1];textbox.setText oResult;int end=sbBuilder.length;//System,out.printin end;sbBuilder.delete0,end;sbBuilder.appendoResult;return;private ActionListenerlistener=new ActionListener{public voidactionPerformedActionEvent e{JButton b=JButton e.getSource;Stringlabel=b.getText;iflabel,equals〃=〃{。
个人认证
优秀文档
获得点赞 0