算法题-统计字符个数(Python题解)

前言

先前笔试做了一道算法题,题目是这样子的:(PS:不用惊讶,是的,我不打算24今年考研了,一是,当初填报的学校不是我想要去的学校(当初想一战成硕,选了个稳点的学校),二是,最近经历了一些事情让我意识到,成为那个学校的研究生,并不能实现我的预想,大概率下可能还是会回到Java开发,或者其他的开发。至于算法工程师,基本上不用想了。那么竟然如此,在考研上继续浪费时间显然是不值得的。已经错过秋招了,没办法,现在只能想着补救了,或者春招了)当然后不后悔呢,说实话,绕了一圈有点后悔,错误的估计了当前形势。但是通过这段时间的备研,我觉得还是学到了不少东西的,最少除了开发,我把408好好过了过,对于里面的思想有了更深刻的理解。这对于以后的技术提高是有很大帮助的,当然花几个月的时间学那确实有点亏。当然也好在,技术一直没有落下,在暑假打比赛的时候就写了一大半的毕设。后面赶上也很快,复杂的部分都写完了。

那么废话不多说,先来看题吧:

思路

这里的话,我们可以直接先简单模拟一遍: 例如:X2Y3XZ ,设S为记录个数

1.-> X 此时:S={X:0} (第一次出现,记录为0,解析出后面的数字) 2. ->2 此时:S={X:2}(解析出了后面的数字) 3.->Y 此时:S={X:3,Y:3} 4.->X 此时:S={X:3,Y:3} (此时S[x]=S[x]+1,后面没有解析到数字时) 5.->Z 此时:S={X:3,Y:3,Z:1} (同理)

最后按序输出即可。

那么对于: 存在嵌套的情况: 例如:Z4(Y2(XZ2)3X3

  1. 先统计出括号内部的元素(先考虑单层括号的情况,此时先记录计算出里面的元素个数,方法同第一种情况一致。此时将这一组记录看作是一个元素,然后按照外层的方式再处理)
  2. 对于括号内有括号嵌套的情况,这里采用递归的方式继续进行处理,得到一组记录,然后再将这一组记录看作是一个元素,同上述处理。

那么思路上的话,我们就非常明确了,你可以发现,这个其实就是一个基本的模拟题,但是里面需要注意的细节是比较多的,但是不管怎么说,时间复杂度是0(n)的。所以这里我们就可以很快的写出代码。

code

ok,这里我们刚刚明确了思路,所以我们来看到代码: (由于代码有注释,那么这里就不多废话了)

python 复制代码
def count_chars(input_str):
    """
    负责统计字符个数
    :param input_str:
    :return:
    """
    char_count = {}
    count_chars_helper(input_str, 1, char_count)
    output = ""
    sorted_keys = sorted(char_count.keys())
    for key in sorted_keys:
        output += key + str(char_count.get(key))
    return output


def count_chars_helper(input_str, count, char_count):
    """
    处理括号翻倍的情况,匹配
    :param input_str:
    :param count:
    :param char_count:
    :return:
    """
    i = 0
    while i < len(input_str):
        c = input_str[i]
        if c == '(':
            #找到(XXXX),然后方面记录里面的元素的个数,方面后面做统计累加
            end_index = find_matching_parenthesis(input_str, i)
            num = get_number_after_parenthesis(input_str, end_index + 1)
            # 处理嵌套括号的问题
            count_chars_helper(input_str[i + 1:end_index], count * num, char_count)
            i = end_index + len(str(num))
        elif c.isalpha():
            # 对统计出的这一组元素*后面的数字的处理,然后累加
            num = get_number_after_parenthesis(input_str, i + 1)
            char_count[c] = char_count.get(c, 0) + count * num
        i += 1


def find_matching_parenthesis(input_str, start_index):
    """
    找到与左括号匹配的右括号的位置
    :param input_str:
    :param start_index:
    :return:
    """
    count = 1
    for i in range(start_index + 1, len(input_str)):
        c = input_str[i]
        if c == '(':
            count += 1
        elif c == ')':
            count -= 1
            if count == 0:
                return i
    return -1


def get_number_after_parenthesis(input_str, start_index):
    """
    获取括号后面的数字
    :param input_str:
    :param start_index:
    :return:
    """
    end_index = start_index
    while end_index < len(input_str) and input_str[end_index].isdigit():
        end_index += 1
    return int(input_str[start_index:end_index]) if end_index > start_index else 1



if __name__ == "__main__":
    print(count_chars("X2Y3XZ"))
    print(count_chars("Z3X(XY)2"))
    print(count_chars("Z4(Y2(XZ2)3)2X2"))

当然这里要注意的细节如下:

  1. 要求是按照字母序号进行输出,所以要对结果进行排序
  2. 在对括号进行处理的时候,可以使用栈进行处理,可以先对表达式做一个预处理,得到下标位置,然后压入栈,这样的话可以减少对下标的处理难度,但是需要对栈有一点了熟练度。并且由于时间复杂度都是0(n)的,直接遍历处理倒也还行。

总结

最后,哥们不想考研了,有没有大哥捞一下~

相关推荐
代码之光_19805 分钟前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端
编程老船长18 分钟前
第26章 Java操作Mongodb实现数据持久化
数据库·后端·mongodb
IT果果日记39 分钟前
DataX+Crontab实现多任务顺序定时同步
后端
姜学迁2 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健2 小时前
MQTT--Java整合EMQX
后端
北极小狐3 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
【D'accumulation】3 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
2401_854391083 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
Cikiss3 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss3 小时前
微服务实战——平台属性
java·数据库·后端·微服务