fork(1) download
  1. #include <iostream>
  2. #include<string>
  3. #include<set>
  4. #include<algorithm>
  5.  
  6. struct property {
  7. std::string name;
  8. int32_t value;
  9.  
  10. bool same_name(property const& o) const {
  11. return name == o.name;
  12. }
  13.  
  14. bool same_value(property const& o) const {
  15. return value == o.value;
  16. }
  17.  
  18. bool operator==(property const& o) const {
  19. return same_name(o) && same_value(o);
  20. }
  21.  
  22. bool operator<(property const& o) const {
  23. if (!same_name(o)) return name < o.name;
  24. else return value < o.value;
  25. }
  26. };
  27.  
  28. std::set<property> tokenify(std::string input) {
  29. bool finding_name = true;
  30. property prop;
  31. std::set<property> properties;
  32. while (input.size() > 0) {
  33. auto colon_index = input.find(':');
  34. if (finding_name) {
  35. prop.name = input.substr(0, colon_index);
  36. finding_name = false;
  37. }
  38. else {
  39. prop.value = std::stoi(input.substr(0, colon_index));
  40. finding_name = true;
  41. properties.insert(prop);
  42. }
  43. if(colon_index == std::string::npos)
  44. break;
  45. else
  46. input = input.substr(colon_index + 1);
  47. }
  48. return properties;
  49. }
  50.  
  51. std::string get_diff_string(std::string const& old_props, std::string const& new_props) {
  52. std::set<property> old_properties = tokenify(old_props);
  53. std::set<property> new_properties = tokenify(new_props);
  54.  
  55. std::string output;
  56.  
  57. for (property const& old_property : old_properties) {
  58. auto predicate = [&](property const& p) {
  59. return old_property.same_name(p);
  60. };
  61. auto it = std::find_if(new_properties.begin(), new_properties.end(), predicate);
  62. if (it == new_properties.end()) {
  63. //We didn't find the property.
  64. output.append("REMOVE:" + old_property.name + ':');
  65. }
  66. else if (!it->same_value(old_property)) {
  67. //Found the property, but the value changed.
  68. output.append(it->name + ':' + std::to_string(it->value) + ':');
  69. }
  70. }
  71.  
  72. //Finally, we need to see which were added.
  73. for (property const& new_property : new_properties) {
  74. auto predicate = [&](property const& p) {
  75. return new_property.same_name(p);
  76. };
  77. auto it = std::find_if(old_properties.begin(), old_properties.end(), predicate);
  78. if (it == old_properties.end()) {
  79. //We didn't find the property.
  80. output.append("ADD:" + new_property.name + ':' + new_property.name + ':' + std::to_string(new_property.value) + ':');
  81. }
  82. //We already checked for changes in the previous loop, so now we don't care.
  83. }
  84.  
  85. if (output.size() > 0)
  86. output = output.substr(0, output.size() - 1); //Trim off the last colon
  87.  
  88. return output;
  89. }
  90.  
  91. int main() {
  92. std::string diff_string = get_diff_string("MASTER:50:SYSTEM:50:STEAM:100:UPLAY:100", "MASTER:30:SYSTEM:50:STEAM:100:ROCKETLEAGUE:80:CHROME:100");
  93. std::cout << "Diff String was \"" << diff_string << '\"' << std::endl;
  94. }
Success #stdin #stdout 0s 16072KB
stdin
Standard input is empty
stdout
Diff String was "MASTER:30:REMOVE:UPLAY:ADD:CHROME:CHROME:100:ADD:ROCKETLEAGUE:ROCKETLEAGUE:80"