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

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

ただいまの
回答率

90.47%

  • C

    3821questions

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

c言語の配列のプログラム問題

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 375

takemark20

score 3

 前提・実現したいこと

6 人で50m走を走ったときの各コースのタイムと順位を配列に格納し、順位順にコースとタイムを表示するプログラムを作成しなさい。 

1コース 6.8秒 2位
2コース 6.5秒 1位
3コース 7.9秒 6位
4コース 7.2秒 4位
5コース 7.1秒 3位
6コース 7.6秒 5位
というのを順位順に並びなおしたいです。 

なお、それぞれの配列は変えずにそのまま使用したいです。

 発生している問題・エラーメッセージ

上手く並べられません。

<実行結果>
1コース  6.8秒  2位
2コース  6.5秒  1位
3コース  7.9秒  6位
4コース  7.2秒  4位
5コース  7.1秒  3位
6コース  7.6秒  5位

1位  1コース  6.5秒
2位  2コース  6.0秒
3位  3コース  7.1秒
4位  4コース  7.0秒
5位  5コース  7.0秒
6位  6コース  7.6秒

このようになります。
例えばtimeという配列とjyuniという配列を関連づける、といったことは可能なのでしょうか?

下のソースコードを見てもらえばわかるんですが、j[6]を順位順に並べ替えても、
c[6](コース)とt[6](時間)を順位順に並べられません。

 該当のソースコード

