如何在python中计算字符串中的重复字符

时间:2019-06-17 09:02:28

标签: python string list

编写一个python函数,该函数对给定的String执行游程长度编码,并返回经过游程长度编码的String。

我使用循环进行了尝试,但无法获得预期的输出。

def encode(message):    
    #Remove pass and write your logic here
    count=0
    encoded_message=[]
    for char in range(0,len(message)-1,1):
        count=1
        while(message[char]==message[char+1]):

             count=count+1;
             char=char+1
        encoded_message.append(str(count)+message[char])

    return encoded_message

encoded_message=encode("ABBBBCCCCCCCCAB")
print(' '.join(encoded_message))

预期输出为1A4B8C1A1B。 我得到的是1A 4B 3B 2B 1B 8C 7C 6C 5C 4C 3C 2C 1C 1A

5 个答案:

答案 0 :(得分:4)

您可以从groupby模块使用itertools

s = "ABBBBCCCCCCCCAB"
from itertools import groupby
expected = ''.join([str(len(list(v)))+k for k,v in groupby(s)])

输出

'1A4B8C1A1B'

groupby(s)返回一个itertools.groupby对象。像[(k,list(v)) for k,v in groupby(s)]这样的对象的列表理解会以有序方式将其返回给我们:

[('A', ['A']), ('B', ['B', 'B', 'B', 'B']), ('C', ['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C']), ('A', ['A']), ('B', ['B'])]

我们可以只计算元组第二个项目中的子项目数,并将其字符串格式添加到元组的第一项之前,然后将它们全部加入。

更新: 您正在尝试通过执行char=char+1来更改循环中的迭代索引,但它不会更改迭代索引,即,循环不会在接下来的2或3或4个迭代中通过。在代码中添加这两条打印行,您将看到在循环时要增加的char变量不仅仅是迭代索引:

...
for char in range(0,len(message)-1,1):
        print('\tchar at first line : ', char, 'char id now : ', id(char))
        count=1
        while(message[char]==message[char+1]):
            count=count+1
            char=char+1
            print('char now : ', char, 'char id now : ', id(char))
            ...

它应该输出类似:

    char at first line :  1 char id now :  11197408
char now :  2 char id now :  11197440
char now :  3 char id now :  11197472
char now :  4 char id now :  11197504

看看,每次id的{​​{1}}是如何变化的。

答案 1 :(得分:0)

您还可以使用re模块对字符串进行编码:

s = 'ABBBBCCCCCCCCAB'

import re

l = ''.join(str(len(c2)+1) + c1 for c1, c2 in re.findall(r'([A-Z])(\1*)', s))

print(l)

打印:

1A4B8C1A1B

答案 2 :(得分:0)

def func(string):
    string +='@'
    dic = []
    tmp =[]
    tmp += [string[0]]

    for i in range(1,len(string)):

        if string[i]==string[i-1]:
            tmp.append(string[i])
        else:
            dic.append(tmp)
            tmp=[]
            tmp.append(string[i])
    res = ''.join(['{}{}'.format(len(i),i[0]) for i in dic])
    return res

string = 'ABBBBCCCCCCCCAB'         
solution = func(string)

print(solution)

输出

1A4B8C1A1B

答案 3 :(得分:0)

使用此逻辑,它将为您返回带有每个字母出现频率的字典。

s = "ABBBBCCCCCCCCAB"
d = {i:0 for i in s}
for i in s:
    d[i] += 1
print(d)

**output:-**
{'A': 2, 'B': 5, 'C': 8}

答案 4 :(得分:0)

如果要修复功能,则为固定的变体:

def encode(message):
    result = []
    i = count = 0
    while i < len(message) - 1:
        count = 1
        while i + count < len(message) and message[i + count - 1] == message[i + count]:
            count += 1
        i += count
        result.append("{}{}".format(count, message[i - 1]))
    if count == 1:
        result.append("1" + message[-1])
    return result

更改之处:

  1. for 循环替换为 while 。为什么?因为您需要跳过索引incide循环。 range(0,len(message)-1,1)返回列表[0, 1, 2, ...],而使用char变量incide循环也没关系,它不会影响下一次迭代。为了有可能跳过一些索引,我在预定义(i = count = 0)的 while 循环中使用了索引并计数变量。
  2. 更改了内部 while 循环的条件。现在有两个条件:
    • message[i + count - 1] == message[i + count]-检查下一个符号是否与当前符号相同;
    • i + count < len(message)-防止内部循环访问超出范围的索引。
  3. 在内部循环之外更新“主”索引(i)。
  4. if count == 1:在循环执行后添加了后置条件,以防遗漏最后一个字符(如果是单个字符)。