{"id":478,"date":"2022-03-20T09:43:34","date_gmt":"2022-03-20T01:43:34","guid":{"rendered":"http:\/\/liyanliang.net\/?p=478"},"modified":"2022-03-20T09:45:37","modified_gmt":"2022-03-20T01:45:37","slug":"cpp_simple_interpreter","status":"publish","type":"post","link":"http:\/\/liyanliang.net\/index.php\/2022\/03\/20\/cpp_simple_interpreter\/","title":{"rendered":"C++\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8bed\u8a00\u89e3\u91ca\u5668"},"content":{"rendered":"\n<p class=\"has-cyan-bluish-gray-background-color has-background\">\u63cf\u8ff0\uff1a \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8bed\u8a00\u89e3\u91ca\u5668\uff0c\u652f\u6301\u4ee5\u4e0b\u6307\u4ee4<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>\u6307\u4ee4\u683c\u5f0f<\/th><th>\u63cf\u8ff0<\/th><\/tr><\/thead><tbody><tr><td>mov a v<\/td><td>\u628a\u6570v\u8d4b\u503c\u7ed9a\uff0c\u5176\u4e2da\u662f\u53d8\u91cf\u540d\u79f0\uff0c\u7531\u4e0d\u8d85\u8fc710\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ec4\u6210\uff0cv\u662f\u53d8\u91cf\u540d\u6216\u8005\u5e38\u6570<\/td><\/tr><tr><td>inc a<\/td><td>\u53d8\u91cfa\u52a01<\/td><\/tr><tr><td>dec a<\/td><td>\u53d8\u91cfa\u51cf1<\/td><\/tr><tr><td>jnz a v<\/td><td>\u5982\u679c\u53d8\u91cfa\u7684\u503c\u4e0d\u662f0\uff0c\u5219\u76f8\u5bf9\u8df3\u8f6cv\u6761\u6307\u4ee4\u3002\u6bd4\u5982-2\uff0c\u5411\u4e0a\u8df3\u8f6c\u4e24\u4e2a\u6307\u4ee4<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u8f93\u5165\u4fdd\u8bc1\u6700\u591a\u6709100\u4e2a\u53d8\u91cf\uff0c100\u6761\u8bed\u53e5\uff1b\u6267\u884cinc, dec\u548cjnz\u4e4b\u524d\uff0c\u76f8\u5e94\u53d8\u91cf\u4e00\u5b9a\u5df2\u7ecf\u7528mov\u8d4b\u503c\u8fc7\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  \u8f93\u5165\uff1a\n  mov bx 2\n  mov ax 5\n  inc bx\n  dec ax\n  jnz ax -2\n  dec ax\n  \u200b\n  \u8f93\u51fa\uff1a\n  ax -1\n  bx<\/pre>\n\n\n\n<p class=\"has-cyan-bluish-gray-background-color has-background\">\u4ee3\u7801\u5b9e\u73b0<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  \u200b\n  #include &lt;iostream>\n  #include &lt;vector>\n  #include &lt;string>\n  #include &lt;list>\n  #include &lt;regex>\n  #include &lt;unordered_map>\n  #include &lt;math.h>\n  #include &lt;memory>\n  \u200b\n  static std::regex movRegex(\"\\\\s*mov\\\\s[a-z]{1,10}\\\\s((-?[1-9][0-9]{0,4})|([1-9][0-9]{0,4}))\\\\s*\");\n  static std::regex jnzRegex(\"\\\\s*jnz\\\\s[a-z]{1,10}\\\\s((-?[1-9][0-9]{0,4})|([1-9][0-9]{0,4}))\\\\s*\");\n  static std::regex incRegex(\"\\\\s*inc\\\\s[a-z]{1,10}\\\\s*\");\n  static std::regex decRegex(\"\\\\s*dec\\\\s[a-z]{1,10}\\\\s*\");\n  \u200b\n  class SimpleInterpreter {\n  public:\n      SimpleInterpreter() {\n          m_counter = 0;\n      }\n  \u200b\n      std::unordered_map&lt;std::string, int> calculation(std::vector&lt;std::string> vctInstructions) {\n  \u200b\n          std::unordered_map&lt;std::string, int> mapRst;\n          bool flag = true;\n          int numeric = 0;\n          std::string split;\n          setCounter(vctInstructions.size());\n          while (flag) {\n              int lineIdx = std::abs((int)vctInstructions.size() - getCounter());\n              if (lineIdx > (int)vctInstructions.size() - 1) {\n                  break;\n              }\n  \u200b\n              std::string strInstruction = vctInstructions[lineIdx];\n              if (std::regex_match(strInstruction, movRegex)) {\n  \u200b\n                  if (!getSlipt(strInstruction, split, numeric)) {\n                      break;\n                  }\n  \u200b\n                  mapRst.insert(std::make_pair(split, numeric));\n                  setCounterPlus();\n              }\n              else if (std::regex_match(strInstruction, incRegex)) {\n  \u200b\n                  if (!getSlipt(strInstruction, split)) {\n                      break;\n                  }\n  \u200b\n                  auto itr = mapRst.find(split);\n                  if (itr != mapRst.end()) {\n                      numeric = itr->second;\n                      mapRst[split] = numeric + 1;\n                      setCounterPlus();\n                  }\n              }\n              else if (std::regex_match(strInstruction, decRegex)) {\n  \u200b\n                  if (!getSlipt(strInstruction, split)) {\n                      break;\n                  }\n  \u200b\n                  auto itr = mapRst.find(split);\n                  if (itr != mapRst.end()) {\n                      numeric = itr->second;\n                      mapRst[split] = numeric - 1;\n                      setCounterPlus();\n                  }\n              }\n              else if (std::regex_match(strInstruction, jnzRegex)) {\n  \u200b\n                  if (!getSlipt(strInstruction, split, numeric)) {\n                      break;\n                  }\n  \u200b\n                  auto itr = mapRst.find(split);\n                  if (itr == mapRst.end()) {\n                      break;\n                  }\n                  int value = itr->second;\n  \u200b\n                  if (value != 0) {\n  \u200b\n                      int counter = getCounter();\n                      setCounter(counter - numeric);\n                  }\n                  else {\n  \u200b\n                      setCounterPlus();\n                  }\n              }\n              if (getCounter() &lt;= 0) {\n  \u200b\n                  flag = false;\n              }\n          }\n          return mapRst;\n      }\n  \u200b\n      bool getSlipt(const std::string&amp; instruction, std::string&amp; split, int&amp; numeric) {\n  \u200b\n          int posSpace1 = instruction.find(' ');\n          int posSpace2 = instruction.find_last_of(' ');\n          if (posSpace1 == std::string::npos || posSpace2 == std::string::npos) {\n              return false;\n          }\n          int count = posSpace2 - posSpace1 - 1;\n          split = instruction.substr(posSpace1 + 1, count);\n  \u200b\n          int length = instruction.length();\n          count = length - 1 - posSpace2;\n          std::string split2 = instruction.substr(posSpace2 + 1, count);\n          numeric = atoi(split2.c_str());\n  \u200b\n          return true;\n      }\n  \u200b\n      bool getSlipt(const std::string&amp; instruction, std::string&amp; split) {\n  \u200b\n          int posSpace = instruction.find(' ');\n          if (posSpace == std::string::npos) {\n              return false;\n          }\n          int length = instruction.length();\n          int count = length - 1 - posSpace;\n          split = instruction.substr(posSpace + 1, count);\n  \u200b\n          return true;\n      }\n  \u200b\n      int getCounter() {\n  \u200b\n          return m_counter;\n      }\n      void setCounter(int counter) {\n  \u200b\n          m_counter = counter;\n      }\n      void setCounterPlus() {\n  \u200b\n          m_counter--;\n      }\n  \u200b\n  private:\n      int m_counter;\n  };\n  \u200b\n  \u200b\n  bool isValidInput(std::string&amp; str)\n  {\n      if (std::regex_match(str, movRegex) || std::regex_match(str, jnzRegex) || std::regex_match(str, incRegex) || std::regex_match(str, decRegex)) {\n  \u200b\n          return true;\n      }\n  \u200b\n      return false;\n  }\n  \u200b\n  int main()\n  {\n      std::cout &lt;&lt; \"\u8bf7\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u96c6. \u63d0\u793a\uff1a\u8f93\u5165finish\u4f1a\u505c\u6b62\u8f93\u5165\uff0c\u4e14\u6700\u591a\u80fd\u8f93\u5165100\u6761\" &lt;&lt; std::endl;\n  \u200b\n      std::vector&lt;std::string> vctInstructions;\n      std::string line;\n      int count = 0;\n      while (std::getline(std::cin, line)) {\n          count++;\n          if (isValidInput(line)) {\n              vctInstructions.push_back(std::move(line));\n          }\n          else if (line.compare(\"finish\") == 0 || count > 100) {\n              std::cout &lt;&lt; \"\u8f93\u5165\u5b8c\u6210\" &lt;&lt; std::endl;\n              break;\n          }\n          else {\n              std::string strError = \"\u60a8\u8f93\u5165\u7684\u6307\u4ee4\uff1a\";\n              strError.append(line);\n              strError.append(\"\u683c\u5f0f\u9519\u8bef\u8bf7\u91cd\u65b0\u8f93\u5165\");\n              std::cout &lt;&lt; strError &lt;&lt; std::endl;\n          }\n      }\n  \u200b\n      std::shared_ptr&lt;SimpleInterpreter> cal(new SimpleInterpreter);\n      std::unordered_map&lt;std::string, int> mapCalculation = cal->calculation(vctInstructions);\n      for (auto itr = mapCalculation.begin(); itr != mapCalculation.end(); ++itr) {\n          std::cout &lt;&lt; itr->first &lt;&lt; \" \" &lt;&lt; itr->second &lt;&lt; std::endl;\n      }\n  \u200b\n      return 0;\n  }\n  \u200b\n  \u200b<\/pre>\n\n\n\n<p>\u5173\u4e8e\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u53c2\u8003\uff1a<\/p>\n\n\n\n<p><a href=\"https:\/\/www.runoob.com\/regexp\/regexp-metachar.html\">https:\/\/www.runoob.com\/regexp\/regexp-metachar.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u63cf\u8ff0\uff1a \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8bed\u8a00\u89e3\u91ca\u5668\uff0c\u652f\u6301\u4ee5\u4e0b\u6307\u4ee4 \u6307\u4ee4\u683c\u5f0f \u63cf\u8ff0 mov a v \u628a\u6570v\u8d4b\u503c\u7ed9a\uff0c\u5176\u4e2da\u662f\u53d8\u91cf\u540d\u79f0\uff0c\u7531\u4e0d\u8d85\u8fc710\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ec4\u6210\uff0cv\u662f\u53d8\u91cf\u540d\u6216\u8005\u5e38\u6570 inc a \u53d8\u91cfa\u52a01 dec a \u53d8\u91cfa\u51cf1 jnz a v \u5982\u679c\u53d8\u91cfa\u7684\u503c\u4e0d\u662f0\uff0c\u5219\u76f8\u5bf9\u8df3\u8f6cv\u6761\u6307\u4ee4\u3002\u6bd4\u5982-2\uff0c\u5411\u4e0a\u8df3\u8f6c\u4e24\u4e2a\u6307\u4ee4 \u8f93\u5165\u4fdd\u8bc1\u6700\u591a\u6709100\u4e2a\u53d8\u91cf\uff0c100\u6761\u8bed\u53e5\uff1b\u6267\u884cinc, dec\u548cjnz\u4e4b\u524d\uff0c\u76f8\u5e94\u53d8\u91cf\u4e00\u5b9a\u5df2\u7ecf\u7528mov\u8d4b\u503c\u8fc7\u3002 \u4ee3\u7801\u5b9e\u73b0 \u5173\u4e8e\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u53c2\u8003\uff1a https:\/\/www.runoob.com\/regexp\/regexp-metachar.html<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-478","post","type-post","status-publish","format-standard","hentry","category-c","tag-c"],"_links":{"self":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/478","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/comments?post=478"}],"version-history":[{"count":2,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/478\/revisions"}],"predecessor-version":[{"id":481,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/478\/revisions\/481"}],"wp:attachment":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/media?parent=478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/categories?post=478"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/tags?post=478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}