记一下遇到的问题:
1、判断外层括号是否匹配
2、相同优先级,从左到右计算
// 思路:题目要求有向无环图,这里采用二叉树,理论上二叉树是特殊的有向无环图(DAG)
// 给符号添加优先级,以优先级最小的符号划分左右字符,递归建立二叉树。
// 关键问题再括号匹配判断中,设level=0;遇到’(’,level+1;遇到’)’,level-1;如果再达到最后一个‘)’前,level==0,则第一个‘(’
// 不和最后一个‘)’匹配,则不用去除外层括号。
// 思路:题目要求有向无环图,这里采用二叉树,理论上二叉树是特殊的有向无环图(DAG)
// 给符号添加优先级,以优先级最小的符号划分左右字符,递归建立二叉树。
// 关键问题再括号匹配判断中,设level=0;遇到'(',level+1;遇到')',level-1;如果再达到最后一个‘)’前,level==0,则第一个‘(’
// 不和最后一个‘)’匹配,则不用去除外层括号。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 2000
typedef struct Snode{
int tag; //标签
char elem;
int prio; //优先级
} Snode; //字符节点
typedef struct MyString{
Snode data[max];
int length;
}MyString; //存储字符串
typedef struct TNode{
Snode data;
struct TNode *lchild,*rchild;
}TNode,BiTree,*PTNode; //二叉树
void Clear(MyString *S)//去除外层多余的括号
{
int level = 0;
if(S->data[0].elem == '(' && S->data[S->length - 1].elem == ')'){
for(int i = 0;i < S->length-1;i++)
{
if(S->data[i].elem == '(')
level++;
else if(S->data[i].elem == ')')
level--;
if(level == 0)
return;
}
for(int i = 1; i < S->length-1;i++)
{
S->data[i-1] = S->data[i];
}
S->length = S->length - 2;
}
}
void InitString(MyString *S){
char c[max];
int len,baselevel = 0;
scanf("%s",c);
len = strlen(c);
for(int i = 0;i < len;i++)
{
S->data[i].elem = c[i];
if (c[i] == '+' || c[i] == '-')
{
S->data[i].tag = 1;
S->data[i].prio = baselevel + 1;
}
else if (c[i] == '*' || c[i] == '/')
{
S->data[i].tag = 1;
S->data[i].prio = baselevel + 2;
}
else if (c[i] == '(')
{
S->data[i].tag = 0;
baselevel = baselevel + 2;
}
else if (c[i] == ')')
{
S->data[i].tag = 0;
baselevel = baselevel - 2;
}
else
{
S->data[i].tag = 0;
}
}
S->length = len;
}
int FindMid(MyString *S){ //返回level最小符号的下标
int pos = 0,min = max;//min 当前最小的level,pos记录下标
for(int i = 0;i < S->length;i++)
{
if(S->data[i].prio <= min && S->data[i].tag == 1)// 优先级相同时,先算前面的,所以将后面的作为中间值划分。
{
min = S->data[i].prio;
pos = i;
}
}
return pos;
}
PTNode CreatTree(MyString *S){
MyString left,right;
PTNode T;
T = (PTNode)malloc(sizeof(TNode));
int midpos,len;
len = S->length;
if(len == 1)
{
T->data = S->data[len-1];
T->lchild = NULL;
T->rchild = NULL;
}
else if(len > 1)
{
midpos = FindMid(S);
left.length = midpos;
for(int i = 0;i < midpos;i++)
{
left.data[i] = S->data[i];
}
right.length = S->length - midpos - 1;
for(int i = 0;i < right.length;i++)
{
right.data[i] = S->data[i+midpos+1];
}
Clear(&left);
Clear(&right);
T->data = S->data[midpos];
T->lchild = (TNode*)malloc(sizeof(TNode));
T->rchild = (TNode*)malloc(sizeof(TNode));
T->lchild = CreatTree(&left);
T->rchild = CreatTree(&right);
}
return T;
}
void Last(BiTree* T){
if(T->lchild == NULL && T->rchild == NULL)
{
printf("%c",T->data.elem);
}
else
{
Last(T->lchild);
Last(T->rchild);
printf("%c",T->data.elem);
}
}
int main(){
MyString s;
s.length = 0;
PTNode T;
InitString(&s);
Clear(&s);
T = CreatTree(&s);
Last(T);
printf("\n");
return 0;
}