• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:鍵括弧を使わないで順番をいれかえる方法)

鍵括弧を使わないで順番をいれかえる方法

このQ&Aのポイント
  • 質問文章:鍵括弧を使わないで順番をいれかえる方法。関数hanten()を作り、プログラムを完成させよ。ただし、関数hanten()の中で、配列を宣言してはならない。例えば、入力が1, 8, 2, 6, 7だとすると、出力は、7 6 2 8 1となる。
  • 考え方の指摘:順番を入れ替えるためには、一時的な変数を使用して要素を入れ替える必要があります。また、配列の要素へのアクセスにはポインタを使用することができます。関数hanten()の中で、forループを使って要素を入れ替えることができます。
  • 提案:以下のようなプログラムを試してみてください。 ``` #include <stdio.h> #define MAX 5 void hanten(int *data, int max); int main(void) { int data[MAX], i; for (i = 0; i < MAX; ++i) { scanf("%d", &data[i]); } hanten(data, MAX); for (i = 0; i < MAX; ++i) { printf("%d ", data[i]); } printf("\n"); return 0; } void hanten(int *data, int max) { int i, tmp; for (i = 0; i < max / 2; ++i) { tmp = data[i]; data[i] = data[max - 1 - i]; data[max - 1 - i] = tmp; } } ``` このプログラムでは、関数hanten()内でforループを使用して要素を入れ替える方法が示されています。試してみて、期待通りの結果が得られるか確認してください。

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

>入力が1, 8, 2, 6, 7 ということであれば、 1)先頭と最後とを入れ替える(結果:7,8,2,6,1) 2)先頭から2番目と最後から2番目とを入れ替える(結果:7,6,2,8,1) 要素数が5個の場合は、ここまで行なうと要求を満たすプログラムができあがります。 一般に、 ・いちばん最初といちばん最後とを入れ替える ・先頭から2番目と最後から2番目とを入れ替える ・先頭から3番目と最後から3番目とを入れ替える ・先頭から4番目と最後から4番目とを入れ替える ... ・先頭からn番目と最後からn番目とを入れ替える この操作を繰り返すと逆順にできますが、nをいくつにすればよいかは もともとの要素数によって異なります。考えてみてください。

izupawapuro
質問者

お礼

一番わかりやすいと思いました。 なるほど・・・そういう手順で入れ替えることもできるのですね・・・ ありがとうございました!

その他の回答 (3)

回答No.3

#1さんの回答で必要十分で、足すところがないのですが、人のコードを見るのもいい勉強になると思いますので、参考までにいろいろと余計なことをしつつ書いてみます。ここでは酔狂のために無駄にポインタを使っていますが、最小限題意を満たすように作るなら、やってきた配列以外の新たな配列を作らなくてもいいですし、ポインタ変数を新たに作る必要もありません。ポインタ変数を使わない場合、hanten関数の中でswap関数に相当する処理をやります。 C99が通らないコンパイラだとコンパイルできませんが、こんな感じで。 (gccを使っている場合、-std=c99と書くとコンパイルできるかもしれません) #include <string.h> #include <stdio.h> #define MAX 5 #define STRING_MAX 1024 #define STRING_MAX_STR "1024" void static inline swap(void *x0, void *x1, int size) { unsigned char tmp[size]; memmove(tmp, x0, size); memmove(x0, x1, size); memmove(x1, tmp, size); } void hanten(void *data, int size, int nmemb) { for (int i = 0; i < nmemb / 2; i++) { swap(data + i * size, data + (nmemb - i - 1) * size, size); } } int main(void) { int data[MAX], i; char buf[STRING_MAX]; printf("Please input %d numbers:\n", MAX); for (i = 0; i < MAX; ++i) { scanf("%d", &data[i]); } hanten(data, sizeof(int), MAX); for (i = 0; i < MAX; ++i) { printf("%d ", data[i]); } printf("\n"); printf("Please type string:\n"); scanf("%" STRING_MAX_STR "s", buf); hanten(buf, sizeof(char), strlen(buf)); printf("%s\n", buf); return 0; } とまぁ、hanten関数とswap関数を型によらないように作ってみました。int型だけを受けうる場合、memmoveやらsizeでデータのサイズを渡しているところやらをやらないでいいことがあるので、そこのところをそんな風に書くと最低限題意を満たすものになるかと。

izupawapuro
質問者

お礼

ネットで探すと構造体系みたいなのと似てますね。 この問題の参考として出してくださったんだと思います ありがとうございました

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

講義で何を期待してこの問題を出したか、によります。 ○ 一番単純な方法は次のものになりますよね? ・新規配列data_newを用意 ・data_newに反転したdataを入れる data_new[0] = data[max-1] ; data_new[1] = data[max-2] ; .. data_new[i] = data[max - 1 -i] ; ... data_new[max-1] = data[0] ; // 0 == (max-1)-(max-1) ・dataにdata_newをコピー data[i] = data_new[i] ; この方法を使うには、「配列」data_newが必要です。 配列を宣言するには、大きさを指定する必要があります。 正しく動作させるには、引数max以上である必要があります。 そのため、「配列で宣言」するにはint data_new[500];等と適当に大きな値を使う必要があります。 # 正確には「ありました」。新しい規格に準拠したC言語では int data_new[max];と変数を使うこともできます。 # ただし、新規格に準拠していないコンパイラもまだまだ残っています。 問題の意図が「maxの値に応じた領域を確保する方法を学ぶ」ものであるなら、上記のような「適当に大きな配列を宣言」しないで ・malloc/callocで領域を確保、ポインタに記憶させる ・return前にfreeで解放 とします。 ○(malloc等で領域を確保するものも含め)同じ大きさの配列を用意することはしない、というのが「配列を宣言しない」の意味なら、「別のやりかたを考えろ」というのが、問題の意図となります。 上のやりかたを良く見ると、 data_new[0] = data[max-1] ; data_new[max-1] = data[0] 等と、2つ1組で入れ替わっていることがわかります。 つまり、data_newを用意しなくても、「data中の2つを入れかえる」を繰り返すだけで同等のことができる、というのがわかります。 「同じ組を2回入れかえたら、元にもどってしまう」ということに注意しましょう。 ○なお、質問にあるhantenですが ・ポインタで宣言しても[]が使えます。次のように書いても、まったく一緒です。 tmp = data[i]; data[i] = data2[i]; data2[i] = tmp; // =元のdata[i] 単に data[i]とdata2[i]を入れ替えただけで、順番は何も変わっていないことがわかります。 ・ポインタは宣言しただけでは、どこを指しているかわかりません。 そのまま *data2 などとすると、その「どこかわからないアドレス」にある「なんだかわからない値」が使われます。 別の変数の値を参照しているかもしれないし、OSの領域を参照しているかもしれません。 その結果、なにごともなく動作しているように見えることもあれば、領域違反でエラー終了することもあります。 ややこしいところですが、ポインタと配列はきちんと整理してしっかり勉強しましょう。

izupawapuro
質問者

お礼

後半の部分でご指摘いただいたことが勉強になりました ありがとうございます!

回答No.1

まずは  data[x] と data[y] とを入れ替える コードを書きます。 それができたら、 x = 0, y = MAX-1 を初期値とし、 x < y である間 {  data[x] と data[y] とを入れ替える  ++x  --y } する。  

izupawapuro
質問者

お礼

参考になりました~ありがとうございます!