如何检测字符串是否包含其他字符串中的所有元素,同时它们的出现顺序排列?

时间:2017-11-25 00:38:46

标签: python

我需要检测字符串'Relim'的元素是否全部在字符串'Berkelium'中,同时'Relim'中的每个字母都出现在字符串{{1}中}} 为了。例如,' Relim '在' r k eli u m '时出现' Relim '在'be r k eli u m '中按顺序排列。

我的主要想法是循环遍历字符串'Berkelium',然后逐个检查'Berkelium'中的字符是否等于字符串'Berkelium'中的元素,如果是,则记录此字符的索引'Relim'。在for循环之后,检查所有元素'Relim'是否出现在'Relim'中,还是按升序排列。由于我循环遍历字符串'Berkelium',然后我可以确保字母的出现顺序,但问题是'Berkelium'中有两个'e',我的代码不起作用。任何人都可以对此有所了解吗?

'Berkelium'

3 个答案:

答案 0 :(得分:1)

据我所知,你想在s2中按顺序找到s1中的每个char。因此,对于s1中的每个char,搜索s2直到找到相同的char或用完。我认为案件无关紧要。

def s_in_s(s1, s2):
    s1 = s1.lower()
    s2it = iter(s2.lower())
    for c1 in s1:
        for c2 in s2it:
            if c2 == c1:
                break
        else:
            return False
    return True

print(s_in_s('Relim', 'Berkelium'))

这样返回True,没有.lower()调用时返回False。

编辑:添加更多测试用例

for seek in ('', 'r', 'BM', 'relim', 'berkelium'):
    print(s_in_s(seek, 'Berkelium'))  # should all be True
print()
for seek in (' ', 'x', 'BMx', 'berkeslium'):
    print(s_in_s(seek, 'Berkelium'))  # should all be False

答案 1 :(得分:1)

你可以试试这个:

def sub_order(string1, string2):

    # get all the matches in the second string
    matches = [char for char in string2.lower() if char in string1.lower()]

    # record the found characters that match
    found = []

    # create stack of string1, to ensure which characters have been found
    stack = list(string1.lower())

    # Go through each character in the substring
    for match in matches:

        # If the stack is not empty, keep checking
        if stack:

            # if a character matches the character at the top of the stack
            if match == stack[0]:

                # append what character was found, and pop the stack
                found.append(match)
                stack.pop(0)

    # check if the string found matches string1
    if "".join(found) == string1.lower():
        return True

    return False

此处使用的方法:

  • 获取string2string1中出现的所有匹配字符。
  • 浏览每个匹配的字符,并使用基于堆栈的方法检查它们,这些方法可以删除已经找到的字符。
  • 如果找到与string1的排序匹配的排序,则返回,否则请继续搜索。

答案 2 :(得分:1)

尝试了一些边缘情况,似乎有效

匹配'向后'转换为列表后,通过.pop()字符串清除每个字符串的结尾

倒计时失误'如果你到了lst1的末尾并且你在lst2中没有足够的匹配......

lst1 = [*'Relim'.lower()]      # list conversion makes copies, the lists get wholly
lst2 = [*'Berkelium'.lower()]  # or partially consumed

ln_lst1, cnt  = len(lst1), len(lst2)

while lst1 and lst2:
    last1 = lst1.pop()
    while lst2 and lst2.pop() != last1:
        cnt -= 1

cnt >= ln_lst1

Out[264]: True