大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

Java堆棧

堆棧的應用

棧的特點: 后進先出

進制轉換

package com.bjpowernode.stack;
/**
 * 使用棧完成進制轉換
 * @author 北京動力節點老崔
 */
public class TestBaseConversion {

	public static void main(String[] args) {
		// 
		System.out.println( convert(100, 2));
		System.out.println( convert(100, 8));
//		System.out.println( convert(100, 16));
		
	}
	/**
	 * 把一個十進制整數 num轉換為decimal指定的進制
	 * @param num		接收十進制整數
	 * @param decimal	指定進制
	 * @return		返回num這個整數對應 的decimal進制的字符串
	 */
	public static String convert(int num,  int decimal) {
		MyArrayStack stack = new MyArrayStack(); 		//保存余數
		int  remainder = num % decimal ; 		//余數
		while( num != 0 ) {
			stack.push( remainder ); 		//余數壓棧
			num = num / decimal;
			remainder = num % decimal ; 
		}
		
		//出棧,余數倒序
		StringBuilder sb = new StringBuilder();
		while( !stack.isEmpty() ) {
			sb.append( stack.pop() );
		}
		
		return sb.toString();
	}

}

檢測表達式中括弧是否匹配

假設表達式中包含三種括弧: 小括弧(), 中括弧[], 大括弧{}, 這三種括弧可以任意嵌套;

(3+5) * [ 3-6] -{23/4}+([{}])

對于任意一個左括弧都需要有一個相應 的右括弧匹配, 最早出現的右括弧應該與最早出現的左括弧匹配. 符合棧的特點。

算法:

• 讀取整個表達式, 如果是左括弧就直接入棧,等待與它對應的右括弧出現;

• 如果是右括弧, 則與當前棧頂的左括弧判斷是否匹配

• 如果不匹配,說明表達式不合法

• 如果是右括弧, 棧已空, 表示不合法

• 讀完整個表達式, 堆棧不空, 表示有左括弧沒匹配上, 表達式不合法; 讀完整個表達式,棧是空的表示所有括弧都能匹配。

package com.bjpowernode.stack;
/**
 * 檢測表達式中的括弧是否匹配
 * @author 北京動力節點老崔
 */
public class TestBracketMatch {

	public static void main(String[] args) {
		// 
		System.out.println( bracketMatch("([{}])"));
		System.out.println( bracketMatch("([{(}])"));
		System.out.println( bracketMatch("([{}]))"));
	}
	
	//檢測expression表達式 中的括弧是否匹配
	public static boolean bracketMatch(String expression) {
		MyArrayStack stack = new MyArrayStack()	;			//保存左括弧
		//遍歷整個表達式, 如果是左括弧就入棧, 如果是右括弧,就出棧進行判斷是否匹配
		for( int i = 0 ;  i < expression.length(); i++) {
			//取出表達式的每個字符
			char cc = expression.charAt(i); 
			switch (cc) {
			case '(':
			case '[':
			case '{':
				stack.push(cc);  	//左括弧入棧, Java可以自動裝箱與拆箱
				break;
			case '}':
				if ( !stack.isEmpty() && stack.pop().equals('{')) {
					break;
				}else {
					return false;
				}
			case ']':
				if ( !stack.isEmpty() && stack.pop().equals('[')) {
					break;
				}else {
					return false;
				}
			case ')':
				if ( !stack.isEmpty() && stack.pop().equals('(')) {
					break;
				}else {
					return false;
				}
				
			}
		}
		
		//表達式遍歷完后,如果棧是空的,表示括弧匹配, 
		if (stack.isEmpty()) {
			return true;
		}else {
			return false;
		}
		
	}

}

算術表達式的求值

1、四則運算的規則 :

先乘除后加減

先括弧內再括弧外

從左到右進行運算

2、表達式:

4 + 3 + ( 6 - 10 + 2*3) * 4

7 + ( 6 - 10 + 2*3) * 4

7 + ( -4 + 2*3) * 4

7 + ( -4 + 6) * 4

7 + 2 * 4

7 + 8

15

3、算法思路:

① 定義兩個棧, 一個存儲操作符operator, 一個存儲操作數operand

② 讀取表達式, 如果是操作數就存儲到operand操作數棧

如果是操作符

• 操作符棧是空, 直接入棧

• 把操作符棧中的棧頂操作符與當前操作符進行優先級比較;

當前操作符優先級高, 操作符入棧;

當前操作符優先級低(棧頂操作符優先級高), 彈出棧頂操作符,從操作數棧中彈出兩個操作數進行運算, 把運算結果存儲到操作數棧中, 繼續判斷當前操作符與棧頂操作符的優先級。

③ 遍歷完整個表達式, 兩個棧都不為空, 依次彈出操作符opertor棧中的運算符與操作數棧中的兩個操作數進行計算 , 把結果再存儲到操作數棧中。

④ 如果操作符棧不為空, 或者操作數棧中的數不止有一個, 則表達式錯誤。

package com.bjpowernode.stack;
/**
 * 使用棧計算算術表達式的值
 * @author 北京動力節點老崔
 */
public class TestCalculateExpression {