#include<stdio.h>
int main()
{
    float t[6] = {6.8, 6.5, 7.9, 7.2, 7.1, 7.6};
    int j[6] = {2, 1, 6, 4, 3, 5};
    int c[6] = {1, 2, 3, 4, 5, 6};
    int i, k, work, work2;

    //配列表示
    for(i=0; i<6; i++){
        printf("%dコース  %.1f秒  %d位\n", c[i], t[i], j[i]);
    }

    //並び替え
    for(i=0; i<=3; i++){
        for(k=5; k>=i+1; k--){
            if(j[k]<j[k-1]){
                work = j[k];
                j[k] = j[k-1];
                j[k-1] = work;
            }
        }
    }
    printf("\n");

    for(i=0; i<=3; i++){
        for(k=i+1; k<=5; k++){
            if(t[i]>t[k]){
                work2 = t[i];
                t[i] = t[k];
                t[k] = work2;
            }
        }
    }
    printf("\n");

    //結果表示
    for(i=0; i<6; i++){
        printf("%d位  %dコース  %.1f秒\n", j[i], c[i], t[i]);
    }
    printf("\n");
    return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+3

順序について並び替えるときに、他の要素も一緒に並び替えちゃえばいいです。

for(i=0; i<=3; i++){
    for(k=5; k>=i+1; k--){
        if(j[k]<j[k-1]){
            // jに関するスワップ
            work = j[k];
            j[k] = j[k-1];
            j[k-1] = work;

            // tに関するスワップ
            ...

            // cに関するスワップ
            ...
        }
    }
}

それと、変数名を考え直すよう、強く推奨します
名前が適当すぎると、後から読み返す際に無駄な苦労をしなければなりません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/02 18:52

    回答ありがとうございます。

    その方法でしっかりと動いたんですが、タイムの小数点以下が上手く表示されません。

    1位 2コース 6.0秒
    2位 1コース 6.8秒
    3位 5コース 7.0秒
    4位 4コース 7.0秒
    5位 6コース 7.0秒
    6位 3コース 7.9秒

    このようになってしまいます。
    どうすればよいでしょうか?

    それと、変数名のアドバイスありがとうございます。

    キャンセル

  • 2018/05/02 18:55

    データを入れ替える際にうっかりミスをしているのが濃厚です。
    今一度確認してみてください。

    キャンセル

  • 2018/05/03 19:05

    for(i=0; i<=3; i++){
    for(k=5; k>=i+1; k--){
    if(j[k]<j[k-1]){
    //順位
    work = j[k];
    j[k] = j[k-1];
    j[k-1] = work;

    //時間
    work2 = t[k];
    t[k] = t[k-1];
    t[k-1] = work2;

    このように書いたのですが、どこが問題かわかりません。
    どういう事でしょうか?

    キャンセル

  • 2018/05/03 19:06

    work2の型がintだからじゃないですか?

    キャンセル

  • 2018/05/03 23:39

    そういえばそうでした...
    見落としてました、無事にうごきました。ありがとうございました。

    キャンセル

+3

既に答えが出ていますので参考までに

 本問題は不自然です。

順位が与えられているのに並び替えを要求するというのはナンセンスです。本来ならば並び替えてから順位を決めるべきです。

 本課題の場合はバケットソートができてしまいます。

これは特殊なソートアルゴリズムであり、限定された状況下でしか使用できず、汎用性がありません。ただし、この時間計算量はO(N)であり理論上のヒープ、マージソートを上回る性能となります。もちろん、実用上はクイックソートよりも速くなります。

(脱線しますが、クイックソートの時間計算量はO(N×N)です。マージソート、ヒープソートと同じくO(N×logN)と記述する資料をよく見かけますが、理論上ではクイックソートの時間計算量はマージソート、ヒープソートに劣ります。実用上、余程極端でない限りはクイックソートの方が速いですが。)

 バケットソートの具体的なアルゴリズム

大きな配列を用意し、ソートキーをインデックスとして値を書き込んでいきます。この処理が終わったら、配列の先頭から順に読み取れば整列済みのデータになっています。(本課題の場合は、「順位」がソートキーです)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/03 07:37

    コメントするか迷いましたが、

    BeatStarさんの回答とコメントの内容を
    見て納得しました。

    前程があって、それがよい回答案、解決策を妨げているとき

    どうやって質問者に伝えるか悩みます。

    回答を求められても

    前程の確かさ、条件の正しさがないと回答できないと

    思います。

    はっきりと意見してる人がいるなと

    すごいなと、思いました。

    おかしいと思って、この質問をスルーした人も多い?。
    即答すると加点の仕組みも???な感じですね。


    どう回答をするのがいいのか、考えるきっかけを。
    いいプラクティスを
    得ました。
    ありがとうございます。

    キャンセル

  • 2018/05/04 00:05

    ご意見ありがとうございます。私は本件のように、質問の本筋に大きくそれた回答もかなりしています。これは賛否両論のようで、マイナス評価をもらうことも若干あります。

    (このGWにたまたま気が付いたのですが、過去の私の脱線した回答について某大型掲示板でネタにされていました。その質問自体も漠然としたものであり、叩かれてもいましたが、それだけ注目もされているのだなあと感慨深いものでもありました。)

    キャンセル

  • 2018/05/04 00:15

    そうでしたか。うまくteratailを使いこなさないといけないですね。

    ”この質問に関して”は
    おかしいと思って、この質問をスルーした人も
    ”若干名”いるはずです

    この点でHogeAnimalLoverさんは正しい。

    いずれにせよ注意することもあるとわかりました。
    気をつけて利用します。
    ありがとうございます。

    キャンセル

+2

配列のインデックスを格納した配列を用意して、それをソートするのが良いでしょう。
また、ソートは自前で実装する必要はありません。つman qsort

#include <stdio.h>
#include <stdlib.h>

int cmp_t(const int *p1, const int *p2, float *t)
{
    if (t[*p1] < t[*p2]) {
        return -1;
    }
    if (t[*p1] > t[*p2]) {
        return 1;
    }
    return 0;
}

int main(void)
{
    float t[6] = {6.8, 6.5, 7.9, 7.2, 7.1, 7.6};
    int j[6] = {2, 1, 6, 4, 3, 5};
    int c[6] = {1, 2, 3, 4, 5, 6};
    int idx[6] = {0, 1, 2, 3, 4, 5};
    int i;

    for (i = 0; i < 6; i++) {
        printf("%dコース  %.1f秒  %d位\n", c[idx[i]], t[idx[i]], j[idx[i]]);
    }
    printf("\n");

    qsort_r(idx, 6, sizeof(int), cmp_t, t);

    for (i = 0; i < 6; i++) {
        printf("%d位  %dコース  %.1f秒\n", j[idx[i]], c[idx[i]], t[idx[i]]);
    }
    printf("\n");
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

正解は他の方だと思いますが、私ならこういう風にする...という感じで書きますね。

方法1:
構造体を用意し、それに格納する。その後、ソートして表示する。

たとえば、

struct Time{
       float t; // タイム
       int c; // コース
       int n; // 順位 ( number )
};


として、

Time::t を基準にしてソートするとか。

でも、"配列を使って"...ですからねぇ。イメージできない...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/02 16:21

    構造体の配列も配列には違いないので、「配列を使って。」る解答になってるとおもいますよ

    キャンセル

  • 2018/05/02 17:42

    a_saitohさん。やっぱりそうですよね。
    やはり、私なら構造体でやりますね。

    キャンセル

  • 2018/05/03 06:06

    自分も問題文読んで同様に思ったところです。本課題では順位が天下り的に提示されていますが、順位を決定してから並び替えるならば、先に並び替えた方が手っ取り早いですね。

    キャンセル

0

実際の競技会でレース内容(各コースのタイムと順位)を記録したら、それを電子掲示板に表示するという状況が想像されますね。

コース数の上限はそんなに多くないでしょうから、ソートせずに単に順位別に検索して表示していってみました。

* 同着だった場合は、コース番号の若い方が先に表示されます。
* コースが棄権や失格だった場合は順位の配列に コース番号以外の数 (0 とか、99 とか)を入力することにします。

order.c

#include<stdio.h>

#define NUM (6) // コースの数

int main()
{
  float time[NUM] = {6.8, 6.5, 7.9, 7.2, 7.1, 7.6};
  int runk[NUM] =   {2,   1,   6,   4,   3,   5};

  // 配列表示
  for (int i = 0; i < NUM; i++) {
    printf("%dコース  %.1f秒  %d位\n", i + 1, time[i], runk[i]);
  }
  printf("\n");

  // 順位順に表示
  for (int j = 1; j <= NUM; j++) {
    // 順位が j のコースを探す
    for (int i = 0; i < NUM; i++) {
      if (runk[i] == j) {
    // 見つけたコース番号、タイムを表示する
    printf("%d位  %dコース  %.1f秒\n", j, i + 1, time[i]);
      }
    }
  }
  return 0;
}

実行例
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

  • 受付中

    素数を出力

    c言語 入力した数までの素数を出力するプログラムの 偶数をチェック対象から外した場合です これを3の倍数をチェック対象から外した場合に 書き直したものを教えて下さい fo

  • 解決済

    結果の表示について

    課題で、 キーボードから入力された数値の平均を計算して表示し、平均以上の数値、平均より小さい数値を表示するプログラムを考えているのですが、 実行例 ./a.out

  • 解決済

    3つの文字列の長さを比較したい

    こんにちは C言語についての質問ですが キーボードから入力された3つの文字列の長さを比較して一番長い文字列をprintf()で表示させたいのですがこの場合strcmp関数で比較する

  • 解決済

    C言語でテキストファイルを読み、入力された行数のテキストを表示するコード

    前提・実現したいこと C言語でテキストファイルを読み、入力された行数のテキストを表示しようとしています。 例えば以下の「Hello.dat」というテキストファイルを読み、以下のよう

  • 受付中

    C言語の配列と関して

    整数型の配列変数dataを作成し、キーボードから入力させ、値を表示させてから3の倍数とそれ以外の数にわけて表示するプログラムです。 思うように動きません。 #include<s

  • 解決済

    配列のaの値を配列bに逆順にコピーするプログラムをつくることができません

    #include <stdio.h> #include <stdlib.h> int main() { int a[N] = { 1,2,3,4,5,6,7,8,9,10

  • 解決済

    C言語: 文字型ポインタの配列

    #include <string.h> int main(void) { int a=0,b=0,c=0; int max = 100; int min

  • 受付中

    int型ぎりぎりの素因数分解がしたい

     前提・実現したいこと 入力した数値を素因数分解し、計算時間を測るプログラムを作っています。  発生している問題・エラーメッセージ 7ケタの数字を入力した場合は無限ループ 52

同じタグがついた質問を見る

  • C

    3821questions

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