繁体   English   中英

给定一个元组列表,检查是否可以构造一个单词,其中元组中的第二个值不连续重复

[英]Given a list of tuples, check to see if it's possible to construct a word in which the second value in the tuple is not consecutively repeated

假设我有一个像这样的元组列表:

list_of_tuples = [('A', 'R'), ('B', 'R'), ('C', 'G'), ('D', 'G'), ('E', 'B'), ('D', 'B'), ('R', 'B'), ('F', 'R'), ('V', 'R'), ('A', 'G')]

每个元组中的第二个值将始终是RBG 我想创建一个函数validate来检查是否可以使用每个元组第一个位置的字母构造某个单词,但前提是该元组的部分位置中的字母不重复。

例如,可以构造单词:

ACE(A, R) , (C, G)(E, B)因为每个元组中的第二个值对应于不连续重复任何字母的RGB

ACED(A, R), (C, G), (E, B), and ('D', 'B')是不可能的,因为这将对应于RGBB在其中有一个连续的B.

请注意,有时同一个字母的第二个位置可以有不同的字母,例如:

('A', 'R') and ('A', 'G') 如果您选择了第一个元组,则只能拼写ACE而不是第二个,否则G会重复。

另请注意,即使第二个位置字母“重复”它们不会连续重复,像GBRBG这样的组合也是可能的。

所以我想要一个可以通过以下方式验证单词的函数:

def validate(submitted_word, list_of_tuples)

一种可能性是构造这个集合可能的序列的每一个可能的组合以及第二个序列中的字母将产生的相应序列,过滤掉有效单词的那些,然后过滤掉那些连续的字母重复,但我担心考虑到元组列表可以变得有多大效率低下。

这是一个图遍历问题。 您的可用节点是 (letter, color) 的元组; 您的边缘是给定单词中的字母转换。

对于每个输入,“简单地”构建该单词的图形。 给定 ACE,你有

Layer 1 -- transition START to any A
START -> AR
START -> AG

Layer 2 -- transition A to C
AR -> CG
not allowed: AG -> CG

Layer 3 -- transition C to E
CG -> EB

Layer 4 -- transition any E to GOAL
EB -> GOAL

现在您只需应用图形遍历功能(任何自尊的图形包都有)来解决您的拼写问题。

请参阅下面的独立解决方案和测试:

list_of_tuples = [
    ('A', 'R'),
    ('B', 'R'),
    ('C', 'G'),
    ('D', 'G'),
    ('E', 'B'),
    ('D', 'B'),
    ('R', 'B'),
    ('F', 'R'),
    ('V', 'R'),
    ('A', 'G')
]

def validate(submitted_word, list_of_tuples):
    # Check length of word
    if len(submitted_word) == 0:
        raise ValueError("len(submitted_word) must be > 0")

    # Initialise options for first character
    options = [[tup for tup in list_of_tuples if tup[0] == submitted_word[0]]]
    # Iterate through the rest of the characters
    for char in submitted_word[1:]:
        # Initialise set of characters in second position of previous tuple
        forbidden_chars = set(tup[1] for tup in options[-1])
        # Add valid options for the next character
        options.append([
            tup
            for tup in list_of_tuples
            if (tup[0] == char) and len(forbidden_chars - set(tup[1])) > 0
        ])
        # If there are no options, then submitted_word does not validate
        if len(options[-1]) == 0:
            print(options)
            return False
    
    print(options)
    return True

print(validate("ACE", list_of_tuples))
print()
print(validate("ACED", list_of_tuples))
print()
print(validate("ACFFFED", list_of_tuples))

控制台输出:

[[('A', 'R'), ('A', 'G')], [('C', 'G')], [('E', 'B')]]
True

[[('A', 'R'), ('A', 'G')], [('C', 'G')], [('E', 'B')], [('D', 'G')]]        
True

[[('A', 'R'), ('A', 'G')], [('C', 'G')], [('F', 'R')], []]
False

我们可以使用回溯,其中状态是每个字母使用的每个 R、G、B 的计数,以及我们构造单词时选择的先前“RGB”。

Python 代码(未记忆):

def f(i, word, prev, state):
  if i == len(word):
    return True

  letter = word[i]

  for second in ["R", "G", "B"]:
    if state[letter][second] and prev != second:
      state[letter][second] -= 1
      is_valid = f(i + 1, word, second, state)
      state[letter][second] += 1
      if is_valid:
        return True

  return False

def get_counts(tuples):
  result = {}
  for letter, rgb in tuples:
    if letter in result:
      result[letter][rgb] += 1
    else:
      result[letter] = {"R": 0, "G": 0, "B": 0}
      result[letter][rgb] = 1
  return result

tuples = [('A', 'R'), ('B', 'R'), ('C', 'G'), ('D', 'G'), ('E', 'B'), ('D', 'B'), ('R', 'B'), ('F', 'R'), ('V', 'R'), ('A', 'G')]

counts = get_counts(tuples)

print f(0, "ACE", "", counts) # True
print f(0, "ACED", "", counts) # True
print f(0, "BF", "", counts) # False

我构建了以下内容。 首先,我们创建一个函数来比较 2 个列表并检查它们是否至少有一个不同的元素。 其次,我们为单词中所有连续字母对的关联列表运行此函数。 我认为单词的所有字母都在 list_of_tuples 中表示。 否则它将需要多几行来检查是否存在(在这种情况下让我知道,以便我添加它们)。

def validate(word, list_of_tuples):
    def rgb(l1,l2):
        return len(set(l1).difference(set(l2)))>0

l=[[i, [k[1] for k in list_of_tuples if k[0]==i]] for i in word]

for i in range(len(l)-1):
    if not rgb(l[i][1], l[i+1][1]):
        return False
return True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM