栈的初步认识
栈的设计
Stack接口
因为栈可以用顺序存储实现也可以用链式存储实现,所以把共性抽取定义出Stack接口
ArrayStack类(栈的顺序存储具体实现)
因为栈本身是一种特殊的线性表,所以我们可以用上一篇博客中完成的ArrayList来实现我们的ArrayStack
public class ArrayStack<E> implements Stack<E> {
//栈的内部用线性表来实现
private ArrayList<E> list;
/**
* 创建默认容量的线性表
*/
public ArrayStack(){
list=new ArrayList<E>();
}
/**
* 创建指定容量的线性表
* @param capacity
*/
public ArrayStack(int capacity){
list=new ArrayList<>(capacity);
}
/**
* 获取线性表中元素个数
* @return
*/
@Override
public int size() {
return list.size();
}
/**
* 判断栈是否为空
* @return
*/
@Override
public boolean isEmpty() {
return list.isEmpty();
}
/**
* 压栈,在表尾添加
* @param element
*/
@Override
public void push(E element) {
list.add(element);
}
/**
* 弹栈一个元素并且返回(在线性表的末尾删除一个元素并且返回)
* @return
*/
@Override
public E pop() {
return list.remove(list.size()-1);
}
/**
* 查看当前栈顶元素(不删除)
* @return
*/
@Override
public E peek() {
return list.get(list.size()-1);
}
/**
* 清空栈
*/
@Override
public void clear() {
list.clear();
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(String.format("ArrayStack:%d/%d[", size(),list.getCapacity()));
if (isEmpty()) {
builder.append("]");//ArrayList:0/10;
} else {
for (int i = 0; i < size(); i++) {
builder.append(list.get(i));
if (i != size() - 1) {
builder.append(",");
} else {
builder.append("]");
}
}
}
return builder.toString();
}
}
十进制和十六进制的互相转换
十进制转为十六进制
public class DecToHex {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入一个十进制数:");
int num=scanner.nextInt();
/**
* 因为会涉及到数字和字母,比如A,B这样的,所以泛型应该是Charcater
* 创建一个栈来存储余数
*/
ArrayStack<Character> stack=new ArrayStack<>();
int mod;
while (num!=0){
//余数入栈
//余数可能是0~9也可能是A~F
mod=num%16;
if (mod<10){
//数字0到9
stack.push((char)(mod+'0'));
}else {
//否则是数字10到15,要转换成A到F
stack.push((char)('A'+mod-10));
}
num/=16;
}
//按照顺序弹栈
while (!stack.isEmpty()){
Character pop = stack.pop();
System.out.print(pop);
}
}
}
十六进制转为十进制
public class HexToDec {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个十六进制的字符串:");
String num = scanner.nextLine();
//创建一个栈,存储每一个字符
ArrayStack<Character> stack = new ArrayStack<>();
for (int i = 0; i < num.length(); i++) {
stack.push(num.charAt(i));
}
// System.out.println(stack);
//依次弹栈并累加计算结果
int sum = 0;
//幂数
int exponent = 0;
char c;
while (!stack.isEmpty()) {
c = stack.pop();
sum += Math.pow(16, exponent) * getNumber(c);
exponent++;
}
System.out.println(sum);
}
/**
* 把字符转换为对应的数字
* 字符是0~9或A~F
*
* @param c
* @return
*/
private static int getNumber(char c) {
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F')) {
throw new IllegalArgumentException("错误的输入十六进制数 " + c);
}
//说明字符是符合十六进制的数字要求的
if (c >= '0' && c <= '9') {
return c - '0';
} else {
return 'A' + c - 10;
}
}
}
判断回文
public class JudgeHw {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.nextLine();
//创建栈
ArrayStack<Character> stack=new ArrayStack<>();
char c;
for (int i = 0; i < str.length(); i++) {
//判断字符串的长度是奇数还是偶数
//如果是奇数的话,则把中间数据过滤掉,不需要压栈
if (str.length()%2==1&& i==str.length()/2){
continue;
}
c=str.charAt(i);
//如果栈空,则入栈
if (stack.isEmpty()){
stack.push(c);
}else{
if (stack.peek()==c){
stack.pop();
}else {
//不相等则入栈
stack.push(c);
}
}
//栈如果非空,则比较栈顶元素和待入栈元素是否相等,如果不相等,则入栈
//如果相等,则出栈
}
//如果最后栈空,则是回文
if (stack.isEmpty()){
System.out.println("是回文");
}else{
System.out.println("不是回文");
}
}
}
有效的括号
20.有效的括号
思路分析
- 遇到左括号就入栈
- 如果遇到右括号
- 看看栈顶是否有元素 ,如果栈为空,说明无法匹配
- 如果栈顶有元素,但是括号不匹配,则说明无法匹配
- 所有字符扫描完毕后,如果栈空,说明有效,否则无效
class Solution {
public boolean isValid(String s) {
Stack<Character> stack=new Stack<>();
int len=s.length();
for (int i = 0; i < len; i++) {
char c=s.charAt(i);
if(c=='('||c=='['||c=='{'){
//入栈
stack.push(c);
}else{
//否则就是右括号
//如果栈是空的,则无法匹配
if (stack.isEmpty()) return false;
//如果栈非空,则出栈进行匹配
Character pop = stack.pop();
if (pop=='(' && c!=')') return false;
if (pop=='{'&& c!='}') return false;
if (pop=='['&& c!=']') return false;
}
}
//所有字符扫描完毕后,如果栈空,说明有效,否则无效
return stack.isEmpty();
}
}