Android Resources$NotFoundException: String resource ID #0x1

今天写一个新界面,需要从其他界面通过intent传来参数,就先拿到之后通过TextView的setText显示来看看传参是否正确,写法:TextView.setText(arg) (arg是int型),然后就玩命报错 “android.content.res.Resources$NotFoundException: String resource ID #0x1”,一直不知道怎么回事,看过API才明白当调用setText()方法时如果传入int型是不会被当成内容而是resourceID来使用!R文件里当然不会有我的参数,所以报错!解决方法:TextView.setText(“” + arg)

Android FragmentTransaction 在不同版本下的奇怪问题

目前在做的一款APP,用到了一个布局块中的Fragment的切换,其中一个按钮按下后的事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
btnTranslate.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
/*当前界面不是翻译界面时才进行下列动作*/
if( MAIN_FRAGMENT_ID != currentFragmentId )
{
setChoosedBtnState(MAIN_FRAGMENT_ID);
FragmentManager fragmentManager = getFragmentManager();
if( null == fragmentTranslate )
fragmentTranslate = new MainUI();
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);
fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");
fragmentTransaction.commit();
currentFragmentId = MAIN_FRAGMENT_ID;
}
}
});

fragmentTransaction.commit();currentFragmentId = MAIN_FRAGMENT_ID;}}});
1
2
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);

这两句本来是为了提高切换速度,并且保存用户产生的数据而选用隐藏/显示来代替replace(remove/add),运行时在Android 4.0的模拟器和我Android 4.1的手机上没有任何问题,效果也很好,但是当我把程序放在我的Android 4.4(Galaxy S5··貌似这个机型问题挺多···)时出现闪退!具体情形是,当我点击一个按钮创建了一个Fragment的实例时程序正常运行,但是当我再次点击已经创建过实例的界面按钮时就会闪退,一直不明白是怎么回事,查了API也没找到相关的说明。

搞了好久,最后看到

1
<pre name="code" class="java">fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");

这句话,它作用就是把产生的Fragment实例加入到指定的布局块中,再联想我的问题,也就是在加入一次然后再次加入出现了问题,所以试着只在第一次创建Fragment实例时调用这条语句,果然问题解决!

修改后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
btnTranslate.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
/*当前界面不是翻译界面时才进行下列动作*/
if( MAIN_FRAGMENT_ID != currentFragmentId )
{
setChoosedBtnState(MAIN_FRAGMENT_ID);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if( null == fragmentTranslate )
{
fragmentTranslate = new MainUI();
fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");
}
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);
fragmentTransaction.commit();
currentFragmentId = MAIN_FRAGMENT_ID;
}
}
});

Android Error: No resource found ···

关于 android:id=”@+id/” 和 android:id=”@id/” 的问题

本以为自己已经理解了这两个,无非就是第一次创建id时用+id/呗
但是没想到这里创建顺序是严格按照代码顺序来的,如:在RelativeLayout中

1
2
3
4
5
6
7
<RelativeLayout
...

<Widget1 android:layout_above="@id/widget_2" .../>
<Widget2 android:id="@+id/widget_2" ... />

<RelativeLayout/>

这样写会报错,大致说是Widget1找不到widget_2!!!!

原来需要在Widget1中这么写:android:layout_above=”@+id/widget_2″
也就是在第一次遇到这个id时就创建它,放心,这个id还是Widget2的,只是先被Widget1拿去创建并引用了而已

【PHP学习】move_uploaded_file() 使用注意

今天刚弄好WAMP,端口问题焦头烂额一上午,最后停止IIS服务就好了。。。

看PHP基本的部分,在用到 move_uploaded_file()时一直是错误,说是无法把文件从临时路径移动到指定路径下,最后发现指定路径不存在。。。就是最后的upload目录没有创建,心里还想着它会自动创建这个目录呢,真是傻了。。。

(代码是W3SCHOOL上的例子,稍有改动)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
if( $_FILES["file"]["type"] == "text/plain" && $_FILES["file"]["type"] < 20000 )
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
$oldPath = $_FILES["file"]["tmp_name"];
$newPath = "D:\\WAMP Server\\wamp\\tmp\\upload\\" . $_FILES["file"]["name"];

echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: $oldPath temporarily!<br />";

if( file_exists($newPath) )
{
echo "$newPath already exists!";
}
else
{
move_uploaded_file($oldPath, $newPath);
echo "Stored in: $newPath !";
}
}
}
else
{
echo "Invalid File!";
}
?>

JAVA 设置 JTable 表格的可编辑性

有时候,我们需要设置JTable表格某些行某些列不可编辑以保证数据准确,用DefaultTableModel初始化的话,需要重写它的public boolean isCellEditable(int, int)方法,写法简单呈现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DefaultTableModel myModel = new DefaultTableModel(dataOfOrder, headOfOrder)	//实例化表格模式
{
/**
*
*/
private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int columnIndex) //重写方法改编可编辑性
{
if( columnIndex == getColumnCount() - 1 )
return true;
return false;
}
};

上述写法是设置只有表格的最后一列可编辑,其他列不可编辑。有了rowIndex和columnIndex这两个参数,可以随意的设置可编辑范围。

注意要达到目的,定义另一个类继承DefaultTableModel,之后在类中重写方法是不可行的!

Java 窗体中按钮布局问题

在Java窗体中,有时需要对按钮的设置进行布局,这时使用GridLayout(x, y)会很方便,意思是把窗口划分为x行y列的小格子,在add的时候就是一行一行的填充,这样可以是按钮得到标准化布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class test_for_blog extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 5136083409273453255L;

private static int JFwidth = 450;
private static int JFheight = 350;

JPanel panel = null;

JButton btnAdd = null;
JButton btnDelete = null;

public test_for_blog()
{
super("按钮添加测试");

panel = new JPanel();

btnAdd = new JButton("Add");
btnDelete = new JButton("Delete");

panel.setLayout( new GridLayout(1, 2) );
panel.add(btnAdd);
panel.add(btnDelete);
this.getContentPane().add(panel, BorderLayout.SOUTH);
}

public static void main(String[] args)
{
test_for_blog test = new test_for_blog();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //获取显示屏尺寸
test.setBounds((screenSize.width - JFwidth) / 2, (screenSize.height - JFheight) / 2, JFwidth, JFheight); //使程序窗口居中
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //窗口设为可关闭
test.setResizable(false); //窗口设为不可调节大小
test.setVisible(true); //窗口设为可见
}
}

数据结构学习之二叉排序树

介绍:二叉排序树是以一定的规则排列树中元素,因而可以进行快速的排序和查询的树状数据结构,一般规则是:对于树中任意一个节点,左孩子严格小于根,根严格小于右孩子,有点像大根堆。(只是大根堆中左右孩子关系并不确定,且和根的关系是统一的,而且有上浮和下沉操作使得大根堆总是一棵完全二叉树,其不断弹出堆顶形成有序列的过程叫做堆排序。虽然二叉排序树中也有旋转操作使得树尽量平衡,但是由于数值大小分明的左右孩子,在进行平衡操作时远不如大根堆方便快捷。)对于一棵已经构造完成的排序二叉树,它的中序遍历序列即为升序排列的有序列,这就是二叉排序树的排序方法。

基本操作:二叉排序树的基本操作为查找、插入和删除。查找操作以及插入操作过程同二分查找类似,用待处理节点和当前节点进行数值比较,如果待处理节点的值小于当前节点的值,则进入当前节点的左子树进行操作,否则进入当前节点的右子树进行操作,直到到达叶子节点或者操作完成。删除操作有好几种实现方法,我是用的是“替罪羊节点法”,即从待删除节点的左子树中找到最大的一个节点(即“替罪羊节点”),用它的值覆盖待删除节点的值,然后删除替罪羊节点即可。在具体操作中还有许多需要注意的细节,在代码注释中有详细介绍。

