如何避免结构体数组中最小距离点对的重复输出?
解决最小距离点对重复输出的问题
首先是你定义的结构体及数组:
struct point{ double x; double y; char name[10]; }; struct point points[1000];
你的原计算输出代码:
int count = 0; for (int i = 0; i < 1000; i++){ for(int j = 0; j < 1000; j++){ if(i != j){ double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2)); if(distance == min){ printf("%s - %s\n", points[i].name, points[j].name); count++; } } } }
问题分析
代码中i和j遍历所有索引组合,会同时处理(i,j)和(j,i)两种情况,导致同一对点对被反向输出两次。
解决方案
有两种简单的逻辑判断可以解决这个问题:
方法1:修改循环范围(推荐,同时提升效率)
将内层循环的j起始值改为i+1,只处理i < j的索引对,这样每个点对只会被计算和输出一次:
int count = 0; for (int i = 0; i < 1000; i++){ // j从i+1开始,避免重复遍历(i,j)和(j,i) for(int j = i + 1; j < 1000; j++){ double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2)); // 注意:浮点数相等建议用阈值判断,避免精度问题 if(fabs(distance - min) < 1e-9){ printf("%s - %s\n", points[i].name, points[j].name); count++; } } }
这种方法不仅避免了重复输出,还减少了一半的计算量,效率更高。
方法2:添加索引判断
如果不想修改循环范围,可以在输出条件中加入i < j的判断,过滤掉反向的点对:
int count = 0; for (int i = 0; i < 1000; i++){ for(int j = 0; j < 1000; j++){ if(i != j){ double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2)); // 新增i<j判断,只输出一次点对 if(fabs(distance - min) < 1e-9 && i < j){ printf("%s - %s\n", points[i].name, points[j].name); count++; } } } }
额外提示
直接用distance == min判断浮点数相等存在精度风险,因为浮点数计算可能存在微小误差。建议用fabs(distance - min) < 1e-9(或其他极小阈值)来判断两者是否近似相等,避免漏判或误判。
内容的提问来源于stack exchange,提问作者Nox5692
相关产品推荐
相关产品推荐

