1. 程式人生 > 實用技巧 >陣列的主元素查詢

陣列的主元素查詢

描述

已知一個整數序列A=(a0, a1,…an-1),其中0≤ai<n(0≤i<n)。若存在ap1=ap2…=apm=x 且m>n/2(0≤pk<n,1≤k≤m),則稱x為A的主元素。例如A=(0,5,5,3,5,7,5,5),則5為主元素;又如A=(0,5,5,3,5,1,5,7),則A中沒有主元素。假設A中的n個元素儲存在一個一維陣列中,請設計一個儘可能高效的演算法,找出A的主元素。若存在主元素,則輸出該元素;否則輸出-1。

輸入

多組資料,每組資料兩行。第一行為一個整數n,代表陣列中有n個元素。第二行為陣列中的n個元素(元素之間用空格分隔)。當n等於0時,輸入結束。

輸出

每組資料輸出一行,若陣列中存在主元素,輸出主元素的值,若陣列中不存在主元素,則輸出-1。

輸入樣例 1

8
0 5 5 3 5 7 5 5
9
0 5 5 3 5 1 5 7 0
0

輸出樣例 1

5
-1

演算法思路: 即求陣列中最多數的問題,再加一步判斷看c是否>n/2.

演算法的基本思想

該演算法的基本思想就是從前向後掃描陣列元素,標記出一個可能成為主元素的元素Num,然後重新計數,確認Num是否是主元素。

演算法的基本步驟

1、

選取候選的主要元素:依次掃描所給陣列中的每一個整數,將第一個遇到的整數Num儲存到c中,記錄Num出現的次數為1,若遇到的下一個整數仍等於Num,則計算器加1,否則計數器減1,當計數器減到0時,將遇到的下一個整數儲存到c中,計數重新記為1,開始新一輪計數,即從當前位置開始重複上述過程,直到掃描完全部元素。

2、

判斷c中元素是否是真正的主元素:再次掃描該陣列,統計c中元素出現的次數,若大於n/2,則為主元素,否則序列中不存在主元素。

演算法核心程式碼:

int Major(int a[], int n) {
    int c, count=1;
    c = a[0];
    for (int i=0; i < n; i++) {
        if (a[i] == c)
            count++;
        else {
            if (count > 0)
                count--;
            else
{ count = 1; c = a[i]; } } } count = 0; for (int i = 0; i < n; i++) { if (a[i] == c) count++; } if (count > n / 2) return c; else return -1; }

本題提交程式碼:

#include<iostream>
using namespace std;

int Major(int a[], int n) {
    int c, count=1;
    c = a[0];
    for (int i=0; i < n; i++) {
        if (a[i] == c)
            count++;
        else {
            if (count > 0)
                count--;
            else {
                count = 1;
                c = a[i];
            }
        }
    }
    count = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == c)
            count++;
    }
    if (count > n / 2)
        return c;
    else
        return -1;
}

int main() {
    while (1) {
        int n,c;
        cin >> n;
        if (n == 0)
            break;
        int a[10000];
        for (int i = 0; i < n; i++)
            cin >> a[i];
        c = Major(a, n);
        cout << c << endl;
    }
}