一些想法:在最初的代码实现中,曾使用静态树,因为考虑到在处理大型数据时,重复的new或者malloc操作会使得程序慢的令人发指(并不是说指针慢,只是申请空间的过程耗费时间),所以一开始就开一段长度合适的空间,另外设置一个指针指示当前数组中可以用的节点,然后new操作在这里的实现就可以这样写:tmp->lc = &Tree[++index],如果当前序列空间不够时,再用malloc或new申请另一段空间,有点类似内存池的概念。这样的静态操作经在线评测系统(POJ)测试,在进行最基本的操作来处理100,000左右的数据量时会快上两个甚至更多的数量级。静态树的查找和插入操作都可以正常进行,但是在进行删除操作时,我自己写的回收空间算法(为了节省空间,删除的节点重新归到可用空间中,想法是把待删除节点和当前排序树二叉树用的最后一个节点进行交换,再把上文提到的指针前移一位即可,代码实现可以写成:swap(*tmp , Tree[index–])。)总是不能正确执行,调了一段时间未果就先放在一边,写现在这个用指针操作实现的排序二叉树。

代码:(内置测试数据,并对于测试数据保证代码正确)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<numeric>
#include<iostream>
#include<algorithm>

#define MAXN 10005
#define MAX_INT 2147483647
#define LC(x) (x << 1)
#define RC(x) ((x << 1) | 1)
#define MID(x,y) ( (x + y) >> 1 )
#define TIME_BEGIN double t1 = clock()
#define TIME_END double t2 = clock();printf("\n%.2fms\n",t2-t1)

using namespace std;

struct node //结构体定义
{
int data;
node *lc , *rc , *fa;
node()//初始化
{
data = -1;
lc = rc = fa = NULL;
}
};
node *root = new node;;

int ary[15] = {0,213,5,12,45,65,2,1,4,8,6,554,52,-1},n = 12;

void myFind(int now , node *&tmp)//查询函数(从参数节点返回信息)
{
tmp = root;
while(tmp)
{
if(now > tmp->data) //查询值大于当前节点值,进入右子树
tmp = tmp->rc;
else if(now < tmp->data)//查询值小于当前值,进入左子树
tmp = tmp->lc;
else //找到查询值,返回
return ;
}
}

void myInsert(int now)//插入函数
{
node *tmp = root;
while(1)
{
if(now > tmp->data) //若待插入节点大于当前节点的值,则进入右子树
{
if(!tmp->rc)//当前节点右子树为空,则将待插入节点插入到此位置
{
tmp->rc = new node;
tmp->rc->data = now;
tmp->rc->fa = tmp;
return ;
}
tmp = tmp->rc;
}
else if(now < tmp->data)//若待插入节点小于当前节点的值,则进入左子树
{
if(!tmp->lc)//当前节点左子树为空,则将待插入节点插入到此位置
{
tmp->lc = new node;
tmp->lc->data = now;
tmp->lc->fa = tmp;
return ;
}
tmp = tmp->lc;
}
else //树中已有待插入节点,则直接返回
return ;
}
}

void myDelete(node *&tmp)//删除函数 (通过节点)
/*
若想通过数值删除,则只需先调用一次myFind函数
*/
/*
删除函数的思想是“替罪羊节点”思想:即在待删除节点左子树中
找到最大的节点p(即替罪羊),用它的值覆盖待删除节点的值,然后删除
p即可,其中有很多细节需要注意
*/
{
node *ano = tmp->lc;
if(!ano)//若待删除节点没有左子树
{
if(tmp == tmp->fa->lc)//若带删除节点是其父节点的左子树
tmp->fa->lc = tmp->rc;
else //若带删除节点是其父节点的右子树
tmp->fa->rc = tmp->rc;
if(tmp->rc) //不能直接访问tmp->rc的父节点,需要先判断tmp->rc是否为空
tmp->rc->fa = tmp->fa;
free(tmp);
}
else
{
while(ano->rc) //寻找左子树中的最大节点
ano = ano->rc;
tmp->data = ano->data;//值覆盖
if(ano->lc) //若“替罪羊”有左孩子
{
if(ano->fa->data < ano->lc->data)
//判断“替罪羊”的左孩子和替罪羊父亲节点的大小关系
ano->fa->rc = ano->lc;
else
ano->fa->lc = ano->lc;
ano->lc->fa = ano->fa;
}
else
{
if(ano->fa == tmp) //判断替罪羊是左子树根还是左子树的其他节点
ano->fa->lc = NULL;
else
ano->fa->rc = NULL;
}
free(ano);
}
}

