数据结构与算法2
栈的应用
中缀表达式转后缀表达式
- 后缀表达式
1、中缀表达式:(10 + 20 /2 * 3)/2 + 8
2、后缀表达式: 10 20 2 / 3 * + 2/ 8 +
方便计算机计算,但对用户不友好
遍历字符串: 如果是数字 就直接进线性表中,如果是字符(看栈顶元素的优先级是否高于遍历到的元素,如果高于,则出栈,进线性表。否则进栈)
后缀表达式的计算
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class ProstfixExpression {
/*
中缀表达式转后缀表达式
*/
public static void main(String[] args) {
String s = "(10+20/2*3)/2+8";
String s1 = prost(s);
//System.out.println(s1);
String[] s2 = s1.split(" ");
// for(int i = 0;i < s2.length;i++){
// System.out.println(s2[i]);
// }
List<String> inter = Inter(s2);
//System.out.println(inter);
//后缀表达式的计算
int calculate = calculate(inter);
System.out.println(calculate);
}
private static int calculate(List<String> inter) {
Stack<Integer> stack = new Stack();
for (int i = 0; i <inter.size(); i++) {
try{
int m = Integer.parseInt(inter.get(i));
stack.push(m);
}catch (Exception e){
int num1 = stack.pop();
int num2 = stack.pop();
if(inter.get(i).equals("+")){
stack.push(num1+num2);
}else if (inter.get(i).equals("-")){
stack.push(num2 - num1);
}else if(inter.get(i).equals("*")){
stack.push(num1* num2);
}else{
stack.push(num2/num1);
}
}
}
return stack.peek();
}
private static List<String> Inter(String[] s2) {
Stack<String> stack = new Stack<>();
List<String> list = new ArrayList<>();
//进栈和进线性表
for (int i = 0; i < s2.length; i++) {
if(s2[i].length()==0){
continue;
}
if(s2[i].equals("+")|| s2[i].equals("-")){
while (!stack.isEmpty()&&(stack.peek().equals("+")||stack.peek().equals("-")||stack.peek().equals("*")||stack.peek().equals("/"))){
list.add(stack.peek());
stack.pop();
}
stack.push(s2[i]);
}else if(s2[i].equals("*")||s2[i].equals("/")){
while (!stack.isEmpty() &&(stack.peek().equals("*")||stack.peek().equals("/"))){
list.add(stack.peek());
stack.pop();
}
stack.push(s2[i]);
}else if(s2[i].equals("(")){
stack.push(s2[i]);
}else if(s2[i].equals(")")){
while (!stack.isEmpty()&&(!stack.peek().equals("("))){
list.add(stack.peek());
stack.pop();
}
stack.pop();
}else {
list.add(s2[i]);
}
}
while (!stack.isEmpty()){
list.add(stack.peek());
stack.pop();
}
return list;
}
private static String prost(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '+'||s.charAt(i) == '-'||s.charAt(i) == '*'||s.charAt(i) == '/'||s.charAt(i) == '('||s.charAt(i) == ')'){
sb.append(' ');
sb.append(s.charAt(i));
sb.append(' ');
}else{
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}
括号匹配
import java.util.Stack;
public class ParenthesesMatching {
/*
括号匹配
*/
public static void main(String[] args) {
String s1 = "{[<>]()}";
boolean matching = Matching(s1);
System.out.println(matching);
}
private static boolean Matching(String s1) {
Stack<Character> st = new Stack();
for (int i = 0; i < s1.length(); i++) {
//进栈 如果是空 或者 ASCII码的差值不为2或者1;
int res = 0;
if(!st.isEmpty()){
res = s1.charAt(i) - st.peek();
if (res ==1 || res == 2){
st.pop();
}else{
st.push(s1.charAt(i));
}
}else{
st.push(s1.charAt(i));
}
}
return st.isEmpty();
}
//
}
进制转化
import jdk.internal.dynalink.linker.ConversionComparator;
import java.util.Stack;
public class BinaryConversion {
public static void main(String[] args) {
/*
进制转化
*/
int num = 654321;
String a = Conversion(num);
System.out.println(a);
String n = "9FBF1";
int p = Con(n);
System.out.println(p);
}
private static int Con(String n) {
// 16--> 10;
Stack <Character>s = new Stack();
int i = 0;
int rs = 0;
while (i < n.length()){
s.push(n.charAt(i));
i++;
}
while(!s.isEmpty()){
for (int j = 0; j < n.length(); j++) {
int p = s.pop();
if(p <=57 &&p >=49){
rs = rs+ (p-48) * mi(16,j);
}else if(p <=70 && p >=65){
rs = rs+ (p-55) * mi(16,j);
}else{
throw new IllegalArgumentException("erro");
}
}
}
return rs;
}
private static int mi(int i, int j) {
int c = 1;
if(i==0){
return 1;
}
for(i =0;i < j;i++){
c = c * 16;
}
return c;
}
private static String Conversion(int num) {
//10 --> 16
StringBuilder sb = new StringBuilder();
Stack<String> s = new Stack();
while (num!=0){
int res = num % 16 ;
if(res < 10 && res >=0){
s.push(res+"");
}else{
s.push((char)(res + 55) +"");
}
num = num/ 16;
}
while (!s.isEmpty()){
sb.append(s.pop());
}
return sb.toString();
}
}
回文字符串
import java.util.Stack;
public class palindrome {
/*
回文字符串
*/
public static void main(String[] args) {
String s = "abcdcba";
boolean b = pai(s);
System.out.println(b);
}
private static boolean pai(String s) {
Stack<Character> stack = new Stack<>();
//如果栈顶元素和遍历到的元素相同则出栈,否则进栈
for (int i =0;i < s.length();i++){
if(s.length() % 2 ==1 && i ==s.length()/2){
continue;
}
if(stack.isEmpty() || stack.peek()!=s.charAt(i)){
stack.push(s.charAt(i));
}else{
stack.pop();
}
}
return stack.isEmpty();
}
}
有bug 比如 当 s = “112233”;会返回true,我们期待它他是false。可以通过让它进一半再来出栈,解决这个bug