所以,我正在寻找一种解决以下问题的算法:
为您提供所需的字符串 s 和图章 t 。 t 也是一个字符串。令开始的字符串为len(s)*"?"
。
是否可以使用图章使用图章将起始字符串转换为字符串s?整个图章必须位于开头的字符串内(图章的边界不得超过????? ...字符串的边界)。
打印所需的图章数量,并为每个图章打印图章的左边框。
示例:
AABCACA (desired result)
ABCA (stamp)
Solution:
3
1 4 2
explanation: ??????? → ABCA??? → ABCABCA → AABCACA.
我的解决方案: 如果图章的首字母不是所需字符串的首字母,则无法执行此任务。最后一个字母也是如此。如果图章没有在所需字符串中包含所有字母,则该任务是不可能的。
我的算法是这样的:尝试在所需的字符串中找到图章。如果找到它,请将其删除并用问号替换。标记图章的左边框。尽可能做到这一点。
然后查找大小为len(stamp)-1的图章的连续子数组。如果发现其中任何一个,请将其删除并替换为问号。标记图章的左边框。
然后查找大小为len(stamp)-2的图章的连续子数组。如果发现其中任何一个,请将其删除并替换为问号。标记图章的左边框。这样做直到完成。在那里,你有答案。
问题 我不确定我的代码有什么问题,因为它似乎无法通过一些测试用例。可能是一个逻辑错误。
import sys
desiredString = input()
stamp = input()
stampingSpots = []
if (len(set(desiredString)) != len(set(stamp)) or stamp[0] != desiredString[0] or stamp[-1] != desiredString[-1]):
print("-1")
sys.exit()
def searchAndReplace(stringToFind, fix): #Search for stringToFind and replace it with len(stringToFind)*"?". Fix is used to fix the position.
global desiredString
for x in range(0, len(desiredString)-len(stringToFind)+1):
if desiredString[x:x+len(stringToFind)] == stringToFind:
stampingSpots.append(x+1-fix) #Mark down the stamping spot
firstPart = desiredString[:x]
firstPart += len(stringToFind)*"?"
firstPart += desiredString[len(firstPart):]
desiredString = firstPart
return True
return False
while(searchAndReplace(stamp,0)): #Search for the full stamp in desiredString
searchAndReplace(stamp,0)
length = len(stamp)-1
while(length > 0):
for firstPart in range(0, len(stamp)-length+1):
secondPart = firstPart+length
while(searchAndReplace(stamp[firstPart:secondPart], firstPart)):
searchAndReplace(stamp[firstPart:secondPart], firstPart)
if len(stampingSpots) > 10*len(desiredString): #Too much output, not possible
print("-1")
sys.exit()
length -= 1
print(len(stampingSpots))
for i in reversed(stampingSpots):
print(i, end = " ")
答案 0 :(得分:4)
您描述的算法从根本上来说是有缺陷的。它产生的结果与图章实际可以做的事情完全不符。例如,使用图章AB
和字符串AAA
,它将尝试在字符串的边界之外盖章以应用最后的A
。它还将尝试将图章AB
的{{1}}和BC
子字符串彼此直接用于字符串ABC
,但图章的实际应用不能做到这一点。
图章不能用于应用图章字符串的任意子字符串。它可以用于在以前的图章应用程序上盖章,但是您的算法没有考虑过盖章的全部复杂性。另外,即使您可以标记图章字符串的任意子字符串,也没有证明算法会最小化图章应用程序。
答案 1 :(得分:0)
我们可以使用分而治之:让f(s)
代表生成字符串s
所需的最小标记,其中“ *”是通配符。然后:
吉利地挑选与图章最大匹配的字符串部分。
将该部分设置为通配符,并将其左右部分分别提供给f
。
例如:
AABCACA (desired result)
ABCA (stamp)
f(AABCACA)
^^^^
ABCA (match)
= 1 + f(A****) + f(****CA)
=> f(A****)
^^^^
ABCA (match)
=> f(****CA)
^^^^
ABCA
Total 3