3

ユーザーは次のような数式を入力します。C12H2COOH

C = 12.01、H = 1.008、O = 16 として、その分子量を計算する必要があります。2 桁の後に 2 桁の要素と、後に数字のない要素に注意するように言われました。また、プログラムは化学式を要求し続け、Enter キーを押すと終了します。

for ループと while ループの辞書を使用してみました。元素の後に1桁の化合物を計算するようになったのC2H2ですが、2桁を入れたり、元素の隣に数字を入れなかったりすると失敗します。可能なルートとして区切り文字を削除せずに文字列を区切る方法も調べていましたか? 皆さんは、この問題にどのように取り組みますか? どんな助けでも大歓迎です、ありがとう!

これが私がこれまでに持っているものです。とても面倒です。

xxx = ["H", "C", "O"]
elements = set(xxx)
while(True):
    chemical_formula = input("Enter chemical formula, or enter to quit: ")
    if chemical_formula == "":
        break
    else:
        characters = list(chemical_formula)
        n = 0
        print(characters)
        for i in characters:
            if characters[n] == "C":
                c = 12.0107
                if elements.intersection(set(characters[n+1])):
                    print(c)
                else:
                    number = int(characters[n+1])
                    print(number*c)

            elif characters[n] == "H":
                h = 1.00794
                if elements.intersection(set(characters[n+1])):
                    print(h)
                else:
                    number = int(characters[n+1])
                    print(number*h)

            elif characters[n] == "O":
                o = 15.9994
                if elements.intersection(set(characters[n+1])):
                    print(c)
                else:
                    number = int(characters[n+1])
                    print(number*o) 
            else:
                numero = int(i)
                print(i*0)

            n = n+1
4

6 に答える 6

3

たとえば、入力文字列を不必要にリストに変換し、それを反復処理しますが、数値インデックスを使用して文字にアクセスします。また、各文字をその場で個別に見るのはあまり役に立ちません。これは、1 桁以上の数字で明らかに壊れるためです。また、遭遇した各要素の重みを個別に出力します。合計を出力すべきではありませんか?

次のコードは、小さなステート マシンを使用して入力文字列を解析し、結合された重みを出力します。すべての数式が要素で始まり、検出されたすべての要素がweights辞書に含まれており、要素名が 1 文字を超えることはありません。

#use a dictionary to map elements to their weights
weights = {"H": 1.00794, "C": 12.0107, "O": 15.9994}

def getInt(clist):
    """helper for parsing a list of chars as an int (returns 1 for empty list)"""
    if not clist: return 1
    return int(''.join(clist))

def getWeight(formula):
    """ get the combined weight of the formula in the input string """
    formula = list(formula)
    #initialize the weight to zero, and a list as a buffer for numbers
    weight = 0
    num_buffer = []
    #get the first element weight
    el_weight = weights[formula.pop(0)]
    while formula:
        next = formula.pop(0)
        if next in weights:
            #next character is an element, add current element weight to total
            weight += el_weight * getInt(num_buffer)
            #get the new elements weight
            el_weight = weights[element]
            #clear the number buffer
            num_buffer = []
        else:
            #next character is not an element -> it is a number, append to buffer
            num_buffer.append(next)
    #add the last element's weight and return the value
    return weight + el_weight * getInt(num_buffer)

while 1:
    #main loop
    chemical_formula = input("Enter chemical formula, or enter to quit: ")
    if not chemical_formula:
        break
    print("Combined weight is %s" % getWeight(chemical_formula))

whileこれは、ループ内の条件を変更しgetWeightて、数字の場合は int バッファーに文字を追加し、そうでない場合は現在の要素名を含む文字列に追加することで、複数文字の要素を処理するように簡単に拡張できます。次に、重みを取得し、名前が辞書''に含まれている場合は名前をリセットします。weights

于 2013-05-22T19:28:47.077 に答える
1

これは、正規表現を使用して式を解析する分子量 Python スクリプトです。

いくつかのデバッグコードが含まれています

import re

#some element data

elements ={}
elements["H"] = 1
elements["C"] = 12
elements["O"] = 16
elements["Cl"] = 35.45


#DDT (1,1,1-trichloro-2,2-di(4-chlorophenyl)ethane)
formula = "(ClC6H4)2CH(CCl3))"

sFormula = formula

print("Original Formula: ", sFormula)

#Search data inside ()

myRegEx = re.compile(r"(\()(\w*)(\))(\d*)",re.I)

myMatches = myRegEx.findall(sFormula)

while myMatches:
    myMatches = myRegEx.findall(sFormula)
    for match in myMatches:
        print (match[1], match[3])
        count = match[3]
        text =""
        if (count == ""):
            count = 1
        else:
            count = int(match[3])
        while (count >= 1):
            text = text + match[1]
            count -= 1
            print(text)
        sFormula = sFormula.replace('(' + match[1] + ')' + match[3], text)
        print("Replaced formula: ",sFormula)

myRegEx = re.compile("(C[laroudsemf]?|Os?|N[eaibdpos]?|S[icernbmg]?|P[drmtboau]?|H[eofgas]?|A[lrsgutcm]|B[eraik]?|Dy|E[urs]|F[erm]?|G[aed]|I[nr]?|Kr?|L[iaur]|M[gnodt]|R[buhenaf]|T[icebmalh]|U|V|W|Xe|Yb?|Z[nr])(\d*)")

myMatches = myRegEx.findall(sFormula)

molecularFormula =""
MW = 0
text =""

for match in myMatches:
    #Search symbol
    symbol = match[0]
    #Search numbers
    number = match[1]
    print(symbol,number)
    if (number == ""):
        number = 1
    else:
        number = int(match[1])
    MW = MW + float(elements[symbol])*number
    while (number >=1):
        molecularFormula = molecularFormula + symbol
        number -= 1 
print(molecularFormula)
print("formula: " + formula + " MW = " + str(MW))
于 2013-10-24T07:50:33.863 に答える