個(gè)人網(wǎng)站模板之家吳中seo網(wǎng)站優(yōu)化軟件
一、前言
遇到一個(gè)需求,需要求數(shù)組中出現(xiàn)次數(shù)最多的元素,查找了一些資料,結(jié)合自己的思路,編寫(xiě)了程序并驗(yàn)證。
只考慮元素為非負(fù)整數(shù)的數(shù)組,如果有出現(xiàn)次數(shù)相同的元素,則返回較小元素。
二、編程思路
以數(shù)組元素?cái)?shù)據(jù)類型為16位整數(shù)為例,元素個(gè)數(shù)也為16位整數(shù),最多65535個(gè)。
遍歷數(shù)組元素,記錄每一個(gè)值出現(xiàn)的次數(shù),因?yàn)槲覀儾恢涝氐闹蹬c出現(xiàn)的次數(shù),到底哪個(gè)最多,可能遍歷到最后一個(gè)元素時(shí)才是次數(shù)最多的那一個(gè),所以,需要把每一個(gè)值出現(xiàn)的次數(shù)都保存起來(lái),到最后才能知道哪個(gè)是我們所要求的。如果要保存上述的結(jié)果,則還需要?jiǎng)?chuàng)建一個(gè)數(shù)組,用來(lái)保存元素的值、值出現(xiàn)的次數(shù),這里有一個(gè)技巧,即利用數(shù)組的下標(biāo),當(dāng)作輸入數(shù)組元素的值,對(duì)應(yīng)的值為該下標(biāo)出現(xiàn)的次數(shù),否則的話新建的數(shù)組需要是二維的。遍歷完輸入數(shù)組后,所創(chuàng)建的數(shù)組,每一個(gè)位置都會(huì)有了一個(gè)值,當(dāng)然,輸入數(shù)組中沒(méi)有出現(xiàn)過(guò)的值,創(chuàng)建的數(shù)組對(duì)應(yīng)的位置會(huì)是0;那么問(wèn)題來(lái)了,應(yīng)該創(chuàng)建一個(gè)長(zhǎng)度為多少的數(shù)組合適呢?可以有以下3種方案:
①、求出輸入數(shù)組中有多少個(gè)不同的值,新建的數(shù)組長(zhǎng)度即為該值,但該方法,不能使用數(shù)組的下標(biāo)表示輸入元素的值,沒(méi)法一一對(duì)應(yīng);
②、因?yàn)檩斎霐?shù)組的元素個(gè)數(shù)不確定,而且里面有多少不同的值也不確定,所以需要新建一個(gè)65536長(zhǎng)度的數(shù)組,以應(yīng)對(duì)輸入數(shù)組中可能出現(xiàn)0~65535不同的值;
③、求出輸入數(shù)組中的最大值,則其中的元素最多就有(最大值+1)種,則新建數(shù)組的長(zhǎng)度為(最大值+1)即可;
以上3種方法,我們選用第3種。
總結(jié)程序流程如下:
①、求輸入數(shù)組的最大值max1
②、創(chuàng)建一個(gè)新的數(shù)組,長(zhǎng)度為max1+1;
③、遍歷輸入數(shù)組的元素,新建數(shù)組的序號(hào),當(dāng)作元素的值,該序號(hào)里保存的值為元素出現(xiàn)的次數(shù),值出現(xiàn)1次則次數(shù)增加1次;
④、求新建數(shù)組的元素的最大值max2;
⑤、遍歷新建數(shù)組的元素,找到第1個(gè)值為max2的元素,跳出循環(huán),該元素對(duì)應(yīng)的序號(hào)(數(shù)組下標(biāo))即為輸入數(shù)組中出現(xiàn)次數(shù)最多的元素;
以一個(gè)較簡(jiǎn)單的數(shù)組為例,說(shuō)明計(jì)算的流程:
1 | 3 | 2 | 2 | 4 | 6 | 5 | 2 | 1 | 3 |
---|
可知數(shù)組長(zhǎng)度為10,最大值為6;新建一個(gè)數(shù)組,長(zhǎng)度為6+1=7,次數(shù)均初始化為0:
元素 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
次數(shù) | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
遍歷數(shù)組,統(tǒng)計(jì)各元素出現(xiàn)的次數(shù):
元素 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
次數(shù) | 0 | 2 | 3 | 2 | 1 | 1 | 1 |
則出現(xiàn)次數(shù)最多的為元素2,共出現(xiàn)3次;
三、主要程序代碼
/******************************************************************************** 函數(shù)名:GetMaxValue* 功 能:獲取數(shù)組元素的最大值* 參 數(shù):Arr:數(shù)組Len:長(zhǎng)度,數(shù)組元素個(gè)數(shù)* 返回值:最大值* 說(shuō) 明:無(wú)
*******************************************************************************/
uint16_t GetMaxValue(uint16_t *Arr, uint16_t Len)
{uint16_t max = 0;uint16_t i;for (i = 0; i < Len; i++){if (*(Arr + i) > max){max = *(Arr + i);}}return max;
}
/******************************************************************************** 函數(shù)名:GetMostFrequentValue* 功 能:獲取數(shù)組中出現(xiàn)次數(shù)最多的元素* 參 數(shù):Arr:數(shù)組Len:長(zhǎng)度,數(shù)組元素個(gè)數(shù)* 返回值:最大值value* 說(shuō) 明:無(wú)
*******************************************************************************/
uint16_t GetMostFrequentValue(uint16_t *Arr, uint16_t Len)
{uint16_t i;uint16_t value = 0;uint16_t max1 = 0;uint16_t max2 = 0;max1 = GetMaxValue(Arr, Len);uint16_t temp[max1 + 1];//用于存放次數(shù)的數(shù)組,該數(shù)組的序號(hào),對(duì)應(yīng)輸入數(shù)組元素的值memset(temp, 0, (max1 + 1) * 2);for (i = 0; i < Len; i++){temp[*(Arr + i)]++;//以元素的值作為temp數(shù)組的序號(hào),值出現(xiàn)1次則次數(shù)增加1次}max2 = GetMaxValue(temp, max1 + 1);//求出次數(shù)的最大值 for (i = 0; i < (max1 + 1); i++)//找到第1個(gè)最大值,跳出循環(huán){if (temp[i] == max2){value = i;break;//如果要返回較大值,則不需要break}}return value;
}
四、驗(yàn)證
運(yùn)行環(huán)境為STM32單片機(jī),計(jì)算的時(shí)候,打印出中間過(guò)程;
1.數(shù)組{1,3,2,2,4,6,5,2,1,3}:
打印數(shù)據(jù)的左側(cè)一列為元素的值,右側(cè)為相應(yīng)的次數(shù),因?yàn)樽畲笾凳?,所以只輸出到6,最后輸出的結(jié)果為2;
2.數(shù)組{10,23,12,3,9,6,5,10,1,10,20,9,3,10,9,8,9,15}:
輸出的數(shù)據(jù)中,元素9和10均出現(xiàn)4次,但輸出結(jié)果為較小值9,正確。
五、總結(jié)
1、程序不考慮時(shí)間和空間復(fù)雜度,并不一定是最優(yōu)的算法,只是流程簡(jiǎn)單,易于理解;
2、該方法利用了數(shù)組的下標(biāo)當(dāng)作與元素對(duì)應(yīng)的值,因此只適用于數(shù)組元素為非負(fù)整數(shù)的情況;
3、輸入數(shù)組的長(zhǎng)度任意,新建的數(shù)組為變長(zhǎng)數(shù)組,所以要用C99的標(biāo)準(zhǔn);
4、新建的數(shù)組下標(biāo)當(dāng)作元素的值,實(shí)際相當(dāng)于給輸入數(shù)組進(jìn)行了排序,所以找到第1個(gè)最大值,跳出循環(huán),如果有出現(xiàn)次數(shù)相同的元素,則返回較小元素;