java四则运算(递归的思想)
- 格式:docx
- 大小:18.71 KB
- 文档页数:7
java 递归算法递归算法是一种编程技术,它使用一种叫做递归的迭代方法,可以解决复杂的问题。
递归算法指的是一种把一个大问题分解为一系列规模较小的子问题来解决的方法。
当容易解决规模较小的子问题时,可以递归地解决规模较大的问题,而无需编写代码。
一般来说,递归算法通过迭代(不断重新评估并重新求解问题)来实现,而无需编写大型程序分支来处理不同输入,只需要利用一个或几个函数就可以处理对问题的不同情况。
递归算法在计算机科学的应用领域非常广泛,它被广泛应用于解决数据结构、搜索算法以及逻辑程序等复杂的问题。
例如,一个树形结构的搜索算法依赖于递归算法来查找相应的结果,从而给出一个实用的解决方案。
本文将就递归算法作一个较为全面的介绍,重点介绍它在 Java 言中的实现。
首先,让我们来了解一下 Java言本身是如何实现递归算法的,即通过何种方式来实现递归的目的。
其核心思想是,一个函数的递归调用是指调用该函数的体内有一个或多个函数调用语句,其中被调用的函数可以是它自身,也可以是另一个函数。
为了实现递归调用,Java 言中提供了一个特殊的语句称为递归函数调用语句(recursive call),可以让一个函数调用它自身。
为了实现递归算法,必须要具备以下三个条件:1.本情形:一个函数在某些情况下不再调用自身,而是直接返回结果,称为基本情形。
2. 不断抽象:对每个问题的解决,都将它抽象成一个规模更小的子问题,这样递归地解决问题才有可能。
3.用自身:在子问题解决完毕后,再调用自身,也就是说调用函数的体内有一个或多个函数调用语句,其中被调用的函数可以是它自身。
接下来,让我们来看一个实际的实现案例,比如说,在 java言中实现一个求阶乘的递归算法。
在 Java言中,可以使用递归函数调用语句(recursive call)来实现递归算法。
以求阶乘的算法为例,其实现代码如下:public static long factorial(int n) {if (n <= 1) {return 1;}return n * factorial(n - 1);}上面的代码中,n 代表要求阶乘的数,此函数调用自身来实现求解,基本情形是当 n 为 1不再调用自身而是直接返回 1,当 n于 1,将 n阶乘计算表示为 n * (n - 1)阶乘的乘积,直到达到基本情形,最终求出阶乘的值。
递归算法java递归算法是一种在编程中常用的算法,它的思想是将一个问题分解成更小的子问题,并通过递归调用自身来解决这些子问题。
在Java编程中,递归算法常用于解决树形结构、图形结构等复杂数据结构的问题。
递归算法的基本原理是将一个大问题分解成若干个小问题,然后通过逐步解决这些小问题来达到解决大问题的目的。
在Java编程中,递归算法通常使用函数或方法来实现。
具体实现过程如下:1. 定义递归函数或方法:首先需要定义一个能够接受参数并返回值的函数或方法。
该函数或方法需要能够判断何时停止递归,并且需要能够处理每个子问题。
2. 设计停止条件:在定义函数或方法时,需要设定一个停止条件。
当满足该条件时,函数或方法将不再继续调用自身,从而结束递归。
3. 处理子问题:在每次调用自身时,需要将原始参数转换为更小的参数,并传入新的函数或方法中。
这样就可以不断地处理子问题。
4. 合并结果:当所有子问题都得到了解决后,在最后一次调用自身时,将所有结果合并起来,并返回给调用方。
递归算法的优点在于能够简化代码结构,使代码更加清晰易懂。
同时,递归算法也可以处理复杂的问题,并且通常比迭代算法更加高效。
但是,递归算法也有一些缺点。
例如,递归算法通常需要大量的栈空间来存储函数或方法的调用信息,从而导致内存占用过高。
下面是一个示例程序,演示了如何使用递归算法来实现阶乘运算:public class Factorial {public static int factorial(int n) {if (n == 0) { // 设定停止条件return 1;} else {return n * factorial(n-1); // 处理子问题}}public static void main(String[] args) {int result = factorial(5); // 调用函数System.out.println(result);}}在上述程序中,函数factorial()接受一个参数n,并返回n的阶乘。
java递归写法递归是一种重要的算法思想,它可以用来解决很多问题,例如数学中的阶乘、斐波那契数列、树的遍历等。
在Java中,递归的写法可以很简单,但是如果不小心就会出现栈溢出等问题。
本文将介绍Java中递归的写法,以及如何避免递归过程中出现的一些问题。
一、递归的概念递归是一种函数调用自身的算法思想。
它通过将一个问题分解为更小的子问题来解决问题。
递归算法的基本思路是:当问题的规模足够小时,直接求解;否则,将问题分解为规模更小的子问题,递归地解决子问题,最后将子问题的结果合并起来得到原问题的解。
递归算法有两个重要的特点:一是递归调用函数本身;二是需要有一个递归终止条件。
递归调用函数本身是为了将问题规模缩小,递归终止条件是为了避免无限递归。
二、递归的实现递归的实现需要考虑两个方面:递归调用和递归终止条件。
递归调用是指在函数中调用自身,递归终止条件是指当问题规模足够小时,直接求解。
例如,求n的阶乘可以使用递归实现。
当n等于1时,阶乘为1;否则,阶乘为n乘以(n-1)的阶乘。
代码如下:```javapublic class Factorial {public static long factorial(int n) {if (n == 1) {return 1;} else {return n * factorial(n - 1);}}}```这段代码中,递归调用在return语句中,递归终止条件是当n 等于1时,直接返回1。
三、递归的应用递归算法可以用来解决很多问题,例如数学中的阶乘、斐波那契数列、树的遍历等。
下面分别介绍这些应用。
1. 阶乘阶乘是指从1到n的所有正整数相乘的积。
例如,5的阶乘为5x4x3x2x1=120。
使用递归算法可以很容易地求出n的阶乘。
代码如下:```javapublic class Factorial {public static long factorial(int n) {if (n == 1) {return 1;} else {return n * factorial(n - 1);}}}```2. 斐波那契数列斐波那契数列是指第n个数等于前两个数之和。
java算法-递归算法递归算法是指在函数的执行过程中,不断地调用自身来解决问题的一种算法,也称为递归函数。
它是一种很有用的技术,用来解决一些复杂的问题。
在Java语言中,递归算法被广泛地应用在各种领域,例如树结构的遍历、图结构的遍历、排序算法、分治算法等。
递归算法的基本思想是:将一个大问题分解成若干个小问题来解决,每个小问题都是与原问题相同的结构。
当小问题满足一定条件时,递归结束,逐级返回答案,将每个小问题的答案合并起来,最终得到大问题的答案。
递归算法的优点在于它简洁、直观、易于理解,而且可以轻松地解决复杂的问题。
但是,递归算法通常会占用大量的内存和时间,而且容易引发死循环等错误。
因此,在使用递归算法时,应该注意编写正确的条件和基准情况,确保递归的正确性和性能。
在Java语言中,递归算法通常可以用函数来实现,例如:```public static int factorial(int n) {if (n <= 1) {return 1;} else {return n * factorial(n - 1);}}```上述代码实现了阶乘算法,当n <= 1时,递归结束,返回1;当n > 1时,递归调用factorial(n - 1)来计算n的阶乘,逐级返回结果,最终得到n的阶乘。
除了阶乘算法,递归算法还可以实现很多其他算法,例如斐波那契数列算法、汉诺塔问题算法、快速排序算法、归并排序算法等。
这些算法均是利用递归算法的思想,将一个大问题分解成若干个小问题来解决。
总之,递归算法是一种非常有用的算法技术,可以用来解决各种复杂的问题。
它的优点在于它简洁、直观、易于理解,而且可以轻松地解决复杂的问题。
但是,在使用递归算法时,应该注意编写正确的条件和基准情况,确保递归的正确性和性能。
递归算法在计算机科学领域中的应用非常广泛,从数据结构到算法,递归的思想几乎无处不在。
下面我们来介绍一些递归算法的实际应用。
java解析四则运算为树形的方法概述及解释说明1. 引言1.1 概述:本文将讨论Java解析四则运算为树形结构的方法。
四则运算是数学中最基础的运算,包括加法、减法、乘法和除法。
通过对四则运算表达式进行解析,可以将其转化为树形结构,以提供更方便的处理和计算方式。
在本文中,我们将介绍四则运算及其解析方式的简介,并重点关注树形结构在这种解析中的应用。
1.2 文章结构:本文共分为5个部分:引言、正文、解释说明、结论和后记。
在引言部分,我们将给出文章的概述,简述整篇文章的内容与目标。
在正文部分,我们将详细介绍四则运算及其解析方式的简介,并探究树形结构在这种解析中的作用。
在解释说明部分,我们会阐述将四则运算表达式转化为树形结构的基本概念和原理,并讨论Java中实现这一过程的方法。
接着,我们还会探讨树形结构在四则运算解析中的优势和应用场景。
在结论部分,我们将总结文章要点和重点论述内容,并对Java解析四则运算为树形的方法进行评价并展望未来的发展方向。
最后,在后记部分,我们将留下一些附加信息和感想。
1.3 目的:本文的目的是提供一个全面且易懂的解析四则运算为树形结构的方法,并探讨这种方法在Java中的应用。
通过深入了解四则运算的解析和树形结构的应用,读者可以更好地理解并使用这些技术,进一步提高程序设计和算法实现能力。
本文还旨在为Java开发者提供一个可靠而有效的工具,以便于他们处理复杂的四则运算表达式。
跟随本文学习并实践这种方法可以增强编码技巧和培养抽象思维能力,在日常开发中收获不少益处。
2. 正文:2.1 四则运算及其解析方式简介:在数学中,四则运算指的是加法、减法、乘法和除法这四种基本运算。
它们是最常见和基础的数学运算,广泛应用于各个领域。
在计算机科学中,我们通常需要将四则运算表达式进行解析,以便计算机能够理解和执行。
2.2 树形结构在四则运算解析中的应用:树形结构是一种非常适合表示嵌套层次关系的数据结构。
Java实现四则运算本次使⽤java语⾔,实现了四则运算习题的⽣成。
⼀、主要功能:(1)算式个数(2)是否有乘除法(3)结果集数值范围(4)加减法有⽆负数(5)除法有⽆余数(6)除法出现⼩数是否⽀持分数显⽰(7)选择⽣成算式导⼊的⽂件(8)输出打印每⾏个数⼆、代码实现:(1)IFormulaGenerationpackage cn.zhl.software;import java.util.Map;public interface IFormulaGeneration {//加法⽣成接⼝,结果范围,加法有⽆负数,⽣成个数public Map<String,Integer> Add(int resultRange,boolean is,int num);//减法⽣成接⼝,结果范围,减法有⽆负数,⽣成个数public Map<String,Integer> Sub(int resultRange,boolean is,int num);//乘法⽣成接⼝,⽣成个数public Map<String,Integer> Mul(int resultRange,int num);//除法⽣成接⼝,结果范围,除法有⽆余数,是否⽀持分数,⽣成个数public Map<String,String> Div(int resultRange,boolean is,boolean is2,int num);//检测算式是否存在重复,如果存在返回truepublic boolean Repeat(Map<?,?> map,String formula);//⽣成特定范围的数值public int nextInt(int min, int max);//算法⽣成器:算式个数,是否有乘除法,数值范围,加减法有⽆负数,除法⼜⽆余数,是否⽀持分数,打印每⾏个数 public Map<String,?> FormulaCustom(int formulaNum,boolean if_MulDiv,int range,boolean ifNeg_AddSub,boolean ifRem_Div,boolean ifRed_Div,int lineNum);}(2)FormulaRealizationpackage cn.zhl.software;import java.util.HashMap;import java.util.Map;import java.util.Random;import java.util.Set;public class FormulaRealization implements IFormulaGeneration {Random random = new Random();@Overridepublic Map<String, Integer> Add(int resultRange, boolean is, int num) {if (resultRange < 0) {resultRange = -resultRange;}Map<String, Integer> addMap = new HashMap<>();int r1 = 0, r2 = 0, n = 0;String formula = "";for (; n < num; ) {r1 = nextInt(-resultRange, resultRange);if (is) {//加法允许出现负数r2 = nextInt(-resultRange - r1, resultRange - r1);} else {r2 = nextInt(-r1, resultRange - r1);}formula = (r1 < 0 ? "(" + r1 + ")" : r1) + "+" + (r2 < 0 ? "(" + r2 + ")" : r2);if (Repeat(addMap, formula)) {}return addMap;}@Overridepublic Map<String, Integer> Sub(int resultRange, boolean is, int num) { if (resultRange < 0) {resultRange = -resultRange;}Map<String, Integer> subMap = new HashMap<>();int r1 = 0, r2 = 0, n = 0;String formula = "";for (; n < num; ) {r1 = nextInt(-resultRange, resultRange);if (is) {//加法允许出现负数r2 = nextInt(-resultRange + r1, resultRange + r1);} else {r2 = nextInt(r1, resultRange + r1);}formula = (r1 < 0 ? "(" + r1 + ")" : r1) + "-" + (r2 < 0 ? "(" + r2 + ")" : r2); if (Repeat(subMap, formula)) {subMap.put(formula, r1 - r2);n++;}}return subMap;}@Overridepublic Map<String, Integer> Mul(int resultRange, int num) {if (resultRange == 0) {resultRange = 1;}if (resultRange < 0) {resultRange = -resultRange;String formula = "";for (; n < num; ) {while (r1 == 0) {r1 = nextInt(-resultRange, resultRange);}r2 = nextInt(-(int) (resultRange / Math.abs(r1)), (int) (resultRange / Math.abs(r1))); formula = (r1 < 0 ? "(" + r1 + ")" : r1) + "*" + (r2 < 0 ? "(" + r2 + ")" : r2);if (Repeat(mulMap, formula)) {mulMap.put(formula, r1 * r2);n++;r1 = nextInt(-resultRange, resultRange);}}return mulMap;}@Overridepublic Map<String, String> Div(int resultRange, boolean is, boolean is2, int num) { if (resultRange == 0) {resultRange = 1;}if (resultRange < 0) {resultRange = -resultRange;}Map<String, String> divMap = new HashMap<>();int r1 = 0, r2 = 0, n = 0;String formula = "";for (; n < num; ) {//r1 = nextInt(-resultRange, resultRange);while (r2 == 0) {r2 = nextInt(-resultRange, resultRange);}if (!is) {//除法没有余数r1 = r2 * nextInt(-(resultRange), resultRange);} else {//有余数r1 = nextInt(-resultRange, resultRange);}formula = (r1 < 0 ? "(" + r1 + ")" : r1) + "/" + (r2 < 0 ? "(" + r2 + ")" : r2);if (Repeat(divMap, formula)) {String result = "";if (is && is2) {//有余数且化为分数if(r1*r2<0){result = "-"+fracReduction(Math.abs(r1), Math.abs(r2));}else {result = fracReduction(Math.abs(r1), Math.abs(r2));}if(r1%r2==0){result = ((double) r1 / r2) + "";}if (is) {result = ((double) r1 / r2) + "";}}if(r1==0){result=0.0+"";}if (r1==-r2){result="-1.0";}divMap.put(formula, result);n++;}}return divMap;}@Overridepublic boolean Repeat(Map<?, ?> map, String formula) { if (map.isEmpty()) {return true;} else {Set<String> strings = (Set<String>) map.keySet(); for (String string : strings) {//如果当前算式与前⾯算式重复返回falseif (string.equals(formula)) {return false;}}//如果当前算式与前⾯算式不存在重复返回truereturn true;}}@Overridepublic int nextInt(int min, int max) {if (min == max) {return max;}return random.nextInt(max - min + 1) + min;public String fracReduction(int numerator, int denominator) {//找到最⼤公约数,然后分别处以最⼤公约数int m = numerator;int n = denominator;int r;while (numerator > 0) {r = denominator % numerator;denominator = numerator;numerator = r;}// if ((m / denominator)==-(n / denominator)){// return "-1.0";// }return m / denominator + "/" + n / denominator;}@Override//算法⽣成器:算式个数,是否有乘除法,数值范围,加减法有⽆负数,除法⼜⽆余数,是否⽀持分数,打印每⾏个数public Map<String, ?> FormulaCustom(int formulaNum, boolean if_MulDiv, int range, boolean ifNeg_AddSub, boolean ifRem_Div, boolean ifRed_Div, int lineNum) {int add = 0, sub = 0, mul = 0, div = 0;add = nextInt(formulaNum/5,formulaNum/3);sub = nextInt((formulaNum - add)/4,(formulaNum - add)/2);mul = nextInt((formulaNum - add - sub)/3,(formulaNum - add - sub)/1);div = formulaNum - add - sub - mul;Map map = new HashMap();if (if_MulDiv) {//如果存在乘除法将算式总数分为四份Map<String, Integer> addMap = Add(range, ifNeg_AddSub, add);Map<String, Integer> subMap = Sub(range, ifNeg_AddSub, sub);Map<String, Integer> mulMap = Mul(range, mul);Map<String, String> divMap = Div(range, ifRem_Div, ifRed_Div, div);map.putAll(addMap);map.putAll(subMap);map.putAll(mulMap);map.putAll(divMap);} else {//不存在则分为两份map.putAll(addMap);map.putAll(subMap);}return map;}}(3)FormulaRealizationTestpackage cn.zhl.test;import cn.zhl.software.FormulaRealization;import org.junit.Test;import java.util.Map;import java.util.Set;public class FormulaRealizationTest {FormulaRealization formulaRealization = new FormulaRealization();@Testpublic void testAdd() {Map<String, Integer> add = formulaRealization.Add(100, false, 5); for (String s : add.keySet()) {System.out.print(s+"="+add.get(s)+" ");}}@Testpublic void testSub() {Map<String, Integer> sub = formulaRealization.Sub(100, true, 5); for (String s : sub.keySet()) {System.out.print(s+"="+sub.get(s)+" ");}}@TestSystem.out.print(s+"="+mul.get(s)+" ");}}@Testpublic void testDiv() {Map<String, String> div = formulaRealization.Div(100, true, true, 5);for (String s : div.keySet()) {System.out.print(s+"="+div.get(s)+" ");}}@Testpublic void test1() {String div = formulaRealization.fracReduction(25,5);System.out.print(div);}}(4)IFileGenerationpackage cn.zhl.fileCreate;import java.util.Map;public interface IFileGeneration {//⽤于将产⽣的算式写⼊到⽂件中public void fileShow(Map<String,?> stringMap,int lineNum,String fileName); }(5)FileRealizationpackage cn.zhl.fileCreate;import java.io.File;import java.io.FileWriter;import java.io.IOException;@Overridepublic void fileShow(Map<String,?> stringMap, int lineNum, String fileName) {int n=0;String answerName=fileName+"_Answer.txt";fileName=fileName+".txt";/*File file1 = new File("\\cn\\zhl\\formulaFile\\" + fileName);File file2 = new File("\\cn\\zhl\\formulaFile\\" + answerName);*/File file1 = new File("Arithmetic_question_generation_system\\src\\cn\\zhl\\formulaFile\\"+fileName);File file2 = new File("Arithmetic_question_generation_system\\src\\cn\\zhl\\formulaFile\\"+answerName);for (String s : stringMap.keySet()) {n++;try(FileWriter formulaWriter = new FileWriter(file1,true); FileWriter answerWriter = new FileWriter(file2,true)) { formulaWriter.write(s+"= ");answerWriter.write(s+"="+stringMap.get(s)+" ");if(n%lineNum==0){formulaWriter.write("\n");answerWriter.write("\n");}} catch (IOException e) {e.printStackTrace();System.out.println("未成功将算式保存到"+fileName+"中,答案保存到"+answerName+"中,请联系开发⼈员!"); }}System.out.println("已成功将算式保存到"+fileName+"中,答案保存到"+answerName+"中,欢迎您的下次使⽤!"); }}(6)FormulaCustomTestpackage cn.zhl.software;import cn.zhl.fileCreate.FileRealization;import java.io.File;import java.io.FileWriter;import java.io.IOException;public class FormulaCustomTest {public static void main(String[] args) {int formulaNum;boolean if_MulDiv;int range;boolean ifNeg_AddSub;boolean ifRem_Div;boolean ifRed_Div;int lineNum;Scanner scanner = new Scanner(System.in);System.out.println("请输⼊需要算式个数:");formulaNum=scanner.nextInt();System.out.println("请输⼊需要乘除法(Y/N):");if(scanner.next().equals("y")||scanner.next().equals("Y")){if_MulDiv=true;}else {if_MulDiv=false;}System.out.println("请输⼊需要结果集范围(默认-n~n):");range=scanner.nextInt();System.out.println("请输⼊允许加减法出现负数(Y/N):");if(scanner.next().equals("y")||scanner.next().equals("Y")){ifNeg_AddSub=true;}else {ifNeg_AddSub=false;}System.out.println("请输⼊允许除法出现⼩数(Y/N):");if(scanner.next().equals("y")||scanner.next().equals("Y")){ifRem_Div=true;}else {ifRem_Div=false;}System.out.println("请输⼊允许除法结果换算成分数(Y/N):"); if(scanner.next().equals("y")||scanner.next().equals("Y")){ifRed_Div=true;}else {lineNum=scanner.nextInt();//⽂件名String fileName="";System.out.println("请输⼊算式需要导⼊的⽂件名:");fileName=scanner.next();System.out.println("定制完成,正在随机⽣成算式。
java递归详解递归是一种常见的编程技巧,它在解决问题时通过调用自身来实现。
在Java中,递归是一种强大而灵活的工具,可以用于解决各种问题。
本文将详细介绍Java递归的原理、应用场景以及一些注意事项。
首先,让我们来了解递归的原理。
递归函数是一种特殊的函数,它在执行过程中会调用自身。
递归函数通常包含两个部分:基本情况和递归调用。
基本情况是递归函数停止调用自身的条件,而递归调用是递归函数在满足基本情况之前一直调用自身。
递归函数的执行过程可以用一个栈来模拟。
每次递归调用时,函数的局部变量和参数都会被保存在栈中,直到满足基本情况时才会逐个弹出栈。
这种栈的结构被称为递归栈。
递归在解决问题时具有很大的灵活性。
它可以用于解决各种问题,如计算阶乘、斐波那契数列、二叉树遍历等。
下面我们以计算阶乘为例来说明递归的应用。
计算阶乘是一个经典的递归问题。
阶乘的定义是n的阶乘等于n乘以(n-1)的阶乘,其中0的阶乘定义为1。
我们可以使用递归函数来计算阶乘。
```javapublic class Factorial {public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}public static void main(String[] args) {int n = 5;int result = factorial(n);System.out.println("The factorial of " + n + " is " + result);}}```在上面的代码中,factorial函数是一个递归函数。
当n等于0时,满足基本情况,函数返回1。
否则,函数调用自身,并将n减1作为参数传递给递归调用。
最终,递归函数的返回值是n乘以(n-1)的阶乘。
递归函数的使用需要注意一些问题。
Java的递归算法详解⽬录⼀、介绍1、介绍2、案例⼆、迷宫问题三、⼋皇后问题四、汉诺塔问题1、问题2、思想3、代码总结⼀、介绍1、介绍递归:递归就是⽅法⾃⼰调⽤⾃⼰,每次调⽤时传⼊不同的变量。
递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
迭代和递归区别:迭代使⽤的是循环结构,递归使⽤的选择结构。
使⽤递归能使程序的结构更清晰、更简洁、更容易让⼈理解,从⽽减少读懂代码的时间。
其时间复杂度就是递归的次数。
但⼤量的递归调⽤会建⽴函数的副本,会消耗⼤量的时间和内存,⽽迭代则不需要此种付出。
递归函数分为调⽤和回退阶段,递归的回退顺序是它调⽤顺序的逆序。
分治:当⼀个问题规模较⼤且不易求解的时候,就可以考虑将问题分成⼏个⼩的模块,逐⼀解决。
2、案例兔⼦繁殖的问题。
(斐波那契数列)。
计算 n! 。
任意长度的字符串反向输出。
折半查找算法的递归实现。
汉诺塔问题⼋皇后问题⼆、迷宫问题问题:寻找⼀条从起始点到达终点的有效路径。
代码⽰例:迷宫public class MiGong {/*** 0:该点没有⾛过, 1:表⽰墙, 2:可以⾛, 3:该点已经⾛过,但是⾛不通\ * 策略: 下->右->上->左, 如果该点⾛不通,再回溯*/private int[][] map;private int desX;private int desY;/*** 构建 row*col的迷宫** @param row ⾏* @param col 列*/public MiGong(int row, int col) {if (row <= 0 || col <= 0) {return;}map = new int[row][col];// 默认上下左右全部为墙for (int i = 0; i < col; i++) {map[0][i] = 1;map[row - 1][i] = 1;}for (int i = 0; i < row; i++) {map[i][0] = 1;map[i][col - 1] = 1;}}/*** 在迷宫内部添加挡板** @param i 横坐标* @param j 纵坐标*/public void addBaffle(int i, int j) {if (map == null) {return;}// 外⾯⼀周都是墙if (i > 0 && i < map.length - 1 && j > 0 && j < map[0].length - 1) { map[i][j] = 1;}}/*** 设置迷宫的终点位置** @param desX 横坐标* @param desY 纵坐标*/public void setDes(int desX, int desY) {this.desX = desX;this.desY = desY;}public boolean setWay(int i, int j) {// 通路已经找到if (map[desX][desY] == 2) {return true;} else {if (map[i][j] != 0) {return false;}// map[i][j] == 0 按照策略下->右->上->左递归// 假定该点是可以⾛通.map[i][j] = 2;if (setWay(i + 1, j)) {return true;} else if (setWay(i, j + 1)) {return true;} else if (setWay(i - 1, j)) {return true;} else if (setWay(i, j - 1)) {return true;} else {// 说明该点是⾛不通,是死路map[i][j] = 3;return false;}}}// 显⽰地图public void show() {for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[0].length; j++) {System.out.print(map[i][j] + " ");}System.out.println();}}} 代码⽰例:测试类// 测试类public class Main {public static void main(String[] args) {MiGong miGong = new MiGong(8, 7);miGong.addBaffle(3, 1);miGong.addBaffle(3, 2);miGong.setDes(6, 5); // 设置⽬的地System.out.println("初始地图的情况");miGong.show();miGong.setWay(1, 1); // 设置起始位置System.out.println("⼩球⾛过的路径,地图的情况");miGong.show();}}// 结果初始地图的情况1 1 1 1 1 1 11 0 0 0 0 0 11 0 0 0 0 0 11 1 1 0 0 0 11 0 0 0 0 0 11 0 0 0 0 0 11 0 0 0 0 0 11 1 1 1 1 1 1⼩球⾛过的路径,地图的情况1 1 1 1 1 1 11 2 0 0 0 0 11 2 2 2 0 0 11 1 12 0 0 11 0 02 0 0 11 0 02 0 0 11 0 02 2 2 11 1 1 1 1 1 1三、⼋皇后问题问题:在8×8格的国际象棋上摆放⼋个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同⼀⾏、同⼀列或同⼀斜线上,问有多少种摆法。
递归--四则运算表达式求值输⼊为四则运算表达式,仅由整数、+、-、*、/ 、(、)组成,没有空格,要求求其值。
假设运算符结果都是整数。
"/"结果也是整数解题思想:因为四则运算有优先级,所以在设计递归的时候,需要注意。
这⾥设计为:表达式-项-因⼦-带括号表达式或整数,这⾥只是给了个名称上的定义,可以不⽤具体的纠结什么是项、什么是因⼦,这些名称你都可以⾃⼰定义。
关键的是要好好理解,“+,-”的运算级别最低,“()”括号的运算级别最好,“乘除”居中,因此递归的调⽤也是参照这样来设计的。
表达式可以是⼀个单独的项,也可以是2个项之间进⾏加、减,项可以是因⼦,或者多个因⼦乘除,因⼦是整数或者再是⼀个带括号的表达式。
举个例⼦:2+3*4,读⼊2后,接着读⼊+符号,接下来是不能直接求2+3的,需要继续下⼀项,递归遍历,就是先计算3*4,运算是先返回3个⼀个整数,然后因⼦做*运算,接着继续递归调⽤,返回4是个整数,然后把3*4的结果返回给上⼀个递归调⽤的函数,把这个计算结果求出来后,再与2相加,这样就很好的解决了运算符优先级的问题。
简单理解:Python代码实现:"""输⼊:(2+3)*(5+7)+9/3输出: 63"""#输⼊需要计算的表达式in_exp = ""#表达式的每个字符的位置pos = 0#计算表达式的值def Expression_value():global in_exp,pos#计算第⼀个表达式的值result = Term_value()more = Truewhile more :pos = pos + 1#判断访问list是否越界if (pos >= len(in_exp)):more = Falsebreakop = in_exp[pos]if (op == "+"or op == "-"):pos = pos + 1value = Term_value()if (op == "+"):result += valueelse:result -= valueelse:more = Falsereturn result#计算项的值def Term_value():global in_exp,pos# 计算第⼀个表达式的值result = Factor_value()more = Truewhile (more):pos = pos + 1# 判断访问list是否越界if (pos >= len(in_exp)):more = Falsebreakop = in_exp[pos]if (op == "*"or op == "/"):pos = pos + 1value = Factor_value()if (op == "*"):result *= valueelse:result /= valueelse:pos = pos - 1more = Falsereturn result#计算因⼦的值def Factor_value():global in_exp,posresult = 0c = in_exp[pos]if (c == "("):pos = pos + 1result = Expression_value()else:while (c.isdigit()):result = 10*result + int(c)pos = pos + 1#判断是否超过list的长度if (pos == len(in_exp)):breakc = in_exp[pos]pos = pos - 1#while (isdigit(c))#result = 10 * result + c - '0';#在ASCII编码中, 0~9 的编码是 0x30~0x39, 所以当c在‘0'~'9'的范围中时,c - '0' 就相当于计算c的实际数值, #例如 c 是 '1', 则 c - '0' = 1, 把字符值转为数字值1了return resultdef main():global in_expin_exp = input("请输⼊需要计算的表达式:")rtn = Expression_value()print("表达式: "+in_exp+"的运算结果为:%d" %rtn)if (__name__ == "__main__"):main()。
四则混合运算的算符优先算法Java实现它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。
它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。
举例:(3 + 4) × 5 - 6 就是中缀表达式- × + 3 4 5 6 前缀表达式3 4 + 5 × 6 - 后缀表达式中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。
中缀表达式是人们常用的算术表示方法。
虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。
对计算机来说,计算前缀或后缀表达式的值非常简单。
前缀表达式(前缀记法、波兰式)前缀表达式的运算符位于操作数之前。
前缀表达式的计算机求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。
例如前缀表达式“- × + 3 4 5 6”:(1) 从右至左扫描,将6、5、4、3压入堆栈;(2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;(4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
可以看出,用计算机计算前缀表达式的值是很容易的。
将中缀表达式转换为前缀表达式:遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从右至左扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是右括号“)”,则直接压入S1;(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最左边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。