作了几年教学改革,理论和形式上我感受基本完备了:html
很重要的一点是厘清“教是老师的责任,学是学生的责任”,也就是“老师当教练,学生作中学”。java
有了SPOC平台蓝墨云班课 ,教学工具上也基本完善了:linux
我在程序设计学习上有一个基本的体会是:android
开始不会编程,最好的学习方式是抄教材,敲代码,还专门写了一篇指导《积极主动敲代码,使用Junit学习Java程序设计》,我认为积极主动敲5000行左右的代码,应该能解决基本语法的问题,基本程序设计的问题,基本工具(git,jdb,junit,idea...)的使用问题git
而后独立编写5000行左右的代码,解决程序逻辑错误的调试,模块分解,问题解决的通常过程等相关问题程序员
有了10000行代码的基础,后面的学习提升要依靠代码阅读了,好比JUnit的源码,JHotdraw的源码,Java Collection API的源码,Java JCE的源码等web
教学中也是想经过这三个步骤进行训练。算法
看了范飞龙博士(博客,微博)的“如何设计题目”和“近发展区/脚手架”,一方面感受龙博不当老师真是亏了,另外一方面是感受本身的题目设计上还有改进的空间。数据库
这篇指导想参考龙博的博客,解决第二层次的问题,从Hello World经过一个个小练习不断迭代,来一步一步提升你们使用Java来解决具体问题的能力。express
这里面的工具每周都要求使用,咱们同窗的博客上也都提交了会使用的证据,课上默认你们熟练掌握了,没有掌握的课下努力了。
这些内容在实验课上都作过了,同窗们也都提交了本身掌握了的证据,咱们在课堂实践测试时每次都会使用相关内容。
由Kernighan和Ritchie合著的经典教程《The C Programming Language》的开篇第一个C程序例子是打印简单的“Hello World!”。今后以后,“Hello World”就成了描述人们编写的第一个程序的代名词---无论你用什么编程语言。
简单的“Hello World”可以运行出来,说明你的开发环境是没有问题的,这就有了进一步学习的基础。经过“Hello World”程序你也能初步理解程序的基本结构。
Java程序设计也不例外,咱们从"Hello World"起步,来看看你的开发环境是否是准备好了。若是开发环境都没有准备好,你号称本学期写了几千行代码基本上就能够归零了。
开发环境的准备有命令行和IDE两种,你们都要掌握,后面的练习会用到命令行和IDE,前面没有掌握好的复习上面的基础内容。
Java中的Hello World程序HelloWorld.java以下:
public class HelloWorld { public static void main(String[] args){ System.out.println("Hello World!"); } }
我在Linux命令行中能够用javac HelloWorld.java
进行编译上面的程序,用java HelloWorld
运行上面的程序:
教材已经学习完毕,咱们知道Java中子系统是以包实现的,咱们如今写个带包的Hello World:
package ljp.is.besti.edu.cn; public class HelloWorld { public static void main(String[] args){ System.out.println("Hello World!"); } }
这时候,用javac编译时要加上-d参数,用java运行时类名前要加上包前缀:
为了方便管理实践考试代码,建议同窗们创建一个以本身学号命名的文件夹,每次实践考试都要提交这个文件夹的码云连接.
咱们养成在项目根目录下也就是2015520ljp文件夹下工做的习惯,这时候经过 javac -d bin src/HelloWorld.java把class文件编译到bin文件夹下,运行时要加上-cp或-classpath参数:
Java程序员有两个角色:
对一个模块,咱们要设计出来一个类,还要有一个测试类,这个测试类是一个带main的public类
第一个任务是设计一个HelloWorld类,里面有一个方法public static void printHello()打印出“Hello World”字符串,在HelloWorldTester类补充代码调用printHello。
HelloWorld.java:
package ljp.is.besti.edu.cn; public class HelloWorld { public static void sayHello(){ System.out.println("Hello World!"); } }
HelloWorldTester.java:
package ljp.is.besti.edu.cn; public class HelloWorldTester { public static void main(String[] args){ //补充代码调用printHello ... } }
下面是补充好的代码和编译运行过程:
package ljp.is.besti.edu.cn; public class HelloWorldTester { public static void main(String[] args){ //补充代码调用printHello HelloWorld.sayHell(); } }
算法设计中很重要的一点是临时变量的使用。好比,咱们定义了两个变量int a=5;int b=6; 咱们怎么把a和b的值交换一下? 很多程序设计的初学者的作法是:
a = b; b = a;
这样是不能实现两个变量的交换的,执行完第一条语句a的值为6,b的值也为6,执行完第二条语句以后a的值为6,b的值也为6,没什么变化。
正确的作法是定义一个临时变量:
int tmp = a; a = b; b = tmp;
不使用临时变量也有办法实现交换,参考交换两个变量的值,不使用第三个变量的四种法方法,那样代码不清晰,咱们不提倡使用。
程序设计中有三种语句:
咱们解决问题时要提升抽象能力,要多使用循环解决问题,分支只是用来解决特殊状况的。
经过使用数组来学习循环的使用。
Java中遍历数组,for-each语法很好用:
//定义一个数组,好比 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int item:arr){ System.out.print(item + " "); } System.out.println();
咱们还能够从前日后遍历数组:
//定义一个数组,好比 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int i=0; i<arr.length; i++){ System.out.print(arr[i] + " "); } System.out.println();
咱们还能够从后往前遍历数组:
//定义一个数组,好比 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int = arr.lenth; i>0; i--){ System.out.print(arr[i-1] + " "); } System.out.println();
实践任务:
//定义一个数组,好比 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int i:arr){ System.out.print(i + " "); } System.out.println(); // 添加代码删除上面数组中的5 ... //打印出 1 2 3 4 6 7 8 0 for(int i:arr){ System.out.print(i + " "); } System.out.println(); // 添加代码再在4后面5 ... //打印出 1 2 3 4 5 6 7 8 for(int i:arr){ System.out.print(i + " "); } System.out.println();
删除一个元素时比较容易,插入时就要用到临时变量了,固然,你能够从数组的最后一个元素开始移动,就避免了临时变量的使用。
参考代码:
1 public class ArrayOperation { 2 3 public static void main(String [] args){ 4 int arr[] = {1,2,3,4,5,6,7,8}; 5 6 for(int i:arr){ 7 System.out.print(i + " "); 8 } 9 System.out.println(); 10 11 for(int i=5; i<arr.length; i++) 12 arr[i-1] = arr[i]; 13 14 arr[7] = 0; 15 16 for(int i:arr){ 17 System.out.print(i + " "); 18 } 19 System.out.println(); 20 21 for(int i=arr.length; i>4; i--) 22 arr[i-1] = arr[i-2]; 23 24 arr[4] = 5; 25 26 for(int i:arr){ 27 System.out.print(i + " "); 28 } 29 System.out.println(); 30 31 } 32 }
咱们再回到Hello World程序:
public class HelloWorld { public static void main(String[] args){ System.out.println("Hello World!"); } }
之前只是说你们只要记住main方法的写法,如今要能深刻理解了,“public static void”是什么意思要清楚。咱们这里要说的是main方法的参数 String [] args. args是一字符串数组,它是从哪里来的?Java程序运行时,会调用main方法,args就是命令行参数。
咱们写一个测试程序CommandLine.java:
1 public class CommandLine { 2 public static void main(String [] args) { 3 for(String arg : args){ 4 System.out.println(arg); 5 } 6 } 7 }
咱们java CommandLine
运行时,没有什么输出。
咱们java CommandLine 1 2 3
运行时,输出以下图,此时 args[0]=="1", args[1]=="2", args[2]=="3",args.lenth == 3。
在IDEA这种IDE中如何传递命令行参数?咱们选择Run->Edit Configuration...
命令行中的参数经过 Programm argumetns传递。
实践内容
提交测试结果截图,课下把代码上传到码云。 求命令行传入整数参数的和。 public class CLSum { public static void main(String [] args) { int sum = 0; // 参考Integer类中的方法把字符串转为整数 // 补充代码求命令行参数的args中整数数据的和 ... // 打印 System.out.println(sum); } }
参考代码:
public class CLSum { public static void main(String [] args) { int sum = 0; // 参考Integer类中的方法把字符串转为整数 // 补充代码求命令行参数的args中整数数据的和 for(String arg: args) sum += Interger.parseInt(arg); // 打印 System.out.println(sum); } }
有同窗想先把传入的字符串数组转化为一个临时的int 数组,能够这样:
1 public class CLSum1 { 2 public static void main(String [] args) { 3 int sum = 0; 4 5 int [] tmp = new int [args.length]; 6 for(int i=0; i<args.length; i++) { 7 tmp[i] = Integer.parseInt(args[i]); 8 } 9 10 for(int t : tmp){ 11 sum += t; 12 13 } 14 15 System.out.println(sum); 16 } 17 }
同窗们还有遇到Integer类中没有parseInt()的问题,这是咱们实验二定义了本身的Integer等类,与Java重名了,就和两个班有重名的同窗同样,区分必须加上班级名,咱们这就要加上包名java.lang.Integer。
递归算法是一种直接或间接地调用自身的算法。在编写程序时,递归算法对解决一大类问题是十分有效的,它每每使算法的描述简洁并且易于理解。
递归用于解决形式相同,规模不一样的问题,能用递归解决的问题均可以转化为循环。递归把一个大型复杂的问题层层转化为一个与原问题类似的规模较小的问题来求解,递归策略只需少许的程序就可描述出解题过程所须要的屡次重复计算,大大地减小了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序每每十分简洁易懂。
递归程序有两个要点:递归公式和结束条件。咱们以求整数的阶乘为例:
有了公式,代码就容易写出来了:
1 public class Factorial { 2 public static void main(String [] args) { 3 System.out.println(fact(5)); 4 } 5 6 public static int fact(int n) { 7 if (n == 0) 8 return 1; 9 else 10 return n * fact(n-1); 11 } 12 }
fact(5)的递推过程以下图:
JDB不可是个调试工具,仍是一个学习工具,参考 《使用JDB调试Java程序》的递归调试部分,看看递归调用的动态过程。
实践:
public class CLSumRecursion { public static void main(String [] args) { int sum = 0; // 参考Integer类中的方法把字符串转为整数 // 补充代码以递归的方式求命令行参数的args中整数数据的和 ... // 打印 System.out.println(sum); } //递归函数 public static int clSum(int [] arr) { ... } }
参考代码:
1 import java.util.Arrays; 2 3 public class CLSumRecursion { 4 public static void main(String [] args) { 5 int sum = 0; 6 7 if(args.length < 1){ 8 System.out.println("Usage: java CLSumRecursion num1 num2 ..."); 9 System.exit(0); 10 } 11 12 int [] tmp = new int [args.length]; 13 for(int i=0; i<args.length; i++) { 14 tmp[i] = Integer.parseInt(args[i]); 15 } 16 17 sum = clsum(tmp); 18 System.out.println(sum); 19 } 20 21 public static int clsum(int [] arr) 22 if (arr.length == 1) 23 return arr[0]; 24 else { 25 int [] tmp = Arrays.copyOf(arr, arr.length-1); 26 return clsum(tmp) + arr[arr.length-1]; 27 } 28 } 29 }
这个题目出的不太好,用递归求1+2+3+...+N就容易理解些:
int sum(int n){ if (n==1) return 1; else return sum(n-1) + n; }
相对于顺序语句来讲,分支语句多用于处理特殊状况,Java中的分支语句有:
这两个语句是等价的。
使用分支语句时要注意MESE原则,MESE是Mutually Exclusive Collectively Exhaustive的缩写,意思是“相互独立,彻底穷尽”。 也就是对于问题的分类要可以作到不重叠、不遗漏。if中的else, switch...case中的default对于不遗漏.
实践:
实现一个简易计算器Calc,支持+ - x / 和%运算, 从命令行传入计算数据,好比: java Calc 2 + 3 结果为 2 + 3 = 5 java Calc 8 - 3 结果为 8 - 3 = 5 java Calc 2 x 3 结果为2 x 3 = 6 java Calc 10 / 2 结果为10 / 2 = 5 java Calc 10 % 3 结果为10 % 3 = 1 1 public class Calc { 2 public static void main(String [] args) { 3 4 int result = 0; 5 6 if (args.length != 3) { 7 System.out.println("Usage: java Calc operato1 operand(+ - X / %) operator2"); 8 } 9 //======如下补充代码===== 10 //+ - x / 和%运算 11 //======以上补充代码====== 12 System.out.println(args[0] + " " + args[1] + " " + args[2] + " = " + result); 13 14 } 15 }
参考代码以下:
1 public class Calc { 2 public static void main(String [] args) { 3 4 int result = 0; 5 6 if (args.length != 3) { 7 System.out.println("Usage: java Calc operato1 operand(+ - x / %) operator2"); 8 } 9 10 switch (args[1]) { 11 case "+": 12 result = Integer.parseInt(args[0]) + Integer.parseInt(args[2]); 13 break; 14 case "-": 15 result = Integer.parseInt(args[0]) - Integer.parseInt(args[2]); 16 break; 17 case "x": 18 result = Integer.parseInt(args[0]) * Integer.parseInt(args[2]); 19 break; 20 case "/": 21 result = Integer.parseInt(args[0]) / Integer.parseInt(args[2]); 22 break; 23 case "%": 24 result = Integer.parseInt(args[0]) % Integer.parseInt(args[2]); 25 break; 26 default: 27 System.out.println("Usage: java Calc operato1 operand(+ - x / %) operator2"); 28 break; 29 30 } 31 System.out.println(args[0] + " " + args[1] + " " + args[2] + " = " + result); 32 33 } 34 }
这个代码要注意的是乘法在命令行参数中不能用“*”, "*"是一个通配符,会返回当前目录的全部文件名。
还有同窗拷贝上面的代码后要一行一行的删除行号,若是用Vim的话,使用列模式很容易就把删除了,Vim 中咱们使用 Ctrl+v
进入列模式,选择前两列,按x就删除了。
IDEA中也支持Vim模式,熟悉Vim的同窗能够安装IDEAVim插件:
咱们经过String类的使用为例说明程序设计的几个问题
咱们先回顾一个Linux命令sort:
咱们关注下面几个选项:
-t<分隔字符>:指定排序时所用的栏位分隔字符; -k: 针对第几列进行排序 -n:依照数值的大小排序; -r:以相反的顺序来排序;
如何实现Linux下Sort的功能对一个字符串数组进行排序?你可能学习过或者据说过冒泡排序,归并排序,插入排序,选择排序,快速排序等算法,咱们要先实现这些算法吗?Java编程中咱们能够先查查API文档:
咱们发现java.util.Arrays类和java.util.Collections类中都实现了sort方法,咱们不用本身编程实现排序算法了,调用这些方法就能够了。
调用java.util.Arrays.sort的示例:
1 import java.util.*; 2 3 public class MySort1 { 4 public static void main(String [] args) { 5 String [] toSort = {"aaa:10:1:1", 6 "ccc:30:3:4", 7 "bbb:50:4:5", 8 "ddd:20:5:3", 9 "eee:40:2:20"}; 10 11 System.out.println("Before sort:"); 12 for (String str: toSort) 13 System.out.println(str); 14 15 Arrays.sort(toSort); 16 17 System.out.println("After sort:"); 18 for( String str : toSort) 19 System.out.println(str); 20 } 21 }
调用java.util.Collections.sort的示例:
1 import java.util.*; 2 3 public class MySort1 { 4 public static void main(String [] args) { 5 String [] toSort = {"aaa:10:1:1", 6 "ccc:30:3:4", 7 "bbb:50:4:5", 8 "ddd:20:5:3", 9 "eee:40:2:20"}; 10 11 System.out.println("Before sort:"); 12 for (String str: toSort) 13 System.out.println(str); 14 15 List<String> list = new ArrayList(); 16 for (String str: toSort) 17 list.add(str); 18 19 Collections.sort(list); 20 21 System.out.println("After sort:"); 22 for( String str : list) 23 System.out.println(str); 24 } 25 }
实践任务:
1 import java.util.*; 2 3 public class MySort { 4 public static void main(String [] args) { 5 String [] toSort = {"aaa:10:1:1", 6 "ccc:30:3:4", 7 "bbb:50:4:5", 8 "ddd:20:5:3", 9 "eee:40:2:20"}; 10 11 System.out.println("Before sort:"); 12 for (String str: toSort) 13 System.out.println(str); 14 15 Integer [] tmp = new Integer [toSort.length]; 16 for(int i=0; i<tmp.length; i++) 17 tmp[i] = ...; 18 19 Arrays.sort(tmp); 20 21 System.out.println("After sort:"); 22 23 for(int i=0; i<tmp.length; i++) 24 for(int j=0; j<toSort.length; j++) 25 if(...) 26 System.out.println(toSort[j]); 27 } 28 }
参考代码
1 import java.util.*; 2 3 public class MySort { 4 public static void main(String [] args) { 5 String [] toSort = {"aaa:10:1:1", 6 "ccc:30:3:4", 7 "bbb:50:4:5", 8 "ddd:20:5:3", 9 "eee:40:2:20"}; 10 11 System.out.println("Before sort:"); 12 for (String str: toSort) 13 System.out.println(str); 14 15 Integer [] tmp = new Integer [toSort.length]; 16 for(int i=0; i<tmp.length; i++) 17 tmp[i] = new Integer(Integer.parseInt(toSort[i].split(":")[3])); 18 19 Arrays.sort(tmp); 20 21 System.out.println("After sort:"); 22 23 for(int i=0; i<tmp.length; i++) 24 for(int j=0; j<toSort.length; j++) 25 if(Integer.parseInt(toSort[j].split(":")[3]) == tmp[i].intValue()) 26 System.out.println(toSort[j]); 27 } 28 }
这里面有几个问题:
《实验二 Java面向对象程序设计》提出编写程序要写三种代码:
咱们学习编程是用来解决实际问题的,咱们使用《别出心裁的Linux系统调用学习法》中的方法进行学习》
栈 (Stack)是一种只容许在表尾插入和删除的线性表,有先进后出(FILO),后进先出(LIFO)的特色。容许插入和删除的一端称为栈顶(top),另外一端称为栈底(bottom)。
Java中有Stack类,不熟悉的同窗能够参考《积极主动敲代码,使用Junit学习Java程序设计》学习一下:
栈的一个应用是用来对四则运算表达式进行求值。
表达式Exp = S1 + OP + S2
(S1 ,S2是两个操做数,OP为运算符)有三种标识方法:
例如:Exp = a * b + (c - d / e) * f
咱们能够看出:
后缀表示法是波兰逻辑学家J.Lukasiewicz于1929年提出的,又叫作逆波兰表达式。
Linux命令dc
能够用来对逆波兰式表达式进行求值,dc
的打印类命令:
dc
的运算符:
dc
支持栈操做:
咱们看一下dc
如何使用:
咱们如何实现dc
? 这要用到栈。对逆波兰式求值时,不须要再考虑运算符的优先级,只需从左到右扫描一遍后缀表达式便可。求值伪代码以下:
此时,栈中仅有一个元素,即为运算的结果。
咱们给出一个例子,求后缀表达式:1 2 + 8 2 - 7 4 - / *
的值:
MyDC.java: 补充代码31-40行
1 import java.util.StringTokenizer; 2 import java.util.Stack; 3 4 public class MyDC 5 { 6 /** constant for addition symbol */ 7 private final char ADD = '+'; 8 /** constant for subtraction symbol */ 9 private final char SUBTRACT = '-'; 10 /** constant for multiplication symbol */ 11 private final char MULTIPLY = '*'; 12 /** constant for division symbol */ 13 private final char DIVIDE = '/'; 14 /** the stack */ 15 private Stack<Integer> stack; 16 17 public MyDC() { 18 stack = new Stack<Integer>(); 19 } 20 21 public int evaluate (String expr) 22 { 23 int op1, op2, result = 0; 24 String token; 25 StringTokenizer tokenizer = new StringTokenizer (expr); 26 27 while (tokenizer.hasMoreTokens()) 28 { 29 token = tokenizer.nextToken(); 30 31 //若是是运算符,调用isOperator 32 if () 33 { 34 //从栈中弹出操做数2 35 //从栈中弹出操做数1 36 //根据运算符和两个操做数调用evalSingleOp计算result; 37 //计算result入栈; 38 } 39 else//若是是操做数 40 //操做数入栈; 41 } 42 43 return result; 44 } 45 46 private boolean isOperator (String token) 47 { 48 return ( token.equals("+") || token.equals("-") || 49 token.equals("*") || token.equals("/") ); 50 } 51 52 private int evalSingleOp (char operation, int op1, int op2) 53 { 54 int result = 0; 55 56 switch (operation) 57 { 58 case ADD: 59 result = op1 + op2; 60 break; 61 case SUBTRACT: 62 result = op1 - op2; 63 break; 64 case MULTIPLY: 65 result = op1 * op2; 66 break; 67 case DIVIDE: 68 result = op1 / op2; 69 } 70 71 return result; 72 } 73 }
测试类,MyDCTester.java ,代码不用修改
1 import java.util.Scanner; 2 3 public class MyDCTester { 4 5 public static void main (String[] args) { 6 7 String expression, again; 8 9 int result; 10 11 try 12 { 13 Scanner in = new Scanner(System.in); 14 15 do 16 { 17 MyDC evaluator = new MyDC(); 18 System.out.println ("Enter a valid postfix expression: "); 19 expression = in.nextLine(); 20 21 result = evaluator.evaluate (expression); 22 System.out.println(); 23 System.out.println ("That expression equals " + result); 24 25 System.out.print ("Evaluate another expression [Y/N]? "); 26 again = in.nextLine(); 27 System.out.println(); 28 } 29 while (again.equalsIgnoreCase("y")); 30 } 31 catch (Exception IOException) 32 { 33 System.out.println("Input exception reported"); 34 } 35 } 36 }
参考代码
1 import java.util.StringTokenizer; 2 import java.util.Stack; 3 4 public class MyDC 5 { 6 /** constant for addition symbol */ 7 private final char ADD = '+'; 8 /** constant for subtraction symbol */ 9 private final char SUBTRACT = '-'; 10 /** constant for multiplication symbol */ 11 private final char MULTIPLY = '*'; 12 /** constant for division symbol */ 13 private final char DIVIDE = '/'; 14 /** the stack */ 15 private Stack<Integer> stack; 16 17 /** 18 * Sets up this evalutor by creating a new stack. 19 */ 20 public MyDC() 21 { 22 stack = new Stack<Integer>(); 23 } 24 25 public int evaluate (String expr) 26 { 27 int op1, op2, result = 0; 28 String token; 29 StringTokenizer tokenizer = new StringTokenizer (expr); 30 31 while (tokenizer.hasMoreTokens()) 32 { 33 token = tokenizer.nextToken(); 34 35 if (isOperator(token)) 36 { 37 op2 = (stack.pop()).intValue(); 38 op1 = (stack.pop()).intValue(); 39 result = evalSingleOp (token.charAt(0), op1, op2); 40 stack.push (new Integer(result)); 41 } 42 else 43 stack.push (new Integer(Integer.parseInt(token))); 44 } 45 46 return result; 47 } 48 49 private boolean isOperator (String token) 50 { 51 return ( token.equals("+") || token.equals("-") || 52 token.equals("*") || token.equals("/") ); 53 } 54 55 private int evalSingleOp (char operation, int op1, int op2) 56 { 57 int result = 0; 58 59 switch (operation) 60 { 61 case ADD: 62 result = op1 + op2; 63 break; 64 case SUBTRACT: 65 result = op1 - op2; 66 break; 67 case MULTIPLY: 68 result = op1 * op2; 69 break; 70 case DIVIDE: 71 result = op1 / op2; 72 } 73 74 return result; 75 } 76 }44 } 45 46 return result; 47 } 48 49 private boolean isOperator (String token) 50 { 51 return ( token.equals("+") || token.equals("-") || 52 token.equals("*") || token.equals("/") ); 53 } 54 55 private int evalSingleOp (char operation, int op1, int op2) 56 { 57 int result = 0; 58 59 switch (operation) 60 { 61 case ADD: 62 result = op1 + op2; 63 break; 64 case SUBTRACT: 65 result = op1 - op2; 66 break; 67 case MULTIPLY: 68 result = op1 * op2; 69 break; 70 case DIVIDE: 71 result = op1 / op2; 72 } 73 74 return result; 75 } 76 }
你们注意两个private 方法isOperator, evalSingleOp的设计,体会一下方法分解。
对通常人来讲,获得后缀表达式就是一件不容易的事。咱们习惯的仍是中缀表达式。Linux中另一个计算器bc
就是用来计算中缀表达式的:
咱们如何编程实现bc
? 把中缀式转化后缀式调用MyDC.java 中的evaluate方法就好了。这样问题转化为如何由中缀式求得后缀式?
由中缀式求得后缀式可使用栈,伪代码以下:
将中缀表达式 (1+2)*((8-2)/(7-4))
变成后缀表达式,栈的变化及输出结果:
算符优先法求解表达式:(生成后缀表达式+后缀表达式求值)
版权声明:自由转载-非商用-非衍生-保持署名| Creative Commons BY-NC-ND 3.0
若是你以为本文对你有帮助,请点一下左下角的“好文要顶”和“收藏该文”