Java栈的实现与简单应用

上一篇博客我们实现了动态数组,今天我们对动态数组进行封装实习我们常用的数据结构栈。

//接口定义
public interface Stack<E> extends Iterable<E> {
	public void push(E e);
	public E pop();
	public E peek();
	public boolean isEmpty();
	public int size();
	public void clear();
}
public class ArrayStack<E> implements Stack<E> {
	//使用动态数组实现栈
	private ArrayList<E> list ; 
	public ArrayStack() {
		list=new ArrayList<>();
	}
	@Override
	public void push(E e) {
		list.add(e);
	}

	@Override
	public E pop() {
		E ret=list.get(list.size()-1);
		list.remove(list.size()-1);
		return ret;
	}

	@Override
	public E peek() {
		return list.get(list.size()-1);
	}

	@Override
	public boolean isEmpty() {
		return list.isEmpty();
	}

	@Override
	public int size() {
		return list.size();
	}

	@Override
	public void clear() {
		list.clear();
		
	}
	@Override
	public Iterator<E> iterator() {
		return list.iterator();
	}
	@Override
	public String toString() {
		return list.toString();
	}

}

我们来看看栈的常见应用
1.进制的转换

/**
 * 该类主要使用栈实现进制转换的内容
 * @author 上杉
 */
public class NumberSystemConversion {
	public static void main(String[] args) {
		int dec=65536;
		String hex=decToHex(dec);
		 dec=hexToDec(hex);
		 System.out.println(hex);
		 System.out.println(dec);
	}
	private NumberSystemConversion() {
		
	}
	public static String decToHex(int dec) {
		Stack<Integer> stack=new ArrayStack<>();
		while(dec>0) {
			stack.push(dec%16);
			dec/=16;
		}
		StringBuilder res=new StringBuilder();
		while(!stack.isEmpty()) {
			int num=stack.pop();
			if(num<10) {
				res.append(num);
			} else {
				res.append('A'+num-10);
			}
		}
		return res.toString();
	}
	public static int hexToDec(String hex) {
		Stack<Integer> stack=new ArrayStack<>();
		for(int i=0;i<hex.length();i++) {
			char c=hex.charAt(i);
			if(!(c>='0'&&c<='9'||c>='A'&&c<='F')) {
				throw new IllegalArgumentException("wrong char "+c);
			}
			if(c>='0'&&c<='9') {
				stack.push(c-'0');
			}else {
				stack.push(c-'A'+10);
			}
		}
		int exponent =0;
		int sum=0;
		while(!stack.isEmpty()) {
			sum+=stack.pop()*Math.pow(16,exponent);
			exponent++;
		}
		return sum;
	}
}

2.括号的匹配

/**
 * 该类主要实现对一个只含有括号的字符串进行匹配
 * @author 上杉
 */

public class BracketMatch {
	public static void main(String[] args) {
		String expression ="{[()<>]()}()[]";
		Stack<Character> stack=new ArrayStack<>();
		for(int i=0;i<expression.length();i++) {
			char c=expression.charAt(i);
			if(stack.isEmpty()||(c-stack.peek()!=1&&c-stack.peek()!=2)) {
				stack.push(expression.charAt(i));
			}else {
				stack.pop();
			}
		}
		if(stack.isEmpty()) {
			System.out.println(expression + " 是匹配的");
		}else {
			System.out.println(expression + " 不是匹配的");
		}
	}
}

3.判断是否为回文串

//该类主要实现了一个字符串是否为回文串
//为了练习栈的使用所以这里采取栈实现,其实使用双指针效率更高一些
public class JudgingPalindrome {
	public static void main(String[] args) {
		String expression ="上海自来水来自海上";
		Stack<Character> stack=new ArrayStack<>();
		for(int i=0;i<expression.length();i++) {
			if(expression.length()%2==1&&i==expression.length()/2) {
				continue;
			}else {
				if(i<expression.length()/2) {
					stack.push(expression.charAt(i));
				}else {
					if(stack.peek()!=expression.charAt(i)) {
						break;
					}
					stack.pop();
				}
			}
		}
		if(stack.isEmpty()) {
			System.out.println(expression+" 是回文串");
		}else {
			System.out.println(expression+" 不是回文串");
		}
	}
}

4.前缀中缀后缀表达式的计算与转换
(1)中缀表达式的计算

/**
 * 
 * @author 上杉
 *在表达式的计算范围栈的计算应用的非常广泛、
 *本类主要使用栈来完成中缀表达式的计算
 */
public class InfixCalculator {
	public static void main(String[] args) {
		String infix="(5+2*4+4/2)/2+8-6";
		int result=getResult(infix);
		System.out.println(result);
		
	}

