如何在Solidity中判断多个坐标点是否存在相邻情况
Solidity 坐标点相邻判断问题解决方案
我正在用Solidity开发代码,需要编写一个函数来判断给定x坐标数组和y坐标数组中,是否存在多个坐标点相邻的情况,目前在此处遇到阻碍。
初始伪代码
function isCoordsAdjacent( uint256 x1, uint256 y1, uint256 x2, uint256 y2 ) public pure returns (bool) { unchecked { if (1 == ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) { return true; } else { return false; } } }
function testCoords(uint256[] calldata x, uint256[] calldata y) public view returns (bool) { for (uint256 i = 0; i < coords.length; i++) { for (uint256 j = 0; j < coords.length; j++) { if ( isCoordsAdjacent(x, y, x, y - 1) isCoordsAdjacent(x, y, (x - 1), y) || isCoordsAdjacent(x, y, (x - 1), (y + 1)) || isCoordsAdjacent(x, y, x, (y - 1)) || isCoordsAdjacent(x, y, x, y) || isCoordsAdjacent(x, y, x, y + 1) || isCoordsAdjacent(x, y, (x + 1), (y - 1)) || isCoordsAdjacent(x, y, (x + 1), y) || isCoordsAdjacent(x, y, (x + 1), (y + 1)) ) { return true; } } } return false; }
更新后的代码(仍无法运行)
function testCoords(uint256[] calldata x, uint256[] calldata y) public pure returns (bool result) { unchecked { for (uint256 i = 0; i < x.length; i++) { for (uint256 j = 0; j < y.length; j++) { if (i == j) { continue; } else if (isCoordsAdjacent(x[i], y[i], x[j], y[j])) { return true; } else { return false; } } } } }
问题分析与正确解决方案
核心问题
isCoordsAdjacent溢出错误:用uint256直接做减法时,若被减数小于减数会触发无符号溢出,导致差值计算完全错误,平方和结果偏离预期。testCoords循环逻辑错误:- 假设x、y数组长度一致,但j遍历
y.length无意义,应统一遍历x.length(需先校验x、y长度相等)。 - j从0开始会重复比较同一对坐标(如i=0,j=1和i=1,j=0),浪费算力。
- 遇到不相邻的坐标对直接
return false,会中断遍历,无法检查后续所有组合。
- 假设x、y数组长度一致,但j遍历
正确代码实现
// 修复溢出问题的相邻判断函数 function isCoordsAdjacent( uint256 x1, uint256 y1, uint256 x2, uint256 y2 ) public pure returns (bool) { unchecked { // 转换为int256计算差值,避免无符号溢出 int256 dx = int256(x2) - int256(x1); int256 dy = int256(y2) - int256(y1); // 上下左右相邻:平方和为1;若需包含对角线,改为<=2 return (dx * dx + dy * dy) == 1; } } // 修复逻辑的坐标数组检查函数 function testCoords(uint256[] calldata x, uint256[] calldata y) public pure returns (bool) { // 先校验数组合法性:长度一致且至少有2个点 if (x.length != y.length || x.length < 2) { return false; } unchecked { // j从i+1开始,避免重复比较同一对坐标 for (uint256 i = 0; i < x.length; i++) { for (uint256 j = i + 1; j < x.length; j++) { if (isCoordsAdjacent(x[i], y[i], x[j], y[j])) { return true; } } } } // 遍历完所有组合都无相邻点,返回false return false; }
关键说明
- 溢出处理:通过
uint256转int256计算差值,确保减法结果正确,不会触发无符号溢出。 - 循环优化:j从i+1开始,每对坐标仅比较一次,提升遍历效率。
- 边界校验:先检查数组长度合法性,避免无效遍历。
- 相邻定义灵活调整:若需要包含对角线相邻,只需将
isCoordsAdjacent的返回条件改为(dx * dx + dy * dy) <= 2即可。
内容的提问来源于stack exchange,提问作者Margherita
相关产品推荐
相关产品推荐

