1 回答

TA貢獻1757條經驗 獲得超7個贊
你幾乎讓程序工作。以下是完成該函數的方法:reachTerminals
import random
psg_rules_str = "S → NP VP\n" \
"NP → Det Adj N | Det N | Adj PropN | PropN\n" \
"VP → Vi | Vt NP | Vc Comp S"
terminals_str = "Det → the | a | some | any | every\n" \
"Adj → green | young | tired | confused\n" \
"N → dog | cat\n" \
"PropN → John | Mary\n" \
"Vi → sleeps | walks\n" \
"Vt → loves | hates\n" \
"Vc → says | thinks | believes\n" \
"Comp → that"
psg_rules_list = [a.split("→") for a in psg_rules_str.split("\n")]
for p in psg_rules_list:
p[0] = "_" + p[0].strip()
p[1] = p[1].split("|")
p[1] = ["_" + a.strip().replace(" ", " _") for a in p[1]]
terminals_list = [a.split("→") for a in terminals_str.split("\n")]
for t in terminals_list:
t[0] = "_" + t[0].strip()
t[1] = t[1].split("|")
t[1] = [a.strip() for a in t[1]]
def reachTerminals(from_nts, with_rules, with_ts):
from_nts = str.upper("_" + from_nts.replace("_", "").strip().replace(" ", " _"))
rule_tags = [a[0] for a in with_rules]
ts_tags = [a[0] for a in with_ts]
nts_todo = [a for a in rule_tags if a in from_nts]
while nts_todo:
for tag in nts_todo:
wr_index = rule_tags.index(tag)
repl_choices = with_rules[wr_index][1]
choice = random.choice(repl_choices)
from_nts = from_nts.replace(tag, choice, 1)
nts_todo = [a for a in rule_tags if a in from_nts]
ts_todo = [a for a in ts_tags if a in from_nts]
while ts_todo:
for tag in ts_todo:
wr_index = ts_tags.index(tag)
repl_choices = with_ts[wr_index][1]
choice = random.choice(repl_choices)
from_nts = from_nts.replace(tag, choice, 1)
ts_todo = [a for a in ts_tags if a in from_nts]
return from_nts
print(reachTerminals(from_nts = "s", with_rules = psg_rules_list, with_ts = terminals_list))
您可以使用的重要工具是 random.option 函數和 str.replace 函數的第三個參數,它只允許您替換子字符串的第一個匹配項。我還沒有徹底測試代碼,但它似乎按預期工作。輸出示例:
green John loves some confused dog
Mary says that the tired dog says that some green cat hates some cat
every green dog loves young John
John loves the tired cat
添加回答
舉報