- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在做 Udacity CS262,对于 Detecting Ambiguity 问题,我不确定我的解决方案是否正确,我也不确定“官方”解决方案是否正确。
问题简要描述:编写一个函数 isambig(grammar, start, string),它接受有限上下文无关文法(编码为 python 字典)、文法的起始符号和一个字符串。如果有两个解析树通向字符串,那么语法是有歧义的(或者至少这是我对歧义的理解 - 如果我弄错了请纠正我)。如果语法有歧义,则返回 True。否则返回 False。
测试用例:
grammar1 = [
("S", [ "P", ]),
("S", [ "a", "Q", ]) ,
("P", [ "a", "T"]),
("P", [ "c" ]),
("Q", [ "b" ]),
("T", [ "b" ]),
]
print isambig(grammar1, "S", ["a", "b"]) == True
print isambig(grammar1, "S", ["c"]) == False
grammar2 = [
("A", [ "B", ]),
("B", [ "C", ]),
("C", [ "D", ]),
("D", [ "E", ]),
("E", [ "F", ]),
("E", [ "G", ]),
("E", [ "x", "H", ]),
("F", [ "x", "H"]),
("G", [ "x", "H"]),
("H", [ "y", ]),
]
print isambig(grammar2, "A", ["x", "y"]) == True
print isambig(grammar2, "E", ["y"]) == False
grammar3 = [ # Rivers in Kenya
("A", [ "B", "C"]),
("A", [ "D", ]),
("B", [ "Dawa", ]),
("C", [ "Gucha", ]),
("D", [ "B", "Gucha"]),
("A", [ "E", "Mbagathi"]),
("A", [ "F", "Nairobi"]),
("E", [ "Tsavo" ]),
("F", [ "Dawa", "Gucha" ])
]
print isambig(grammar3, "A", ["Dawa", "Gucha"]) == True
print isambig(grammar3, "A", ["Dawa", "Gucha", "Nairobi"]) == False
print isambig(grammar3, "A", ["Tsavo"]) == False
我已经添加了我自己的测试用例。我不确定这是否正确,但我只能看到导致字符串“a b”的可能的一棵解析树,因此该字符串不能证明语法有歧义。而且我不认为语法有歧义。
grammar4 = [ # Simple test case
("S", [ "P", "Q"]),
("P", [ "a", ]),
("Q", [ "b", ]),
]
print isambig(grammar4, "S", ["a", "b"]) == False
这是“官方”程序:
def expand(tokens_and_derivation, grammar):
(tokens,derivation) = tokens_and_derivation
for token_pos in range(len(tokens)):
for rule_index in range(len(grammar)):
rule = grammar[rule_index]
if tokens[token_pos] == rule[0]:
yield ((tokens[0:token_pos] + rule[1] + tokens[token_pos+1:]), derivation + [rule_index])
def isambig(grammar, start, utterance):
enumerated = [([start], [])]
while True:
new_enumerated = enumerated
for u in enumerated:
for i in expand(u,grammar):
if not i in new_enumerated:
new_enumerated = new_enumerated + [i]
if new_enumerated != enumerated:
enumerated = new_enumerated
else:
break
result = [xrange for xrange in enumerated if xrange[0] == utterance]
print result
return len(result) > 1
这是我自己的,更长的程序:
def expand(grammar, symbol):
result = []
for rule in grammar:
if rule[0] == symbol:
result.append(rule[1])
return result
def expand_first_nonterminal(grammar, string):
result = []
for i in xrange(len(string)):
if isterminal(grammar, string[i]) == False:
for j in expand(grammar, string[i]):
result.append(string[:i]+j+string[i+1:])
return result
return None
def full_expand_string(grammar,string, result):
for i in expand_first_nonterminal(grammar,string):
if allterminals(grammar,i):
result.append(i)
else:
full_expand_string(grammar,i,result)
def isterminal(grammar,symbol):
for rule in grammar:
if rule[0] == symbol:
return False
return True
def allterminals(grammar,string):
for symbol in string:
if isterminal(grammar,symbol) == False:
return False
return True
def returnall(grammar, start):
result = []
for rule in grammar:
if rule[0] == start:
if allterminals(grammar,rule[1]):
return rule[1]
else:
full_expand_string(grammar, rule[1], result)
return result
def isambig(grammar, start, utterance):
count = 0
for i in returnall(grammar,start):
if i == utterance:
count+=1
if count > 1:
return True
else:
return False
现在,我的程序通过了所有测试用例,包括我添加的测试用例(grammar4),但是官方解决方案通过了除我添加的测试用例之外的所有测试用例。看来要么是测试用例不对,要么就是官方的方案不对。
官方解法正确吗?我的解决方案正确吗?
最佳答案
对我来说,grammar4
似乎没有歧义。只有一棵解析树:
S -> PQ
P -> a
Q -> b
S
|
___|____
P Q
| |
a b
但是官方程序说是模棱两可的,因为它使用了规则P -> a
和 Q -> b
连续:
[(['a', 'b'], [0, 1, 2]), (['a', 'b'], [0, 2, 1])]
(现在有两个规则序列 0,1,2
和 0,2,1
。)
因此“官方”程序似乎将 grammar4
错误地检测为有歧义。
更新:我查看了您的代码并做了一些测试,除了没有处理递归(官方版也不处理递归),你的程序似乎正确地区分了模棱两可的和明确。
简单测试:
grammar5 = [
("S", ["A", "B"]),
("S", ["B", "A"]),
("A", ["a"]),
("B", ["a"]),
]
print(isambig(grammar5, "S", ["a", "a"]))
S -> AB
S -> BA
A -> a
B -> a
S
|
___|____
A B
| |
a a
S
|
___|____
B A
| |
a a
您的版本返回“模棱两可”(“官方”版本也是如此。)
如果您删除 ("S", ["B", "A"])
,您的版本正确切换到“不模糊”,而另一个版本仍然返回“模糊”(我们回到 grammar4 的情况。)
也许其他人(比我更有经验)可以插话。
更新 2: Ira Baxter 提到这是一个无法确定的问题上下文无关文法是有歧义的。
另见 How is proving a context free language to be ambiguous undecidable?
关于python - 这些用于检测有限语法歧义的 Python 程序是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25621146/
在此处回答的另一个问题中,我发现了以下 JavaScript代码: function _dom_trackActiveElement(evt) { if (evt && evt.target)
if (A == 0) OR (B == 0) 怎么说? 最佳答案 只是为了讽刺: if (A === 0 || B === 0) 关于语法,我们在Stack Overflow上找到一个类似的问题:
var ret = [] ,xresult = document.evaluate(exp, rootEl, null, X
我一直在寻找一些类似于下例的 JavaScript。有人可以解释一下吗,因为我以前从未见过这样编写的 JavaScript。 “SomethingHere”和冒号代表什么?我习惯于看到函数 myFun
这是我的程序: delimiter // drop procedure if exists migContactToActor; create procedure migContactToActor(
我遇到了一个问题。我一直在使用 gcc 编译/汇编我的 C 代码一段时间,并且习惯了阅读 Intel 汇编语法。我在生成程序集文件时使用了 -masm=intel 标志。 但是最近因为公司迁移,拿到了
自上而下和自下而上语法有什么区别?举个例子就太好了。 最佳答案 首先,语法本身不是自上而下或自下而上的,解析器是(尽管有些语法可以被其中一个解析,但不能被另一个解析)。 从实践的角度来看,主要区别在于
我知道这是草率的代码,但它是: display dialog ("Start Screensaver. Please type: matrix, coffee, waffles, star, wate
这个问题已经有答案了: Giving name to a loop (6 个回答) 已关闭 8 年前。 我见过这个字符在 C# 中使用,就像 Java 中的扩展一样,但最近我在代码中发现了这个 loo
我正在尝试编写一个函数来检查字符串是否为回文,但我认为在使用字符串指针时存在一些错误。这段代码有什么问题? #include #include #define MAX 1000 int IsPalin
所以在this question我询问了一些 Javascript 是如何被压缩的。问题已得到解答,但以下片段让我非常困惑,以至于我不得不问另一个问题。在这里: for (Y = 0; $ = 'zx
假设我有一个接受这些参数的函数。 int create(Ptr * p,void * (*insert)(void *, void *)) { //return something later } 结
这个问题已经有答案了: Bitwise '&' operator (6 个回答) 已关闭 5 年前。 我在代码中找到了这个,但我从未遇到过像 & 这样的事情,仅 && if ((code & 1) =
我在处理继承类及其中的构造函数和方法的语法时遇到了问题。 我想实现一个类日期和一个子类 date_ISO,它们将按特定顺序设置给定的日、月、年,并通过一种方法将其写入字符串。我觉得我的基类日期工作正常
我正在尝试通过存储过程填充表,如下所示: SET @resultsCount = (SELECT COUNT(*) FROM tableA); SET @i = 0; WHILE @i THEN
谁能解释一下下面代码中的“<<”? mysql test<
刚刚开始学习 MySQL,这是一个菜鸟问题,也是我在 StackOverflow 上的第一个问题。 假设我有 12 个订单状态,我想从其中的 5 个中选择总计。我会使用: SELECT SUM(tot
我的编程背景是在学校学过一点Java。由于某些原因,JavaScript 语法往往让我感到困惑。下面的 JavaScript 代码是一种我不知道如何构成的语法模式: foo.ready = funct
我正在阅读 javascript 源代码,并且我以前没有编写过 javascript。我对它的一些语法感到困惑。 $(function () { window.onload=function
我什至不知道如何命名我想要的东西。那么让我举个例子来解释一下。 虽然火狐使用textContent,但其他浏览器支持innerText属性。顺便说一句,如果我使用了错误的术语,请纠正我。无论如何,到目
我是一名优秀的程序员,十分优秀!