You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;
                }
            }
        }
    }
}

问题分析与正确解决方案

核心问题

  1. isCoordsAdjacent溢出错误:用uint256直接做减法时,若被减数小于减数会触发无符号溢出,导致差值计算完全错误,平方和结果偏离预期。
  2. testCoords循环逻辑错误:
    • 假设x、y数组长度一致,但j遍历y.length无意义,应统一遍历x.length(需先校验x、y长度相等)。
    • j从0开始会重复比较同一对坐标(如i=0,j=1和i=1,j=0),浪费算力。
    • 遇到不相邻的坐标对直接return false,会中断遍历,无法检查后续所有组合。

正确代码实现

// 修复溢出问题的相邻判断函数
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:35:23