Expressions(表达式)

NKoj1751

题目大意:给出后缀表达式序列,求出层次遍历的结果

解决:还原树的形状,bfs之后就是结果,先直接开辟树结点数组,将数据导入结点,然后寻找节点间父子关系,从而完成建树过程

ac代码: 

 1 #include <iostream>
2 #include <cctype>
3 #include <queue>
4 #include <string>
5 #include <vector>
6 using namespace std;
7 string str;
8 struct node
9 {
10 char data;
11 bool mark;
12 node*lch,*rch;
13 };
14 node *root=NULL;
15 node tree[10005];
16 //树的层次遍历过程
17 void bfs(int n)
18 {
19 node *root=&tree[n-1];
20 queue<node*> q;//结点指针的队列
21 vector<char> v(n);//放结果的数组
22 int t=0;
23 node* tmp;
24 q.push(root);
25 while(!q.empty())
26 {
27 v[t++]=q.front()->data;
28 tmp=q.front();
29 q.pop();
30 if(tmp->lch)q.push(tmp->lch);
31 if(tmp->rch)q.push(tmp->rch);
32 }
33 for(int i=n-1;i>=0;i--)cout<<v[i];
34 cout<<endl;
35
36 }
37 void creat(string str)
38 {
39 int len=str.size();
40 for(int i=0;i<len;i++){tree[i].data=str[i];tree[i].lch=tree[i].rch=NULL;tree[i].mark=0;}
41 int pos=0,t=0,n=len;
42 while(n!=1)
43 {
44 while(islower(str[pos])){t++;pos++;}
45 int i=t-1;
46 while(tree[i].mark)i--;
47 tree[t].rch=&tree[i];
48 tree[i].mark=1;i--;
49 while(tree[i].mark)i--;
50 tree[t].lch=&tree[i];
51 tree[i].mark=1;
52 n-=2;
53 str.erase(pos-2,2);
54 t++;
55 pos--;
56 }
57 bfs(len);
58 }
59 int main()
60 {
61
62 int icase;
63 cin>>icase;
64 while(icase--)
65 {
66 cin>>str;
67 creat(str);
68 }
69 // system("pause");
70 return 0;
71 }

未ac代码总结:

#include <iostream>

#include <cctype>

#include <queue>

#include <string>

#include <vector>

using namespace std;

string str;

struct node

{

    char data;

    node*lch,*rch;

    node(){lch=rch=NULL;}

};

node *root=NULL;

node tree[10005];

void bfs(int n)

{

    node *root=&tree[n-1];

    queue<node*> q;

    vector<char> v(n);

    int t=0;

    node* tmp;

    q.push(root);

    while(!q.empty())

    {

        v[t++]=q.front()->data;

        tmp=q.front();

        q.pop();

/ *下边两行纠结了很久,原来是手误,应该是结点非空是进入队列,应该是

    if(tmp->lch)q.push(tmp->lch);

    if(tmp->rch)q.push(tmp->rch);

*/

        if(!tmp->lch)q.push(tmp->lch);

        if(!tmp->rch)q.push(tmp->rch);

    }

    for(int i=n-1;i>=0;i--)cout<<v[i];

    cout<<endl;

    

}

void creat(string str)

{

    int len=str.size();

/* 由于是多组数据,每次必须初始化,所以一次初始化工作是不够的,

 下边这行不行,开辟数组是也不用一次初始化,只需在此处修改为

for(int i=0;i<len;i++)

{

  tree[i].data=str[i];

  tree[i].lch=treee[i].rch=NULL;//孩子结点初始化

 tree[i].mark=false;//标志域初始化

}

*/

    for(int i=0;i<len;i++)tree[i].data=str[i];

    int pos=0,t=0;

    while(len!=1)

    {

        while(islower(str[pos])){t++;pos++;}

  /*下边的根节点可以用t,但是左子树不是t-1,而是左边没用过的第一个和第二个元素

   而且不一定是紧邻的,这是我可以为每个结点定义一个标志mark,用过了就打上标记

  然后用while循环找到子节点即可  */

        tree[t].rch=&tree[t-1];

        tree[t].lch=&tree[t-2];

        len-=2;//len已经改变,下边将len传入一定为1,应该在上边在定义一个变量等于len

        str.erase(pos-2,2);

        t++;

        pos--;//pos一定是减,因为我一次删除了两个字符pos是字符的下标,变大了要减去

    }

    bfs(len);

}

int main()

{

    

    int icase;

    cin>>icase;

    while(icase--)

    {

        cin>>str;

        creat(str);

    }

    system("pause");

    return 0;

}

你可能感兴趣的:(express)