2

我正在阅读 UVA 的练习,我需要模拟确定性堆栈自动机,以查看 DSA 在给定条目上是否接受某些字符串,格式如下:

输入的第一行将是一个整数 C,表示测试用例的数量。每个测试用例的第一行包含五个整数 E、T、F、S 和 C,其中 E 表示自动机中的状态数,T 表示转换数,F 表示最终状态数,S 表示初始状态和C 分别为测试字符串的数量。下一行将包含 F 个整数,代表自动机的最终状态。然后是 T 行,每行有 2 个整数 I 和 J 以及 3 个字符串 L、T 和 A,其中 I 和 J (0 ≤ I, J < E) 分别表示过渡状态的起始状态和目的地状态。L 表示从磁带中读取的字符进入过渡,T 表示在堆栈顶部找到的符号,A 表示在此转换结束时使用堆栈顶部执行的操作(用于表示堆栈底部的字符始终为 Z。字符串,或unstack 不考虑栈顶的动作用于转换字符£)。堆栈的字母表将是大写字母。对于链 A,符号从右到左堆叠(与程序 JFlap 的方式相同,即栈的新顶部将是左侧的字符)。然后是 C 行,每行都有一个输入字符串。输入字符串可能包含小写字母和数字(不一定存在于任何转换中)。或 unstack 不考虑堆栈顶部的操作用于转换字符£)。堆栈的字母表将是大写字母。对于链 A,符号从右到左堆叠(与程序 JFlap 的方式相同,即栈的新顶部将是左侧的字符)。然后是 C 行,每行都有一个输入字符串。输入字符串可能包含小写字母和数字(不一定存在于任何转换中)。或 unstack 不考虑堆栈顶部的操作用于转换字符£)。堆栈的字母表将是大写字母。对于链 A,符号从右到左堆叠(与程序 JFlap 的方式相同,即栈的新顶部将是左侧的字符)。然后是 C 行,每行都有一个输入字符串。输入字符串可能包含小写字母和数字(不一定存在于任何转换中)。

每个测试用例第一行的输出必须显示以下字符串“Case G:”,其中 G 表示测试用例的数量(从 1 开始)。如果自动机接受字符串,则在 C 行上打印单词“OK”,否则打印“Reject”。

例如:

Input:
2
3 5 1 0 5
2
0 0 1 Z XZ
0 0 1 X XX
0 1 0 X X
1 1 1 X £
1 2 £ Z Z
111101111
110111
011111
1010101
11011
4 6 1 0 5
3
1 2 b A £
0 0 a Z AZ
0 1 a A AAA
1 0 a A AA
2 3 £ Z Z
2 2 b A £
aabbb
aaaabbbbbb
c1bbb
abbb
aaaaaabbbbbbbbb

这是输出:

Output:
Case 1:
Accepted
Rejected
Rejected
Rejected
Accepted

Case 2:
Accepted
Accepted
Rejected
Rejected
Accepted   

我需要一些帮助,或者知道如何模拟这个 DSA,我不是在问我解决问题的代码,因为我想制作自己的代码(这个想法是学习对吗??),但我需要一些帮助(一些想法或伪代码)开始实施。

4

1 回答 1

2

您首先需要一个数据结构来保持转换。您可以将向量与包含转换五元组的转换结构一起使用。但是您可以使用状态是整数的事实并创建一个保持在索引 0 的向量,从状态 0 转换;在索引 1 处,像这样从状态 1 转换。这样,您可以减少查找正确过渡的搜索时间。

您可以轻松地将 stl 库中的堆栈用于堆栈。您还需要搜索功能,如果您使用第一种方法,它可以根据您的实现进行更改,您可以使用如下功能:

int findIndex(vector<quintuple> v)//which finds the index of correct transition otherwise returns -1

然后使用返回值获取 newstate 和 newstack 符号。

或者,您可以在向量和 bool 标志上使用 for 循环来表示是否找到了转换。

在第二种方法中,您可以使用一个函数来引用新状态和新堆栈符号,并在找到合适的转换时设置它们。

对于输入,您可以使用矢量或矢量等内容,具体取决于个人喜好。您可以使用 for 循环实现 main 方法,但如果您想要额外的困难,您可以实现递归函数。愿它容易。

于 2011-07-13T19:27:06.803 回答