算法设计与分析-众数问题(不需要预排序)

算法设计与分析-众数问题(不需要预排序)

众数问题

问题描述:

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。例如,S={1,2,2,2,3, 5}。多重集S的众数是2,其重数为3。

算法设计:

对于给定的由n个自然数组成的多重集S,计算S的众数及其重数。1

数据输入:

输入数据的第1行为多重集S中元素个数n;在接下来的n行中,每行有一个自然数。


结果输出:

将计算结果输出命令行窗口。输出格式为 (num).[count] ,其中num为众数,count为该众数的重数。

 

解决思路:

借鉴归并排序的思想,使用一个数据结构记录数字和重数,然后归并,具体步骤如下:

(1) 若规模为1,则申请一块空间,记录这个数字,并标记重数为1,返回该数据结构。

(2) 若规模大于1,则将数组一分为二,分别递归,然后获取返回的数据结构,使用归并方法,将两个数据结构归并为一个数据结构。

归并时:

若两个数字相同时,合并为一个,重数加和,加入到新数组中。

若两个数字不相同是,取最小的一个加入到新数组中。

经过上述步骤,我们相当于获得了一个集合,这个集合中的元素为数字-重数对,然后我们扫描这个集合的所有元素,找到重数最大的一个即可得到答案。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

struct Number {
	int num;
	int count;
	Number(int num , int count):num(num),count(count) {

	}
	Number() {}
	friend ostream & operator << (ostream & cout, Number & a) {
		cout << " (" << a.num << ")" << "." << "[" << a.count << "] ";
		return cout;
	}
};

int n;

struct Set {
	Number * mp;
	int num;
	Set():mp(NULL),num(0) {

	}
};

void print_set(Set & s)
{
	for (int i = 0; i < s.num; i++) {
		cout << s.mp[i] << " ";
	}
	cout << endl;
}

int *tp = NULL;

void init() {
	cout << "input the number :" << endl;
	cin >> n;
	tp = new int[n + 1];
	cout << "input the data : " << endl;
	for (int i = 1; i <= n; i++) {
		cin >> tp[i];
	}
}

Set Merge(Set &a , Set &b) {
	Set demo;
	demo.mp = new Number[a.num + b.num];
	int i = 0;
	int j = 0;
	int t = 0;
	while (i < a.num && j < b.num) {
		if (a.mp[i].num == b.mp[j].num) {
			demo.mp[t++] = Number(a.mp[i].num, a.mp[i].count + b.mp[j].count);
			i++, j++;
		}
		else if (a.mp[i].num < b.mp[j].num) {
			demo.mp[t++] = a.mp[i++];
		}
		else {
			demo.mp[t++] = b.mp[j++];
		}
	}
	while (i < a.num) {
		demo.mp[t++] = a.mp[i++];
	}
	while (j < b.num) {
		demo.mp[t++] = b.mp[j++];
	}
	demo.num = t;
	delete[]a.mp;
	delete[]b.mp;
	return demo;
}

Set Mode(int L , int R) {

	if (L == R) {
		Set demo;
		demo.num = 1;
		demo.mp = new Number[1];
		demo.mp->num = tp[L];
		demo.mp->count = 1;
		return demo;
	}
	int med = (L + R) / 2;
	Set lf = Mode(L, med);
	Set rgt = Mode(med + 1, R);

	Set demo = Merge(lf, rgt);
	//print_set(demo);
return demo;
}

int main() {

	init();

	Set demo = Mode(1, n);
	Number ans(0,0);
	for (int i = 0; i < demo.num; i++) {
		if (demo.mp[i].count > ans.count) {
			ans = demo.mp[i];
		}
	}
	cout << "The answer is (num).[count]: " << endl;
	cout << ans << endl;
	
	return 0;
}

 

posted @ 2023-10-09 21:21  菜鸡一枚  阅读(213)  评论(0)    收藏  举报