【问题标题】:Counting occurrences of char in string计算字符串中 char 的出现次数
【发布时间】:2019-02-26 23:53:08
【问题描述】:

大家好,我正在尝试以aaaabbcaaddd 的输入获得a4b2c1a2d3 的输出。我认为我下面的代码的问题是我实现以前的计数器的方式。 index > 0: 有问题吗?

string1 = "aaaabbcaaddd" 
previous = ""
finalstr = ""
finalint = 1
for index, val in enumerate(string1):
    if index > 0:
        previous = string1[index - 1]
        if previous == val:
            finalint += 1
        else:
            finalstr += previous + str(finalint)
            finalint = 1
print(finalstr)

#outputs "a4b2c1a2"

【问题讨论】:

  • 您忘记在循环之后添加最后一个计数:finalstr += previous + str(finalint)
  • 仅供参考,因为您在采访中提到您有这个问题。这个问题直接取自 Gayle McDowell 的《Cracking the Coding Interview (CTCI)》一书,基本上到处都推荐这本书用于面试准备。它在关于数组/字符串的第一章,我的第三版中的问题 1.6,称为“字符串压缩”。无论如何,我建议如果你在面试这样的算法时遇到问题,一定要尝试看看这本书并解决其中的问题(并且有解决方案可以仔细检查!)
  • 啊,我确实经历了一点,但我很难理解问题和解决方案,因为(如果我没记错的话)它们是用 Java 编写的?而且我只处理过 JS 和 Python,抱歉,编程才 6 个月。谢谢顺便说一句!

标签: python string python-3.x for-loop


【解决方案1】:

正如我在评论中所说,您忘记在循环之后添加最后一个计数

finalstr += previous + str(finalint)

但是,除非您将此作为分配的家庭作业,否则有一种更简洁的解决问题的方法:

from itertools import groupby
''.join(char + str(len(list(group))) for char,group in groupby(string1))
#'a4b2c1a2d3'

你自己的代码可以在没有索引的情况下被重写(它们总是会造成麻烦):

cnt = 1
finalstr = ''
for x,y in zip(string1, string1[1:]):
    if x==y:
        cnt += 1
    else:
        finalstr += x + (str(cnt) if cnt > 1 else '')
        cnt = 1
finalstr += x + (str(cnt) if cnt > 1 else '')
finalstr
#'a4b2ca2d3'

【讨论】:

  • 啊,是的!感谢那!我在一次采访中遇到了这个问题,我在实现之前和当前变量时遇到了麻烦......目前如果我添加最后一个计数,我仍然有像“a4b2c1a2d3”这样的输出问题......你如何建议我删除1 来自“c1”,所以输出只是“a4b2ca2d3”?
  • 您将需要另一个if 语句来检查是否添加计数。 (请参阅更新的答案。)
【解决方案2】:

这称为“游程编码”。在 Python 库 more-itertools 中有一个函数可以进行这种编码:

>>> from more_itertools import run_length
... 
... string1 = "aaaabbcaaddd"
... list(run_length.encode(string1))
[('a', 4), ('b', 2), ('c', 1), ('a', 2), ('d', 3)]

我们可以通过将其展平并对其进行字符串化来获得您想要的输出。

>>> list(flatten(run_length.encode(string1)))
['a', 4, 'b', 2, 'c', 1, 'a', 2, 'd', 3]

>>> list(map(str, flatten(run_length.encode(string1))))
['a', '4', 'b', '2', 'c', '1', 'a', '2', 'd', '3']

>>> ''.join(map(str, flatten(run_length.encode(string1))))
'a4b2c1a2d3'

【讨论】:

    【解决方案3】:

    如果有人对我得到的解决方案感到好奇(基于 DYZ 的帮助)

    string1 = "aaaabbcaaddd" 
    finalstr = ""
    previous = ""
    finalint = 0
    for c, v in enumerate(string1):
        if c > 0:
            previous = string1[c - 1]
            if previous == v:
                finalint += 1
            else:
                finalstr += previous + str((finalint) if finalint > 1 else '')
                finalint = 1
    finalstr += previous + str((finalint) if finalint > 1 else '')
    print(finalstr)
    #outputs a3b2ca2d3
    

    【讨论】:

      【解决方案4】:
      from itertools import groupby
      string1 = "aaaabbcaaddd"
      string2 = ''
      for c, g in groupby(string1):
          string2 += '%s%d'%(c, len(list(g)))
      

      【讨论】:

      • 请用文字描述原始解决方案有什么问题,以及您的解决方案是如何工作的。
      • 在您的算法中,您错过了一个案例。当您到达终点时,您的案例 previous = string1[index - 1] if previous == val: 将无法正常工作,因为最后的值和之前的值将相同。所以它不会添加最后一项
      • 为了做到这一点,您应该添加or 声明。因此,您的案例应该看起来像 if previous != val or index+1 == len(string1) 而不是简单的 else
      【解决方案5】:

      您可以使用 itertools groupby 来做同样的事情。

      from itertools import groupby
      string1 = 'aaaabbcaaddd'
      result = [[k, len(list(g))] for k, g in groupby(string1)]
      final = "".join([i[0]+str(i[1]) for i in result])
      final 
      
      output: #'a4b2c1a2d3'
      

      【讨论】:

        【解决方案6】:

        我是编程新手,写了我的第一条评论,我决定这样做:

        string = "qaabbaaccaqwewdssss"
        count = 0
        temp = str()
        
        for i in range(len(string) - 1):
            count += 1
            if string[i] != string[i + 1]:
                temp += string[i] + str(count)
                count = 0
            elif i + 1 == len(string) - 1:
                count += 1
                temp += string[i] + str(count)
                count = 0
        
        print(temp)
        #output: q1a2b2a2c2a1q1w1e1w1d1s4
        

        【讨论】:

          【解决方案7】:

          只需使用 itertools 中的 groupby 即可完成。而且没有必要将所有内容放在一行中。

          import itertools
          
          s = "aaaabbcaaddd"
          
          iterator = itertools.groupby(s)
          f= ""
          
          for key, group in iterator:
              f += str(key) + str(len(list(group)))
          
          print(f)
          
          #output: a4b2c1a2d3
          

          【讨论】:

          • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
          猜你喜欢
          • 2011-05-13
          • 1970-01-01
          • 1970-01-01
          • 2014-04-24
          • 1970-01-01
          • 1970-01-01
          • 2012-06-24
          • 2020-02-21
          相关资源
          最近更新 更多