数据结构:栈及其应用

news/2024/11/25 19:41:28/

  • 栈的初步认识
  • 栈的设计
    • Stack接口
    • ArrayStack类(栈的顺序存储具体实现)
  • 十进制和十六进制的互相转换
    • 十进制转为十六进制
    • 十六进制转为十进制
  • 判断回文
  • 有效的括号
  • 逆波兰表达式求值

栈的初步认识

在这里插入图片描述

栈的设计

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*/@Overridepublic int size() {return list.size();}/*** 判断栈是否为空* @return*/@Overridepublic boolean isEmpty() {return list.isEmpty();}/*** 压栈,在表尾添加* @param element*/@Overridepublic void push(E element) {list.add(element);}/*** 弹栈一个元素并且返回(在线性表的末尾删除一个元素并且返回)* @return*/@Overridepublic E pop() {return list.remove(list.size()-1);}/*** 查看当前栈顶元素(不删除)* @return*/@Overridepublic E peek() {return list.get(list.size()-1);}/*** 清空栈*/@Overridepublic void clear() {list.clear();}@Overridepublic Iterator<E> iterator() {return list.iterator();}@Overridepublic 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~Fmod=num%16;if (mod<10){//数字0到9stack.push((char)(mod+'0'));}else {//否则是数字10到15,要转换成A到Fstack.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();}
}

逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

注意 两个整数之间的除法只保留整数部分。

可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
在这里插入图片描述

这道题目可以遍历一下字符串,如果是字符是数字的话,则入栈,如果为运算符,则把栈顶的两个元素弹出,进行运算,注意它们的顺序,栈是后进先出的特点,如果是减法或除法,注意:是后面弹出的数减去或者除去前面弹出的一个数,然后把运算结果存入栈中

class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for(int i = 0; i <tokens.length;i++){String str = tokens[i];//获取下标为 i 字符串元素if(isOperator(str)){// 如果 str 是运算符 为 true,否则为falseint num2 = stack.pop();// 获取 栈顶 的 两个数字数据(出栈)int num1 = stack.pop();switch(str){// 判断 str 具体是 哪一个字符串,就执行对应的运算,并将其结果入栈case "+":stack.push(num1 + num2);break;case "-":stack.push(num1 - num2);break;case "*":stack.push(num1 * num2);break;case "/":stack.push(num1 / num2);break;}}else{// 将 数字字符转换成 整形数据 存入 栈中stack.push(Integer.parseInt(str));}}return stack.pop();// 返回/出栈   最终存入栈中的结果}public boolean isOperator(String s){// 判断 str 是运算符 返回 true;否则,返回 falseif(s.equals("+") || s.equals("-")|| s.equals("*") || s.equals("/")){return true;}return false;}
}

http://www.ppmy.cn/news/606277.html

相关文章

LeetCode简单题之反转字符串

题目 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&#xff1a; 输入&#xff1a;s [“h”,“e”,“l”,…

pytorch nn.Embedding

pytorch nn.Embeddingclass torch.nn.Embedding(num_embeddings, embedding_dim, padding_idxNone, max_normNone, norm_type2, scale_grad_by_freqFalse, sparseFalse) num_embeddings (int) - 嵌入字典的大小 embedding_dim (int) - 每个嵌入向量的大小 padding_idx (int, op…

LeetCode简单题之Fizz Buzz

题目 给你一个整数 n &#xff0c;找出从 1 到 n 各个整数的 Fizz Buzz 表示&#xff0c;并用字符串数组 answer&#xff08;下标从 1 开始&#xff09;返回结果&#xff0c;其中&#xff1a; answer[i] “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。 answer[i] “Fizz” 如果…

chown:修改权限

参考文章&#xff1a;Linux 命令&#xff08;31&#xff09;: chown 命令 功能&#xff1a;通过 chown 改变文件的拥有者和群组。在更改文件的所有者或所属群组时&#xff0c;可以使用用户名称和用户识别码设置。普通用户不能将自己的文件改变成其他的拥有者。其操作权限一般为…

[Spring MVC学习01] Spring MVC环境搭建以及工作流程了解

1.Spring MVC的初步了解1.1MVC是什么1.2 Spring MVC 是什么1.3Spring MVC可以帮我们做什么1.4工作原理2.Spring MVC环境搭建2.1开发环境2.2新建maven webapp2.3pom.xml坐标添加2.4配置web.xml2.5springmvc.xml配置2.6页面控制器的编写2.7添加视图页面2.8启动Tomcat服务器2.9第一…

python 直接if判断和is not None的区别

tmpName if tmpName: print tmpName #没有输出 if tmpName is not None: print tmpName #有输出&#xff0c;是空行

LeetCode简单题之旋转字符串

题目 给定两个字符串, A 和 B。 A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A ‘abcde’&#xff0c;在移动一次之后结果就是’bcdea’ 。如果在若干次旋转操作之后&#xff0c;A 能变成B&#xff0c;那么返回True。 示例 1: 输入: A ‘abcde’, B ‘cdeab…

[Spring MVC学习02]URL地址映射

1.RequestMapping的介绍2.映射单个URL3.映射多个URL4.映射URL在控制器上5.RequestMapping的常用属性5.1value属性5.2method属性5.3params属性6.小结1.RequestMapping的介绍 通过RequestMapping&#xff0c;我们可以把请求地址和方法进行绑定的&#xff0c;可以在类、方法上进行…