	public static void main(String[] args) {
		// 
		String expression = "4+3+(6-10+2*3)*4";
		double result = calculate( expression );
		System.out.println( result );
	}
	//定義方法計算 指定表達式的值 :  6834+3+(6-10+2*3)*43
	private static double calculate(String expression) {
		MyArrayStack operatorStack = new MyArrayStack(); 	//存儲操作符
		MyArrayStack operandStack = new MyArrayStack(); 	//存儲操作數
		//遍歷表達式中的操作數與操作符
		for( int i = 0 ;  i < expression.length() ; i++ ) {
			char cc = expression.charAt(i);
			//如果cc是數字
			if ( Character.isDigit(cc)) {
				//取出操作數
				StringBuilder sb = new StringBuilder();
				//只要是數字就是操作數的一部分
				while( Character.isDigit(cc)) {
					sb.append(cc);			//6
					i++; 					//取下個字符
					if ( i >= expression.length() ) { 	//表達式結束 
						break;
					}
					cc = expression.charAt(i); 		//取下個字符
				}
				//操作數入棧
				operandStack.push(sb.toString());
				//修正i變量的值
				i--;
//				System.out.println( sb );
			}else { 	//如果是操作符
				//4+3+(6-10+2*3)*4
				//1)棧為空, 直接把操作符入棧
				if (operatorStack.isEmpty()) {
					operatorStack.push(cc);
					continue;
				}
				//2)操作符棧不為空的情況
				while( !operatorStack.isEmpty()) {
					char op1 = (char) operatorStack.peek();
					//判斷棧中運算符與當前運算符的優先級
					if ( compareOperator(op1, cc) < 0 ) {
						//當前運算符的優先級高于棧頂運算符的優先級
						operatorStack.push(cc);
						break;
					}else if ( compareOperator(op1, cc) == 0) {
						//當前運算符的優先級等于 棧頂運算符的優先級, 只有一種 情況, 左一半小括弧遇到右一半小括弧的情況
						operatorStack.pop() ; 		//棧中左一半小括弧出棧
						break;
					}else { 	//棧頂運算符優先級高
						//取出兩個操作數
						if (operandStack.isEmpty()) {
							throw new RuntimeException("表達式錯誤");
						}
						double num1 = Double.parseDouble(operandStack.pop().toString());
						if (operandStack.isEmpty()) {
							throw new RuntimeException("表達式錯誤");
						}
						double num2 = Double.parseDouble(operandStack.pop().toString());
						//取棧頂運算符
						char  operator = (char) operatorStack.pop();
						//計算   num2 op  num1
						double result = compute(operator , num2, num1 );
						//把結果存儲到操作數棧中
						operandStack.push(result);
						//如果當前操作符棧為空, 新的操作符入棧
						if ( operatorStack.isEmpty()) {
							operatorStack.push(cc);
							break;
						}
					}
				}
				
			}
		}
		
		//當表達式 遍歷完后, 如果操作符棧不為空, 需要繼續計算 
		while( !operatorStack.isEmpty()) {
			char operator = (char) operatorStack.pop();
			//如果操作數棧為空, 表達式錯誤
			if (operandStack.isEmpty()) {
				throw new RuntimeException("表達式錯誤");
			}
			double num1 = Double.parseDouble(operandStack.pop().toString());
			if (operandStack.isEmpty()) {
				throw new RuntimeException("表達式錯誤");
			}
			double num2 = Double.parseDouble(operandStack.pop().toString());
			double result = compute(operator , num2, num1 );
			operandStack.push(result);
		}
		//當操作符棧為空, 操作數棧中多于一個數, 表達式錯誤
		if ( operandStack.getSize() > 1) {
			throw new RuntimeException("表達式錯誤");
		}
		
		return Double.parseDouble(operandStack.pop().toString());
	}
	//計算 num1  op num2 表達式的值
	private static double compute(char operator, double num1, double num2) {
		switch (operator) {
		case '+':
			return num1 + num2;
			
		case '-':
			return num1 - num2;
			
		case '*':
			return num1 * num2;
			
		case '/':
			return num1 / num2;
		}
		return 0;
	}
	//判斷兩個運算符的優先級 ,如果op1優先級高返回正數, op2優先級高返回負數
	private static int compareOperator(char op1, char op2) {
		if ( op1 == '+' || op1 == '-') {
			if (op2 == '*' || op2 =='/' || op2 =='(') {
				//第一個運算符是 +-, 第二個運算符是 * / (
				return -1;
			}
		}
		if (op1 =='*' || op1 =='/') {
			if ( op2 =='(') {
				//第一個是*/, 第二個是(
				return -1;
			}
		}
		if ( op1 == '(') {
			if (op2 == ')') {
				return 0;
			}else {
				return -1;
			}
		}
		return 1;
	}

}

 

全部教程
主站蜘蛛池模板: 99影视在线视频免费观看 | 手机看高清特黄a大片 | 国产一级片毛片 | 狠狠操天天操视频 | 欧美高清亚洲欧美一区h | 一级成人毛片免费观看 | 欧美一级成人一区二区三区 | 久久这里只有精品18 | 久久久精品成人免费看 | 久操成人 | 人与拘一级a毛片 | 久久精品国产精品2020 | 最新国产在线精品91尤物 | 看一级特黄a大一片 | 日本特级爽毛片叫声 | 黑人和黑人激情一级毛片 | 完整日本特级毛片 | 免费不卡| 最近中文字幕在线 | 中文 | 欧美在线观看a | 免费一级a毛片免费观看欧美大片 | 色综合a | 国产成人精品久久一区二区三区 | 一级aaa级毛片午夜在线播放 | 中文字幕一区二区三区 精品 | 在线视频欧美日韩 | 暗香影院午夜国产精品 | 日韩欧国产精品一区综合无码 | 成人黄色网 | 波多野结衣一区在线观看 | 亚洲va国产日韩欧美精品色婷婷 | 久久精品一| 亚洲精品国产成人中文 | 伊人青青草视频 | 亚洲最新视频在线观看 | 国产精品欧美韩国日本久久 | 神马影院午夜我不卡 | 成人a免费α片在线视频网站 | 99免费精品| 麻豆一区二区三区在线观看 | 色老头久久久久久久久久 |