用匠心精神解决LeetCode第726题原子的数量

726.原子的数量

难度:困难

问题描述:

给你一个字符串化学式formula,返回每种原子的数量。

原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字。

如果数量大于1,原子后会跟着数字表示原子的数量。如果数量等于1则不会跟数字。

例如,"H2O"和"H2O2"是可行的,但"H1O2"这个表达是不可行的。

两个化学式连在一起可以构成新的化学式。

例如"H2O2He3Mg4"也是化学式。

由括号括起的化学式并佐以数字(可选择性添加)也是化学式。

例如"(H2O2)"和"(H2O2)3"是化学式。

返回所有原子的数量,格式为:第一个(按字典序)原子的名字,跟着它的数量(如果数量大于1),然后是第二个原子的名字(按字典序),跟着它的数量(如果数量大于1),以此类推。

示例1:

输入:formula="H2O"

输出:"H2O"

解释:原子的数量是{'H':2,'O':1}。

示例2:

输入:formula="Mg(OH)2"

输出:"H2MgO2"

解释:原子的数量是{'H':2,'Mg':1,'O':2}。

示例3:

输入:formula="K4(ON(SO3)2)2"

输出:"K4N2O14S4"

解释:原子的数量是{'K':4,'N':2,'O':14,'S':4}。

提示:

1<=formula.length<=1000

formula由英文字母、数字、'('和')'组成

formula总是有效的化学式

问题分析及解决思路:

为了使问题处理更加简便,对化学式中原子符号是两个或两个以上字母的,用原子符号大写字母之后的第一个小写字母进行替换,这样简化成每一个原子都只用一个字母代表,在处理完成之后,再替换回原来的原子符号

刚开始,我认为只要对原始字符串formula一层层去括号,括号去完之后,再将数字转换为相应数量的原子字符,最后再统计各原子的数量,整理得到题目要求的结果。比如形如(AB)2(CD(EF)2)2(CD)2这样的化学式,其处理步骤如下:

(AB)2(CD(EF)2)2(CD)2--->ABABCD(EF)2CD(EF)2CDCD---->ABABCDEFEFCDEFEFCDCD--->统计各原子个数--->A2B2C4D4E4F4

结果发现把最外层的括号一次性全部去掉的处理使问题变得较为复杂

其实,可以使处理更加简便单纯,每次只处理第一个括号,处理完成后再处理新生成的字符串的第一个括号,直到字符串中没有括号为止。比如上面的化学式,可以这样处理:

(AB)2(CD(EF)2)2(CD)2--->ABAB(CD(EF)2)2(CD)2--->ABABCD(EF)2CD(EF)2(CD)2--->ABABCDEFEFCD(EF)2(CD)2--->ABABCDEFEFCDEFEF(CD)2--->ABABCDEFEFCDEFEFCDCD--->统计各原子个数--->A2B2C4D4E4F4

其实,这种简化处理印证了一种思维,函数功能尽量简单单纯,不要复杂,这样使程序的可读性变强,处理思路更加清晰,功能更加容易实现,正如python之禅所说:Simple is better than complex.

根据上面的处理思路,设计了如下一些函数来处理:

  1. 函数fposition(s),功能是对字符串s,寻找第一个括号的起始位置和结束位置的索引号,并返回
  2. 函数getnum(s,end),功能是根据字符串s中括号的结束位置end,找到其后所跟数字并返回,如果没有数字或括号的结束位置已经处于s的结尾,则返回1
  3. 函数clyc(s),功能是对字符串s找到第一个括号的起始位置和结束位置,并根据结束位置找到其后的数字,将数字作用于括号中的字符处理的结果字符串返回
  4. 函数nposition(s),功能为查找字符串s中数字出现的索引号,如果没有数字,返回0,这个函数配合getnum(s,end)函数,是在将字符串中的括号处理完之后,只剩下字母和数字的情况下使用的
  5. 函数lastcl(s),功能是对已经处理完括号的字符串s进行数字的反复处理,返回一个没有数字的字符串
  6. 函数find2atom(s),功能将原子符号是两个或两以上的找出,并以列表形式返回

程序如下:
#在字符串s中找到第一个括号的起始位置和对应的结束位置并返回
def fposition(s):
    n=len(s)
    k=0
    start=0
    end=0
    for i in range(n):
        if s[i]=='(':
            if k==0:
                start=i
            k=k+1
        elif s[i]==')':
            k=k-1
            if k==0:
                end=i
                break
    return start,end

#在字符串s中根据右括号的位置end找到在其右的数字并返回,如果没有数字或已经处于s的结尾,返回1
def getnum(s,end):
    n=len(s)
    if end==n-1 or end<n-1 and not s[end+1].isnumeric():
        return 1
    else:
        for i in range(end+1,n):
            if s[i].isnumeric():
                continue
            else:
                return int(s[end+1:i])
        else:
            return int(s[end+1:])

#对字符串s根据括号和其后的数字进行一次处理,并返回处理之后的字符串
def clyc(s):
    n=len(s)
    start,end=fposition(s)
    num=getnum(s,end)
    s1=s[:start]
    s2=s[start+1:end]*num
    k=end+len(str(num))
    if k==n-1:
        s3=''
    else:
        s3=s[k+1:]
    return s1+s2+s3

