定义一个聚类函数 cluster(int data[], int len, int radius); data中的值没有重复,长度为len, 把按照数值的聚类进行分为n组, 对于组G中任意一个数值a,总是能在本组G中找到一个数值b, 使 |a-b| < radius . 在函数内部打印出所有n个组成员,分成n行输出 (要求:不能使用数组排序操作) 例如: 输入 data[] = { 1, 20, 89, 22, 72, 2,39, 3,56,86, 5, 93,13, 15, 18, 73, 79, 81, 25, 38, 43, 83,48, 52, 59,92,84,95,87 }; 正确的屏幕输出为组及成员为(每行为一组,行之间顺序随意,组内成员顺序随意): 1, 2, 3, 5, 13, 15, 18, 20, 22, 25, 39, 38, 43, 48, 52, 56, 59, 73, 72, 79, 89, 92, 84, 95,87,86, 93,81, 83,
思路:遍历一遍数组,每来一个新的元素,就判断该元素是否在已经存在的组里,这里每个组是一个聚类。如果哦不存在任意一个聚类,则新建一个聚类,否则将 * 所有包含该数字的聚类再合并。
typedef pair,pair> grouptype;
bool isInThisGroup(const int radius, const int num, grouptype& group) {
int min = group.second.first;
int max = group.second.second;
if (num >= min - radius && num <= max + radius)
return true;
return false;
}
void mergegroup(grouptype& g1,grouptype& g2) {
int min1 = g1.second.first;
int max1 = g1.second.second;
int min2 = g2.second.first;
int max2 = g2.second.second;
int min = min1 < min2 ? min1 : min2;
int max = max1 > max2 ? max1 : max2;
auto& g1_v = g1.first;
auto& g2_v = g2.first;
for(auto e : g2_v)
g1_v.push_back(e);
g1.second.first = min;
g1.second.second = max;
}
void updateEdge(grouptype& g, int num) {
if (num < g.second.first)
g.second.first = num;
if (num > g.second.second)
g.second.second = num;
}
void cluster(int data[], int len, int radius)
{
if (len < 1)
return;
vector res;
for (int i = 0; i < len; ++i) {
int cu = data[i];
// 遍历数组
vector inGroup;
for (int j = 0; j < res.size(); ++j) {
// 遍历当前组,判断当前数字是否可以聚类到某个组里
if (isInThisGroup(radius, data[i], res[j])) {//如果当前数字在该组内
inGroup.push_back(j);
}
}
// 处理组的合并
if (inGroup.size() == 0) { // 当前数字不在已经存在的任意一组
// 新建组
vector tempgroup;
tempgroup.push_back(data[i]);
res.push_back(grouptype(tempgroup, std::make_pair(data[i],data[i])));
} else if (inGroup.size() == 1) {
// 只需要更新组边界,不需要合并
res[inGroup[0]].first.push_back(data[i]);
updateEdge(res[inGroup[0]], data[i]);
} else if (inGroup.size() > 1) {
// 需要合并组,并且更新最终合并组的边界
for (int k = 1; k < inGroup.size(); ++k) {
mergegroup(res[inGroup[0]], res[inGroup[k]]);
}
res[inGroup[0]].first.push_back(data[i]);
updateEdge(res[inGroup[0]], data[i]);
// 从原来的结果总删除已经合并的组
for (int k = 1; k < inGroup.size(); ++k) {
res[inGroup[k]] = res.back();
res.pop_back();
}
}
}
// 打印最终结果
for(auto& e : res) {
for (auto& el : e.first) {
cout << el << ',';
}
cout << endl;
}
}