给出一个字符串格式的化学分子式,计算原子的个数
每个化学元素都是由一个大写字母,或者一个大写字母后跟着若干个小写字母组成,例如H是一个化学元素,Mg也是一个化学元素。
每个分子式中,原子的个数写在元素后面,如果原子个数是1,那么原子个数省略。例如H2O和H2O2都是有效的分子式,但H1O2不是有效分子式。
每个分子式中包含若干括号,为简单起见,分子式中只有小括号。
每次输入一个分子式,对每个给定的分子式,求出每个原子的个数,按照原子字母表的顺序排列,并输出。
一行,一个字符串表示输入的分子式
按要求输出答案
H2O
H2O
Mg(OH)2
H2MgO2
K4(ON(SO3)2)2
K4N2O14S4
""" 若为元素名加个数,则直接求解元素名及其原子个数,更新到字典中; 若包含括号,对括号内表达式递归求解。 """ def get_digit(s): # 求从s[0]开始的数字,若没有数字返回1,并返回数字的位数 k = 0 while k < len(s) and s[k].isdigit(): k += 1 num = 1 if k == 0 else int(s[:k]) return num, k def fun(s, dic, buff): # buff为化学分子式s括号外的加成 t, n = 0, len(s) # t从0到n对s遍历 while t < n: if s[t].isupper(): # 若为大写字母,则求元素名对应的个数 j = t + 1 while j < n and s[j].islower(): j += 1 num, tmp = get_digit(s[j:]) # 得到表达式所示的个数 if s[t:j] not in dic: dic[s[t:j]] = 0 dic[s[t:j]] += num * buff # num*buff t = j + tmp elif s[t] == '(': # 括号情况,对括号内表达式递归 stack = ['('] j = t + 1 while stack: # 找到与外层括号配对的右括号下标j-1 if s[j] == '(': stack.append('(') elif s[j] == ')': stack.pop() j += 1 num, tmp = get_digit(s[j:]) fun(s[t + 1:j - 1], dic, num * buff) # 对括号内s[t + 1:j - 1]表达式递归求解 t = j + tmp if __name__ == "__main__": s = input().strip() # 化学分子式 dic = {} # 存储化学原子及其个数 fun(s, dic, 1) # 构造dic ans = "" # 排序并按要求输出 for i in sorted(list(dic.keys())): ans += i if dic[i] > 1: ans += str(dic[i]) print(ans)
#include <bits/stdc++.h> using namespace std; int main(){ string s, t="", r=""; cin>>s; deque<int> Q; vector<string> S; vector<int> v; int l=s.length(), m=1, cnt=0, k=0; for(int i=l-1;i>=0;i--){ if(isdigit(s[i])) t = s[i] + t; else{ if(t!=""){ Q.push_front(stoi(t)); m *= stoi(t); cnt++; t = ""; } if(islower(s[i])) r = s[i] + r; else if(isupper(s[i])){ S.push_back(s[i]+r); v.push_back(m); if(cnt>k){ if(m!=1){ m /= Q.front(); Q.pop_front(); } cnt--; } r = ""; }else{ if(s[i]==')') k++; else if(s[i]=='('){ if(m!=1){ m /= Q.front(); Q.pop_front(); } cnt--; k--; } } } } map<string, int> M; for(int i=0;i<S.size();i++) M[S[i]] += v[i]; for(map<string,int>::iterator it=M.begin();it!=M.end();it++){ if(it->second==1) cout<<it->first; else cout<<it->first<<it->second; } cout<<endl; return 0; }
class MainActivity: def main(self): # Read the data s = input() # Get the results results = self.__traverse(s) # Construct the result results = sorted(list(results.items()), key=lambda x: x[0]) results = list(map(lambda x: '%s%d' % (x[0], x[1]) if x[1] > 1 else x[0], results)) result = ''.join(results) print(result) def __traverse(self, s): # Initialization results = dict() cnt = 0 elementCache = [] ptr = 0 # Traverse while ptr < len(s): char = s[ptr] if ord('A') <= ord(char) <= ord('Z'): if cnt and elementCache: element = ''.join(elementCache) if cnt > 1: cnt = int(str(cnt)[1:]) results[element] = results.get(element, 0) + cnt cnt = 1 elementCache = [char] ptr += 1 elif ord('a') <= ord(char) <= ord('z'): elementCache.append(char) ptr += 1 elif char.isnumeric(): cnt = cnt * 10 + int(char) ptr += 1 else: # ( # Add the cache first if cnt and elementCache: element = ''.join(elementCache) if cnt > 1: cnt = int(str(cnt)[1:]) results[element] = results.get(element, 0) + cnt elementCache = [] cnt = 1 # Cope with the content in the bracket bracketCnt = 1 cacheS = [] ptr += 1 while bracketCnt: cacheS.append(s[ptr]) if bracketCnt and s[ptr] == ')': bracketCnt -= 1 elif s[ptr] == '(': bracketCnt += 1 ptr += 1 cacheS.pop() # Remove the outer ')' subS = ''.join(cacheS) subResult = self.__traverse(subS) while ptr < len(s) and s[ptr].isnumeric(): cnt = cnt * 10 + int(s[ptr]) ptr += 1 if cnt > 1: cnt = int(str(cnt)[1:]) for element, times in subResult.items(): results[element] = results.get(element, 0) + times * cnt if cnt: element = ''.join(elementCache) if cnt and element: if cnt > 1: cnt = int(str(cnt)[1:]) results[element] = results.get(element, 0) + cnt return results if __name__ == '__main__': M = MainActivity() M.main()
#include <iostream> #include <stack> #include <string> #include <map> using namespace std; string countOfAtoms(string formula) { string res = ""; stack<map<string, int> > st; map<string, int> cur; int n = formula.size(), pos = 0; while (pos < n) { if (formula[pos] == '(') //遇到“(”压栈, 清空当前cur { ++pos; st.push(cur); cur.clear(); } else if(formula[pos] == ')') //出栈“)”出栈, { int i = ++pos; while (pos < n && isdigit(formula[pos])) //统计“)”后的数字 { ++pos; } int multiple = stoi(formula.substr(i, pos - i)); //for (auto a : cur) //{ // st.top()[a.first] += a.second * multiple; //在当前栈顶,添加新元素 //} //cur = st.top(); //st.pop(); map<string, int> preCur = st.top(); //此时preCur保存了上一时刻的元素 st.pop(); for (auto a : cur) //合并当前cur的元素到preCur { preCur[a.first] += a.second*multiple; } cur = preCur; } else { int i = pos++; while (pos < n && islower(formula[pos])) //识别元素 { pos++; } string elem = formula.substr(i, pos - i); i = pos; while (pos < n && isdigit(formula[pos])) //识别元素后面的数字 { ++pos; } string cnt = formula.substr(i, pos - i); cur[elem] += cnt.empty() ? 1 : stoi(cnt); //当前元素存入cur } } for (auto a : cur) { res += a.first + (a.second == 1 ? "" : to_string(a.second)); } return res; } int main() { string formula, result; cin >> formula; result = countOfAtoms(formula); cout << result << endl; }
#include<bits/stdc++.h> using namespace std; int main() { // 原子格式 大写的单个字符 // 或者双字符 第一个大写 第二个小写 string s; vector<char>v; string tmp = ""; while(cin>>s) { for(int i=0;i<s.size();++i) { if(s[i]=='(') v.push_back('#'); else if(s[i]==')'){ while(v.back()!='#') { tmp = v.back()+tmp; v.pop_back(); } v.pop_back(); } else if((s[i]<='Z'&&s[i]>='A')||(s[i]>='a'&&s[i]<='z')) v.push_back(s[i]); else{ int cnt = 0; string last = ""; if(s[i-1]>='A'&&s[i-1]<='Z') last += s[i-1]; else { last = last + s[i-1]; last = s[i-2] + last; } while(i<s.size()&&s[i]>='0'&&s[i]<='9') { cnt = cnt*10 + (s[i]-'0'); ++i; } if(tmp!=""){ while(cnt--) { for(char c:tmp) v.push_back(c); } } else{ cnt-=1; while(cnt--) { for(char c:last) v.push_back(c); } } //for(char t:v) // cout<<t; //cout<<endl; tmp.clear(); --i; } } } map<string,int>mp; while(!v.empty()) { string tmp = ""; char c = v.back(); v.pop_back(); if(c>='A'&&c<='Z') tmp += c; else { tmp+=c; tmp = v.back()+tmp; v.pop_back(); } mp[tmp] += 1; } for(auto it=mp.begin();it!=mp.end();++it) { if(it->second>1) cout<<it->first<<it->second; else cout<<it->first; } return 0; }
#include <bits/stdc++.h> using namespace std; struct node{ string s; int num; node (string s, int num){ this->s = s; this->num = num; } }; string int_to_string(int i){ string res; stringstream ss; ss << i; ss >> res; return res; } int main() { string s; map<string, int> mp; map<string, string> decode; vector <string> st; vector <string> tu; vector <node> ret; cin >> s; for (int i = 0; i < s.length(); i++){ string ans = ""; string str = ""; if(s[i] >= 'A' && s[i] <= 'Z'){ ans += (int_to_string(i)); str.push_back(s[i]); while((i + 1) < s.length() && s[i + 1] >= 'a' && s[i + 1] <= 'z'){ i++; str.push_back(s[i]); } if((i + 1) < s.length()){ if(s[i + 1] >= '0' && s[i + 1] <= '9'){ int bar = 0; while((i + 1) < s.length() && s[i + 1] >= '0' && s[i + 1] <= '9'){ i++; bar = bar * 10 + (s[i] - '0'); } mp[ans] = bar; } else { mp[ans] = 1; } } else { mp[ans] = 1; } decode[ans] = str; st.push_back(ans); //cerr << "ans == " << ans << endl; //cerr << "str == " << str << endl; } else if(s[i] == '('){ string cur = "("; st.push_back(cur); } else if(s[i] == ')'){ int foo; if((i + 1) < s.length() && s[i + 1] >= '0' && s[i + 1] <= '9'){ foo = 0; while((i + 1) < s.length() && s[i + 1] >= '0' && s[i + 1] <= '9'){ i++; foo = 10 * foo + (s[i] - '0'); } } else { foo = 1; } //cerr << "foo == " << foo << endl; while(!st.empty()){ string use = st.back(); // cerr << "use == " << use << endl; // cerr << "str == " << decode[use] << endl; if(use == "("){ st.pop_back(); break; } mp[use] *= foo; tu.push_back(use); st.pop_back(); } while(!tu.empty()){ st.push_back(tu.back()); tu.pop_back(); } } } for (int i = 0; i < st.size(); i++){ //cerr << decode[st[i]] << endl; ret.push_back(node(decode[st[i]], mp[st[i]])); } sort(ret.begin(), ret.end(), [&](node a, node b){return a.s < b.s;}); for (int i = 0; i < (int)ret.size(); i++){ int num = ret[i].num; if((i + 1) < (int)ret.size() && ret[i].s == ret[i + 1].s){ while((i + 1) < ret.size() && ret[i].s == ret[i + 1].s){ i++; num += ret[i].num; } } cout << ret[i].s; if(num > 1){ cout << num; } } cout << "\n"; return 0; }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @Auther:srd-czk * @Date:2019/9/7 * @Description:a2019 * @version:1.0 */ public class Main { private static String toString(int i) { StringBuilder sb = new StringBuilder(); sb.append((char)('A' + i / 27)); if (i % 27 != 0) sb.append((char)('a' + i % 27 - 1)); return sb.toString(); } private static int[] process(char[] chs, int i, int j) { int[] res = new int[26 * 27]; while (i < j + 1) { if (chs[i] >= 'A' && chs[i] <= 'Z') { char c = chs[i]; if (i + 1 < j + 1 && chs[i + 1] >= 'a' && chs[i + 1] <= 'z') { i++; int k = (c - 'A') * 27 + 1 + (chs[i] - 'a'); if (i + 1 < j + 1 && Character.isDigit(chs[i + 1])) { int p = 0; i++; while (i < j + 1 && Character.isDigit(chs[i])) { p = p * 10 + chs[i++] - '0'; } res[k] += p; } else { res[k]++; i++; } } else if (i + 1 < j + 1 && Character.isDigit(chs[i + 1])) { int p = 0; i++; while (i < j + 1 && Character.isDigit(chs[i])) { p = p * 10 + chs[i++] - '0'; } res[27 * (c - 'A')] += p; } else { res[27 * (c - 'A')]++; i++; } } else { int cnt = 1; int start = ++i; while (i < j + 1 && cnt != 0) { if (chs[i] == '(') cnt++; else if (chs[i] == ')') cnt--; i++; } int[] sub = process(chs, start, i - 2); int p = chs[i++] - '0'; while (i < j + 1 && Character.isDigit(chs[i])) { p = p * 10 + chs[i++] - '0'; } for (int k = 0; k < sub.length; k++) { res[k] += sub[k] * p; } } } return res; } public static void main(String[] args) throws IOException { BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String s = bf.readLine(); int[] res = process(s.toCharArray(), 0, s.length() - 1); for (int i = 0; i < res.length; i++) { if (res[i] > 0) { System.out.print(toString(i)); if (res[i] > 1) System.out.print(res[i]); } } System.out.println(); bf.close(); } }