web-dev-qa-db-ja.com

配列内で最大および2番目に大きい数を見つけるプログラム

私はこの質問について多くのウェブサイトを検索しました。彼らはいくつかの異なるアプローチでそれをやっています。このコードは、配列の最初の要素を最大値として入力した場合、つまりa[0]。多少の変更が必要だと思います。誰か教えてもらえますか?

#include <stdio.h>

int main() {
    int a[10], n;
    int largest1, largest2, i;

    printf("enter number of elements you want in array");
    scanf("%d", &n);
    printf("enter elements");
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    largest1 = a[0];
    for (i = 0; i < n; i++) {
        if (a[i] > largest1) {
            largest1 = a[i];
        }
    }
    largest2 = a[0];
    for (i = 1; i < n; i++) {
        if (a[i] > largest2 && a[i] < largest1)
            largest2 = a[i];
    }
    printf("First and second largest number is %d and %d ", largest1, largest2);
}
2
Bhart Kumar

入力の処理を無視しますが、気を散らすだけです。

簡単な方法は、ソートすることです。

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

int cmp_int( const void *a, const void *b ) {
    return *(int*)a - *(int*)b;
}

int main() {
    int a[] = { 1, 5, 3, 2, 0, 5, 7, 6 };
    const int n = sizeof(a) / sizeof(a[0]);

    qsort(a, n, sizeof(a[0]), cmp_int);
    printf("%d %d\n", a[n-1], a[n-2]);
}
_

しかし、それはO(n log n)であるため、最も効率的ではありません。つまり、配列が大きくなると、比較の回数が速くなります。速すぎず、指数関数的より遅くなりますが、もっとうまくやることができます。

O(n)または「線形時間」でそれを行うことができます。これは、配列が大きくなるにつれて、比較の数が同じ割合で増加することを意味します。

最大値を追跡する配列をループします。これが最大値を見つける通常の方法です。新しい最大値を見つけると、古い最大値が2番目に大きい数値になります。

2番目に大きい番号を見つけるための2番目のループを使用する代わりに、2番目に大きい番号に到達するための特別なケースをスローします。

_#include <stdio.h>
#include <limits.h>

int main() {
    int a[] = { 1, 5, 3, 2, 0, 5, 7, 6 };
    // This trick to get the size of an array only works on stack allocated arrays.
    const int n = sizeof(a) / sizeof(a[0]);

    // Initialize them to the smallest possible integer.
    // This avoids having to special case the first elements.
    int max = INT_MIN;
    int second_max = INT_MIN;

    for( int i = 0; i < n; i++ ) {
        // Is it the max?
        if( a[i] > max ) {
            // Make the old max the new 2nd max.
            second_max = max;
            // This is the new max.
            max = a[i];
        }
        // It's not the max, is it the 2nd max?
        else if( a[i] > second_max ) {
            second_max = a[i];
        }
    }

    printf("max: %d, second_max: %d\n", max, second_max);
}
_

もっとエレガントな方法があるかもしれませんが、それでもせいぜい2nの比較しかできません。せいぜいnだけです。

_{ 1, 2, 3, 3 }_をどうするかという未解決の問題があることに注意してください。それは_3, 3_または_2, 3_を返す必要がありますか?それを決定し、それに応じて調整するのはあなたにお任せします。

5
Schwern

既存の配列で最大および2番目に大きい要素を見つける必要がある場合は、上記の回答を参照してください(Schwernの回答には、私が使用したアプローチが含まれています)。

しかしながら;既存の配列で最大の要素と2番目に大きい要素を見つける必要があるのは、通常、設計上の欠陥を示しています。配列全体が魔法のように表示されるわけではありません。それらはどこかから来ます。つまり、最も効率的な方法は、配列の作成中に「現在の最大および2番目に大きい」を追跡することです。

例えば;元のコードの場合、データはユーザーから送信されます。また、ユーザーから値を取得するループ内で「ユーザーが入力した最大および2番目に大きい値」を追跡することにより、ユーザーがキーを押すのを待つ時間によって情報追跡のオーバーヘッドが隠されます。ユーザーが結果を待っている間に検索を行う必要がなくなり、配列もまったく必要なくなりました。

次のようになります。

int main() {
    int largest1 = 0, largest2 = 0, i, temp;

    printf("enter number of elements you want in array");
    scanf("%d", &n);
    printf("enter elements");
    for (i = 0; i < n; i++) {
        scanf("%d", &temp);
        if(temp >= largest1) {
            largest2 = largest1;
            largest1 = temp;
        } else if(temp > largest2) {
            largest2 = temp;
        }
    }
    printf("First and second largest number is %d and %d ", largest1, largest2);
}
1
Brendan

