I stuck at this simple scenario & not able to find smart solution to Reverse a string
that has negative number.
Example 1: str = "stack-1flow" #Expected output- wolf-1kcats
#Note may input contain multiple negative like
Example 2: str = "-1-2stack-1flow" #Expected output - wolf-1kcats-2-1
I want to reverse this such that i must preserve negative number format. In my case it is pretty sure that no Hyphen's will appear in input string except from Negative numbers
.
Expected output
wolf-1kcats
I've tried normal sort it wont yeild required resulsts
(wolf1-kcats
- wrong)'stack-1flow'[::-1] #outputs wolf1-kcats -wrong
Tried appending to list & then reversed the list yeild same(
wolf1-kcats
- wrong)list('stack-1flow') # ['s', 't', 'a', 'c', 'k', '-', '1', 'f', 'l', 'o', 'w'] #Reversing fails as you can see `-1` not preserved
Tried
eval
same results.
Note: I prefer Regex will be my last option..Before that I want to take help of 1.9M community people suggests me is there is any way to solve without
Regex
.
CodePudding user response:
You can do with re
,
import re
re.search(r'-\d', s).group().join(map(lambda x:x[::-1], re.split(r'-\d', s)[::-1]))
# 'wolf-1kcats'
Split the string with re.split
(using a regex) and revere the list of elements and join the values with the same regex.
EDIT
For the updated requirements you can do this,
''.join(i if i.lstrip('-').isdigit() else i[::-1] for i in re.split(r"(-?\d )", s)[::-1])
# 'wolf-1kcats-2-1'
CodePudding user response:
Alternative solution, without re
:
s = "-1-2-87a"
to_sort = []
i, flag = 0, 0
for ch in s:
if ch == "-":
flag = 1
i = 1
elif flag and not ch.isdigit():
flag = 0
i = 1
to_sort.append(-i)
i = not flag
print("".join(s[idx] for _, idx in sorted(zip(to_sort, range(len(s))))))
Prints:
a-87-2-1
CodePudding user response:
Here is my plan:
- First reverse the whole string: "stack-1flow" -> "wolf1-kcats"
- Use the
re.sub
to reverse the numbers: "1-" -> "-1", "321-" -> "-123"
Code:
import re
def reverse_negative_number(match: re.Match):
result = "".join(reversed(match[0]))
return result
def reverse_string_with_negative_numbers(input_string):
print(f"Input: {input_string}")
out1 = "".join(reversed(input_string))
print(f"Reversed1: {out1}")
out2 = re.sub(r"\d -", reverse_negative_number, out1)
print(f"Reversed2: {out2}")
return out2
input_strings = [
"stack-1flow",
"abc-123def-456ghi",
]
for input_string in input_strings:
result = reverse_string_with_negative_numbers(input_string)
print(result)
print()
Output:
Input: stack-1flow
Reversed1: wolf1-kcats
Reversed2: wolf-1kcats
wolf-1kcats
Input: abc-123def-456ghi
Reversed1: ihg654-fed321-cba
Reversed2: ihg-456fed-123cba
ihg-456fed-123cba
Notes
A little known fact. The
re.sub
function:re.sub(pattern, repl, string, count=0, flags=0)
can take in a function in place of the replacement,
repl
. This function must accept are.Match
object.That function in this case is
reverse_negative_number
, which takes in something like "321-" and reverse it.These functions look long, but because they have a bunch of
print()
for demo/debug purpose. Once you are happy with the result, you can delete them.