Python 对非重复字符进行排序,然后对重复字符进行排序?
我正在做以下编程练习:。声明如下: 任务 您将收到一个由小写字母和大写字母组成的字符串 字母和数字作为输入。您的任务是将此字符串作为 用短划线(“-”)分隔的块。块的元素应该是 根据下面列出的层次结构和每个块进行排序 不能包含同一字符的多个实例 层次结构是:Python 对非重复字符进行排序,然后对重复字符进行排序?,python,string,algorithm,sorting,testing,Python,String,Algorithm,Sorting,Testing,我正在做以下编程练习:。声明如下: 任务 您将收到一个由小写字母和大写字母组成的字符串 字母和数字作为输入。您的任务是将此字符串作为 用短划线(“-”)分隔的块。块的元素应该是 根据下面列出的层次结构和每个块进行排序 不能包含同一字符的多个实例 层次结构是: lowercase letters (a - z), in alphabetic order uppercase letters (A - Z), in alphabetic order digits (0 - 9), in ascendi
lowercase letters (a - z), in alphabetic order
uppercase letters (A - Z), in alphabetic order
digits (0 - 9), in ascending order
例子
"21AxBz" -> "xzAB12" - since input does not contain repeating characters, you only need 1 block
"abacad" -> "abcd-a-a" - character "a" repeats 3 times, thus 3 blocks are needed
"" -> "" - an empty input should result in an empty output
祝你好运
我编写了以下代码:
def blocks(s):
print("s: "+s)
lowers = []
uppers = []
digits = []
for c in s:
if c.islower():
lowers.append(c)
if c.isupper():
uppers.append(c)
if c.isdigit():
digits.append(c)
lowers.sort()
uppers.sort()
digits.sort()
print("lowers: ")
print(lowers)
print("uppers: ")
print(uppers)
print("digits: ")
print(digits)
result = ""
sorted = lowers+uppers+digits
removedLetters = 0
needsNextBlock = False
nextBlock = "-"
while len(sorted) > 0:
for i, c in enumerate(sorted):
print(i, c)
print("result: ")
print(result)
if c not in result:
result += c
print("we want to delete: ")
print(c)
sorted = sorted[0:i-removedLetters] + sorted[i+1-removedLetters:]
removedLetters += 1
print("new sorted: ")
print(sorted)
else:
if c not in nextBlock:
needsNextBlock = True
nextBlock += c
sorted = sorted[0:i-removedLetters] + sorted[i+1-removedLetters:]
removedLetters += 1
print("new sorted: ")
print(sorted)
if needsNextBlock:
result += nextBlock
needsNextBlock = False
nextBlock = "-"
return result
还有一个bug,因为当我们进行以下测试时:
Test.assert_equals(blocks("abacad"), "abcd-a-a")
追踪是:
s: abacad
lowers:
['a', 'a', 'a', 'b', 'c', 'd']
uppers:
[]
digits:
[]
0 a
result:
we want to delete:
a
new sorted:
['a', 'a', 'b', 'c', 'd']
1 a
result:
a
new sorted:
['a', 'b', 'c', 'd']
2 a
result:
a
3 b
result:
a
we want to delete:
b
new sorted:
['a', 'c', 'd']
4 c
result:
ab
we want to delete:
c
new sorted:
['a', 'd']
5 d
result:
abc
we want to delete:
d
new sorted:
['a']
0 a
result:
abcd-a
new sorted:
['a']
0 a
result:
abcd-a-a
new sorted:
['a']
0 a
result:
abcd-a-a-a
new sorted:
['a']
0 a
result:
abcd-a-a-a-a
new sorted:
['a']
0 a
(infinite loop)
因此,正如我们看到的,当我们执行以下操作时,会产生困难:
sorted = sorted[0:i-removedLetters] + sorted[i+1-removedLetters:]
removedLetters += 1
因为我们之前已经传递了重复的字母,在本例中是“a”,但我们没有计算它,所以新排序的子字符串的演算保持不变
我尝试了一种天真的方法:
def blocks(s):
print("\n\n\ns: "+s)
lowers = []
uppers = []
digits = []
for c in s:
if c.islower():
lowers.append(c)
if c.isupper():
uppers.append(c)
if c.isdigit():
digits.append(c)
lowers.sort()
uppers.sort()
digits.sort()
print("lowers: ")
print(lowers)
print("uppers: ")
print(uppers)
print("digits: ")
print(digits)
result = ""
sorted = lowers+uppers+digits
removedLetters = 0
needsNextBlock = False
nextBlock = "-"
while len(sorted) > 0:
initialIterationLength = len(sorted)
for i, c in enumerate(sorted):
print(i, c)
print("result: ")
print(result)
if c not in result:
result += c
print("we want to delete: ")
print(c)
sorted = sorted[0:i-removedLetters] + sorted[i+1-removedLetters:]
removedLetters += 1
print("new sorted: ")
print(sorted)
else:
if c not in nextBlock:
needsNextBlock = True
nextBlock += c
sorted = sorted[0:i-removedLetters] + sorted[i+1-removedLetters:]
removedLetters += 1
if initialIterationLength == len(sorted):
sorted = []
print("new sorted: ")
print(sorted)
if needsNextBlock:
result += nextBlock
needsNextBlock = False
nextBlock = "-"
return result
如您所见,当我们开始while循环时,我添加了一句话:initialIterationLength=len(sorted)
,在循环内部,在if条件下:
if initialIterationLength == len(sorted):
sorted = []
它确实适用于正在讨论的测试,但是对于较大的输入,它将不起作用
例如,当输入为:
ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T
我们的结果是:
aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx
预计:
aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x
我认为应该有一个更好的算法
我读过:
我们如何对不重复的字符进行排序,然后再对重复的字符进行排序?您可以使用计数器根据重复的数字跟踪所需的迭代
import string
from collections import Counter
ORDER = {s:i for i, s in enumerate(string.ascii_letters + string.digits)}
def my_sorted(s):
c = Counter(s)
res = []
it = 1
to_sort = set(c)
while len(to_sort) > 0:
res.append(sorted(to_sort ,key=lambda x:ORDER[x]))
to_sort = [k for k in c if c[k] > it]
it+=1
return "-".join(["".join(l) for l in res])
例如:
>>> s="ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-gpwxSVZ-wx-x-x
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'
从@abc的答案中窃取
import string
from collections import Counter
ORDER = {s:i for i, s in enumerate(string.ascii_letters + string.digits)}
def my_sorted(s):
c = Counter(s)
res = []
while c:
res.append(''.join(sorted(c, key=ORDER.get)))
c -= Counter(set(c))
return "-".join(res)
例如:
>>> s="ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-gpwxSVZ-wx-x-x
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'
仍在窃取@abc的设置,但完全不同的解决方案。我附加所需数量的破折号,然后根据1)字符出现的次数和2)aA0顺序对所有内容进行排序
import string
from collections import Counter
ORDER = {s:i for i, s in enumerate(string.ascii_letters + string.digits + '-')}
def my_sorted(s):
return ''.join(sorted(s + '-' * (max(Counter(s).values()) - 1),
key=lambda c, ctr=Counter(): (ctr.update(c) or ctr[c], ORDER[c])))
例如:
>>> s="ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-gpwxSVZ-wx-x-x
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'
>>> s = "ZrXx2VpVJMgPs54SwwxSophZEWvwKUxzqNxaxlgY0T"
>>> my_sorted(s)
'aghlopqrsvwxzEJKMNPSTUVWXYZ0245-gpwxSVZ-wx-x-x'