一道算法题
假定二维空间平面内有n个圆,现在我们需要将存在交集
的圆进行分组,输出结果为n个组,每个组包含i个圆.
交集算法: 两圆心的距离 小于 两圆半径之和.
假设圆数据为: (用数组表示圆)
[
{ X: 0, Y: 0, Radius: 1 },
{ X: 3, Y: 2, Radius: 2 },
{ X: 2, Y: 1, Radius: 3 },
{ X: 5, Y: 2, Radius: 4 },
{ X: 1, Y: 3, Radius: 5 },
{ X: 2, Y: 4, Radius: 6 },
{ X: 2323, Y: 121, Radius: 7 },
{ X: 2323, Y: 121, Radius: 7 },
{ X: 2322, Y: 121, Radius: 7 },
]
那么输出的结果为:
[ [ { X: 0, Y: 0, Radius: 1 },
{ X: 2, Y: 1, Radius: 3 },
{ X: 1, Y: 3, Radius: 5 },
{ X: 2, Y: 4, Radius: 6 },
{ X: 3, Y: 2, Radius: 2 },
{ X: 5, Y: 2, Radius: 4 } ],
[ { X: 2323, Y: 121, Radius: 7 },
{ X: 2323, Y: 121, Radius: 7 },
{ X: 2322, Y: 121, Radius: 7 } ] ]
假设代码结构为如下:
{ X: 1, Y: 0.7, Radius: 0.6 },
{ X: 0, Y: 0, Radius: 0.6 },
{ X: 1, Y: 0, Radius: 0.5 },
//圆1和圆2并不交集
//圆2和圆3存在交集
//圆1和圆3存在交集
//那么结果为
[cir1,cir2,cir3]//他们应该是一组的.
用JavaScript设计代码并实现
//圆类
class Circle {
constructor (id, x, y, r) {
this.id = id;
this.x = x;
this.y = y;
this.radius = r;
}
}
//计算圆心距
function computeCenDist (circle1, circle2) {
let x = circle1.x - circle2.x;
let y = circle1.y - circle2.y;
return Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
}
//计算半径和
function computeRadiusSum (circle1, circle2) {
return circle1.radius + circle2.radius;
}
//构造圆类对象数组
let input = [ { X: 0, Y: 0, Radius: 1 },
{ X: 3, Y: 2, Radius: 2 },
{ X: 2, Y: 1, Radius: 3 },
{ X: 5, Y: 2, Radius: 4 },
{ X: 1, Y: 3, Radius: 5 },
{ X: 2, Y: 4, Radius: 6 },
{ X: 2323, Y: 121, Radius: 7 },
{ X: 2323, Y: 121, Radius: 7 },
{ X: 2322, Y: 121, Radius: 7 },];
let circle = new Array(input.length);
let id = 0;
for(let i = 0;i < input.length;i++){
let x = input[i].X;
let y = input[i].Y;
let r = input[i].Radius;
circle[i] = new Circle(id, x, y ,r);
id++;
}
//进行圆的分组
let classifiedId = [];
let output = [];
for(let i = 0;i < circle.length;i++){
let group = [];
//判断待分组圆是否已在分组中
if(classifiedId.indexOf(circle[i].id) == -1) {
classifiedId.push(circle[i].id);
group.push(circle[i]);
//把与该圆有交集的圆归为一组
for(let j = i + 1;j < circle.length ;j++){
if(computeCenDist(circle[i], circle[j]) < computeRadiusSum(circle[i], circle[j])){
classifiedId.push(circle[j].id);
group.push(circle[j]);
}
}
let flag = false;
//将新分组与已有分组进行合并
for(let key in output) {
let o = new Set(output[key]);
if(group.filter(x => o.has(x)).length != 0) {
output[key] = Array.from(new Set([...group, ...output[key]]));
flag = true;
break;
}
}
if(!flag){
output.push(group);
}
}
}
//输出圆的分组结果
console.log(JSON.stringify(output));