• ベストアンサー

文字の並べ替えについて質問

以下のような標準入力したアルファベットの文字列(jgoaihoghohgo...みたいな)を昇順に並べ替えるプログラムを作成して思ったのですが、各文字の比較ってやっぱりアスキーコードの数字を比較しているのでしょうか? だとするとif(s[i]<s[j])の部分で少し疑問を感じました。 if(s[i]>s[j])ではないのでしょうか?こうでないとs[i]にaがs[j]にbが格納されているときに並べ替えが起きてしまうような気がするのです。 基本的なことのようですがお願いしますm(__)m あとプログラムに関して不備を感じましたら訂正のアドバイスをお願いします。 #include<stdio.h> #include<string.h> int main(void){ char s[BUFSIZ]; char s2[BUFSIZ]; int i,j,m; printf("input sentense.\n"); scanf("%s",s); m=strlen(s); for(i=0;i<m;i++){ for(j=0;j<m;j++){ if(s[i]<s[j]){ s2[10]=s[i]; s[i]=s[j]; s[j]=s2[10]; } } } printf("%s",s); return(0); }

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

>if(s[i]>s[j])ではないのでしょうか? 紙に書いて実際に動きをトレースしてみると判ると思いますが、 0<=i<m 0<=j<m でループするために、一回比較が終わったハズの部分がもう一回比較される時に逆になるのでこれでソートできるということだと思います。 つまり前半部で、いったん大きいモノが前に来るがそれが、もう一回交換されることで小さいモノが先にくるという。 例えば、 bca の並びの文字列があったとすると、 最初(iが0の時のループ) cbaになります。 ところが(iが1の時のループで) bca になります。 つまり、iで着目している部分より前にいったん大きいモノが集まり、そこを過ぎると小さいモノに置き換えられると言うことになると言うことだと思います。 >プログラムに関して不備を感じましたら訂正のアドバイス このソート自体は、同じペアについて2回比較されるので、ムダですよね。 あと、s2は、結局一文字しか使用していないので、一文字だけでよいと思います。 また、BUFSIZのサイズを知った上で使用してるのでしょうが、 BUFSIZは、コンパイラによって変わる可能性があるので、 そういう不定のサイズであるということから、 s2[10]のような使い方はよろしくないと思います。

you-two
質問者

お礼

今まで一回の比較で済むものと思ってました!! すんごい分かりやすかったです☆ ずっと思っていた疑問が解決できました! 文字列の使用の注意など感謝します。

すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.3

まず、プログラムについてのコメントですが char s2[BUFSIZ]; ↓ char c; s2[10]=s[i]; s[i]=s[j]; s[j]=s2[10]; ↓ c=s[i]; s[i]=s[j]; s[j]=c; にしても動きますので、こちらの方が良いと思いますよ。 本題ですが、 ご存知のとおり、文字はアスキーコードで表しています。 ここで注目するところは、このプログラムのアルゴリズムです。 このアルゴリズムでは if( s[i] < s[j] ) が正解です。 これと似た書き方をするバブルソートというアルゴリズムがあります。 (これをやりたかったのかな^_^;) 参考までに記述しておきます。 for(i=0; i<m; i++) { for(j=i; j<m; j++) { if( s[i] > s[j] ) { c = s[i]; s[i] = s[j]; s[j] = c; } } } このアルゴリズムでは if( s[i] > s[j] ) と書きます。 これで、解決したでしょうか? アルゴリズムに関しては理解に苦しむかもしれませんが がんばってください(^_^)

you-two
質問者

お礼

アドバイス感謝です☆ 文字列と文字の使い方にも今まで疑問を持ってたんですが おかげで解決できました!! 文字ってこんな風に使うんですね~。勉強になりました。

すると、全ての回答が全文表示されます。
  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.2

BLUEPIXYさんの回答に加えて、scanf(3)はBuffer Over flowの危険があるので、fgets(3)にしたほうが良いでしょう。 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- #include <stdio.h> #include <string.h> int main(void) { char s[BUFSIZ]; char c; int i, j, m; printf("input sentense.\n"); fgets(s, BUFSIZ, stdin); m = strlen(s); s[--m] = 0; for (i = 0; i < m; i++) { for (j = i; j < m; j++) { if (s[i] > s[j]) { c = s[i]; s[i] = s[j]; s[j] = c; } } } printf("%s\n", s); return (0); }

you-two
質問者

お礼

なるほどです!! これだとfor文で無駄なループがないっすね。 いや、マジで感謝します。 文字と文字列の違いが分かりやすく為になります~

すると、全ての回答が全文表示されます。

関連するQ&A