Java数据结构与算法解题集(持续更新)

题目1
  1. 正文:
    输入一个字符串类型的算术表达式子,返回一个数值,表示它的计算结果
    例如:输入:“7+1021+4-5” ,输出:72。

  2. 思路分析:

    • 首先需要遍历这个字符串,然后将每一个字符都进行判断然后分类
    • 如果是一个数字改如何处理?如果是一个运算符又如何处理?
    • 显然,这里的难点在于运算符是有优先级的,当前运算符能否直接运算取决于下一个运算符的优先级,所以我们得根据下一运算符的优先级来判断当前的运算符,反过来说,我们可以根据当前运算符与上一个运算符优先级的比较来确定运算顺序
    • 我们以人的思维来计算这一串的运算表达式
      	7+10*2*1+4-5
      	=7+10*2+4-5
      	=7+20+4-5
      	=27+4-5
      	=31-5
      	=26
      
    • 从上面的式子可以知道,我们将暂时不运算的式子存储在容器中,然后通过运算符优先级的判断来决定是否进行当前运算(如果是后面的运算的优先级小于当前运算符的优先级,则直接运算;否则需要存储在容器中,再往后看一个运算符)
    • 显然后面一个运算符是比较对象,所以我们将比较的顺序变成当前运算符和前一个运算符之间的优先级比较,显然比较是从第二个运算符开始。
  3. 实现:

    • 用一个数栈来存储数值,用一个符号栈来存储运算符
    • 遍历字符串类型的算术表达式
      • 如果是数值,直接入栈
      • 如果是运算符分情况讨论:
        • 如果栈中没有运算符,直接压入栈中
        • 如果栈中有运算符,则比较运算符的优先级
          • 如果优先级大于栈顶的运算符,则压入栈中
          • 如果优先级小于或等于栈顶运算符,则从数栈中取出两个数,从运算符栈中取出一个运算符进行计算,然后将运算的结果压入数栈,最后把当前运算符压入栈中
    • 遍历完成之后,如果符号栈不为空,则重复执行取出数值和运算符运算,然后将结果压入数栈的步骤,
    • 最后当符号栈中的数被取完,数栈中的元素只有一个时,把它取出即为最后的结果
  4. 代码:

    	public static void main(String[] args) {
    //		System.out.println((int)'0');//0的符号的值为48,数值和字符型的数字相差48,数值=数字-48
    
    		System.out.println(count("1*3/2+4+7+8+7"));
    	}
    	/**
    	 * 实现方法
    	 * @param exp 表达式的字符串
    	 * @return 最总的结果
    	 */
    	public static Double count(String exp) {
    //		1.创建两个栈,一个是数栈,一个是符号栈
    		Stack<Double> num = new Stack<>();
    		Stack<Character> ope = new Stack<Character>();
    		char c = '0';
    		for(int index=0;index < exp.length();index++) {
    			c = exp.charAt(index);
    			if(isOperational(c)) {//判断是否是运算符
    				if(ope.isEmpty()||precedence(c,ope.peek())){//如果栈为空,或者优先级较高,则直接压入栈中
    					ope.push(c);
    				}else {//
    					double a = num.pop();
    					double b = num.pop();
    					char ch = ope.pop();
    					num.push(count(b,a,ch));
    					ope.push(c);
    					
    				}
    			}else {//如果不是运算符,则该字符为数字,直接入栈
    				num.push((double) (c-48));
    			}
    			
    		}
    		while(num.size()>=2) {
    			Double a = num.pop();
    			Double b = num.pop();
    			char ch = ope.pop();
    			num.push(count(a,b,ch));
    		}
    		return num.pop();
    	}
    //	判断是不是数字字符
    	public static boolean isOperational(char ch) {
    		return ch<48;
    	}
    //	判断字符的优先级
    	public static boolean precedence(char a,char b) {
    		double ap = 0;double bp = 0;
    		if(a=='-'||a=='+') {
    			ap = 0;
    		}else {
    			ap = 1;
    		}
    		if(b=='-'||b=='+') {
    			bp = 0;
    		}else{
    			bp = 1;
    		}
    		
    		return ap>bp;
    	}
    //	运算输入的字符
    	public static double count(double a,double b,char c) {
    		if(c=='+') {
    			return a+b;
    		}
    		if(c=='-') {
    			return a-b;
    		}
    		if(c=='*') {
    			return a*b;
    		}
    		if(c=='/'&& b != 0) {
    			return a/b;
    		}else {
    			System.out.println("没有找到结果");
    			return -9999999;
    		}
    	}
    }
    
  5. 改进:多位数的四则运算

	public static void main(String[] args) {
//		System.out.println((int)'0');//0的符号的值为48,数值和字符型的数字相差48,数值=数字-48
//		System.out.println((int)'/');
		//'+' 43
		//'-' 45
		//'*' 42
		//'/' 47
		System.out.println(count("200000/10"));//只能做个位数的加减
	}
	/**
	 * 实现方法
	 * @param exp 表达式的字符串
	 * @return 最总的结果
	 */
	public static Double count(String exp) {
//		1.创建两个栈,一个是数栈,一个是符号栈
		Stack<Double> num = new Stack<>();
		Stack<Character> ope = new Stack<Character>();
		char c = '0';
		String keepNum="";
		for(int index=0;index < exp.length();index++) {
			c = exp.charAt(index);
			if(isOperational(c)) {//判断是否是运算符
				if(ope.isEmpty()||precedence(c,ope.peek())){//如果栈为空,或者优先级较高,则直接压入栈中
					ope.push(c);
				}else {//栈部
					double a = num.pop();
					double b = num.pop();
					char ch = ope.pop();
					num.push(count(b,a,ch));
					ope.push(c);
					
				}
			}else {//如果不是运算符,则该字符为数字,直接入栈
				keepNum +=c;
				if(index==exp.length()-1) {
					num.push((double) Integer.parseInt(keepNum));
					
				}else if(isOperational(exp.substring(index+1,index+2).charAt(0))) {
					num.push((double) Integer.parseInt(keepNum));
					//重要 keepNum清空
					keepNum = "";
				}
			}
			
		}
		while(num.size()>=2) {
			Double a = num.pop();
			Double b = num.pop();
			char ch = ope.pop();
			num.push(count(b,a,ch));
		}
		return num.pop();
	}
