Rearranging numbers in a string
Asked Answered
H

6

6

Rearrange Numbers in String

Given a string, write a program to re-arrange all the numbers appearing in the string in decreasing order. Note: There will not be any negative numbers or numbers with decimal part.

Input

The input will be a single line containing a string.

Output

The output should be a single line containing the modified string with all the numbers in string re-ordered in decreasing order.

Explanation:

For example, if the given string is "I am 5 years and 11 months old", the numbers are 5, 11. Your code should print the sentence after re-ordering the numbers as "I am 11 years and 5 months old".

#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

My approach:

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()))

Output:

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

But there should be space between 28months

Hyaluronidase answered 9/7, 2021 at 11:12 Comment(1)
Nice first post, thanks for taking your time to fix the errors.Lavonia
L
1

You do a lot of string manipulation on a character by character basis in your code. Finding numbers digit-wise is a complicated way to do what you must do. Your lost space is caused by your approach:

Hint: check the length's of your numbers in your text - you may not always replace a 1-digit number by another 1-digit number - sometimes you would need to replace a 1-digit number by a 3 digit number:

"Try 1 or 423 or 849 things."

and in that case your "char-by-char" replacing will get wonky and you loose the space.

Essentially you replace "2 " by a 2-digit number (or "12 " by a 3-digit one etc. killing the space).


It would be better to

  • detect all numbers
  • sort detected numbers by their integer value descending
  • replace all detected numbers in your text with format-placeholder '{}'
  • use string.formt() to substitute numbers in correct order

like so:

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 $23 and 45."]:

    print(sortNumbers(text))

Output:

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 $45 and 23.
Lavonia answered 9/7, 2021 at 11:36 Comment(1)
Your clarification is Upto Mark. Thank you for elaborating @Patrick ArtnerHyaluronidase
F
0

You could use a regular expression to find all numbers:

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

Out:

I am 55 years 28 months 11 weeks and 9 days old
Felicle answered 9/7, 2021 at 11:36 Comment(0)
B
0

You can try this:

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()))

Sample run.

I am 28 years 9 months 11 weeks and 55 days old
I am 9 years 11 months 28 weeks and 55 days old
Brnaby answered 9/7, 2021 at 11:39 Comment(0)
K
0

You can use string.split() and list comprehension. To populate the new string you can transform the sorted list of numbers in an iterator:

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
Keeley answered 9/7, 2021 at 12:15 Comment(0)
S
0

You can use re.sub and re.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]

Output:

['I am 11 years and 5 months old', 'I am 55 years 28 months 11 weeks and 9 days old']
Shivery answered 9/7, 2021 at 16:0 Comment(0)
C
0

this code is lengthy and only for beginner those who just started coding and stuck at some point and unable to solve the problem but need to complete it.

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))
Clarino answered 30/5, 2022 at 20:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.