• 締切済み

C++文字配列ソート関数を教えてください

C++文字配列ソート関数を教えてください 配列に格納されている文字列をソートして完全一致するかを確認するロジックを作成したいのですが、上手くいきません。ネットなどでいろいろ調べたのですが>< 一応、以下に今の状態のソースを貼りました。 class StringSuzeLess { public; bool operator()( const std::string& Ihs, const std::string& rhs ) const { retrun ihs.size() < rhs.size(); } } int main() { // 文字列格納変数 chra str1[10][5+1]; char str2[10][5+1]; // 初期化 memset(str1, 0x00, sizeof(str1)); memset(str2, 0x00, sizeof(str2)); // 文字列設定 strcpy(str1[0], "AAAAA"); strcpy(str1[1], "BBBBB"); strcpy(str1[2], "CCCCC"); strcpy(str2[0], "CCCCC"); strcpy(str2[1], "BBBBB"); strcpy(str2[2], "AAAAA"); std::vector< std::string > vsmozi1; std::vector< std::string > vsmozi2; // ベクタに文字列設定 for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { vsmozi1.push_back( std::string( str1[LoopCnt] ) ); } for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { vsmozi2.push_back( std::string( str2[LoopCnt] ) ); } // ソート std::stable_sort( vsmozi1.begin(), vsmozi1.end(), StringSuzeLess()); std::stable_sort( vsmozi2.begin(), vsmozi2.end(), StringSuzeLess()); // ソート後の先頭から取得 for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { // 不一致の場合 if(vsmozi1[LoopCnt] != vsmozi2[LoopCnt]) { return -1; } } return 0; }

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

なにがどう「うまくいかない」のですか?

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.1

なぜ、StringSuzeLess::()内で size()を比較しているのでしょうか? 文字列の長さ順にソートしたいのですか? 全部同じ長さですから、ソート前後で変化無いですよね。 この仕様なのでしょうか? 他にも明らかなミスがあります。 修正したソースを載せます。 文字列順で比較するよう仕様変更しました。 本来の仕様に合致しているか保障の限りではありません。 (長さ順のソートが正しい仕様かも・・・) //// ここからソース ////////////////////////////////// // ヘッダを追加しました #include <string> #include <vector> #include <algorithm> class StringSuzeLess { public: // 些細なことですがrhsに対してはl(エル)hsではないでしょうか? bool operator()( const std::string& lhs, const std::string& rhs ) const { // return lhs.size() < rhs.size(); return lhs < rhs; } // クラスの終わりにセミコロンがありません }; int main() { // 文字列格納変数 char str1[10][5+1]; char str2[10][5+1]; // 初期化 memset(str1, 0x00, sizeof(str1)); memset(str2, 0x00, sizeof(str2)); // 文字列設定 strcpy(str1[0], "AAAAA"); strcpy(str1[1], "BBBBB"); strcpy(str1[2], "CCCCC"); strcpy(str2[0], "CCCCC"); strcpy(str2[1], "BBBBB"); strcpy(str2[2], "AAAAA"); std::vector< std::string > vsmozi1; std::vector< std::string > vsmozi2; // ベクタに文字列設定 for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { vsmozi1.push_back( std::string( str1[LoopCnt] ) ); } for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { vsmozi2.push_back( std::string( str2[LoopCnt] ) ); } // ソート std::stable_sort( vsmozi1.begin(), vsmozi1.end(), StringSuzeLess()); std::stable_sort( vsmozi2.begin(), vsmozi2.end(), StringSuzeLess()); // ソート後の先頭から取得 for(short LoopCnt = 0; LoopCnt < 3; LoopCnt++) { // 不一致の場合 if(vsmozi1[LoopCnt] != vsmozi2[LoopCnt]) { return -1; } } return 0; }

関連するQ&A

  • std::stringクラスのc_str()で取得した文字列をいじることは可能ですか?

    c++で、以下のようなコードは問題ないでしょうか? // chrの中身の小文字を大文字にする void func(char* chr); std::string str("aaa"); const char* str_p = std.c_str(); func((char*)str_p); ←これは大丈夫ですか? //このあとstrに対して文字列を追加したりいろいろ処理する。 このようにc_strで取得したconst char*をconstをはずして 強引にいじくることは問題ないでしょうか?

  • C++での戻り値について

    C++で以下のソースを書きました。 どうしてaaaは問題ないのにbbbはだめなのかがわかりません。 どちらも、func1()、func2()で設定した文字列・vectorのポインタを返したいです。 int main() { const char* aaa = NULL; std::vector<const char*>* bbb = NULL; aaa = func1(); bbb = func2(); } const char* func1() { const char* str = NULL; str = "test"; return str; } std::vector<const char*>* func2() { std::vector<const char*>* str2 = NULL; str2->push_back("test2"); str2->push_back("test3"); return str2; } 現在必要に迫られてC++勉強中です。よろしくお願いいたします。

  • C言語での文字列ソート動作について

    任意の文字列を入力し、その文字列を昇順にソートするプログラムを作ったのですが、入力する文字の文字数が大きく異なると期待した結果が得られません。 文字数が少なくなったり、他の配列の文字が混ざったりと言う結果に成ってしまっています。 何が原因か分からない状態です。 以下にサンプルを記載させて頂きますので、助言よろしくお願いします。 /*----------------------------------------- 入力例 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC BBBBBBBBBBBBBBBB AAAAAA -----------------------------------------*/ #include <stdio.h> #include <string.h> #include <stdlib.h> void swapc(char *cx , char *cy){ char tmp[100]; strcpy(tmp, cx); strcpy(cx, cy); strcpy(cy, tmp); } int main(){ char *num[100]; char str_tmp[100]; //文字列一時格納 int moji_cnt; //入力した文字列のカウント int n , m; // 文字列入力処理開始 printf("文字列を入力してください\n"); for( moji_cnt = 0 ; moji_cnt != 3 ; moji_cnt++){ scanf("%s", str_tmp); *(num+moji_cnt) = (char *)malloc(sizeof(char) * (strlen(str_tmp)+1)); //メモリ確保 strcpy(*(num+moji_cnt), str_tmp); } puts("\n"); // 文字数ソート処理 for(n = 0 ; n < moji_cnt-1 ; n++){ for(m = 1 ; m < moji_cnt-n ; m++){ if(strcmp(*(num+n) , *(num+n+m)) > 0){ swapc(*(num+n) , *(num+n+m)); // 文字列入れ替え } } } puts("\n"); for(n = 0;n != moji_cnt;n++){ printf("%s\n" , *(num+n)); } free(num); }

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

  • C言語の配列をC++のvectorに高速に変換したい

    質問は表題のとおりです。 単純な方法では以下の通りになると思いますが、 (C言語文字列から string への変換のように) 一括変換の仕組みは vector にないのでしょうか? static const int n=5; int a[n]={0,1,2,3,4}; std::vector<int> v(n); std::vector<int>::iterator vit=v.begin(); for(int i=0; i<n; i++){ *vit++ = a[i]; } 上記の例では n=5 ですが、nがとても大きな場合に適用したいと考えています。 ちなみに、gcc 3.4.3 を使っています。

  • c++のstd::stringについて

    VC++2008でフォームアプリケーションを作成しています。 シリアルポートから受け取った文字列の一部を抜き出して処理をするため,VBではmid関数に相当するような機能として,std::stringを使用しようとしています。 しかし, std::string str("ABC" ,1,2); とした場合は『BC』が問題なく返ってきましたが, std::string str(recieveddata ,1,2); のように,文字列の部分を変数にしたら,ビルドエラーになってしまいます。(ポインタ?を理解する必要があるのでしょうか?) どのようにすれば,VBのmid相当の機能を実現できるでしょうか?

  • ostringstreamからCの文字列を得る方法

    ostringstreamからCの文字列を得る方法について質問です。 ostringstreamのstr()メソッドを使えば、string型が得られると思うのですが、 以下の様にすると期待する様な結果が得られません。 ostringstream hoge; hoge << "HOGE" << "FUGA"; const char* p; p = hoge.str().c_str(); // NG str()メソッドで取得した結果を一旦string型に入れると期待する文字列を得る事が出来ます。 string tmp = hoge.str(); p = tmp.c_str(); // OK なぜp = hoge.str().c_str();では期待する結果("HOGEFUGA")を得る事が出来ないのでしょうか? コンパイラはVC++ 2010 Express Editionです。 よろしくお願いします。

  • constについて

    void SMonster::walk(const std::string& str){ std::cout<<"てきてき"<<std::endl; power--; } のconst std::string& strと書くと効率がよいと本に書いてあったのですが、なぜ効率がいいのでしょうか?

  • ライブラリ関数

    文字列をコピーする(strcpy) 文字列の長さを調べる(strlen) 配列の長さを調べる(sizeof) #include <stdio.h> #include <string.h> int main(void) { char s1[128] = "ABCD"; char s2[128] = "EFGH"; char s3[128] = "IJKL"; strcpy(s2, s1); strcpy(s3, s2); puts("s1をs2にs2をs3にコピーしました。"); printf("s1 = %s\n", s1); printf("s2 = %s\n", s2); printf("s3 = %s\n", s3); printf("文字列%sの長さは%uです。\n",s3,(unsigned)strlen(s3)); printf("文字列%sの長さは%uです。\n",s3,strlen(s3)); return (0); } char *strcpy(char *d, const char *s) { while (*d++ = *s++) printf("pointer=%s \n",d); } /* 文字列sをdにコピーする[配列版] */ char *strcpy(char d2[], const char s2[]) { unsigned i=0; while (d2[i] = s2[i]){ i++; printf("hairetsu=%s\n",&d2[i]); } } /*--- 文字列strの長さを返す[ポインタ版] ---*/ size_t strlen(const char *s) { size_t len = 0; while (*s++) len++; return (len); } /*--- 文字列strの長さを返す[配列版] ---*/ unsigned strlen(const char str[]) { unsigned len = 0; while (str[len]) len++; return (len); } c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(48) : error C2084: 関数 'char *strcpy(char *,const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の前の定義を確認してください c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(68) : error C2084: 関数 'size_t strlen(const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(80) : 'strlen' の前の定義を確認してください 上記の問題が解決できません。助けてください><

  • str メンバ関数について

    str メンバ関数について 下記のstring Date::to_string() const のstr()メンバ関数が日付クラスDate、 (インタフエース部、実装部)に定義等が記入されていないので、何処に定義されているか教えてください。 ************************************************************* // 日付クラスDate(第2版:実装部) #include <ctime> #include <sstream> #include <iostream> #include "Date.h" using namespace std; //--- 文字列表現を返却 ---// string Date::to_string() const { ostringstream s; s << year << "年" << month << "月" << day << "日"; return s.str(); } ****************************************************************** // 日付クラスDate(第2版:インタフェース部) #include <string> #include <iostream> using namespace std; class Date { int year; // 西暦年 int month; // 月 int day; // 日 public: Date(); // デフォルトコンストラクタ Date(int y, int m = 1, int d = 1); // コンストラクタ int Year() const { return year; } // 年を返却 int Month() const { return month; } // 月を返却 int Day() const { return day; } // 日を返却 string to_string() const; // 文字列表現を返却 }; ostream& operator<<(ostream& s, const Date& x); // 挿入子