質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

6回答

2236閲覧

(C言語)配列の特定の要素より前の要素を後ろに移動するプログラムの記述方法

gqh

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/10/30 06:26

配列の特定の要素より前の要素を後ろに移動するプログラムの記述したいと考えています.

例えば,
x = [1,5,4,3,2,6]
という配列があった時に,ある要素を探し出して,それよりも前の要素を後ろに移動させたいです.

ある要素が4だった場合は,4よりも前の要素である[1,5]を後ろに移動させ,
x = [4,3,2,6,1,5]
という順番に入れ替えたいです.

このようなプログラムの記述方法を教えていただきたいです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/10/30 07:30

アルゴリズムの書籍等を調べたりはされていないのでしょうか。
ppaul

2021/10/30 10:08

x = [1,5,4,3,4,6]で、ある要素が4だった場合は、どうしたいのでしょう?
guest

回答6

0

1234AB を入れ替えて AB1234 にするには

  1. 1234 と AB をそれぞれ反転する 4321BA
  2. (1)全体を反転する AB1234

はい、できあがり。

C

1#include <stdio.h> 2 3// x[first~last-1] を反転する 4void reverse(int x[], int first, int last) { 5 while ( first < last ) { 6 --last; 7 int tmp = x[first]; 8 x[first] = x[last]; 9 x[last] = tmp; 10 ++first; 11 } 12} 13 14// x[first~mid-1] と x[mid~last-1] を入れ替える 15void rotate(int x[], int first, int mid, int last) { 16 reverse(x, first, mid); 17 reverse(x, mid, last); 18 reverse(x, first, last); 19} 20 21// x[0~n-1]をプリントする 22void print(int x[], int n) { 23 for ( int i = 0; i < n; ++i ) 24 printf("%d ", x[i]); 25 printf("\n"); 26} 27 28int main() { 29 int x[6] = { 1,5,4,3,2,6 }; 30 print(x,6); 31 rotate(x, 0, 2, 6); 32 print(x,6); 33 return 0; 34}

投稿2021/10/30 23:04

編集2021/10/30 23:19
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

別の配列を使わずにやってみました。

c

1#include <stdio.h> // printf, putchar 2 3void reverse(int x[], int i, int j) 4{ 5 for (int t; i < --j; i++) 6 t = x[i], x[i] = x[j], x[j] = t; 7} 8 9void f(int x[], int n, int k) 10{ 11 for (int i = 0; i < n; i++) 12 if (x[i] == k) { 13 reverse(x, 0, i); 14 reverse(x, i, n); 15 reverse(x, 0, n); 16 return; 17 } 18} 19 20int main(void) 21{ 22 int x[] = { 1, 5, 4, 3, 2, 6 }; 23 int n = sizeof x / sizeof *x; 24 f(x, n, 4); 25 for (int i = 0; i < n; i++) printf(" %d", x[i]); 26 putchar('\n'); 27}

もちろん、やり方はいくつでもあります。
他のやり方も考えてみてください。

投稿2021/10/30 08:54

編集2021/10/30 09:00
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

バブルソートの動きを模したり、前(対象を含まない)を反転・後ろ(対象を含む)を反転・全体を反転 等で出来ます。

投稿2021/10/30 07:22

編集2021/10/30 07:23
jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まず、前提が違います。プログラミングは「こう書けばいい」というものではありません。
ロジックを考えるのです。

プログラミングは簡単に言えば『現実世界のシミュレーション』です。

なので、C言語で~とかは置いといて、現実世界で考えてみてください。

つまり、

[依頼] ある数列anと対象データxを渡すので、あなたはanの中にあるxの値よりも前にある数字すべて後ろに持ってきてbnを作る処理をしてください。 [例1] an = { 1, 2, 3, 4, 5 } x = 2 ↓ bn = { 2, 3, 4, 5, 1 } [例2] an = { 1, 2, 3, 5, 6 } x = 3 ↓ bn = { 3, 5, 6, 1, 2 }