#返回字符串s中第一个数字的位置,如果没有数字,返回0
def nposithon(s):
    n=len(s)
    for i in range(n):
        if s[i].isnumeric():
            return i
    else:
        return 0

#对已经处理完括号的字符串s按其中的数字反复处理,返回一个没有数字的字符串
def lastcl(s):
    i=nposithon(s)
    while i!=0:
        n = getnum(s, i-1)
        s1=s[:i-1]
        s2=s[i-1]*n
        s3=s[i+len(str(n)):]
        s=s1+s2+s3
        i=nposithon(s)
    return s

#查找并返回字符串s中含有两个或两个以上字母的原子
def find2atom(s):
    a=[]
    n=len(s)
    k=0
    start=0
    for i in range(n):
        if s[i].islower():
            if k==0:
                start=i-1
            k=k+1
        else:
            if k!=0:
                a.append(s[start:i])
                start=0
                k=0
            else:
                continue
    if k!=0:
        a.append(s[start:])
    return a

#主程序
formula=input('pls input formula=')

#查找formula中包含两个或两个以上字母的原子
a=find2atom(formula)

# 对formula中有两个或两个以上字母的原子用该原子的第一个小写字母替换
for i in a:
    formula=formula.replace(i,i[1])

#去掉所有括号
while '(' in formula:
    formula=clyc(formula)

#处理数字,变成无数字字符的字符串
s=lastcl(formula)

#统计各字符的个数并按字典顺序重新合成新的字符串
d=list(set(list(s)))
e=[]
for i in d:
    c=s.count(i)
    e.append([i,str(c) if c>1 else ''])

#将替换为小写字母的原子替换回原来多个字母形式的原子符号
for i in e:
    for j in a:
        if i[0]==j[1]:
            i[0]=j

#按字典序排序
e.sort(key=lambda x:x[0])

#组合成最终结果并输出
s=''.join(list(map(lambda x:''.join(x),e)))
print(s)

运行实例一

pls input formula=Mg(OH)2

H2MgO2

运行实例二

pls input formula=(AB)2(CD(EF)2)2(CD)2

A2B2C4D4E4F4

运行实例三

pls input formula=K4(ON(SO3)2)2

K4N2O14S4

运行实例四

pls input formula=Aggg3(Cu(OH)2)2(NaOH)2

Aggg3Cu2H6Na2O6

感悟:

编程犹如雕刻,雕刻用雕刀雕出精美的艺术品,独具匠心,编程则用编程语言和算法思想对问题抽丝剥茧,可谓匠心独运。要提高技艺,都需要反复练习,或心细如发,或大巧若拙,熟能生巧,方能形成智慧的结晶。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920688.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode 远程连接ssh 密钥方式

目录 1. powershell 生成key&#xff1a; 2. 在服务器上安装公钥 3).为了确保连接成功&#xff0c;输入如下指令以保证以下文件权限正确&#xff1a; 3 开启 ssh 密钥登录 vscode 远程连接配置 python连接 1. powershell 生成key&#xff1a; 在命令行执行ssh-keygen来创…

web——upload-labs——第十一关——黑名单验证,双写绕过

还是查看源码&#xff0c; $file_name str_ireplace($deny_ext,"", $file_name); 该语句的作用是&#xff1a;从 $file_name 中去除所有出现在 $deny_ext 数组中的元素&#xff0c;替换为空字符串&#xff08;即删除这些元素&#xff09;。str_ireplace() 在处理时…

vue中mixin(混入)的使用

目录 mixin(混入) 使用方式 第一步定义混合 ​编辑 第二步使用混入 局部混入 全局混合 mixin(混入) 功能&#xff1a;可以把多个组件共用的配置提取成一个混入对象 使用方式 第一步定义混合 { data(){....}, methods:{....} .... } 第二步使用混入 …

Block Successive Upper Bound Minimization Method(BSUM)算法

BSUM优化方法学习 先验知识参考资料1 A Unified Convergence Analysis of Block Successive Minimization Methods for Nonsmooth OptimizationSUCCESSIVE UPPER-BOUND MINIMIZATION (SUM) 连续上限最小化算法THE BLOCK SUCCESSIVE UPPER-BOUND MINIMIZATION ALGORITHM 块连续上…

[STM32]从零开始的STM32 HAL库环境搭建

一、前言 之前在搭建STM32的标准库环境时就告诉过大家&#xff0c;开发STM32的方式主要有三种。一种是最原始但是效率最高的寄存器开发&#xff0c;另一种是效率仅次于寄存器难度相对较低的标准库开发&#xff0c;最后一种是最为简单但是程序效率最低的HAL库开发。如果对于初学…

【论文笔记】Large Brain Model (LaBraM, ICLR 2024)

Code: https://github.com/935963004/LaBraM Data: 无 目录 AbstractIntroductionMethodNeural tokenizer training&#xff1a;Pre-training LaBraM&#xff1a; ResultsExperimental setup&#xff1a;Pre-training result&#xff1a;Comparison with SOTA&#xff1a;Pre-t…