	private static int getResult(String infix) {
		infix=expressionFormat(infix);
		String[] spilt=infix.split(" ");
		Stack<Character> opers=new ArrayStack<>();
		Stack<Integer> nums=new ArrayStack<>();
		for(String s:spilt) {
			if(s.length()==0) {
				continue;
			}
			if(s.charAt(0)=='(') {
				opers.push(s.charAt(0));
			} else if(s.charAt(0)==')') {
				while(opers.peek()!='(') {
					processAnOper(opers,nums);
				}
				opers.pop();
			}else if(s.charAt(0)=='*'||s.charAt(0)=='/'){
				while(!opers.isEmpty()&&(opers.peek()=='*'||opers.peek()=='/')) {
					processAnOper(opers,nums);
				}
				opers.push(s.charAt(0));
			}else if(s.charAt(0)=='+'||s.charAt(0)=='-') {
				while(!opers.isEmpty()&&opers.peek()!='(') {
					processAnOper(opers,nums);
				}
				opers.push(s.charAt(0));
			}else {
				nums.push(Integer.valueOf(s));
			}
		}
		while(!opers.isEmpty()) {
			processAnOper(opers,nums);
		}
		return nums.pop();
	}

	private static void processAnOper(Stack<Character> opers, Stack<Integer> nums) {
		char oper=opers.pop();
		int num1=nums.pop();
		int num2=nums.pop();
		switch(oper) {
		case '+':
			nums.push(num2+num1);
			break;
		case '-':
			nums.push(num2-num1);
			break;
		case '*':
			nums.push(num2*num1);
			break;
		case '/':
			nums.push(num2/num1);
			break;
		}
		
	}

	public static String expressionFormat(String infix) {
		StringBuilder res=new StringBuilder();
		for(int i=0;i<infix.length();i++) {
			char c=infix.charAt(i);
			if(Character.isDigit(c)) {
				res.append(c);
			}else {
				res.append(" ");
				res.append(c);
				res.append(" ");
			}
		}
		return res.toString();
	}
}

(2)中缀表达式转后缀表达式

public class InfixToSuffix {
	public static void main(String[] args) {
		String infix="(5+2*4+4/2)/2+8-6";
		String suffix=getSuffix(infix);
		System.out.println(suffix);
	}
	public static String getSuffix(String infix) {
		infix=InfixCalculator.expressionFormat(infix);
		String[] split=infix.split(" ");
		Stack<Character> opers=new ArrayStack<>();
		List<String> list =new ArrayList<>();
		for(String s:split) {
			if(s.length()==0) {
				continue;
			}
			if(s.charAt(0)=='(') {
				opers.push(s.charAt(0));
			}else if(s.charAt(0)==')') {
				while(opers.peek()!='(') {
					list.add(opers.pop()+"");
				}
				opers.pop();
			}else if(s.charAt(0)=='+'||s.charAt(0)=='-') {
				while(!opers.isEmpty()&&opers.peek()!='(') {
					list.add(opers.pop()+"");
				}
				opers.push(s.charAt(0));
			}else if(s.charAt(0)=='*'||s.charAt(0)=='/') {
				while(!opers.isEmpty()&&(opers.peek()=='*'||opers.peek()=='/')) {
					list.add(opers.pop()+"");
				}
				opers.push(s.charAt(0));
			}else {
				list.add(s);
			}
		}
		while(!opers.isEmpty()) {
			list.add(opers.pop()+"");
		}
		StringBuilder str=new StringBuilder();
		for(String s:list) {
			str.append(s+" ");
		}
		return str.toString();
	}
}

(3)后缀表达式的计算

public class SuffixCalculator {
	public static void main(String[] args) {
		String suffix="5 2 4 * + 4 2 / + 2 / 8 + 6 - ";
		int res=getResult(suffix);
		System.out.println(res);
	}
	public static int getResult(String suffix) {
		String[] spilt=suffix.split(" ");
		Stack<Integer> nums=new ArrayStack<>();
		for(String s:spilt) {
			if(s.length()==0) {
				continue;
			}
			if(s.charAt(0)=='+'||s.charAt(0)=='-'||s.charAt(0)=='*'||s.charAt(0)=='/') {
				processAnOper( s.charAt(0) , nums);
			}else {
				nums.push(Integer.valueOf(s));
			}
		}
		return nums.pop();
	}

	private static void processAnOper(char oper,Stack<Integer> nums) {
		int num1=nums.pop();
		int num2=nums.pop();
		switch(oper) {
		case '+':
			nums.push(num2+num1);
		break;
		case '-':
			nums.push(num2-num1);
		break;
		case '*':
			nums.push(num2*num1);
		break;
		case '/':
			nums.push(num2/num1);
		break;
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值