'RLE ALgorithm in python
like the title suggest I want to do an RLE algorithm and I have few problems with that
for example in RLE algorithm if we take aaaabbbccd it should return a4b3c2d1 as a result
the rle function should return the compressed string of aaabbbccccddddd
rle(data : str) : str
so it would be a3b3c4d5
Here's the code I know it's wrong but I don't know If it was a good way to begin
def rle(data):
data = 'aaabbbccccddddd'
for i in range(0,len(data)):
if data.count(f'{i}') > 1:
data.replace(i, data.count(f'{i}'))
print(data)
print(rle(data))
Solution 1:[1]
data = 'aaabbbccccddddd'
seq = []
r = None
for d in data:
if d != r:
seq.append(d)
seq.append(str(1))
r = d
else:
seq[-1] = str(int(seq[-1]) + 1)
print("".join(seq))
I thought that this code snippet is simple, and so didn't explain it...
we have a str and want to convert it to Char-TheNumberOfRepetitions pairs, like ['a',3,'b',3,'c',4,...], so we loop a char over str and when it is new, we add [char, 1] to list, otherwise, we add 1 to last element of list while we get a new char...
r variable is for new char recognition and is a temp variable that we store every new char (if a char was not equal to it, replace)
finally, we convert ['a',3,'b',3,'c',4,...] to str, using join
why we use str() and int()? because python join method is a bit silly :) and throw an exception, if an element of list be int... and everytime we convert it to int to add 1 and then convert to str, again...
why not map? because I assume that OP is beginner and map is complicate for him...
and, a more pythonic way:
def rle(data: str) -> str:
seq = [data[0], 1]
for elem in data[1:]:
if elem != seq[-2]:
seq += [elem, 1]
else:
seq[-1] += 1
return ''.join(map(str, seq))
and reverse:
def reverse_rle(data: str, end_char = '$') -> str:
def convert(): return seq[:-2] + [seq[-2] * (seq[-1] or 1)]
seq = [data[0], 0]
for elem in data[1:] + end_char:
if elem.isdigit():
seq[-1] = seq[-1] * 10 + int(elem)
else:
seq = convert()
if elem != end_char:
seq += [elem, 0]
return "".join(seq)
and if you dont want to use end_char:
def reverse_rle(data: str) -> str:
def convert(): return seq[:-2] + [seq[-2] * (seq[-1] or 1)]
seq = [data[0], 0]
for elem in data[1:]:
if elem.isdigit():
seq[-1] = seq[-1] * 10 + int(elem)
else:
seq = convert() + [elem, 0]
return "".join(convert())
Solution 2:[2]
This should work better
def rle(data):
# Initialize a few variables
prev = None
cnt = 0
res = ""
for i in data:
if i == prev:
# if same char as previous one, just add one to counter
cnt += 1
else:
# Check that we are not at first round and add to result
if prev != None:
res += "%s%s" % (cnt,prev)
# Set new character as previous one
prev = i
# Add last char to result
res += "%s%s" % (cnt,prev)
return res
print(rle("aaabbbccccddddd"))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | snoob dogg |
