[英]String manipulation algorithm to find string greater than original string
我有很少的单词(字符串),如'hefg','dhck','dkhc','lmno'
,它将通过交换部分或全部字符转换为新单词,使新单词大于原始单词的字典顺序新词也是比原词更重要的词。 例如'dhck'
应该输出'dhkc'
而不是'kdhc'
, 'dchk'
或任何其他。
我有这些输入
hefg
dhck
dkhc
fedcbabcd
哪个应该输出
hegf
dhkc
hcdk
fedcbabdc
我在python中试过这个代码,除了'dkhc'
和'fedcbabcd'
之外,它适用于所有人。 我已经发现在'fedcbabcd'
情况'fedcbabcd'
一个字符是最大的,所以它没有被交换。我得到"ValueError: min() arg is an empty sequence"
如何修改算法修复案例?
list1=['d','k','h','c']
list2=[]
maxVal=list1.index(max(list1))
for i in range(maxVal):
temp=list1[maxVal]
list1[maxVal]=list1[i-1]
list1[i-1]=temp
list2.append(''.join(list1))
print(min(list2))
你可以尝试这样的事情:
示例代码:
def next_word(word):
word = list(word)
seen = {}
for i in range(len(word)-1, -1, -1):
if any(x > word[i] for x in seen):
x = min(x for x in seen if x > word[i])
word[i], word[seen[x]] = word[seen[x]], word[i]
return ''.join(word[:i+1] + sorted(word[i+1:]))
if word[i] not in seen:
seen[word[i]] = i
for word in ["hefg", "dhck", "dkhc", "fedcbabcd"]:
print(word, next_word(word))
结果:
hefg hegf
dhck dhkc
dkhc hcdk
fedcbabcd fedcbabdc
在一般情况下,最大字符及其位置不会影响算法。 例如,对于'fedcbabcd'
,你可以在字符串的开头添加a
或一个z
,它不会改变你需要交换最后两个字母的事实。
考虑输入'dgfecba'
。 这里的输出是'eabcdfg'
。 为什么? 请注意,最后六个字母按递减顺序排序,因此通过更改任何内容,您会按字典顺序获得一个较小的字符串,这是不好的。 因此,您需要替换初始的'd'
。 我们应该把它放在什么位置? 我们想要比'd'
更大的东西,但要尽可能小,所以'e'
。 剩下的六封信怎么样? 同样,我们想要一个尽可能小的字符串,因此我们按字典顺序对字母进行排序: 'eabcdfg'
。
所以算法是:
i
成为s[i] < s[i + 1]
的最右边的位置; 在我们的例子中,那是i
= 0; i
- 1不变; i+1 ... n-1
包含大于s[i]
的最小符号的位置; 叫这个职位j
; 在我们的例子中, j
= 3; s[i]
和s[j]
; 在我们的例子中,我们获得'egfdcba'
; s[i+1] ... s[n-1]
; 在我们的例子中,我们获得'eabcdfg'
。 您的问题可以重新编写为查找字符串的下一个字典排列 。
上述链接中的算法描述如下:
1)找到最长的非增加后缀
2)后缀左边的数字是我们的支点
3)在后缀中找到最右侧的枢轴的后继者
4)交换后继者和枢轴
5)反转后缀
上述算法特别有趣,因为它是O(n) 。
def next_lexicographical(word):
word = list(word)
# Find the pivot and the successor
pivot = next(i for i in range(len(word) - 2, -1, -1) if word[i] < word[i+1])
successor = next(i for i in range(len(word) - 1, pivot, -1) if word[i] > word[pivot])
# Swap the pivot and the successor
word[pivot], word[successor] = word[successor], word[pivot]
# Reverse the suffix
word[pivot+1:] = word[-1:pivot:-1]
# Reform the word and return it
return ''.join(word)
如果该单词已经是最后一个词典排列,则上述算法将引发StopIteration
异常。
words = [
'hefg',
'dhck',
'dkhc',
'fedcbabcd'
]
for word in words:
print(next_lexicographical(word))
hegf
dhkc
hcdk
fedcbabdc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.