fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <cctype>
  4. #include <map>
  5. #include <stack>
  6.  
  7. struct Molecule
  8. {
  9. std::string name;
  10. int count;
  11.  
  12. Molecule() : name(""), count(1) {}
  13. Molecule(const std::string& name) : name(name), count(1) {}
  14. Molecule(const std::string& name, int count) : name(name), count(count) {}
  15. };
  16. std::stack<Molecule> parseInput(const std::string& line);
  17.  
  18. int main()
  19. {
  20. std::string line;
  21. while(getline(std::cin, line))
  22. {
  23. std::cout << line << std::endl;
  24. auto stack = parseInput(line);
  25. std::map<std::string, int> moleculeCount;
  26. while(!stack.empty())
  27. {
  28. auto molecule = stack.top();
  29. stack.pop();
  30. moleculeCount[molecule.name] += molecule.count;
  31. }
  32.  
  33. for(const auto& kv: moleculeCount)
  34. std::cout << kv.first << " : " << kv.second << std::endl;
  35. std::cout << std::endl;
  36. }
  37. return 0;
  38. }
  39.  
  40. std::stack<Molecule> parseInput(const std::string& line)
  41. {
  42. std::stack<Molecule> stack;
  43. size_t i = 0;
  44. while(i < line.length() - 1)
  45. {
  46. char curr = line[i];
  47. char next = line[i + 1];
  48. if(std::isupper(curr) && std::islower(next))
  49. {
  50. if(i + 2 < line.length() && isdigit(line[i + 2]))
  51. {
  52. std::string name;
  53. name += curr;
  54. name += next;
  55. Molecule molecule(name);
  56. std::string number;
  57. for(int j = i + 2; std::isdigit(line[j]); j++)
  58. number += line[j];
  59. molecule.count = std::stoi(number);
  60. i += 2; //molecule name
  61. i += number.length(); //following number
  62. stack.push(molecule);
  63. }
  64. else
  65. {
  66. std::string name;
  67. name += curr;
  68. name += next;
  69. Molecule molecule(name);
  70. stack.push(molecule);
  71. i += 2;
  72. }
  73. continue;
  74. }
  75.  
  76. if(std::isupper(curr) && std::isdigit(next))
  77. {
  78. std::string name;
  79. std::string number;
  80. for(int j = i + 1; std::isdigit(line[j]); j++)
  81. number += line[j];
  82. name += curr;
  83. Molecule molecule(name, std::stoi(number));
  84. stack.push(molecule);
  85. i += 1; //molecule name
  86. i += number.length();
  87. continue;
  88. }
  89.  
  90. if(std::isupper(curr) && !std::isdigit(next))
  91. {
  92. std::string name;
  93. name += curr;
  94. Molecule molecule(name, 1);
  95. stack.push(molecule);
  96. i++;
  97. continue;
  98. }
  99.  
  100. if(curr == '(')
  101. {
  102. stack.push(Molecule("(", 0)); //probably not a good idea
  103. i++;
  104. continue;
  105. }
  106.  
  107. if(curr == ')')
  108. {
  109. std::vector<Molecule> molecules;
  110. int multiple = next - '0';
  111. while(true)
  112. {
  113. auto molecule = stack.top();
  114. stack.pop();
  115. if(molecule.name == "(")
  116. break;
  117. molecules.push_back(molecule);
  118. }
  119. for(auto& m: molecules)
  120. {
  121. m.count *= multiple;
  122. stack.push(m);
  123. }
  124. i += 2;
  125. continue;
  126. }
  127. }
  128. return stack;
  129. }
Success #stdin #stdout 0s 16080KB
stdin
C6H12O6
CCl2F2
NaHCO3
C4H8(OH)2
PbCl(NH3)2(COOH)2
stdout
C6H12O6
C : 6
H : 12
O : 6

CCl2F2
C : 1
Cl : 2
F : 2

NaHCO3
C : 1
H : 1
Na : 1
O : 3

C4H8(OH)2
C : 4
H : 10
O : 2

PbCl(NH3)2(COOH)2
C : 2
Cl : 1
H : 8
N : 2
O : 4
Pb : 1