在数组中找到出现频率大于1/4的数

算法的核心思想很简单,每次删去不同的4个数,最后剩下的元素有可能是频繁项。

假设数组有15个元素,若一个元素的出现频率大于1/4,其必须出现4次。不妨设数组为{1,2,1,4,1,4,2,9,1,7,4,3,9,4,3},d表示删去该数。我们来模拟一下算法的过程。

第一次 1d,2d,1,4d,1,4,2,9d,1,7,4,3,9,4,3 剩下 1,1,4,2,1,7,4,3,9,4,3

第二次 1d,1,4d,2d,1,7d,4,3,9,4,3 剩下 1,1,4,3,9,4,3

第三次 1d,1,4d,3d,9d,4,3 剩下 1,4,3

那么 1,4,3 即为候选频繁项

对 1,4,3 逐个进行检验,统计其再数组中出现的次数,若其超过出现频率阈值,则输出。

代码如下:

#include <iostream>

using namespace std;

#define ARRAY_SIZE 15
#define RESULT_NUM 3 //数组中出现频率的大于1/(RESULT_NUM+1)
int gl_array[ARRAY_SIZE] = {1,2,1,4,1,4,2,9,1,7,4,3,9,4,3};//给定的数字集合

struct Result
{
	int iNumber;
	int iTempTimes;
};

int GetEmptyElemInResult(Result r[], int iArrayLength)
{
	int i = 0;
	for (i = 0; i < iArrayLength; i++)
	{
		if (r[i].iTempTimes <= 0)
		{
			return i;
		}
	}
	return -1;
}

int GetNumberPosInResult(int iNumber, Result r[], int iArrayLength)
{
	int i = 0;
	for (i = 0; i < iArrayLength; i++)
	{
		if (r[i].iNumber == iNumber && r[i].iTempTimes > 0)
		{//iNumber出现在候选中,并且有效(在给定的数字集合中,出现次数大于0)
			return i;
		}
	}
	return -1;
}

int main(int argc, char** argv)
{
	Result resultArray[RESULT_NUM];//结果候选集合
	int i, j, iTemp;
	for (i = 0; i < RESULT_NUM; i++)
	{
		resultArray[i].iNumber = 0;
		resultArray[i].iTempTimes = 0;
	}
	for (i = 0; i < ARRAY_SIZE; i++)
	{
		iTemp = GetNumberPosInResult(gl_array[i], resultArray, RESULT_NUM);
		if (-1 != iTemp)
		{//若当前数出现在候选集合中,且有效,则其出现次数+1
			++resultArray[iTemp].iTempTimes;
		}
		else//不在候选中
		{
			iTemp = GetEmptyElemInResult(resultArray, RESULT_NUM);
			if (-1 != iTemp)
			{//结果候选不满RESULT_NUM个元素,将当前数插入在候选集合中
				resultArray[iTemp].iNumber = gl_array[i];
				resultArray[iTemp].iTempTimes = 1;
			}
			else
			{//当前数与候选集合中的所有元素都不相同,执行“删除”操作
				for (j = 0; j < RESULT_NUM; j++)
				{
					--resultArray[j].iTempTimes;
				}
			}
		}
	}

	//test the result in the array
	for (i = 0; i < RESULT_NUM; i++)
	{
		if (resultArray[i].iTempTimes > 0)
		{
			iTemp = 0;
			for (j = 0; j < ARRAY_SIZE; j++)
			{
				if (resultArray[i].iNumber == gl_array[j])
				{
					++iTemp;
				}
			}
			if (iTemp > ARRAY_SIZE / (RESULT_NUM+1))//出现次数大于阈值
			{
				cout << resultArray[i].iNumber << ": " << iTemp << endl;
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值