のようなものですかね。

私なら、

[Flow 1] 1. xの値がある場所を調べる 2. (1)でわかった場所より一個前までの数字群を後ろに持ってくる

のような感じにします。

で、方法は今思いつくものだと、2種類ですかね。

一つ目は、『xを基準点として二つに分割して考えて、後ろ -> 前の順番にする』。
二つ目は、『xが出るまで後ろに追加していく』。

たとえば、an = { 1, 2, 3, 5, 6 }, x = 3 であれば、

xの値がある場所は (初項から考えると) 第3項ですね。
そうすると、前 = 初項第2項、後ろ = 第4項第5項 ですね。
そして、最終的な並びは bn = { 3, 5, 6, 1, 2 } ですね。

この場合は規則性を見付けると楽です。

an から bn の変化を見ると、依頼にあるようなものとは別に、『移動した値もすべて元の並びになっている』ですね。
*bn = { 3, 6, 5, 2, 1 } のようにでたらめに並んでいるわけではありません。

ということは、

cn = { 1, 2 }, dn = { 5, 6 }, 基準 = 3 という風になっていますね。

で、出てくる数字を見ると、基準 + dn + cn となっています。

ということは、まず基準値と 後ろにある dn = { 5, 6 } を先端から末尾まで別の数列として定義する。

en = { {3}, {5, 6} }

そして、さらに cnを追加する。

en = { {3}, {5, 6}, {1, 2} }

そして最後に、enをbnと読み替えて答えとする。

と考えるとどうでしょうか。

二つ目のやつは、単純に、

1. 先頭にxが出るまで繰り返す 1.1. その位置のデータを取り出して元のデータを削除 1.2. (1.1)で得たデータを末尾に追加

的なロジックになるかなと。

ただ、この二つ目の方法はC言語でやるとなると少々メンドクサイ気がします。

後はこういう考え方をC言語とかのようなやつで書き下して、エラーが出たらエラーに対処する。
これだけです。

投稿2021/10/30 07:11

BeatStar

総合スコア4962

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同じ配列を使うとめんどくさいので、別の配列を用意して、見つかったところから順番に1つずつ別の配列にコピーしていけばいいと思います。

投稿2021/10/30 06:50

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

c.c

c

1#include <stdio.h> // printf, putchar 2 3// 配列の内容を表示する 4void show_array(int *ary, int size) { 5 for (int i = 0; i < size; i++) { 6 printf(" %d", ary[i]); 7 } 8 putchar('\n'); 9} 10 11// 配列を左に1つ回転させる 12void shift_left(int * ary, int size) { 13 if (size <= 0) { 14 return; 15 } 16 17 int x = ary[0]; 18 for (int i = 0; i < size -1; i++) { 19 ary[i] = ary[i + 1]; 20 } 21 ary[size - 1] = x; 22} 23 24// 配列を左に count 回, 回転させる 25void shift_left_multi(int * ary, int size, int count) { 26 for (int i = 0; i < count; i++) { 27 shift_left(ary, size); 28 } 29} 30 31// 配列中の x に位置を調べる 32int find_x(int * ary, int size, int x) { 33 for (int i = 0; i < size; i++) { 34 if (ary[i] == x) { 35 return i; // find 36 } 37 } 38 return -1; // not find 39} 40 41int main(void) { 42 int x[] = { 1, 5, 4, 3, 2, 6 }; 43 int size = sizeof(x) / sizeof(int); 44 show_array(x, size); 45 46 // 4 を指定 47 int p = find_x(x, size, 4); 48 shift_left_multi(x, size, p); 49 show_array(x, size); 50 51 // 1 を指定 52 p = find_x(x, size, 1); 53 shift_left_multi(x, size, p); 54 show_array(x, size); 55 56 // 配列に存在しない値を指定したときは、変化しない 57 p = find_x(x, size, 9); 58 shift_left_multi(x, size, p); 59 show_array(x, size); 60} 61

実行例
イメージ説明

投稿2021/10/31 20:03

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問