时间:2021-07-01 10:21:17 帮助过:60人阅读
1、给出一个模板,让句子的各个内容知道自己该出现在哪个部位;
2、根据当前信息,生成句子;
3、将当前句子作为输入,再次执行第 2 步的操作;
4、直到句子各部分内容的信息都正确。
简单来说,就是一个不断迭代修正的过程。
其中需要注意的是,每次迭代时应该尽量只改动一个地方,以免两处同时变化相互影响,造成死循环;另外,如果句子中有多处地方需要修正,尽量随机选取一处进行修正,而不要按一定顺序进行修正,同样是为了减少陷入死循环的风险。
不过,即使如此,某些情况下还是有可能陷入死循环,比如如果某一步得到了下面这样的句子:
上面这句话明显是错误的,因为其中只有两个“2”。那么,我们把那个“3”改为“2”,是不是就对了呢?很容易发现,如果我们做了这样的改动之后,句子将变成:
这时,句子中又包含三个“2”了。像这样的句子就似乎无法简单地改为正确的自我描述语句,因为无论如何改都会陷入死循环。
最后,我用来生成最上面的那句自我描述语句的 Python 脚本如下:
- # -*- coding: utf-8 -*-
- import random
- class SelfDesc(object):
- ignore_chars = u",。“”"
- def __init__(self, template):
- self.template = template
- self.length = 0
- self.detail = ""
- self.content = ""
- self.chars = ""
- self.char_count = {}
- self.makeContent()
- self.char_count = self.getCharCount()
- self.getCharCount()
- self.makeContent()
- def __str__(self):
- return self.content
- def makeContent(self):
- self.makeDetail()
- self.content = self.template.replace(u"{length}", u"%d" % self.length)
- .replace(u"{detail}", self.detail)
- self.getChars()
- def getChars(self):
- chars = self.content
- for c in self.ignore_chars:
- chars = chars.replace(c, "")
- self.chars = chars
- return chars
- def getLength(self):
- self.length = len(self.chars)
- def getCharCount(self):
- d = {}
- for c in self.chars:
- if c in self.ignore_chars:
- continue
- d.setdefault(c, 0)
- d[c] += 1
- return d
- def makeDetail(self):
- d = self.char_count
- items = d.items()
- items.sort(key=lambda x: -x[1])
- s = []
- for c, n in items:
- s.append(u"%d个“%s”" % (n, c))
- self.detail = u",".join(s)
- def correct(self):
- print "-" * 50
- char_count = self.getCharCount()
- items = char_count.items()
- random.shuffle(items)
- for c, n in items:
- if n <= 1 and c in self.char_count:
- del self.char_count[c]
- continue
- if self.char_count.get(c) == n:
- continue
- else:
- self.char_count[c] = n
- return True
- else:
- len = self.length
- self.getLength()
- if len != self.length:
- return True
- return False
- def generate(self):
- icount = 0
- while self.correct():
- icount += 1
- self.makeContent()
- print u"#%d %s" % (icount, self)
- def main():
- template = u"这是一段自我描述的语句,除了标点符号外,它共包含{length}个字符,其中{detail}。"
- sd = SelfDesc(template)
- sd.generate()
- print u"%s" % sd
- if __name__ == "__main__":
- main()