1

Unicode 文字列があり、次の要件と比較したいと考えています。

紛らわしい s [1] 文字は同じ文字と見なす必要があります。例: T (LATIN CAPITAL LETTER TU 0054) should be == T (GREEK CAPITAL LETTER TAU U03A4) など

(* [1] 例 http://unicode.org/cldr/utility/confusables.jsp?a=TESTt&r=None *)

http://www.unicode.org/Public/security/revision-03/confusablesSummary.txt

コードを作成するために上記のファイルを使用しますが、無料のライブラリが既にある場合はそれを使用したいと思います。

私は、コードがustringすべての紛らわしい文字を対応するラテン文字に置き換える一時的なものを作成すると考えています。

実際のプログラムでは、それぞれ 1 つの単語を含む 10x5000x10000 文字列をテストします。

テストプログラム:

 std::locale::global(std::locale(""));

 std::cout.imbue(std::locale());

 Glib::ustring s1,s2;

 s1="TEST";

 s2="TΕST";

 s1.normalize(Glib::NORMALIZE_NFKD    );

 s2.normalize(Glib::NORMALIZE_NFKD   );

 std::cout<<"1->true, 0->false  (s1==s2) =>  "<<(s1==s2)<<"\n";

テスト プログラムの出力:

1->true, 0->false  (s1==s2) =>  0

Ubuntuロケールコマンドの出力:

Ubuntu 12.04 64 bit>$ locale  
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

お時間をいただきありがとうございます!

4

2 に答える 2

2

user1675224 が言うように、独自のアルゴリズムをロールしようとするのではなく、ICU を使用する必要があります。

たとえば、次のように使用しますuspoof_areConfusable

UErrorCode status = 0;
USpoofChecker *sc = uspoof_open(&status);
int result = uspoof_areConfusable(sc, s1.data(), s1.length(), s2.data(), s2.length(), &status);
uspoof_close(sc);

多数の文字列を相互に比較する場合は、 を使用してそれらをスケルトンに変換し、それをuspoof_getSkeletonセットまたはハッシュ セットに入れる必要があります。

于 2012-09-18T16:33:34.793 に答える
0
 std::string s1,s2;
    s1="TEst";
    s2="TΕst";
    std::cout<<" s1.length()="<<s1.length()<<"\n";
    std::cout<<" s2.length()="<<s2.length()<<"\n";

 UErrorCode status = U_ZERO_ERROR ;
 USpoofChecker *sc = uspoof_open(&status);
 char p[100];
 int result = uspoof_getSkeletonUTF8    (sc,USPOOF_ANY_CASE, s1.data(),s1.length(),p,100,&status);
 std::string skeleton1(p,result);
 std::cout<<" result in bytes="<<result<<" status="<<status<<"\n";
 std::cout<<" skeleton1="<<skeleton1<<"\n";
 std::cout<<"1->true, 0->false  (s1==skeleton1) =>  "<<(s1==skeleton1)<<"\n";
 //
 char p2[100];
 int result2 = uspoof_getSkeletonUTF8   (sc,USPOOF_ANY_CASE , s2.data(),s2.length(),p2,100,&status);
 std::string skeleton2(p2,result2);
 std::cout<<" result2 in bytes="<<result2<<" status="<<status<<"\n";
 std::cout<<" skeleton2="<<skeleton2<<"\n";
 std::cout<<"1->true, 0->false  (s2==skeleton2) =>  "<<(s2==skeleton2)<<"\n";
 std::cout<<"1->true, 0->false  (s1==s2) =>  "<<(s1==s2)<<"\n";
 std::cout<<"1->true, 0->false  (skeleton1==skeleton2) =>  "<<(skeleton1==skeleton2)<<"\n";
 //
 uspoof_close(sc);

出力

 s1.length()=4
 s2.length()=5
 result in bytes=4 status=0
 skeleton1=TEst
 1->true, 0->false  (s1==skeleton1) =>  1
 result2 in bytes=4 status=0
 skeleton2=TEst
 1->true, 0->false  (s2==skeleton2) =>  0
 1->true, 0->false  (s1==s2) =>  0
 1->true, 0->false  (skeleton1==skeleton2) =>  1

ありがとうございました。

于 2012-09-19T08:43:13.970 に答える