void myInit()//初始化整棵树
{
root->data = MAX_INT;
for(int i = 1;i <= n;i ++)
myInsert(ary[i]);
}

void myPrint(node *tmp)//中序遍历方式输出整棵树,形成有序列
{
if(!tmp)
return ;
myPrint(tmp->lc);
cout<<tmp->data<<" ";
myPrint(tmp->rc);
}

void myInit_test() //myInit测试函数
{
cout<<endl;
cout<<"====myInit函数测试开始==========="<<endl;
cout<<endl;
myInit();
cout<<endl;
cout<<"====myInit函数测试结束==========="<<endl;
cout<<endl;
}

void myPrint_test() //myPrint测试函数
{
cout<<endl;
cout<<"====myPrint函数测试开始==========="<<endl;
cout<<endl;
myPrint(root->lc);
cout<<endl;
cout<<endl;
cout<<"====myPrint函数测试结束==========="<<endl;
cout<<endl;
}

void myFind_test() //myFind测试函数
{
cout<<endl;
cout<<"====myFind函数测试开始==========="<<endl;
cout<<endl;
for(int i = 1;i <= n;i ++)
{
node *tmp;
myFind(ary[i] , tmp);
cout<<tmp->data<<" ";
}
cout<<endl;
cout<<endl;
cout<<"====myFind函数测试结束==========="<<endl;
cout<<endl;
}

void myDelete_test() //myDelete测试函数
{
cout<<endl;
cout<<"====myDelete函数测试开始==========="<<endl;
cout<<endl;
for(int i = 1;i <= n;i ++)
{
node *tmp;
myFind(ary[i] , tmp);
myDelete(tmp);
myPrint(root->lc);
cout<<endl;
myInsert(ary[i]);
}
cout<<endl;
cout<<"====myDelete函数测试结束==========="<<endl;
cout<<endl;
}

int main()
{
TIME_BEGIN;
myInit_test(); //myInit函数测试
myPrint_test(); //myFind函数测试
myFind_test(); //myFind函数测试
myDelete_test(); //myDelete函数测试
TIME_END;
}

字典树

字典树,就是一种最大限度的利用单词的公共前缀高效查询单词(但不止是单词,所有有前缀的都可以类似进行查找)的数据结构。节点定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct node
{
node *next[26];//26个字母,NULL则表示没有相应字母的分支
bool isWord;//true表示从根节点到当前节点路途中所有字母连成的单词已经在字典中
int point;//指向单词的信息域(如释义等)
node()//初始化函数
{
for(int i = 0;i < 26;i ++)
next[i] = NULL;
isWord = false;
point = 0;
}
}

建树和查询都非常方便,删除操作并不常用,比较偷懒的方法就是找到待删除单词的最后一个字母所在节点,把isWord标记置为false即可。代码就不给出了。

需要注意的是,在实际建树过程中,如果动态分配空间无论是new还是malloc都会很慢,一般都会TLE的,所以代码都是静态实现,即先分配一定的空间,需要用新节点时就从空间里拿。

例题:

一、POJ 2503 Babelfish

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
poj 2503
17664K 235MS
*/
#include<cstdio>
#include<cstring>
#include<iostream>

#define MAXN 150005

using namespace std;

struct node
{
node *next[26];
bool isWord;
int point;//不在结构体内设置字符数组而是模拟一个指针指向储存区这样可以节省不少空间
node()
{
for(int i = 0;i < 26;i ++)
next[i] = NULL;
isWord = false;
point = 0;
}
}all[MAXN];

int index = 1,size;
char store[100005][11];

void insert(char *str1,char *str2)
{
node *tmp = &all[0];
int len = strlen(str1);
for(int i = 0;i < len;i ++)
{
int num = str1[i] - 'a';
if(!tmp->next[num])
tmp->next[num] = &all[index++];
tmp = tmp->next[num];
}
tmp->isWord = true;
size ++;
tmp->point = size;
strcpy(store[size] , str2);
}

void find(char *s)
{
node *tmp = &all[0];
int len = strlen(s);
for(int i = 0;i < len;i ++)
{
int num = s[i] - 'a';
if(!tmp->next[num])
{
printf("eh\n");
return ;
}
tmp = tmp->next[num];
}
if(tmp->isWord)
printf("%s\n",store[tmp->point]);
else
printf("eh\n");
}