AnythingLLM - 任何文档资源内容转换为任何LLM

更多AI开源软件&#xff1a; AI开源 - 小众AIhttps://www.aiinn.cn/sources 一个全栈应用程序&#xff0c;使您能够将任何文档、资源或内容转换为任何 LLM 都可以在聊天期间用作参考的上下文。此应用程序允许您选择要使用的 LLM 或矢量数据库&#xff0c;并支持多用户管理和权…

PDF内容提取,MinerU使用

准备环境 # python 3.10 python3 -m pip install huggingface_hub python3 -m pip install modelscope python3 -m pip install -U magic-pdf[full] --extra-index-url https://wheels.myhloli.com下载需要的模型 import json import osimport requests from huggingface_hub…

【阅读记录-章节3】Build a Large Language Model (From Scratch)

目录 3 Coding attention mechanisms3.1 The problem with modeling long sequences背景&#xff1a;注意力机制的动机 3.2 Capturing data dependencies with attention mechanismsRNN的局限性与改进Transformer架构的革命 3.3 Attending to different parts of the input wit…

Kubernetes配置管理ConfigMap、Secret

Your burden will become a gift, and your suffering will light your way. 应用部署的一个最佳实践是将应用所需的配置信息与程序分离,这样可以使应用程序被更好地复用,通过不同的配置也能实现更灵活的功能。将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在…

141. Sprite标签(Canvas作为贴图)

上节课案例创建标签的方式&#xff0c;是把一张图片作为Sprite精灵模型的颜色贴图,本节给大家演示把Canvas画布作为Sprite精灵模型的颜色贴图&#xff0c;实现一个标签。 注意&#xff1a;本节课主要是技术方案讲解&#xff0c;默认你有Canvas基础&#xff0c;如果没有Canvas基…

「OpenCV交叉编译」ubuntu to arm64

Ubuntu x86_64 交叉编译OpenCV 为 arm64OpenCV4.5.5、cmake version 3.16.3交叉编译器 gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu 可在arm或linaro官网下载所需版本&#xff0c;本文的交叉编译器可点击链接跳转下载 Downloads | GNU-A Downloads – Arm Developer L…

鸿蒙网络编程系列48-仓颉版UDP回声服务器示例

1. UDP回声服务器简介 回声服务器指的是这样一种服务器&#xff0c;它接受客户端的连接&#xff0c;并且把收到的数据原样返回给客户端&#xff0c;本系列的第2篇文章《鸿蒙网络编程系列2-UDP回声服务器的实现》中基于ArkTS语言在API 9的环境下实现了UDP回声服务器&#xff0c…

【WPF】Prism学习(七)

Prism Dependency Injection 1.注册类型&#xff08;Registering Types&#xff09; 1.1. Prism中的服务生命周期&#xff1a; Transient&#xff08;瞬态&#xff09;&#xff1a;每次请求服务或类型时&#xff0c;都会获得一个新的实例。Singleton&#xff08;单例&#xf…

springboot基于Hadoop的NBA球员大数据分析与可视化(1)(6)

摘 要 科学技术日新月异&#xff0c;人们的生活都发生了翻天覆地的变化&#xff0c;NBA球员大数据分析与可视化系统当然也不例外。过去的信息管理都使用传统的方式实行&#xff0c;既花费了时间&#xff0c;又浪费了精力。在信息如此发达的今天&#xff0c;可以通过网络这个媒…

Q3净利增长超预期,文心大模型调用量大增,百度未来如何分析?

首先&#xff0c;从百度发布的2024年第三季度财务报告来看&#xff0c;其净利润同比增长17%&#xff0c;超出了市场预期&#xff0c;显示出百度整体财务表现的强劲。这一增长不仅体现在总营收和百度核心营收上&#xff0c;更具体地反映在归属百度核心的净利润上&#xff0c;这标…

Vscode/Code-server无网环境安装通义灵码

Date: 2024-11-18 参考材料&#xff1a;https://help.aliyun.com/zh/lingma/user-guide/individual-edition-login-tongyi-lingma?spma2c4g.11186623.0.i0 1. 首先在vscode/code-server插件市场中安装通义插件&#xff0c;这步就不细说了。如果服务器没网&#xff0c;会问你要…

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS&#xff0c;并结合cpolar内网穿透工…

实战 | C#中使用YoloV8和OpenCvSharp实现目标检测 (步骤 + 源码)

导 读 本文主要介绍在C#中使用YoloV8实现目标检测,并给详细步骤和代码。 详细步骤 【1】环境和依赖项。 需先安装VS2022最新版,.NetFramework8.0,然后新建项目,nuget安装 YoloSharp,YoloSharp介绍: https://github.com/dme-compunet/YoloSharp 最新版6.0.1,本文…

IDE配置tomcat

1.导航到 Tomcat 安装目录 E:\apache-tomcat-9.0.95-windows-x64\apache-tomcat-9.0.95 2.启动 Tomcat 服务&#xff1a;bin\startup.bat