中缀转后缀(c语言和java代码实现)
之前这个问题一直困扰着我,最近再研究了一下发现代码可以运行出那个结果,有点嗨森,一口气写了c语言版的和java版的。
这个思路是参考一位博主的,在此对他(她)表示感谢!!
**将中缀转为后缀的大致思路如下:
- 如果遇到左括号,则直接让它进栈
- 如果遇到右括号,则让栈里的运算符出栈,并让出栈的运算符放到一个队列里,直到遇到左括号,由括号不进栈,左括号不进队列
- 如果是运算符,则比较运算符的优先级**
如果该运算符的优先级大于栈顶元素的优先级,或者栈顶元素是左括号,则直接进栈
如果该运算符的优先级不大于栈顶元素的优先级,则让栈里的元素依次出栈,直到栈顶元素的优先级低于该运算符的优先级或者遇到左括号
4.如果是操作数(数字或者字母),不进栈而是进队列
以下是我手写的一个过程(字巨丑【捂脸】)
话不多说,上代码
c语言版
#include<stdio.h>
#include<string.h>
typedef struct
{
double num;
char op;
int flag;
}node;
typedef struct
{
int top;
char data[50];
}stack;
typedef struct
{
int head;
int rear;
char data[50];
}queue;
queue q;
stack s;
int compare(char a,char b)
{
if(a=='+'||a=='-')
{
if(b=='-'||b=='+')
return 0;
if(b=='*'||b=='/')
return -1;
}
if(a=='*'||a=='/')
{
if(b=='*'||b=='/')
return 0;
if(b=='+'||b=='-')
return 1;
}
return -1;
}
void change(char str[])
{
int i;
s.top=0;
q.head=0;
q.rear=0;
int len=strlen(str);
for(i=0;i<len;i++)
{
if(str[i]=='(') //1.遇到左括号,将其进栈
{
s.data[s.top]=str[i];
s.top++;
}
else if(str[i]==')') //2.遇到右括号,执行出栈操作,直到遇到左括号
{
s.top--;
while(s.top>=0&&s.data[s.top]!='(')
{
q.data[q.rear]=s.data[s.top];
q.rear++;
s.top--;
}
//if(s.top=='(')
// s.top--;
//s.top++;
}
else if((str[i]>='0'&&str[i]<='9')||(str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')) //3.遇到操作数,直接进队列
{
q.data[q.rear]=str[i];
q.rear++;
}
else //4.遇到其他运算符
{
s.top--;
while(s.top>=0&&compare(s.data[s.top],str[i])>=0) //如果该运算符的优先级不高于栈里的运算符的优先级
{
q.data[q.rear]=s.data[s.top];
q.rear++;
s.top--;
}
s.top++;
s.data[s.top]=str[i];
s.top++;
}
}
s.top--;
while(s.top>=0)
{
q.data[q.rear]=s.data[s.top];
q.rear++;
s.top--;
}
}
int main()
{
char str[50];
scanf("%s",str);
change(str);
while(q.head<q.rear)
{
printf("%c",q.data[q.head]);
q.head++;
}
return 0;
}
运行结果:
java版
package Stack;
import java.awt.List;
import java.util.ArrayList;
import java.util.Queue;
import java.util.Stack;
import java.util.Scanner;
public class HouZhui {
private static ArrayList<Character> change(String str)
{
Stack<Character> opStack=new Stack<Character>();
ArrayList<Character> resultList=new ArrayList<Character>();
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)=='(') //1.如果是左括号,直接进栈
opStack.push(str.charAt(i));
else if(str.charAt(i)==')') //2.如果是右括号,则出栈,直到遇到(
{
while(!opStack.isEmpty()&&!(opStack.peek()=='('))
{
resultList.add(opStack.pop());
}
if(opStack.peek()=='(')
opStack.pop();
//opStack.push(str.charAt(i));
}
else if(isOperator(str.charAt(i))) //3.是运算符
{
while(!opStack.isEmpty()&&priority(opStack.peek(),str.charAt(i))>=0)
{
resultList.add(opStack.pop());
}
opStack.push(str.charAt(i));
}
else //4.是操作数
{
resultList.add(str.charAt(i));
}
}
while(!opStack.isEmpty())
resultList.add(opStack.pop());
return resultList;
}
public static boolean isOperator(char item)
{
if(item=='+'||item=='-'||item=='*'||item=='/')
return true;
return false;
}
public static int priority(char a,char b)
{
if(a=='+'||a=='-')
{
if(b=='+'||b=='-')
return 0;
if(b=='*'||b=='/')
return -1;
}
if(a=='*'||a=='/')
{
if(b=='+'||b=='-')
return 1;
if(b=='*'||b=='/')
return 0;
}
return -1;
}
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
String str=null;
//ArrayList<String> arr1=new ArrayList<String>();
ArrayList<Character> arr2=new ArrayList<Character>();
String arr1=input.next();
arr2=change(arr1);
for(char a:arr2)
System.out.print(a);
}
}
运行结果:
这么大片文字能够一口气看完的人,果然不一般呀!如果对代码有什么建议的可以评论区留意,嘻嘻