1

在这里,我在列表中有一个字符串:

['aaaaaaappppppprrrrrriiiiiilll']

我想在列表中得到“四月”这个词,但不仅仅是其中一个,而是“四月”这个词实际出现在字符串中的次数。

输出应该是这样的:

['aprilaprilapril']

因为“四月”这个词在那个字符串中出现了 3 次。

好吧,这个词实际上并没有出现三次,所有字符都出现了。所以我想将这些字符排序为“四月”,它们在字符串中出现了多少次。

我的想法基本上是从一些随机字符串中提取单词,但不仅仅是提取单词,而是提取字符串中出现的所有单词。应该提取每个单词,并且应该按照我想要的方式对单词(字符)进行排序。

但是在这里我有一些烦人的情况;您不能删除列表中的所有元素,然后将它们替换为单词“april”(您不能将整个字符串替换为单词“april”);您只能从字符串中提取“四月”,而不是替换它们。您也不能删除带有字符串的列表。想想所有的字符串都有非常重要的数据,我们只想要一些数据,但是这些数据必须是有序的,我们需要删除所有与我们的“数据链”不匹配的数据(单词'april') . 但是一旦删除整个字符串,您将丢失所有重要数据。你不知道如何制作另一个这些“数据链”,所以我们不能只把“四月”这个词放回列表中。

如果有人知道如何解决我奇怪的问题,请帮帮我,我是初学者 python 程序员。谢谢!

4

4 回答 4

2

使用正则表达式怎么样?

import re

word = 'april'
text = 'aaaaaaappppppprrrrrriiiiiilll'

regex = "".join(f"({c}+)" for c in word)
match = re.match(regex, text)

if match:
    # Find the lowest amount of character repeats
    lowest_amount = min(len(g) for g in match.groups())
    print(word * lowest_amount)
else:
    print("no match")

输出:

aprilaprilapril

奇迹般有效

于 2021-07-15T01:43:02.483 回答
2

一种方法是使用itertools.groupbywhich 将单独对字符进行分组并解包和迭代它们,使用zipwhich 将迭代 n 次给定 n 是最小组中的字符数(即具有最少字符数的组)

from itertools import groupby
'aaaaaaappppppprrrrrriiiiiilll'
result = ''
for each in zip(*[list(g) for k, g in groupby('aaaaaaappppppprrrrrriiiiiilll')]):
    result += ''.join(each)

# result = 'aprilaprilapril'    

另一种可能的解决方案是创建一个自定义计数器来计算每个唯一的字符序列(请注意,此方法仅适用于 Python 3.6+,对于较低版本的 Python,不保证字典的顺序):

def getCounts(strng):
    if not strng:
        return [], 0
    counts = {}
    current = strng[0]
    for c in strng:
        if c in counts.keys():
            if current==c:
                counts[c] += 1
        else:
            current = c
            counts[c] = 1
    return counts.keys(), min(counts.values())

result = ''
counts=getCounts('aaaaaaappppppprrrrrriiiiiilll')
for i in range(counts[1]):
    result += ''.join(counts[0])

# result = 'aprilaprilapril'
于 2021-07-15T01:29:00.957 回答
0

一个单词只会出现最少字母重复出现的次数。考虑到单词中重复字母的可能性(例如,appril您需要考虑这个计数。这是使用 的一种方法collections.Counter

from collections import Counter

def count_recurrence(kernel, string):
     # we need to count both strings
     kernel_counter = Counter(kernel)
     string_counter = Counter(string)

    # now get effective count by dividing the occurence in string by occurrence
    # in kernel
    effective_counter = {
        k: int(string_counter.get(k, 0)/v)
        for k, v in kernel_counter.items()
    }

    # min occurence of kernel is min of effective counter
    min_recurring_count = min(effective_counter.values())

    return kernel * min_recurring_count
于 2021-07-15T02:22:27.977 回答
0

这是一种更原生的方法,具有简单的迭代。

它的时间复杂度为 O(n)。

它使用外部循环遍历搜索键中的字符,然后使用内部 while 循环消耗搜索字符串中该字符的所有出现,同时维护一个计数器。一旦当前字母的所有连续出现都已被消耗,它会将 a 更新minLetterCount为其先前值或此新计数的最小值。一旦我们遍历了键中的所有字母,我们就会返回这个累积的最小值。

def countCompleteSequenceOccurences(searchString, key):
    left = 0
    minLetterCount = 0
    letterCount = 0
    for i, searchChar in enumerate(key):
        while left < len(searchString) and searchString[left] == searchChar:
            letterCount += 1
            left += 1
        
        minLetterCount = letterCount if i == 0 else min(minLetterCount, letterCount)
        letterCount = 0
        
    return minLetterCount

测试:

testCasesToOracles = {
    "aaaaaaappppppprrrrrriiiiiilll": 3,
    "ppppppprrrrrriiiiiilll": 0,
    "aaaaaaappppppprrrrrriiiiii": 0,
    "aaaaaaapppppppzzzrrrrrriiiiiilll": 0,
    "pppppppaaaaaaarrrrrriiiiiilll": 0,
    "zaaaaaaappppppprrrrrriiiiiilll": 3,
    "zzzaaaaaaappppppprrrrrriiiiiilll": 3,
    "aaaaaaappppppprrrrrriiiiiilllzzz": 3,
    "zzzaaaaaaappppppprrrrrriiiiiilllzzz": 3,
}

key = "april"
for case, oracle in testCasesToOracles.items():
    result = countCompleteSequenceOccurences(case, key)
    assert result == oracle

用法:

key = "april"
result = countCompleteSequenceOccurences("aaaaaaappppppprrrrrriiiiiilll", key)
print(result * key)

输出:

aprilaprilapril

于 2021-07-15T01:46:33.683 回答