自我描述的語句指這樣一種語句:它的內容就是對它本身的描述。(廢話……)比如下面這句句子:
代碼如下:
這是一段自我描述的語句,除了標點符號外,它共包含125個字符,其中33個“個”,29個“2”,5個“3”,3個“符”,3個“5”,2個“一”,2個“它”,2個“包”,2個“的”,2個“標”,2個“了”,2個“我”,2個“外”,2個“含”,2個“中”,2個“是”,2個“1”,2個“段”,2個“點”,2個“描”,2個“9”,2個“字”,2個“這”,2個“句”,2個“除”,2個“自”,2個“語”,2個“共”,2個“述”,2個“號”,2個“其”。
這句話是我用一段 Python 腳本生成的,生成原理大致如下:
1、給出一個模板,讓句子的各個內容知道自己該出現在哪個部位;
2、根據當前信息,生成句子;
3、將當前句子作為輸入,再次執行第 2 步的操作;
4、直到句子各部分內容的信息都正確。
簡單來說,就是一個不斷迭代修正的過程。
其中需要注意的是,每次迭代時應該盡量只改動一個地方,以免兩處同時變化相互影響,造成死循環;另外,如果句子中有多處地方需要修正,盡量隨機選取一處進行修正,而不要按一定順序進行修正,同樣是為了減少陷入死循環的風險。
不過,即使如此,某些情況下還是有可能陷入死循環,比如如果某一步得到了下面這樣的句子:
代碼如下:
這句很 2 的話包含 3 個“2”。
上面這句話明顯是錯誤的,因為其中只有兩個“2”。那么,我們把那個“3”改為“2”,是不是就對了呢?很容易發現,如果我們做了這樣的改動之后,句子將變成:
代碼如下:
這句很 2 的話包含 2 個“2”。
這時,句子中又包含三個“2”了。像這樣的句子就似乎無法簡單地改為正確的自我描述語句,因為無論如何改都會陷入死循環。
最后,我用來生成最上面的那句自我描述語句的 Python 腳本如下:
# -*- coding: utf-8 -*-import randomclass 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" % sdif __name__ == "__main__": main()
新聞熱點
疑難解答