1

括弧で囲まれた式を処理するために、次の手書きのループがあります。

while (!punctuators.empty() && punctuators.back().kind != '(')
{
    output.push_back(punctuators.back());
    punctuators.pop_back();
}
if (punctuators.empty())
    throw invalid_expression(") without matching matching (");
punctuators.pop_back();

(outputpunctuatorsはどちらも 型std::vector<token>で、は aとデータ メンバーで構成されるtoken非常に単純なものです。)structchar kindunsigned value

手書きのループからアルゴリズムに切り替えると可読性が向上するかどうか疑問に思っていました。

auto p = std::find_if(punctuators.rbegin(), punctuators.rend(),
                      [](token t){ return t.kind == '('; });
if (p == punctuators.rend())
    throw invalid_expression(") without matching matching (");
output.insert(output.end(), punctuators.rbegin(), p);
punctuators.erase(std::prev(p.base()), punctuators.end());

しかし、どういうわけか、おそらく逆イテレータの使用と、特に通常のイテレータへの変換が原因で、このコードはかなり読みにくいと感じています。より良い解決策はありますか?手書きのループの方が読みやすいと思いますか?それとも、アルゴリズムに関しては、まだ光が見えていないだけですか?

4

1 に答える 1

3

必要なのは適切なアルゴリズムだけです。

(未テストのコード)

boost::algorithm::copy_while ( 
    punctuators.rbegin (), punctuators.rend (), 
    std::back_inserter ( output ),
    [](token t){ return t.kind != '('; });

ブーストを使用していない場合は、copy_whileかなり簡単に自分で書くことができます。

アルゴリズムに魔法のようなものはありません。自分で書く習慣を身につける必要があります。

于 2013-02-06T20:06:21.710 に答える