2012-04-18 16 views
2

文字列を次のように比較する必要があります。誰か私にいくつかの洞察力やアルゴリズムを提供することができますC + +で。たとえば :2つの英数字の文字列を比較する

"a5" < "a11"  - because 5 is less than 11 
"6xxx < 007asdf" - because 6 < 7 
"00042Q < 42s"  - because Q < s alphabetically 
"6 8" < "006 9" - because 8 < 9 

答えて

1

この順番で比較を実行したいとします。数字の範囲は1〜9です。数字の値。桁数。数字の後の文字列の値。

これはC言語ですが、C++ std :: stringクラスを使用して簡単に変換できます。

int isdigit(int c) 
{ 
    return c >= '1' && c <= '9'; 
} 

int ndigits(const char *s) 
{ 
    int i, nd = 0; 
    int n = strlen(s); 

    for (i = 0; i < n; i++) { 
     if (isdigit(s[i])) 
      nd++; 
    } 
    return nd; 
} 

int compare(const char *s, const char *t) 
{ 
    int sd, td; 
    int i, j; 

    sd = ndigits(s); 
    td = ndigits(t); 

    /* presence of digits */ 
    if (!sd && !td) 
     return strcasecmp(s, t); 
    else if (!sd) 
     return 1; 
    else if (!td) 
     return -1; 

    /* value of digits */ 
    for (i = 0, j = 0; i < sd && j < td; i++, j++) { 
     while (! isdigit(*s)) 
      s++; 
     while (! isdigit(*t)) 
      t++; 

     if (*s != *t) 
      return *s - *t; 
     s++; 
     t++; 
    } 

    /* number of digits */ 
    if (i < sd) 
     return 1; 
    else if (j < td) 
     return -1; 

    /* value of string after last digit */ 
    return strcasecmp(s, t); 
} 
+0

私は "5 a" <"5 b"のようにしようとしたスペースについては –

+0

@ user765443:( "5"、 "5 b"最後の行 'return strcmp(s、t);'が評価されます。 strcmpは、ASCIIテーブルに従って文字列の残りの部分を比較します。これは、(0x20 0x61)と(0x20 0x62)を比較していることを意味します。最初の文字列は小さくなります。 –

+0

これは "a5" "a11"のケースを正しく処理しないことに注意してください - 私はそれを書いたときに少し急いでいました。 '/ *桁の値* /'の部分に内部ループを追加する必要があります。 –

-3

はこれを試してみて、およそstd::string.compareをお読みください。

#include <iostream> 
using namespace std; 


int main(){ 
    std::string fred = "a5"; 
    std::string joe = "a11"; 

    char x; 

    if (fred.compare(joe)) 
    { 
     std::cout << "fred is less than joe" << std::endl; 
    } 
    else 
    { 
      std::cout << "joe is less than fred" << std::endl; 
    } 


    cin >> x; 
} 
+1

あなたは正しく)(比較の戻り値を処理していない:0は等号を意味し、そうでない場合はサインがhttp://www.cplusplus.com/reference/string/string/compare/ –

+1

大きくなっているかを示しますあなたは答えのOP質問をしなかったし、悪い例を提供 – Ulterior

2

あなたの例のみを表示する数字、文字、およびスペース。だから、私はあなたが他のすべてのシンボルを無視して(効果的にそれらをスペースとして扱う)と仮定します。また、大文字と小文字を同等のものとして扱いたいと思うようです。

数字のランは「用語」として解釈され、文字は「用語」として解釈され、文字と数字の間の遷移はスペースに相当します。単一のスペースは、任意の数のスペースと同等と見なされます。

(注意:

"5a" vs "a11" 
"a5" vs "11a" 

だから、あなたは、文字列と数値の用語の比較に直面したときにどうするかをうまくする必要があります。あなたが目立つような場合に何をすべきかの例が欠けています「5 a」==「5a」というだけでなく、「5b」「012a」のような本質的な均等性については言及していません。

これを行うには1つの明確な方法があります文字列を "terms"のstd::vectorに変え、文字列を比較しようとするのではなく、これらのベクトルを比較します直接)。これらの用語は、数値または文字列のいずれかです。仲介は、一回限りの比較では速くなりますせずに文字列を自分自身に取り組んで

how to split a string value that contains characters and numbers

トリッキーな方法:これは、あなたが始める特にSTLの答えを助けるかもしれません。しかし、理解して変更するのが難しく、繰り返し同じ構造を比較しようとすると遅くなる可能性があります。

構造体への解析の優れた点は、プロセス内のデータの内在的な「クリーンアップ」が得られることです。 canonical formに情報を取得することは、そのようなさまざまな入力を許容するプログラムではしばしば目標です。

3

アルゴリズムstrverscmpを使用することをお勧めします。実際には、この機能があなたのために働くかもしれません。

この機能の機能は次のとおりです。両方の文字列が等しい場合は、 は0を返します。そうでない場合は、 の直後には、両方の文字列が等しい前にある プロパティで2バイト間の位置を見つけます。この位置を含む(または開始位置または終了位置にある)最大の連続数字文字列 を探します。これらの両方が空の場合は、 が空の場合は、(3)には (バイト値の数値順)が返されます。それ以外の場合は、 の数値ストリングを数値的に比較してください。 先行ゼロの数字ストリングは、前に小数点があるかのように解釈されます。 (特に、先行ゼロの数字ストリングが ゼロ)。従って、順序は 000,00,01,010,09,0,1,9,10である。

関連する問題