
广义表的设计
题目要求
广义表的应用
【任务】由于广义表在结构上较线性表复杂得多,因此、广义表的运算也不如线性表简单。本设计要求实现的广义表的建立、查找、输出、取表头和取表尾以及求深度、求逆表等。
【功能要求】设计一个主控菜单,控制6个子系统的运行
1)建立广义表
2)输出广义表
3)结点的查找
4)求广义表表头
5)求广义表表尾
6)求广义表的深度
题目设计过程
需求分析
完成广义表的生成,查找,输出,取表头表尾,求深度并设计可视化界面呈现广义表的上述变化
- 输入的形式和输入值的范围:生成广义表需要输入的广义表合法,例如(A,B,(C)),查找广义表需要输入字符或字符串,在所有输入中,元素都应该合法
- 输出的形式:在所有的六种操作后都将结果正确显示在文本框中,不合法操作将输出错误弹窗
- 实现功能:完成广义表的生成,查找,输出,取表头表尾
- 测试数据:在建表操作中依次输入(A,B,C),(A,(B,C)),((A),B,C),观察任意功能的结果
概要设计
为了实现上述功能,需要定义数据结构
数据结构模块-广义表(Model层)
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
31GLNode
{
数据对象:D={ai|ai∈object}
数据关系:R={<ai,ai+1>|ai,ai+1 ∈ D}
}
基本操作:
GLNode<char> Create()
操作结果:创建广义表
string Write()
操作结果:输出广义表
int GetDepth(GLNode<char> node
操作结果:获取广义表的深度
int GetLength(GLNode<char>node)
操作结果:获取广义表的长度
string fuckHeads(string item)
操作结果:获取广义表的头
string fuckTails(string item)
操作结果:获取广义表的尾
GLNode<char> Reverse(GLNode<char> node)
操作结果:转置广义表
GLNode<char> Append(GLNode<char> head, GLNode<char> tail)
操作结果:广义表增添节点
GLNode<char> Copy(GLNode<char> node)
操作结果:复制广义表
bool findKey(string item,string find)
操作结果:查找目标节点
bool IsEmpty(GLNode<char> node)
操作结果:广义表空判断
bool Verify(string item)
操作结果:广义表的合法判断View-Model层
1
2
3
4
5
6
7
8
9
10
11
12
13
14void ToCreateGL(object sender, RoutedEventArgs e)
操作结果:在文本框显示建立广义表的提示语句
void ToOutGL(object sender, RoutedEventArgs e)
操作结果:在文本框显示输出广义表的提示语句
void ToFindNodeGL(object sender, RoutedEventArgs e)
操作结果:在文本框显示寻找节点广义表的提示语句
void ToFindHeadGL(object sender, RoutedEventArgs e)
操作结果:在文本框显示寻找广义表头的提示语句
void ToFindTail(object sender, RoutedEventArgs e)
操作结果:在文本框显示寻找广义表尾的提示语句
void ToOutDepth(object sender, RoutedEventArgs e)
操作结果:在文本框显示输出广义表深度的提示语句
void AllDoButton(object sender, RoutedEventArgs e)
操作结果: 根据选择的功能,更新文本框内的输出
- 主函数模块
1 | MainWindow() |
详细设计
定义广义表类
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//节点标识
public enum NodeType { Atom,List}
//对节点的声明
public class GLNode<T>
{
public NodeType Type { get; set; }
public GLNode<T> Next { get; set; }
public object Item { get; set; } //Save list or T in it by Type.
public GLNode()
{ this.Next = null; }
}
//广义表定义
public class GL
{
public GLNode<char> _Root;//关键节点
private char[] _CharArray;//广义表字符
private int i = 0;//递归标识
public GL(string item)
{ this._CharArray = item.ToCharArray(); }
public int Depth
{
//调用获取深度函数直接获取深度
}
#region 广义表的建立
public GLNode<char> Create()
{
//根据GL的charArray来递归建立广义表
//从charArray的第一个字符开始,遇到“(”则更新节点的标识(标识为0为普通字符元素,标识为1为表)则递归调用creat()函数,遇到普通字符元素则直接更新节点标识,节点内容储存该值
}
#endregion
#region 广义表的输出
public string Write()
{
return this.Write(this._Root);
}
public string Write(GLNode<char> node)
{
//创建StringBuilder实例sb来储存结果
//依次匹配节点标识,当节点type为普通字符则直接添加到sb中,当type为list则先添加“(”到sb中,再调用write()方法来对list进行上述操作并添加“)”到sb中
//返回结果sb
}
#endregion
#region 广义表的深度
public int GetDepth(GLNode<char> node)
{
//深度的求法是每个元素的括号匹配数加1的最大值
}
#endregion
#region 广义表的长度
public int GetLength(GLNode<char>node)
{
//长度的求法是最大括号中的逗号数加1
}
#endregion
#region 广义表的转置
public GLNode<char> Reverse(GLNode<char> node)
{
//GL节点为空则返回空值
//匹配节点的标识,当节点标识是普通元素字符时,调用Append()函数在广义表尾后添加头节点
//当节点标识是list时,调用Append()函数在表尾后添加新node,新node的内容需要再调用reverse()函数来得到
}
#endregion
#region 广义表增加节点
public GLNode<char> Append(GLNode<char> head, GLNode<char> tail)
{
//node为空直接返回需要增加的tail节点
//返回倒置的GLNode节点
//节点不空,则一直遍历到尾,知道添加tail节点
}
#endregion
#region 广义表获取表头
public GLNode<char> GetHead(GLNode<char> node)
{
//node为空则返回空
//直接返回node的item值
}
#endregion
#region 广义表获取表尾
public GLNode<char> GetTail(GLNode<char> node)
{
//node为空则返回空
//除去头就是尾
}
#endregion
#region 广义表复制
public GLNode<char> Copy(GLNode<char> node)
{
//匹配节点的标识,当节点标识是普通元素字符时,直接将其存储在item中
//当节点标识是list时,再调用copy()方法
//最终返回复制的node
}
#endregion
#region 广义表空判断
public bool IsEmpty(GLNode<char> node)
{ //node为空返回true }
#endregion
#region 广义表合法判断
public bool Verify(string item)
{
//遍历GL的广义表的字符,记录左括号,右括号,逗号,普通字符
//当左括号不等于右括号则为不合法
//当左括号为0也不合法
////当逗号数+1不等于普通字符数时也不合法
}
#endregion
#region 奇怪的表头尾输出
//像狗屎一样的遍历括号找头尾的方法
public string fuckHeads(string item)
{
//像狗屎一样的遍历括号找头尾的方法
}
#endregion
#region 省事的表尾输出
public string fuckTails(string item)
{
//去掉广义表头就是广义表尾
}
#endregion
#region 查找目标节点
public bool findKey(string item,string find)
{
//在GL字符串中查找目标字符find
//若存在则返回true,否则返回false
}
#endregion
}主函数定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class MainWindow : MetroWindow, INotifyPropertyChanged
{
private string _AllPut=string.Empty;
public string AllPut //全部展示在文本框的数据都是它
{
get { return _AllPut; }
set
{
_AllPut = value;
OnPropertyChanged("AllPut");
}
}
public bool CanDo { get; set; } //可操作标识,主要用来判断所有操作是否先创表
public int Flag { get; set; }//用于简陋的区分各类事件
public GL myGL { get; set; }//存储广义表
}交互
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//更新flag和allput值
private void ToCreateGL(object sender, RoutedEventArgs e)
private void ToOutGL(object sender, RoutedEventArgs e)
private void ToFindNodeGL(object sender, RoutedEventArgs e)
private void ToFindHeadGL(object sender, RoutedEventArgs e)
private void ToFindTail(object sender, RoutedEventArgs e)
private void ToOutDepth(object sender, RoutedEventArgs e)
//实现确定按钮的功能
private void AllDoButton(object sender, RoutedEventArgs e)
{
//当选择的功能为创表时,先判断文本框输入是否为空,若不为空则判断输入的广义表是否合法,若不合法,则弹出错误提示框,若正确则建立广义表,并更新可操作标识为true
//若可操作标识为true,且表不空则进行下列操作
//若选择的功能是输出广义表时,调用write()方法更新allput的值,并显示在文本框
//当选择的功能是寻找元素时,调用findkey()方法,若该元素存在,则更新allput值为“该元素存在”,并显示在文本框中,若不存在,则显示“该元素不存在”
//当选择的功能是输出表头时,调用fuckHeads()方法,更新allput值为广义表的头,并显示在文本框
//当选择的功能是输出表尾,调用fuckTails()方法,更新allput值为广义表的尾,并显示在文本框
//当选择的功能是输出深度,调用depth()方法,更新allput值为广义表的深度,并显示在文本框
}前端设计Xaml
编程设计
后端设计
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404namespace Model
{
public enum NodeType { Atom,List}
public class GLNode<T>
{
public NodeType Type { get; set; }
public GLNode<T> Next { get; set; }
public object Item { get; set; } //Save list or T in it by Type.
public GLNode()
{ this.Next = null; }
}
public class GL
{
public GLNode<char> _Root;
private char[] _CharArray;
private int i = 0;//for create GLNode by recursion.
public GL(string item) { this._CharArray = item.ToCharArray(); }
public int Depth
{
get
{
return GetDepth(this._Root);
}
}
public GLNode<char> Create()
{
GLNode<char> node = null;
char t = this._CharArray[i++];
if (i <= this._CharArray.Length)
{
node = new GLNode<char>();
switch (t)
{
case '(':
node.Type = NodeType.List;
node.Item = Create();
break;
case ')':
node = null;
break;
default:
node.Type = NodeType.Atom;
node.Item = t;
break;
}
}
else { return CreateReturn(node); }
if (i == this._CharArray.Length) return CreateReturn(node);
t = this._CharArray[i++];// For Next.
if (node != null)
{
switch (t)
{
case ',':
node.Next = Create();
break;
default:
node.Next = null;
break;
}
}
return CreateReturn(node);
}
private GLNode<char> CreateReturn(GLNode<char> node) { return this._Root = node; }
public string Write()
{
return this.Write(this._Root);
}
public string Write(GLNode<char> node)
{
StringBuilder sb = new StringBuilder();
switch (node.Type)
{
case NodeType.Atom:
sb.AppendFormat("{0}", node.Item.ToString());
break;
case NodeType.List:
sb.Append('(');
if (node.Item != null)
sb.Append(Write((GLNode<char>)node.Item));
sb.Append(')');
break;
}
if (node.Next != null)
{
sb.Append(",");
sb.Append(Write(node.Next));
}
return sb.ToString();
}
public int GetDepth(GLNode<char> node)
{
int max, depth;
if (node == null) return 1;
if (node.Next == null && node.Item == null) return 1;
for (max = 0; node != null; node = node.Next)
{
if (node.Type == NodeType.List)
{
depth = GetDepth((GLNode<char>)node.Item);
if (depth > max) max = depth;
}
}
return max + 1;
}
public int GetLength(GLNode<char>node)
{
int length=1;
if (node == null) return 1;
else
{
while(node.Next!=null)
{
length++;
node = node.Next;
}
}
return length;
}
public GLNode<char> Reverse(GLNode<char> node)
{
if (IsEmpty(node)) return null;
switch (node.Type)
{
case NodeType.Atom:
if (node.Next != null)
node = Append(Reverse(GetTail(node)), GetHead(node));
break;
case NodeType.List:
node = Append(Reverse(GetTail(node)), new GLNode<char>() { Item = Reverse((GLNode<char>)node.Item), Type = NodeType.List });
break;
}
return node;
}
public GLNode<char> Append(GLNode<char> head, GLNode<char> tail)
{
if (IsEmpty(head)) return tail;
var pre = head;
var cur = head.Next;
while (cur != null)
{
pre = cur;
cur = cur.Next;
}
pre.Next = tail;
return head;
}
public GLNode<char> GetHead(GLNode<char> node)
{
if (IsEmpty(node)) return null;
var item = new GLNode<char>();
item.Type = node.Type;
item.Item = node.Item;
return item;
}
public GLNode<char> GetTail(GLNode<char> node)
{
if (IsEmpty(node)) return null;
var temp = new GLNode<char>();
return temp = Copy(node.Next);
}
public GLNode<char> Copy(GLNode<char> node)
{
GLNode<char> temp = null;
if (node != null)
{
temp = new GLNode<char>();
temp.Type = node.Type;
switch (temp.Type)
{
case NodeType.Atom:
temp.Item = node.Item;
break;
case NodeType.List:
temp.Item = Copy((GLNode<char>)node.Item);
break;
}
temp.Next = Copy(node.Next);
}
return temp;
}
public bool IsEmpty(GLNode<char> node)
{ return node == null; }
public bool Verify(string item)
{
int commaNum = 0;
int charNum = 0;
int leftMarkNum = 0;
int rightMarkNum = 0;
foreach (char ch in item.ToCharArray())
{
switch (ch)
{
case '(':
leftMarkNum++;
break;
case ')':
rightMarkNum++;
break;
case ',':
commaNum++;
break;
default:
charNum++;
break;
}
}
if (leftMarkNum != rightMarkNum) return false;
if(leftMarkNum==0)return false;
if (commaNum != 0)
if (commaNum + 1 != charNum) return false;
return true;
}
//像狗屎一样的遍历括号找头尾的方法
public string fuckHeads(string item)
{
int commaNum = 0;
int leftMarkNum = 0;
int rightMarkNum = 0;
StringBuilder sb = new StringBuilder();
int flag = 0;
foreach (char ch in item.ToCharArray())
{
Console.WriteLine(ch);
if (flag != 2)
{
Console.WriteLine(ch);
switch (ch)
{
case '(':
leftMarkNum++;
if (flag != 0)
{
sb.Append(ch);
}
break;
case ')':
rightMarkNum++;
sb.Append(ch);
break;
case ',':
commaNum++;
sb.Append(ch);
break;
default:
sb.Append(ch);
break;
}
if (leftMarkNum - rightMarkNum == 1)
{
flag += 1;
}
}
}
string fuckTail = item;
return sb.ToString();
}
public string fuckTails(string item)
{
int commaNum = 0;
int leftMarkNum = 0;
int rightMarkNum = 0;
StringBuilder sb = new StringBuilder();
int flag = 0;
foreach (char ch in item.ToCharArray())
{
Console.WriteLine(ch);
if (flag != 2)
{
Console.WriteLine(ch);
switch (ch)
{
case '(':
leftMarkNum++;
if (flag != 0)
{
sb.Append(ch);
}
break;
case ')':
rightMarkNum++;
sb.Append(ch);
break;
case ',':
commaNum++;
sb.Append(ch);
break;
default:
sb.Append(ch);
break;
}
if (leftMarkNum - rightMarkNum == 1)
{
flag += 1;
}
}
}
Console.WriteLine($"POK:{sb}");
string fuckTail = item;
//去掉广义表头就是广义表尾
fuckTail = fuckTail.Replace(sb.ToString() + ",", "");
return fuckTail;
}
public bool findKey(string item,string find)
{
GLNode<char> temp=new GLNode<char>();
if (item.Contains(find)) return true;
else return false;
}
}
}交互
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
144namespace GeneralizedListDesign
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : MetroWindow, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
private string _AllPut=string.Empty;
public string AllPut
{
get { return _AllPut; }
set
{
_AllPut = value;
OnPropertyChanged("AllPut");
}
}
private string _AllOut=string.Empty;
public string AllOut
{
get { return _AllOut; }
set
{
_AllOut = value;
OnPropertyChanged("AllOut");
}
}
public bool CanDo { get; set; }
public int Flag { get; set; }
public GL myGL { get; set; }
private void ToCreateGL(object sender, RoutedEventArgs e)
{
Flag = 1;
CanDo = false;
AllPut = "请输入合法的广义表例如(A,B,(C))";
}
private void ToOutGL(object sender, RoutedEventArgs e)
{
Flag = 2;
AllPut = "是否输出广义表";
}
private void ToFindNodeGL(object sender, RoutedEventArgs e)
{
Flag = 3;
AllPut = "请输入要寻找的元素";
}
private void ToFindHeadGL(object sender, RoutedEventArgs e)
{
Flag = 4;
AllPut = "是否查找表头";
}
private void ToFindTail(object sender, RoutedEventArgs e)
{
Flag = 5;
AllPut = "是否查找表尾";
}
private void ToOutDepth(object sender, RoutedEventArgs e)
{
Flag = 6;
AllPut = "是否输出深度";
}
private void AllDoButton(object sender, RoutedEventArgs e)
{
if (Flag == 1)
{
if (AllPut != null)
{
myGL = new GL(AllPut);
if (myGL.Verify(AllPut))
{
myGL.Create();
CanDo = true;
}
else
{
AllPut = string.Empty;
AduMessageBox.Show("输入的广义表不合法,请重新选择功能");
}
}
}
if (!myGL.IsEmpty(myGL._Root) && CanDo)
{
if (Flag == 2)
{
AllPut = "广义表为:\n"+myGL.Write(myGL._Root);
}
if (Flag == 3)
{
string temp = myGL.Write(myGL._Root);
if (temp.Contains(AllPut))
{
AllPut = "该元素存在";
}
}
if (Flag == 4)
{
AllPut = "广义表表头为:\n" + myGL.fuckHeads(myGL.Write(myGL._Root));
}
if (Flag == 5)
{
AllPut = "广义表表尾为:\n"+myGL.fuckTails(myGL.Write(myGL._Root));
}
if (Flag == 6)
{
AllPut = "深度为" + myGL.Depth;
}
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
}
}前端设计
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<AduSkin:MetroWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:AduSkin="clr-namespace:AduSkin.Controls.Metro;assembly=AduSkin"
xmlns:local="clr-namespace:GeneralizedListDesign"
xmlns:Model="clr-namespace:Model;assembly=Model" x:Class="GeneralizedListDesign.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width=" Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<AduSkin:MetroButton Margin="3" Grid.Row="0" Click="ToCreateGL" Background="#FFEE796F" >
<AduSkin:MetroButton.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</AduSkin:MetroButton.BorderBrush>
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="创建广义表"/></TextBlock>
</AduSkin:MetroButton>
<AduSkin:MetroButton Margin="3" Grid.Row="1" Click="ToOutGL">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="输出广义表"/></TextBlock>
</AduSkin:MetroButton>
<AduSkin:MetroButton Margin="3" Grid.Row="2" Click="ToFindNodeGL">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="查找节点"/></TextBlock>
</AduSkin:MetroButton>
<AduSkin:MetroButton Margin="3" Grid.Row="3" Click="ToFindHeadGL">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="查找表头"/></TextBlock>
</AduSkin:MetroButton>
<AduSkin:MetroButton Margin="3" Grid.Row="4" Click="ToFindTail">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="查找表尾"/></TextBlock>
</AduSkin:MetroButton>
<AduSkin:MetroButton Margin="3" Grid.Row="5" Click="ToOutDepth">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="输出深度"/></TextBlock>
</AduSkin:MetroButton>
</Grid>
<GridSplitter Grid.Column="1" Width="3" HorizontalAlignment="Center" VerticalAlignment="Stretch" ShowsPreview="False"/>
<Grid Grid.Column="2" Cursor="Hand">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height=" Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox x:Name="输入处" Text="{Binding AllPut, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Margin="148,45,148,145" Height="100" Width="300" FontSize="28" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top" BorderBrush="#FFEE796F" BorderThickness="10,7,10,10" TextWrapping="WrapWithOverflow" />
<AduSkin:MetroButton Margin="198,210,198,0" Grid.Row="1" Click="AllDoButton" Height="80" Width="200">
<TextBlock Foreground="Black" FontSize="35" FontFamily="SimHei" HorizontalAlignment="Center" VerticalAlignment="Top"><Run Text="确定"/></TextBlock>
</AduSkin:MetroButton>
<GridSplitter Grid.Row="1" Height="3" VerticalAlignment="Center" HorizontalAlignment="Stretch" ShowsPreview="False"/>
</Grid>
<Canvas Grid.Column="2" Margin="0,0,0,426" Background="#FFE0AAAA"/>
</Grid>
</AduSkin:MetroWindow>
测试结果
问题和讨论
WPF- textbox数据绑定的问题:解决方法:设置属性UpdateSourceTrigger=PropertyChanged,Mode=TwoWay
WPF-dataContact无法找到绑定数据(主函数直接定义的属性)的问题:解决方法:设置属性 RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}
广义表深度的求法:解决办法:每个元素的括号匹配数加1的最大值
广义表长度的求法:长度的求法为最大括号中的逗号数加1
实训的总结和体会
在本次数据结构广义表的实训中,我们使用C#语言和WPF框架实现了广义表的基本功能,并且为广义表添加了可视化界面。通过这次实训,我对数据结构广义表有了更深入的了解,并且掌握了使用C#语言和WPF框架实现广义表的方法。
在实训中,我们首先学习了广义表的定义和基本操作。广义表是一种扩展了线性表的数据结构,它可以包含其他广义表作为其元素,从而形成了一个多层次的结构。广义表的基本操作包括创建广义表,查找元素,查找表头表尾等。
在实现广义表的基本功能和可视化界面时,我们首先设计了广义表的数据结构,同样使用链表来表示广义表。然后,我们使用C#语言和WPF框架实现了广义表的创建,查找表头表尾操作,并且计划设计了一个可视化界面来展示广义表的结构和操作。
但在实训过程中,我遇到了一些困难和问题。其中一个困难是如何将广义表的结构可视化展示出来。由于广义表可以包含其他广义表,所以在展示广义表的结构时,我需要考虑如何递归地遍历广义表的每个节点,并将其展示在界面上。为了解决这个问题,我使用了递归的方法,在遍历广义表节点时,递归地调用展示函数,并且使用WPF框架的布局控件来展示广义表的结构,但还是遇到了奇怪问题,时间有限最终只能放弃,这倒是我比较遗憾的地方,还有比较折腾的是wpf数据绑定的问题,因为设计是需要双向绑定的,但是按照微软的说明文档(看得比较玄),当我的后台数据更新时前台居然没有显示,于是乎在网上四处搜索,一个比一个玄乎,且毫无作用,有的似乎正确但是又出现了别的问题,最后临机一动直接用blend进行数据绑定,成功发现其实是父类的问题,问题解决。
通过这次实训,我不仅学到了广义表的基本概念和操作,还提高了我的编程能力,并且学会了使用WPF框架实现可视化界面,之前可能winform用的比较多(大一倒是有去使用,大二不知道在干嘛),当然也是比较简陋的使用。在实现广义表的过程中,我需要考虑如何设计数据结构、如何处理特殊情况以及如何展示广义表的结构等,这对我的编程能力提出了一定的要求。同时,我也学会了使用WPF框架来实现简单的可视化界面。
总的来说,这次数据结构广义表的实训让我对广义表有了更深入的了解,掌握了使用C#语言和WPF框架实现广义表的方法,并且实现了可视化界面。通过实践,我提高了我的编程能力,并且对数据结构和界面设计有了更深入的理解。我相信这次实训对我的学习和工作都有很大的帮助。