首页 > 解决方案 > 没有 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:字符串索引超出范围

标签: pythonstring

解决方案


由于这似乎是家庭作业,因此我不会为您重写该方法,但我会指出您可以自己实现的算法。

  • 从设置为空字符串的输出字符串开始,前一个字符设置为None,前一个字符计数设置为 0。
  • 对于字符串中的每个字符:
    • 如果字符与前一个字符相同,则增加前一个字符计数,并且不执行任何其他操作。
    • 如果不同:
      • 如果有前一个字符(不是None),则将计数和前一个字符附加到输出字符串。
      • 将前一个字符设置为当前字符,并将计数设置为 1。
  • 循环完成后,如果前一个字符计数不为零,则将计数和前一个字符附加到输出字符串。
  • 返回输出字符串。

关于这个算法的一些重要的事情:

  1. 它不使用递归。递归版本可以,但这里的迭代更简单。您的函数尝试遍历字符串递归调用自身,这很混乱。
  2. 它不打印。尝试计算结果并将其打印在同一个函数中是初学者的常见错误。它经常导致混乱。如果您的函数计算结果并返回它,您总是可以只print(rle_encode(str))在屏幕上获取结果,但您可以选择将其存储以供以后使用,并且您不必担心操作顺序(尤其是使用递归——递归函数很容易最终将其结果向后、交错或多次打印!)
  3. 它不修改str. 作为一般规则,不可变数据比可变数据更容易推理。更具体地说,最好避免在循环时修改某些内容,尤其是修改您正在循环的内容的长度。这就是您看到的错误的原因——您让i循环遍历 的所有原始索引str,但str同时又变短了。如果不仔细更正,这会导致两个问题:跳过部分输入,并尝试读取输入的末尾。不修改输入并写入单独的输出字符串可能会使用更多的内存,但这意味着您不需要推理不断变化的输入。

推荐阅读