int main()
{
char str1[12] = {0},str2[12] = {0},s[24];
while(gets(s) && s[0])
{
sscanf(s,"%s %s",str1,str2);
insert(str2,str1);
}
while(scanf("%s",s) != EOF)
{
find(s);
}
return 0;
}

二、POJ 3630、Phone List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
poj 3630
4628K 219MS
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

#define MAXN 100005

using namespace std;

struct alp
{
char s[11];
}per[MAXN / 10 + 5];

struct node
{
bool isWord;
node *next[10];
node()//初始化函数很重要!
{
isWord = false;
for(int i = 0;i < 10;i ++)
next[i] = NULL;
}
}all[MAXN];

bool cmp(alp a,alp b)
{
return strlen(a.s) < strlen(b.s);
}

void doIt()
{
memset(all , 0 , sizeof(all));
int n,index = 0;
cin>>n; node *root, *tmp;
root = &all[index++];
for(int i = 1;i <= n;i ++)
scanf("%s",per[i].s);
sort(per + 1 , per + n + 1 , cmp);
//要先按字符串长度从小到大排序,不然对于 12 1之类的数据会出错
for(int p = 1;p <= n;p ++)
{
tmp = root;
int len = strlen(per[p].s);
for(int i = 0;i < len;i ++)
{
int num = per[p].s[i] - '0';
if(tmp->next[num])
{
if(tmp->next[num]->isWord)
{
printf("NO\n");
return ;
}
}
else
tmp->next[num] = &all[index++];
tmp = tmp->next[num];
}
tmp->isWord = true;
}
printf("YES\n");
return ;
}

int main()
{
int T;
cin>>T;
while(T --)
{
doIt();
}
return 0;
}

由二叉树的两个遍历序列求另一个遍历序列

二叉树的重要的遍历序列有三种:先序遍历,中序遍历,后序遍历。其中中序遍历可以由其他两种遍历序列定位的根来划分出左右两棵子树,所以已知的两种遍历序列中必须有中序遍历。

示意图(先序+中序->后序)

示意图

对于先序遍历序列,树根一定是第一个元素(后序遍历的根则是最后一个),知道树根后在中序遍历中找到树根,则根前面的就是左子树,后面的就是右子树,再递归的对左右子树执行上述操作直到序列为空,输出序列就是另一种序列。对于求先序序列,每次都是找到树根就输出,而求后序序列时是先递归处理完左右子树后再输出根。

代码:

输入中序和后序,求先序

输入:

DBKFIAHEJCG
DKIFBHJEGCA

输出:

ABDFKICEHJG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<cstdio>
#include<cstring>
#include<iostream>

#define MAXN 150

using namespace std;

char in[MAXN],post[MAXN];

void make_pre(char *a,char *b,int len)
{
cout<<b[len-1];
int le1 = 0,le2 = 0;
for(int i = 0;i < len;i ++,le1 ++)
if(a[i] == b[len-1])
break;
le2 = len - le1 - 1;
if(le1 > 0)
make_pre(a,b,le1);
if(le2 > 0)
make_pre(&a[le1+1],&b[le1],le2);
}

int main()
{
freopen("./tree_trans.in" , "r" , stdin);
cin>>in>>post;
make_pre(in,post,strlen(in));
return 0;
}

输入中序和先序,求后序

输入:

DBKFIAHEJCG
ABDFKICEHJG

输出:

DKIFBHJEGCA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<cstdio>
#include<cstring>
#include<iostream>

#define MAXN 150

using namespace std;

char in[MAXN],pre[MAXN];

void make_post(char *a,char *b,int len)
{
int le1 = 0,le2 = 0;
for(int i = 0;i < len;i ++,le1 ++)
if(a[i] == b[0])
break;
le2 = len - le1 - 1;
if(le1 > 0)
make_post(a,&b[1],le1);
if(le2 > 0)
make_post(&a[le1+1],&b[le1+1],le2);
cout<<b[0];
}

int main()
{
freopen("./tree_trans.in" , "r" , stdin);
cin>>in>>pre;
make_post(in,pre,strlen(in));
return 0;
}