2012-03-13 11 views
0

最初にエスケープされていないが特定の文字列に出現するのを見つける最も良い方法は何ですか?最初にエスケープされていない文字を見つける

これは私のやり方ですが、それは過度に複雑な感じがします。

/* 
* Just like strchr, but find first -unescaped- occurrence of c in s. 
*/ 
char * 
strchr_unescaped(char *s, char c) 
{ 
    int i, escaped; 
    char *p; 

    /* Search for c until an unescaped occurrence is found or end of string is 
    reached. */ 
    for (p=s; p=strchr(p, c); p++) { 
    escaped = -1; 
    /* We found a c. Backtrace from it's location to determine if it is 
     escaped. */ 
    for (i=1; i<=p-s; i++) { 
     if (*(p-i) == '\\') { 
     /* Switch escaped flag every time a \ is found. */ 
     escaped *= -1; 
     continue; 
     } 
     /* Stop backtracking when something other than a \ is found. */ 
     break; 
    } 
    /* If an odd number of escapes were found, c is indeed escaped. Keep 
     looking. */ 
    if (escaped == 1) 
     continue; 
    /* We found an unescaped c! */ 
    return p; 
    } 
    return NULL; 
} 
+0

最高の定義に依存しますが、:それを使用するCライブラリルーチンは、あなたがこのことについてどのように、少しあなたのアプローチを引き締めるためにC.

に書くことができます任意のループよりもはるかに高速に実行されますあなたの解決策は必要以上に多くの仕事のように思えます。むしろstrchrとバックトラック(それぞれのバックスラッシュを2回見ます)を使用すると、前方を読み取り、状態(エスケープ/エスケープされていない状態)を追跡することができ、各文字を1回だけ見ることができます。 –

+0

私はあなたが何を意味するかを見ます。一方、エスケープが本当に必要であることが分かっているときは、エスケープだけをテストすることができます。あなたの解決策では、エスケープの有無を問わず、検査されたすべてのキャラクターに対してエスケープを追跡するコストが支払われます。私は、テストされた文字列の性質、すなわちエスケープされた文字の比率に依存して、どちらが良いかを推測します。 –

+0

「コスト」の意味に依存します。 strchr()は、あなたのコードがエスケープであることをチェックするのを避けているそれらの文字すべてを見ているので、テストされていないのと同じではありません。ルックアップテーブルを使用した場合は、両方を同時に確認できますが、非常にコストがかかるようです)。 –

答えて

1

検索文字がかなりまれである場合、あなたのアプローチは妥当です。一般に、strchrのようなCライブラリルーチンは厳密な機械語でコード化されており、Cでコード化したほとんどすべてのループより高速に実行されます。ハードウェアの一部のモデルでは、

#define isEven(a) ((a) & 1) == 0) 

char* p = strchr(s, c); 
while (p != NULL) { /* loop through all the c's */ 
    char* q = p; /* scan backwards through preceding escapes */ 
    while (q > s && *(q-1) == '\\') 
     --q; 
    if (isEven(p - q)) /* even number of esc's => c is good */ 
     return p; 
    p = strchr(p+1, c); /* else odd escapes => c is escaped, keep going */ 
} 
return null; 
関連する問題