質問はあいまいです。配列に重複した値が含まれている可能性がある場合、2つの最大の別個の値または2つの最大の同一の可能性のある値を見つけることになっていますか?

コードは最初のアプローチが必要であることを示しているようですが、最大値が_a[0]_の場合は問題があります。まだ別の値を見つけたかどうかを追跡するには、追加のブール値を使用する必要があります。

また、さまざまなscanf()呼び出しの戻り値をテストし、main()から0を返す必要があります。

変更されたバージョンは次のとおりです。

_#include <stdio.h>

int main(void) {
    int a[10], n, i;
    int largest1, largest2, has_largest2;

    printf("enter number of elements you want in array: ");
    if (scanf("%d", &n) != 1)
        return 1;
    if (n < 2) {
        printf("need at least 2 elements\n");
        return 1;
    }
    printf("enter elements: ");
    for (i = 0; i < n; i++) {
        if (scanf("%d", &a[i]) != 1) {
            printf("input error\n");
            return 1;
        }
    }
    largest1 = a[0];
    for (i = 1; i < n; i++) {
        if (a[i] > largest1) {
            largest1 = a[i];
        }
    }
    has_largest2 = largest2 = 0;
    for (i = 0; i < n; i++) {
        if (a[i] < largest1) {
            if (!has_largest2) {
                has_largest2 = 1;
                largest2 = a[i];
            } else
            if (a[i] > largest2) {
                largest2 = a[i];
            }
        }
    }
    if (has_largest2) {
        printf("First and second largest number is %d and %d\n",
               largest1, largest2);
    } else {
        printf("All values are identical to %d\n", largest1);
    }
    return 0;
}
_
0
chqrlie

3番目のループを使用して、配列内の2番目に大きい数を確認する必要はありません。使用できるループは2つだけです(1つは挿入用で、もう1つはチェック用です。

このコードを参照してください。

#include <stdio.h>

int main()

{
int a[10], n;

int i;

printf("enter number of elements you want in array");

scanf("%d", &n);

printf("enter elements");

for (i = 0; i < n; i++) {
    scanf("%d", &a[i]);
}

int largest1 = a[0],largest2 = a[0];

for (i = 0; i < n; i++) 
{
    if (a[i] > largest1) 
    {
         largest2=largest1;
         largest1 = a[i];
    }
}

printf("First and second largest number is %d and %d ", largest1, largest2);
}

このコードが役に立つことを願っています。

コーディングをお楽しみください:)

0
Nitish Gupta

文字列関数を使用せずに2番目に大きい数を見つけます

int array[];//Input array
int firstLargest, secondLargest;
int minNumber = -1;//whatever smallest you want to add here
/*There should be more than two elements*/
if (array_size < 2)
{
    printf("Array is too small");
    return;
}

firstLargest = secondLargest = minNumber;
for (index = 0; index < array_size ; ++index)
{
    //Largest number check
    if (array[index] > first)
    {
        secondLargest = firstLargest;
        firstLargest = array[index];
    }

    //It may not larger than first but can be larger than second number
    else if (array[index] > secondLargest && array[index] != firstLargest)
{
        secondLargest = array[index];
}

//Finally you got your answer
if (secondLargest == minNumber)
{
    printf("No Second largest number");
}
else
{
    printf("Second Largest Number is %d", secondLargest);
}
0
Sarat Patel

これで試してみてください:

    firstMax = arr[0];

    for (int i = 0; i<n; i++) {

        if (firstMax < arr[i]  ) {
            secondMax = firstMax;
            firstMax = arr[i];
        }
    }
0
Shourob Datta

これを試して:

public static void main(String[] args) throws IndexOutOfBoundsException {

    int[] a = { 12, 19, 10, 3, 9, 8 };
    int n = a.length;
    int larg = a[0];
    int larg2 = a[0];

    for (int i = 0; i < n; i++) {
        if (larg < a[i]) {
            larg = a[i];

        }
        if (a[i] > larg2 && larg < a[i]) {
            larg2 = a[i];

        }
    }

    System.out.println("largest " + larg);
    System.out.println("largest2 " + larg2);

}
0
Viraj Giri

コードの問題は論理的な問題です(これはほとんどのコーディングの目的です)。最大数が最初の場合、2番目に大きい数が間違っています...なぜですか?

さて、2番目に大きい数を決定するためのロジックを見てください。最初に配列の最初の要素と等しくなるように設定し、次に要素を現在の2番目に大きい数よりも大きい場合は配列を調べてインデックスを変更します(既に設定されているため、trueにはなりません)最大数!)。

