python - 没有 count() 方法的 RLE 编码
问题描述
我试图将一个字符串作为输入,然后输出每个带有重复值的字母。例如:aaab
应该输出3a1b
. 但我不能count()
用来做这个。
我试图编写它,但我很困惑,因为我使用了比我的大脑可以处理的更多的 for 循环和 if 语句:
def rle_encode(str):
count = 1
for i in range(len(str)):
if i != len(str):
if str[i] == str[i+1]:
count += 1
str = str[i].replace(str[i],'')
str = str[i+1].replace(str[i+1],'')
continue
else:
print(str(count) + str(str[i]))
rle_encode(str)
else:
break
我收到以下错误str = str[i+1].replace(str[i+1],'')
:
IndexError:字符串索引超出范围
解决方案
由于这似乎是家庭作业,因此我不会为您重写该方法,但我会指出您可以自己实现的算法。
- 从设置为空字符串的输出字符串开始,前一个字符设置为
None
,前一个字符计数设置为 0。 - 对于字符串中的每个字符:
- 如果字符与前一个字符相同,则增加前一个字符计数,并且不执行任何其他操作。
- 如果不同:
- 如果有前一个字符(不是
None
),则将计数和前一个字符附加到输出字符串。 - 将前一个字符设置为当前字符,并将计数设置为 1。
- 如果有前一个字符(不是
- 循环完成后,如果前一个字符计数不为零,则将计数和前一个字符附加到输出字符串。
- 返回输出字符串。
关于这个算法的一些重要的事情:
- 它不使用递归。递归版本也可以,但这里的迭代更简单。您的函数尝试遍历字符串并递归调用自身,这很混乱。
- 它不打印。尝试计算结果并将其打印在同一个函数中是初学者的常见错误。它经常导致混乱。如果您的函数计算结果并返回它,您总是可以只
print(rle_encode(str))
在屏幕上获取结果,但您也可以选择将其存储以供以后使用,并且您不必担心操作顺序(尤其是使用递归——递归函数很容易最终将其结果向后、交错或多次打印!) - 它不修改
str
. 作为一般规则,不可变数据比可变数据更容易推理。更具体地说,最好避免在循环时修改某些内容,尤其是修改您正在循环的内容的长度。这就是您看到的错误的原因——您让i
循环遍历 的所有原始索引str
,但str
同时又变短了。如果不仔细更正,这会导致两个问题:跳过部分输入,并尝试读取输入的末尾。不修改输入并写入单独的输出字符串可能会使用更多的内存,但这意味着您不需要推理不断变化的输入。
推荐阅读
- machine-learning - 如何使用 opencl 实现 pytesseract 代码以使其在 GPU 上运行?
- angular - Angular Inject 参数化提供程序
- php - 如何从选择表单中获取值到 SQL 查询中
- java - 定义antmatcher时Spring安全默认表单登录页面失败
- apache-spark - Spark + s3 - 错误 - java.lang.ClassNotFoundException:找不到类 org.apache.hadoop.fs.s3a.S3AFileSystem
- python - micropython usocket.IPPROTO_SEC 不可用
- matplotlib - Matplotlib 滑块在 imshow 时失去交互性
- excel - 在某些列中查找重复项
- arrays - 它是一种为测试和部署环境创建引用并随后在 yaml 中添加额外步骤的方法吗?
- c# - 从 Azure Function 将文件上传到 SFTP 位置