LeetCode.726 原子的数量 原题链接:原子的数量

1. 题意:

将化学式的各个元素按字典序排序,以(元素+元素个数)的形式依次累加成字符串

2. 思路

  • 通过pair的形式,将每个元素和该元素的个数对映,括号也与括号后的个数对映,如下图
    图片名称
  • 利用栈结构匹配(),将括号的外的个数,乘以括号里各元素对应的个数。
  • 哈希表统计各元素的个数,并以字典序排序

3. 代码注释

变量定义的解释

vector<pair<char, int>> vec: 每个字母、括号与后面的数字的键值对,char为字母或括号,int为对应的字母或括号后面的数字

stack<pair<char, int>> sta: pair中含义与vec中相似

map<string, int> maps;:每个元素与后面的数字的键值对,string为对元素,例如Mg、H、O等,int为元素的个数

string res:返回的目标字符串

string countOfAtoms(string formula) {
        vector<pair<char, int>> vec;
        map<string, int> maps;
        stack<pair<char, int>> sta;
        string res = "";
        for (int i = 0; i < formula.size(); i++)                                        //将原子的数量储存在‘)’或元素的pair中
        {
            if (formula[i] >= '0' && formula[i] <= '9')
                continue;
            int sum = 1;
            string temp = formula.substr(i + 1);
            if ( i+1<formula.size()&&formula[i + 1] >= '0' && formula[i + 1] <= '9')
                sum = stoi(temp);
            vec.push_back({ formula[i],sum });
        }
        for (int i = 0; i < vec.size(); i++)                                             //除了‘)’都压入栈中
        {
            if (vec[i].first == ')')                                                     //为')'时,把栈元素以此弹出直到弹出匹配的'('                
            {
                stack<pair<char, int>> temp;
                int mult = vec[i].second;
                while (!sta.empty() && sta.top().first != '(')
                {
                    temp.push({ sta.top().first,sta.top().second * mult });             //每个元素乘以括号外的数字
                    sta.pop();
                }
                sta.pop();                                                              //弹出‘(’
                while (!temp.empty())                                                   //再将乘了括号外数量的元素压入栈中
                {
                    sta.push(temp.top());
                    temp.pop();
                }
                continue;
            }
            sta.push({ vec[i].first,vec[i].second });                                   //不是')'就压入
        }
        while (!sta.empty())                                                            //依次弹出栈中的元素到maps中,计算每个元素的个数
        {
            string str = "";
            int mul = sta.top().second;
            str += sta.top().first;
            if (sta.top().first >= 'a' && sta.top().first <= 'z')                       //特殊的类似 Mg 两个字母的元素
            {
                mul = sta.top().second;
                sta.pop();
                str += sta.top().first;
                swap(str[0], str[1]);
            }
            maps[str] += mul;
            sta.pop();
        }
        for (auto i : maps)                                                             //maps中统计好了元素按字典序放入字符串中
        {
            res += i.first;
            if (i.second > 1)                        
                res += to_string(i.second);
        }
        return res;
}

测试代码

int main()
{
    string str = "H2O";
    string str1 = "Mg(OH)2";
    string str2 = "K4(ON(SO3)2)2";
    string str3 = "Be32";
    string str4 = "((N42)24(OB40Li30CHe3O48LiNN26)33(C12Li48N30H13HBe31)21(BHN30Li26BCBe47N40)15(H5)16)14";
    cout << countOfAtoms(str) << endl;
    cout << countOfAtoms(str1) << endl;
    cout << countOfAtoms(str2) << endl;
    cout << countOfAtoms(str3) << endl;
    cout << countOfAtoms(str4) << endl;
   return 0;
}

测试图片

图片名称