これを解決するには、これを特別なケースにすることができます:最大数が最初であるかどうかを確認し、そうであれば、それを2番目の要素に設定します(そして、特別な場合、配列の終わりを超えて読み取ります。)

これをすべて1つのパスで行うには、chqrlieの答えに記載されている方法が最適だと思います。そして論理的でもあります:最大数を見つけるためのプログラムを書いてください。 2番目に大きい数です。これは、以前は最大でした。

0
dave

//私はそのシンプルなようだと思います

#include<stdio.h>
int main()

{
int a1[100],a2[100],i,t,l1,l2,n;
printf("Enter the number of elements:\n");
scanf("%d",&n);
printf("Enter the elements:\n");
for(i=0;i<n;i++)
{
    scanf("%d",&a1[i]);
}
l1=a1[0];
for(i=0;i<n;i++)
{
    if(a1[i]>=l1)
    {
        l1=a1[i];
        t=i;
    }
}
for(i=0;i<(n-1);i++)
{
    if(i==t)
    {
        continue;
    }
    else
    {
        a2[i]=a1[i];
    }
}
l2=a2[0];
for(i=1;i<(n-1);i++)
{
    if(a2[i]>=l2 && a2[i]<l1)
    {
        l2=a2[i];
    }
}
printf("Second highest number is %d",l2);
return 0;
}
0

配列メンバーのインデックスをそのまま保持する必要がありますunique以下に、変更の少ない作業コードを示します。

#include<stdio.h>
int main()
{
    int a[10],n;
    int largest1,largest2,i;

    printf("enter number of elements you want in array");
    scanf("%d",&n);
    printf("enter elements");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    largest1=0;
    for(i=0;i<n;i++)
    {
        if(a[i]>a[largest1])
        {
            largest1=i;
        }
    }
    if(largest1!=0) // this condition to select another index than the largest
        largest2=0;
    else
        largest2=n-1;
    for(i=0;i<n && i != largest1 ;i++)
    {
        if(a[i]>a[largest2])
            largest2=i;
    }
    printf("First and second largest number is %d and %d ",a[largest1],a[largest2]);
}

配列のサイズが1の場合、値は同じになることに注意してください。

これは、単一のforループの答えです。

int array[] = { 10, 15, 13, 20, 21, 8, 6, 7, 9, 21, 23 };
const int count = sizeof(a) / sizeof(a[0]);
int lastMaxNumber = 0;
int maxNumber = 0;

for (int i = 0; i < count; i++) {

    // Current number
    int num = array[i];

    // Find the minimum and maximum from (num, max)
    int maxValue = (num > maxNumber) ? num : maxNumber;
    int minValue = (num < maxNumber) ? num : maxNumber;

    // If minValue is greater than lastMaxNumber, update the lastMaxNumber
    if minValue > lastMaxNumber {
        lastMaxNumber = minValue;
    }

    // Updating maxNumber
    maxNumber = maxValue;
}

printf("%d", lastMaxNumber);
0
TheTiger

1回のパスで最高の結果を得ることができます。

最大および最大2は、エントリ時にINT_MINに設定されます。次に、配列をステップスルーします。最大値が数値よりも小さい場合、最大値2が最大値になり、最大値が新しい数値になります(重複を許可する場合はそれ以下になります)。最大数が新しい数より大きい場合は、最大値2をテストします。

このアルゴリズムは、面倒になりすぎて並べ替えるよりも前に、配列の上位3つまたは4つを見つけるようにスケーリングされることに注意してください。

0
Malcolm McLean
package secondhighestno;

import Java.util.Scanner;

/**
 *
 * @author Laxman
 */
public class SecondHighestno {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Scanner sc=new Scanner(System.in);
        int n =sc.nextInt();
        int a[]=new int[n];
        for(int i=0;i<n;i++){
            a[i]=sc.nextInt();
        }
        int max1=a[0],max2=a[0];
        for(int j=0;j<n;j++){
            if(a[j]>max1){
                max1=a[j];
            }
        }
        for(int k=0;k<n;k++){
            if(a[k]>max2 && max1>a[k]){
                max2=a[k];
            }
        }
        System.out.println(max1+" "+max2);
    }
}
0
lucky