1

トークン化する文字列があります。その形式はHHmmssffHmsf数字です。

4 つの 2 桁の数字にトークン化されるはずですが、短縮形も受け入れる必要があるsffため、 と解釈され00000sffます。を使用したかったboost::tokenizeroffset_separatorですが、正のオフセットでのみ機能するようで、逆方向に機能させたいと思います。

わかりました、1 つのアイデアは文字列の左から 0 をパディングすることですが、おそらくコミュニティは非常にスマートな何かを思いつきます。;)

編集: 追加の要件が登場しました。

よりスマートなソリューションの基本的な必要性はfssff、 、などのすべてのケースを処理することでしたが、その省略形のmssffように、より完全な時間表記も受け入れることでした。HH:mm:ss:ffs:ffs:s:00

文字列が I で終わる場合は、:明らかに 2 つのゼロを埋め込むこともできます。次に、数字だけを残してすべてのセパレータを取り除き、結果の文字列を精力的に解析します。

しかし、オフセット トークナイザーを文字列の末尾 (オフセット -2、-4、-6、-8) からさかのぼって、数値をレキシカルに s にキャストする方法があれば、少し簡単になるようintです。

4

3 に答える 3

1

BNF記法を説き続けています。問題を定義する文法を書き留めることができれば、Boost.Spirit パーサーに簡単に変換できます。

TimeString := LongNotation | ShortNotation

LongNotation := Hours Minutes Seconds Fractions

Hours := digit digit
Minutes := digit digit
Seconds := digit digit
Fraction := digit digit

ShortNotation := ShortSeconds Fraction
ShortSeconds := digit

編集:追加の制約

VerboseNotation = [ [ [ Hours ':' ] Minutes ':' ] Seconds ':' ]  Fraction
于 2008-11-13T13:56:25.080 に答える
0

正規表現が思い浮かびます。のような"^0*?(\\d?\\d?)(\\d?\\d?)(\\d?\\d?)(\\d?\\d?)$"ものboost::regex。サブマッチは数字の値を提供します。数字の間にコロンを使用して、他の形式に採用するのは難しくありません (sep61.myopenid.com の回答を参照)。boost::regex最速の正規表現パーサーの 1 つです。

于 2008-11-13T13:56:56.173 に答える
0

「パフォーマンスフリークになるつもりはありませんが、このソリューションには文字列のコピーが含まれます(入力はconstとstd :: stringです)」というコメントに応えて。

正規表現のような大きな古いライブラリを使用できないほどパフォーマンスを本当に気にしている場合は、BNF パーサーを危険にさらすことはありません。したがって、STL 文字列関数を使用できません)、文字列 chars をバッファーにコピーして、左に '0' 文字を埋め込むことさえできません。

void parse(const string &s) {
    string::const_iterator current = s.begin();
    int HH = 0;
    int mm = 0;
    int ss = 0;
    int ff = 0;
    switch(s.size()) {
        case 8:
            HH = (*(current++) - '0') * 10;
        case 7:
            HH += (*(current++) - '0');
        case 6:
            mm = (*(current++) - '0') * 10;
        // ... you get the idea.
        case 1:
            ff += (*current - '0');
        case 0: break;
        default: throw logic_error("invalid date");
        // except that this code goes so badly wrong if the input isn't
        // valid that there's not much point objecting to the length...
   }
}

しかし、基本的に、これらの int 変数を 0 で初期化するだけで、文字列をパディング付きの char バッファーにコピーするのとほぼ同じ作業になるため、パフォーマンスに大きな違いは見られません。したがって、時期尚早の最適化の演習として、実際にはこのソリューションを実際にはお勧めしません。

于 2008-11-13T14:20:26.920 に答える