//	判断是不是数字字符
	public static boolean isOperational(char ch) {
		return ch<48;
	}
//	判断字符的优先级
	public static boolean precedence(char a,char b) {
		double ap = 0;double bp = 0;
		if(a=='-'||a=='+') {
			ap = 0;
		}else {
			ap = 1;
		}
		if(b=='-'||b=='+') {
			bp = 0;
		}else{
			bp = 1;
		}
		
		return ap>bp;
	}
//	运算输入的字符
	public static double count(double a,double b,char c) {
		if(c=='+') {
			return a+b;
		}
		if(c=='-') {
			return a-b;
		}
		if(c=='*') {
			return a*b;
		}
		if(c=='/'&& b != 0) {
			return a/b;
		}else {
			System.out.println("没有找到结果");
			return -9999999;
		}
	}
	
	```
	
1.和队列的共同特点是(只允许在端点处插入和删除元素) 4.通常采用的两种存储结构是(线性存储结构和链表存储结构) 5.下列关于的叙述正确的是(D) A.是非线性结构B.是一种树状结构C.具有先进先出的特征D.有后进先出的特征 6.链表不具有的特点是(B)A.不必事先估计存储空间 B.可随机访问任一元素 C.插入删除不需要移动元素 D.所需空间与线性表长度成正比 7.用链表表示线性表的优点是(便于插入和删除操作) 8.在单链表中,增加头结点的目的是(方便运算的实现) 9.循环链表的主要优点是(从表中任一结点出发都能访问到整个链表) 10.线性表L=(a1,a2,a3,……ai,……an),下列说法正确的是(D) A.每个元素都有一个直接前件和直接后件 B.线性表中至少要有一个元素 C.表中诸元素的排列顺序必须是由小到大或由大到小 D.除第一个和最后一个元素外,其余每个元素都有一个且只有一个直接前件和直接后件 11.线性表若采用链式存储结构时,要求内存中可用存储单元的地址(D) A.必须是连续的 B.部分地址必须是连续的C.一定是不连续的 D.连续不连续都可以 12.线性表的顺序存储结构和线性表的链式存储结构分别是(随机存取的存储结构、顺序存取的存储结构) 13.树是结点的合,它的根结点数目是(有且只有1) 14.在深度为5的满二叉树中,叶子结点的个数为(31) 15.具有3个结点的二叉树有(5种形态) 16.设一棵二叉树中有3个叶子结点,有8个度为1的结点,则该二叉树中总的结点数为(13) 17.已知二叉树后序遍历序列是dabec,中序遍历序列是debac,它的前序遍历序列是(cedba) 18.已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为(DGEBHFCA) 19.若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是(gdbehfca) 20.数据库保护分为:安全性控制、 完整性控制 、并发性控制和数据的恢复。 1. 在计算机中,算法是指(解题方案的准确而完整的描述) 2.在下列选项中,哪个不是一个算法一般应该具有的基本特征(无穷性) 说明:算法的四个基本特征是:可行性、确定性、有穷性和拥有足够的情报。 3. 算法一般都可以用哪几种控制结构组合而成(顺序、选择、循环) 4.算法的时间复杂度是指(算法执行过程中所需要的基本运算次数) 5. 算法的空间复杂度是指(执行过程中所需要的存储空间) 6. 算法分析的目的是(分析算法的效率以求改进) ............ .................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值