アプリ版:「スタンプのみでお礼する」機能のリリースについて

int num[10]という配列に、適当な整数が入っています。

この中から、数字が大きいものを上から3つ取り出して出力するプログラムを書きたいのですが、どうしたら良いでしょうか?

簡単なIF文で最大や最小を取り出すことは出来るのですが、上から3つというのが分かりません。
以前作ったバブルソートのプログラムを使って取り出せたのですが、もう少し簡単にできるような気がするのです。

ヒントなど、教えて頂けませんか?

A 回答 (7件)

int num[10] の整数に誘われて、ちょっとデータが重なる場合はご容赦願うとして、if を使わない度数ソートを紹介します。






/* Int type sorting program by Mac OSX
* file neme: ab.c
* compile: gcc ab.c
* execution: ./a.out
*/

#include <stdio.h>
#include <time.h>/* time() */
#include <stdlib.h>/* srand() */

#define MEMSIZ 10/* ご利用枠 */
#define MAX 100/* 0以上の最大の整数値 */
#define OUTPUT 3/* 取り出す個数 */

int main(void) {
int num[MEMSIZ];
int sort[MAX + 1];
int i, count;

/* 初期値設定 */
for(i=0; i<=MAX; i++)
sort[i] = -1;
srand(time(NULL));
for(i=0; i<MEMSIZ; i++)
num[i] = rand() % (MAX + 1);

/* 使用データの出力 */
printf("num[%d]: ", MEMSIZ);
for(i=0; i<MEMSIZ; i++)
printf("%d ", num[i]);
printf("\n");

/* 度数ソート(ただし、程々の正の整数値であること) */
for(i=0; i<MEMSIZ; i++)
sort[num[i]] = num[i];

/* 抽出結果の出力 */
printf("result : ");
i = MAX;
count = 0;
while(count<OUTPUT && --i>=0) {
if(sort[i] >= 0) {
printf("%d ", sort[i]);
count += 1;
}
}
printf("\n");

return 0;
}
    • good
    • 0

バブルソートでも良いと思いますが、根本的だし。


あなたなりには、おおげさじゃないかという疑問が生じたのだと思います。確かにそうです。

子の場合は良いとして、例えば、特殊な場合で、スピードを要求するとか、数万個の配列から3つだけとかの場合は、幼稚なやりかたで良いんじゃないですか?

例えば、

int num[MAX_CNT];
int flag[MAX_CNT] = {0, }; /*ゼロに初期化*/
int maxes[3];
int max=-32675;
int i=0;
int flag_index=0;

for (j=0; j<3; j++)
{
for (i=0; i<MAX_CNT; i++)
{
if (flag[i]==0)
continue;
if (max < num[i])
   {
max = num[i];
flag_index=i;
}
}
flag[flag_index]=1;
maxes[j] = max;
}

こんなものかもしれません。
もう少し本格的にというか綺麗にしたいのならば、フラグを使わず、キューを使ってやると良いでしょ。でも、スピードの観点からだと、上記の幼稚なコードが早いでしょうね。
    • good
    • 0

> もう少し簡単にできるような気がするのです。



何をもって簡単というのかわかりませんが、

std::sort(a + 0, a + 10, std::greater<int>());
std::copy(a + 0, a + 3, std::ostream_iterator<int>(std::cout, "\n"));

のように2行で済むのでは?
(実際にはヘッダをインクルードしなければなりませんが...)
    • good
    • 0

・バブルソートや選択ソートで、大きい3つが確定した段階でやめる


どちらの場合でも、ソートのプログラムの昇順/降順とアルゴリズムをよく確認する。
昇順で最大値から確定する
→num[7],num[8],num[9]が確定したら止める
降順で最大値から確定する
→num[0],num[1],num[2]が確定したら止める
最小値から確定する
→全部ソートしなければならない

問題点:配列 numの順番が入れ替わってしまう
→ 順番が関係ないなら問題なし。
残しておきたいのなら、int num1[10]とか作って、内容をコピーして、コピーの方を並び換える

・int num2[4]とかして長さ4の配列を準備
1) num2[0~3]にnum[0~3]をコピー→降順でソート→num2[0~2]が暫定トップ3.num2[3]は脱落
2) num2[3] = num[4]→降順でソート→num2[0~2]が暫定トップ3.num2[3]は脱落
3) num2[3] = num[5] (以下略)
4) num[9]まで同様にくりかえし、最後に残ったnum2[0~2]がトップ3
num2のソートには、num2の規模、状態などから挿入ソートが最適でしょう

・numの値に同じものは一つもない場合のみで使える方法
1)最大値max1を取り出す
2) num[i] < max1 となるnum[i]の中から最大値max2を取り出す
2) num[i] < max2 となるnum[i]の中から最大値max3を取り出す
    • good
    • 0

降順にソートして、配列の先頭から3個取り出すのが


いちばん簡単な方法でありましょう。
    • good
    • 0

>簡単なIF文で最大や最小を取り出すことは出来るのですが、上から3つというのが分かりません。



同じだと思うんですけど、上から2つでもわからない?
    • good
    • 0

「一度取り出すごとに」「取り出された値をクリア」しながら「3回」取り出しを行う。

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!