我的代码需要帮助。我需要将一个输入单词转换为另一个输入单词,一次更改一个字母。目前,我的程序执行此操作,但是效率很低,并且找不到最短的路径。任何帮助,将不胜感激。

import re
def same(item, target):
  return len([c for (c, t) in zip(item, target) if c == t])

def build(pattern, words, seen, list):
  return [word for word in words
                 if re.search(pattern, word) and word not in seen.keys() and
                    word not in list]

def find(word, words, seen, target, path):
  list = []
  for i in range(len(word)):
    list += build(word[:i] + "." + word[i + 1:], words, seen, list)
  if len(list) == 0:
    return False
  list = sorted([(same(w, target), w) for w in list])
  for (match, item) in list:
    if match >= len(target) - 1:
      if match == len(target) - 1:
        path.append(item)
      return True
    seen[item] = True
  for (match, item) in list:
    path.append(item)
    if find(item, words, seen, target, path):
      return True
    path.pop()

fname = 'dictionary.txt'
file = open(fname)
lines = file.readlines()
while True:
  start = input("Enter start word:")
  words = []
  for line in lines:
    word = line.rstrip()
    if len(word) == len(start):
      words.append(word)
  target = input("Enter target word:")
  break

count = 0
path = [start]
seen = {start : True}
if find(start, words, seen, target, path):
  path.append(target)
  print(len(path) - 1, path)
else:
  print("No path found")


编辑:以下是我通过尝试其他方法来解决此问题的另一次失败尝试。这次似乎无法正确循环。

def find(start, words, target): # find function. Word = start word, words =

  start=list(start)
  target=list(target)

  print("Start word is ", start)
  print("Target word is ", target)


  letter = 0
  while start != target:
      if letter == len(target):
          letter = 0
          continue

      elif start[letter] == target[letter]:
          letter = letter + 1
          continue

      else:
          testword = list(start)
          testword[letter] = target[letter]
          testword = ''.join(testword)
          if testword in words:
              start[letter] = target[letter]
              letter = letter + 1
              print(start)
              continue
          else:
              letter = letter + 1
              continue

      letter = letter + 1
      continue




fname = "dictionary.txt"
file = open(fname) # Open the dictionary
lines = file.readlines() # Read each line from the dictionary and store it in lines
while True: # Until ended
  start = input("Enter start word:") # Take a word from the user
  words = [] # Inititialise Array 'words'
  for line in lines: # For each line in the dictionary
    word = line.rstrip() #strip all white space and characters from the end of a string
    if len(word) == len(start):
      words.append(word)

  if start not in words:
      print("Your start word is not valid")
      continue

  target = input("Enter target word:")
  if len(start) != len(target):
      print("Please choose two words of equal length")
      continue

  if target not in words:
      print("Your target word is not valid")
      continue


  break


编辑:这是代码的基本算法。 (两种变体都符合我的目的)。

-input start word
-input target word
- if len(start) = len(target)
       continue
       -check dictionary to see if target and start words are present
       - find what letters are different from the start to target word
       - change one different letter in the start word until start word
        =target
        word #after each letter change, output must be valid word in dictionary
The goal is to achieve this in the least amount of steps which is not achieved, the first section of code does this, I think but in a huge amount of steps I know could be far more efficient

最佳答案

这是不使用任何第三方模块的广度优先搜索。我不保证它会找到最短的解决方案,但它似乎可以工作。 ;)在找到解决方案时停止,但是由于集合的随机顺序,程序的每次运行都可能为给定的开始和目标对找到不同的解决方案。

import re

# The file containing the dictionary
fname = '/usr/share/dict/words'

start, target = 'hide', 'seek'

wlen = len(start)
wrange = range(wlen)

words = set()
with open(fname) as f:
    for word in f:
        w = word.rstrip()
        # Grab words of the correct length that aren't proper nouns
        # and that don't contain non-alpha chars like apostrophe or hyphen
        if len(w) == wlen and w.islower() and w.isalpha():
            words.add(w)
print('word set size:', len(words))

# Build a regex to find words that differ from `word` by one char
def make_pattern(word):
    pat = '|'.join(['{}.{}'.format(word[:i], word[i+1:]) for i in wrange])
    return re.compile(pat)

# Find words that extend each chain of words in `seq`
def find(seq):
    result = []
    seen = set()
    for current in seq:
        pat = make_pattern(current[-1])
        matches = {w for w in words if pat.match(w)} - seen
        if target in matches:
            return current + (target,)
        result.extend(current + (w,) for w in matches)
        seen.update(matches)
        words.difference_update(matches)
    seq[:] = result

# Search for a solution
seq = [(start,)]
words.discard(start)
while True:
    solution = find(seq)
    if solution:
        print(solution)
        break
    size = len(seq)
    print(size)
    if size == 0:
        print('No solutions found')
        break


典型输出

word set size: 2360
9
55
199
479
691
('hide', 'hire', 'here', 'herd', 'heed', 'seed', 'seek')




我应该提到的是,所有这些词链都占用了一些RAM,我将尝试考虑一种更紧凑的方法。但这在现代机器上应该不是真正的问题,除非您使用的是很大的单词。

关于python - 将源词转换成目标词,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45785582/

10-11 11:24