【问题标题】:How can I divide the contents of a string based on a chemical formula?如何根据化学式划分字符串的内容?
【发布时间】:2019-02-07 19:50:29
【问题描述】:

我必须验证一个应该模拟化学公式的字符串(不包括电荷 (+/-) 等符号),并且它必须尊重公式的编写方式(正确使用括号,每个最多两个字母元素,并且缺少不是括号的非字母数字字符)。然而,它不需要知道提交的分子是否能够存在——只要字符串本身是有效的。

假设要验证的字符串的内容如下所示:“Na3(CO2)3”

假设我已经验证了字符串不是空的并且它没有任何非法字符或不正确使用括号,则有必要将字符串分开,比如说符号,这样我就可以存储单个元素(我指的是所有元素。在这种情况下,3 个 Na 和 3 个 CO2 粒子)。

所以应该这样划分:

"Na",
"3",
"(",
"C"
"O"
"2"
")"
"3"

我尝试将它与for 分开,但有很多条件可以“分离”字符串,我不确定如何正确地做到这一点 - 特别是考虑到一个元素可以有 1 个或 2 个字符。

目前,我的代码看起来像这样,忽略了其他很容易验证的东西。

public boolean validerFormuleChimique(String formuleChimique, StringWrapper message)
{
  ArrayList<String> symbolSubmited = new ArrayList<String>();
  symbolSubmited.add(new String());
        symbolSubmited.get(0).equals("");
        for (int i =0; i< formuleChimique.length(); i++)
        {
            if(!Character.isLetterOrDigit(formuleChimique.charAt(i)) &&
                    ( formuleChimique.charAt(i) != '(' || 
                      formuleChimique.charAt(i) != ')' ))
            {
                message.contenu = messagesErreur[9];
                return false;
            }
        }
        return false;
}

我在代码中看到的另一个问题是我无法在 ArrayList 中使用 += 修改字符串。我可以使用数组,但在验证之前无法知道公式的长度。就是这样。

我希望我不仅可以验证公式,而且可以将公式的每个“符号”(包括数字和括号)存储在字符串的 ArrayList 中。

【问题讨论】:

  • 编写解析器可能是一件棘手的事情,我认为您需要花一些时间写下要解析的字符串的规则和“语法”。像“小写字母和前一个字母是一个元素”或“大写字母后跟另一个大写字母本身构成一个元素”等等。也许创建一个简单的 Element 类也会使事情变得更容易,这样您就不必跟踪这么多的字符串了。

标签: java string arraylist


【解决方案1】:

当您进行迭代时,您基本上需要计算令牌。括号是简单的标记。数字很​​简单——只要下一个字符是数字,你就必须继续前进。

真正的诀窍是元素名称的字符。有几种方法可以解决这个问题。如果您可以使用标准符号计算元素,则可以简单地假设小写字母是当前标记的延续,而大写字母是新标记的开头。因此 NaCl 会正确地变成两个标记,Na 和 Cl,而 CO2 会变成三个标记,C、O 和 2。

如果你不能指望标准化的大写,你的生活会变得更加艰难。

【讨论】:

  • 再一次 - 真正的关键是除了当前字符之外,您还需要查看下一个字符(如果有的话!)。
【解决方案2】:

如果您可以假设小写字母是当前标记的延续,则可以使用以下示例:

    public static void main(String[] args) {
    String test = "Na3(CO2)3";
    Pattern r =  Pattern.compile("A[cglmrstu]|B[aehikr]?|C[adeflmnorsu]?|D[bsy]|E[rsu]|F[elmr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airuv]|M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|S[bcegimnr]?|T[abcehilm]|U(u[opst])?|V|W|Xe|Yb?|Z[nr]|\\d|\\(|\\)");
    Matcher matcher =r.matcher(test);
    while (matcher.find()) {
        System.out.print("Start index: " + matcher.start());
        System.out.print(" End index: " + matcher.end() + " ");
        System.out.println(matcher.group());
    }
}

这是输出:

Start index: 0 End index: 2 Na
Start index: 2 End index: 3 3
Start index: 3 End index: 4 (
Start index: 4 End index: 5 C
Start index: 5 End index: 6 O
Start index: 6 End index: 7 2
Start index: 7 End index: 8 )
Start index: 8 End index: 9 3

【讨论】:

    猜你喜欢
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2021-01-18
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多