數據結構——數組(3) 在有序數組中找出重複的次數最多的數

先總結有序數組,無序的後面再總結。。
1.以空間換時間法。
算法思想:目標數組array[length],是一個有序數組,比如int array[]={1,1,2,2,4,4,4,4,4,5,5,6,10};總共有13個元素,其中數字最多的數是4,總計5次。
因此,額外定義一個數組count[length],並將該數組初始化爲0。然後,使用count[array[i]]++操作,統計從0-length-1,總共length個數出現的次數。並將統計次數結果記錄在count[]數組中。如count[]={0,2,2,0,5,2,1,0,0,0,1,0,0,0}即數0出現0次;數1出現2次;數2出現2次;數3出現0次;數4出現5次……等等,以此類推。
最後,從count[]數組中找出最大的數(即出現最多的次數),該次數對應的下標即爲出現最多的數本身。

#include<stdio.h>
#include<iostream>
using namespace std;

int GetMaxNum(int a[],int len,int& num)
{
    int index=a[0];
    int i;
    for(i=0;i<len;i++)
    {
            if(a[i]>index)//找出最大的數,即爲最大次數作爲index,對應的數組下標就是該數值本身
            {
                index=a[i];
                num=i;
            }
    }
    return index;
}

int main()
{
    int array[]={1,1,2,2,4,4,4,4,4,5,5,6,10};
    int length=sizeof(array)/sizeof(array[0]);

    int *count=new int(length);
    for(int i=0;i<length;i++)
        count[i]=0;
    for(int i=0;i<length;i++)
        count[array[i]]++;
    int num=0;
    int Max_count=GetMaxNum(count,length,num);
    int Max_num=num;
//  cout<<"出現最多次的數爲:"<<Max_num<<endl;
//  cout<<"該數重複最多次數爲:"<<Max_count<<endl;

    printf("出現最多次的數爲:%d\n",Max_num);
    printf("該數重複最多次數爲:%d\n",Max_count);
    getchar();

}

注意:該方法最終可以運行處結果,但是會提示有堆棧破壞等警告和中斷信息。
而且,除非內存空間非常大,一般不採用這種方法。

2.使用map映射表
map表是STL中的一個關聯容器,提供一對一的數據處理能力。其中,第一個爲關鍵字,且每個關鍵字只能在map中唯一出現一次;第二個爲該關鍵字的值。
(key-value關鍵字-值)關鍵字:其索引作用;值表示與索引相關聯的數據。map中所有元素會根據元素值自動排序。同時,map不允許兩個元素有相同的關鍵字。
注意:使用時必須包含#include頭文件。map底層通常用二叉搜索樹實現。

   定義map對象,要明確關鍵字和值的類型,建立key-value映射關係,默認構造:map<key,vlaue>m;  再舉個例子:map<int,int>m;
   拷貝構造:map<key,value>m(const map& m1);//用m1構造m
   成員函數:empty():判斷map是否爲空;
   成員函數:size():返回map中元素的大小,即key-value的個數;
   成員函數:max_size():返回由於存儲空間限制,map可能包含的最大元素數量
   元素訪問:操作符[]:m[k]:返回關聯容器m中Key爲k的元素的value的引用。[]操作符會使得map的大小+1
   元素訪問:at():m.at(k):返回關聯容器map中Key爲k的元素的value的引用。使用at()不會增加元素,不會增加map的大小。
   其他操作:insert:插入;erase:刪除;swap:交換;clear:清空一個容器的所有元素;find:查找;count:計數;等等
#include <iostream>
#include<map>
using namespace std;
bool findMostFrequentInArray(int *a,int len,int &val, int& count)
{
    if(a==NULL || len<=0)
        return false;
    map<int,int>m;//定義map映射表
    for(int i=0;i<len;i++)
    {
        if( ++m[a[i]] >= m[val] )//找出次數最多的一個key關鍵字,記錄對應的關鍵字
            val=a[i];
    }
        count=m[val];//記錄找出的重複次數最多關鍵字對應的最大次數
    return true;        
}
int main()
{
    int array[]={1,1,2,2,4,4,4,4,4,5,5,6,10};
    int length=sizeof(array)/sizeof(array[0]);
    int val=0;
    int count=0;
    if(findMostFrequentInArray(array,length,val,count))
    cout<<"重複最多的數爲:"<<val<<endl;
    cout<<"最大重複次數爲:"<<count<<endl;

    int b[]={1,3,2,5,7,3,2,6,7,4,3,1};
    int length_b=sizeof(b)/sizeof(b[0]);
    if(findMostFrequentInArray(b,length_b,val,count))
        cout<<val<<endl;
        cout<<count<<endl;

getchar();
}

對map映射的操作,部分如下:

#include <map>
#include<iostream>
#include <utility>
using namespace std;
int main()
{
    map<int,int>m;
    m[0]=5;
    m[1]=4;
    m[2]=3;
    m[3]=2;

    //at()函數查找輸入鍵值爲對應的元素
    cout<<"map容器中關鍵字key=2時,對應的value爲:"<<m.at(2)<<endl;

    cout<<"從頭遍歷該map元素:"<<endl;
    map<int,int>::iterator it =m.begin();   //返回map中第一個元素位置的迭代器
    while (it!=m.end())
    {
        cout<<it->first<<"->>>"<<it->second<<endl;
        ++it;//讓迭代器跳轉到下一個元素的位置
    }
    cout<<"find一個元素的迭代器並且訪問它:"<<endl;
    cout<<m.find(3)->first << " ->>> "<<m.find(3)->second<<endl;

    cout<<"*************刪除***************"<<endl;
    cout<<"刪除一個key之後,遍歷map:對應的key-value被刪掉了。"<<endl;    
    m.erase(1);

    map<int,int>::iterator it1 =m.begin();  //返回map中第一個元素位置的迭代器
    while (it1 !=m.end())
    {
        cout<<it1->first<<"->>>"<<it1->second<<endl;
        ++it1;//讓迭代器跳轉到下一個元素的位置
    }

    cout<<"*************插入***************"<<endl;
    m.insert(pair<int,int>(5,4));   //注意:insert操作時,元素類型必須是pair,pair的頭文件爲<utility>

    map<int,int>::iterator it2 =m.begin();  //返回map中第一個元素位置的迭代器
    while (it2 !=m.end())
    {
        cout<<it2->first<<"->>>"<<it2->second<<endl;
        ++it2;//讓迭代器跳轉到下一個元素的位置
    }


    getchar();

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章