重新排列字符串中的数字

Rearranging numbers in a string

重新排列字符串中的数字

给定一个字符串,编写一个程序,将字符串中出现的所有数字按降序重新排列。注意:不会有任何负数或带小数部分的数字。

输入

输入将是包含字符串的单行。

输出

输出应该是包含修改后的字符串的单行,字符串中的所有数字按降序重新排序。

解释:

例如,如果给定的字符串是“I am 5 years and 11 months old”,则数字为 5、11。您的代码应在将数字重新排序后打印句子“I am 11 years and 5 个月大。

#Sample Input:
I am 5 years and 11 months old

#Sample Output:
I am 11 years and 5 months old

#Sample input:
I am 28 years 9 months 11 weeks and 55 days old

#Sample output:
I am 55 years 28 months 11 weeks and 9 days old

我的做法:

def RearrangeNumbers(source):
    tmp0 = list(source)
    tmp1 = [c if c.isdigit() else ' ' for. 
             c in tmp0 ]
    tmp2 = "".join(tmp1)
    tmp3 = tmp2.split()
    numbers = []
    for w in tmp3:
        numbers.append(int(w))
    if len(numbers) < 2:
        return source
    numbers.sort(reverse=True)
    result_string = ''
    i = 0
    while i < len(source): 
        c = source[i]
        if not c.isdigit():
            result_string += c
        else:
            result_string += str(numbers[0])
            numbers = numbers[1:]
            i+=1
        i+=1
    return result_string

print(RearrangeNumbers(input()))

输出:

I am 55 years 28months 11 weeks and 9 days old

但是28个月之间应该有space

您可以使用正则表达式查找所有数字:

import re
inp = 'I am 28 years 9 months 11 weeks and 55 days old'
numbers = tuple(sorted(map(int, re.findall(r'([\d]+)', inp)), reverse=True)) # find all numbers, converts each number to int, sort them and convert to tuple
inpPlaceholders = re.sub(r'([\d]+)', '%s', inp) # replace all numbers in the string to %s placeholders
print(inpPlaceholders % numbers) # rebuild the string, using %s string formatting

输出:

I am 55 years 28 months 11 weeks and 9 days old

您在代码中逐个字符地进行了大量字符串操作。按数字查找数字是一种完成您必须做的事情的复杂方法。你的丢失space是你的做法造成的:

提示:检查文本中数字的长度 - 您可能不会总是用另一个 1 位数字替换 1 位数字 - 有时您需要用 3 位数字替换 1 位数字:

"Try 1 or 423 or 849 things."

在这种情况下,您的“逐个字符”替换会变得不稳定,您会丢失 space。

本质上,您用 2 位数字替换 "2 "(或将 "12 " 替换为 3 位数字等。杀死 space)。


最好

  • 检测所有数字
  • 检测到的数字按整数值降序排列
  • 将文本中所有检测到的数字替换为格式占位符“{}”
  • 使用 string.formt() 以正确的顺序替换数字

像这样:

def sortNumbers(text):
    # replace all non-digit characters by space, split result
    numbers = ''.join(t if t.isdigit() else ' ' for t in text).split()

    # order descending by integer value
    numbers.sort(key=lambda x:-int(x))  

    # replace all found numbers - do not mess with the original string with 
    # respect to splitting, spaces or anything else - multiple spaces
    # might get reduced to 1 space if you "split()" it.
    for n in numbers:
        text = text.replace(n, "{}")

    return text.format(*numbers)  # put the sorted numbers back into the string

for text in ["I am 5 years and 11 months old",
            "I am 28 years 9 months 11 weeks and 55 days old",
            "What is 5 less then 45?",
            "At 49th Street it is 500.", "It is  and 45."]:

    print(sortNumbers(text))

输出:

I am 11 years and 5 months old
I am 55 years 28 months 11 weeks and 9 days old
What is 45 less then 5?
At 500th Street it is 49.
It is  and 23.

你可以试试这个:

def RearrangeNumbers(source):
    tmp0=source.split()
    int_l=[]
    for j,i in enumerate(tmp0):
      try:
        tmp0[j]=int(i)
        int_l.append(int(i))
      except ValueError:
        pass
    int_l.sort()
    for j,i in enumerate(tmp0):
      if isinstance(i,int):
        tmp0[j]=str(int_l[0])
        int_l.pop(0)
    return ' '.join(tmp0)

print(RearrangeNumbers(input()))

示例 运行.

I am 28 years 9 months 11 weeks and 55 days old
I am 9 years 11 months 28 weeks and 55 days old

您可以使用 string.split() 和列表理解。要填充新字符串,您可以在迭代器中转换已排序的数字列表:

string = "I am 28 years 9 months 11 weeks and 55 days old"

numbers = [int(substring) for substring in string.split() if substring.isdigit()]
sorted_numbers = iter(sorted(numbers, reverse=True))
output =  " ".join([substring if not substring.isdigit() else str(next(sorted_numbers)) for substring in string.split()])

print(output)

# I am 55 years 28 months 11 weeks and 9 days old

您可以使用 re.subre.findall:

import re
def reposition(s):
   return re.sub('\d+', '{}', s).format(*sorted(map(int, re.findall('\d+', s)), reverse=True))

vals = ['I am 5 years and 11 months old', 'I am 28 years 9 months 11 weeks and 55 days old']
result = [reposition(i) for i in vals]

输出:

['I am 11 years and 5 months old', 'I am 55 years 28 months 11 weeks and 9 days old']

此代码冗长,仅适用于刚开始编码并卡在某个点无法解决问题但需要完成的初学者。

string_list = input().split(" ")
num_list = []
new_list = []
for each_word in string_list:
    num = ''
    new_word = ''
    for each_char in enumerate(each_word):
        index, character = each_char
        if (character.isdigit()) :
            num += character
        elif(character.isdigit() == False and num != ''): 
            num_list += [int(num)]
            num = ''
            new_word += "{}" + character 
        else:
            new_word += character

    if (each_word.isdigit() or num != ''):
        num_list += [int(num)]
        new_word += "{}"
    if new_word != '':
        new_list += [new_word]
    if each_word == "":
        new_list += [""]


num_list = sorted(num_list, reverse= True)
print(" ".join(new_list).format(*num_list))