c_cpp 嵌套一堆托架
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 嵌套一堆托架相关的知识,希望对你有一定的参考价值。
#include <functional>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <tuple>
#include <utility> // for pair
#include <vector>
using namespace std;
class parser
{
public:
parser(const vector<pair<string, string>> &bracket_pairs) :
m_syntax(build_syntax(bracket_pairs))
{
}
void parse(const string &expr) const
{
stack<unsigned int> s;
size_t pos = 0;
foreach_symbol(expr, [&](const symbol_info &info)
{
pos++;
if (info.id == 0) return;
if (info.begin)
{
s.push(info.id);
}
else
{
if (s.empty() || s.top() != info.id) throw pos;
s.pop();
}
});
if (s.size() > 0) throw pos + 1;
}
private:
enum { MAX_SYMBOL_LEN = 2 };
struct symbol_info
{
unsigned int id; // 0 is preserved for symbols that not predefined.
bool begin;
};
map<string, symbol_info> m_syntax;
private:
void foreach_symbol(const string &expr, function<void(const symbol_info &)> yield) const
{
for (size_t i = 0, step; i < expr.length(); i += step)
{
symbol_info info;
tie(info, step) = foreach_symbol_subroutine(expr, i);
yield(info);
}
}
tuple<symbol_info, size_t> foreach_symbol_subroutine(const string &expr, size_t i) const
{
for (size_t len = MAX_SYMBOL_LEN; len > 0; len--)
{
auto token = expr.substr(i, len);
try
{
return { m_syntax.at(token), token.length() };
}
catch (const out_of_range &ex)
{
}
}
return { symbol_info{ 0, false }, 1 };
}
static map<string, symbol_info> build_syntax(const vector<pair<string, string>> &bracket_pairs)
{
map<string, symbol_info> syntax;
unsigned int id = 1;
for (auto &bracket_pair : bracket_pairs)
{
int count = 0;
for (auto &symbol : { bracket_pair.first, bracket_pair.second })
{
syntax[symbol] = symbol_info{ id, (0 == count++) };
}
id++;
}
return syntax;
}
};
void parse_expr(const string &expr)
{
static const parser p551({
{ "(", ")" },
{ "[", "]" },
{ "{", "}" },
{ "<", ">" },
{ "(*", "*)" }
});
p551.parse(expr);
}
int main()
{
string expr;
while (getline(cin, expr))
{
try
{
parse_expr(expr);
cout << "YES" << endl;
}
catch (size_t position)
{
cout << "NO " << position << endl;
}
}
return 0;
}
以上是关于c_cpp 嵌套一堆托架的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 使用一堆C ++ 11/14特性和“老派”C ++开发人员的单一函数甚至不再像C ++那样阅读.Specificall