组合算法中的循环

发布于 2024-10-16 00:00:18 字数 991 浏览 2 评论 0原文

我想执行特定类型的搜索。我不知道它是否有名称,但我可以描述它,并有执行它的工作代码。

对于二维矩阵,从点 0,0 开始并向右下方工作,搜索生成将如下所示:

  • 1, 4, 9, 16,
  • ... ; 2、 3、8、15、...
  • 5、 6、7、14、...
  • 10、11、12 , 13, ...
  • ...

所以第一个搜索循环将检查 1,第二个循环检查 2, 3, 4,第三个循环检查 5, 6, 7, 8, 9 等。

生成此搜索的代码是:

$row_search = 0;
$point_not_found = true;

while ($point_not_found && $row_search < $matrix_height/2)
{
    $current = array(0, $row_search);

    while ($current[0] < $row_search)
    {
        if (searchForPoint( $matrix, $current ) !== false)
            $point_not_found = false;

        ++$current[0];
    }

    if (!$anchor_not_found)
        break;

    while ($current[1] >= 0)
    {
        if (searchForPoint( $matrix, $current ) !== false)
            $point_not_found = false;

        --$current[1];
    }

    ++$row_search;
}

我对搜索被分成两个循环的方式不满意,因为循环内的代码几乎相同。您能否建议一种组合或嵌套循环并消除对 searchForPoint 的冗余调用的方法?

I want to perform a specific-type of search. I do not know if it has a name, but I can describe it, and have working code for its execution.

For a 2-dimensional matrix, starting at point 0,0 and working down-right, the search generation would look like:

  •   1,  4,  9, 16, ...
  •   2,  3,  8, 15, ...
  •   5,  6,  7, 14, ...
  • 10, 11, 12, 13, ...
  • ...

So the first search loop would inspect 1, the second loop inspects 2, 3, 4, the third loop inspects 5, 6, 7, 8, 9, etc.

The code to produce this search is:

$row_search = 0;
$point_not_found = true;

while ($point_not_found && $row_search < $matrix_height/2)
{
    $current = array(0, $row_search);

    while ($current[0] < $row_search)
    {
        if (searchForPoint( $matrix, $current ) !== false)
            $point_not_found = false;

        ++$current[0];
    }

    if (!$anchor_not_found)
        break;

    while ($current[1] >= 0)
    {
        if (searchForPoint( $matrix, $current ) !== false)
            $point_not_found = false;

        --$current[1];
    }

    ++$row_search;
}

I am unhappy with how the search is broken into two loops, as the code within the loops is nearly identical. Can you suggest a way to either combine or nest the loops and eliminate redundant calls to searchForPoint?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪歌 2024-10-23 00:00:18

像这样的事情怎么样

$pointFound = false;
$row = 0;

while(!$pointFound && $row < $matrixSize)
{
    $y = $row;
    $x = 0;
    while($y >= 0)
    {
        if (searchForPoint($matrix,$x,$y) !== false)
        {
            $pointFound = true;
            break;
        }

        // If we reached the right column, start moving upwards (decreasing y)
        if($x == $row)
            $y--;
        // Else move right
        else
            $x++;
    }
    // EDIT (forgot the next line)
    $row++;
}

What about something like this

$pointFound = false;
$row = 0;

while(!$pointFound && $row < $matrixSize)
{
    $y = $row;
    $x = 0;
    while($y >= 0)
    {
        if (searchForPoint($matrix,$x,$y) !== false)
        {
            $pointFound = true;
            break;
        }

        // If we reached the right column, start moving upwards (decreasing y)
        if($x == $row)
            $y--;
        // Else move right
        else
            $x++;
    }
    // EDIT (forgot the next line)
    $row++;
}
终难遇 2024-10-23 00:00:18

存在一种嵌套循环的方法,但是将问题分解为两个循环的方法非常直观,而且最重要的是,已经可以工作了。

假设我们正在计算数学表达式 ln(x^2 + 1) - sqrt(x^2 + 1)。写成f(x) = ln(g(x)) - sqrt(g(x)), g(x) = x^2 + 1不是很方便吗?这似乎是你问题的本质,这个类比的要点是你应该考虑两个函数。

您有一种从左上到右下迭代的方法。给这个策略一个名称并将其抽象为迭代器。如果您愿意,请使用 OOP。然后,您就有了对迭代器提供给您的每件事做一些事情的概念。给那个东西一个名字并让它使用你的迭代器。额外的好处:您可以在找到匹配项后立即中止搜索,而不是过了一段时间。

伪代码:

$iterator = new MatrixRippleIterator($matrix);
$needle = 1337;
$found_match = false;
while ($iterator->hasNext()) {
    $current = $iterator->next();
    if ($current == $needle) {
        $found_match = true;
        break;
    }
}

There exists a way to nest the loops, but the way you've broken down the problem into two loops is quite intuitive and, foremost, already works.

Say we are evaluating the math expression ln(x^2 + 1) - sqrt(x^2 + 1). Wouldn't it be convenient to write it as f(x) = ln(g(x)) - sqrt(g(x)), g(x) = x^2 + 1? That seems to be the nature of your question, and the point of this analogy is that you should consider two functions.

You have a method of iterating, from top left to bottom right. Give this strategy a name and abstract it as an iterator. Use OOP if you like. Then, you have the concept of doing something with each thing the iterator gives you. Give that thing a name and have it use your iterator. Added bonus: you can abort searching immediately after you find a match, not some time after.

Pseudo-code:

$iterator = new MatrixRippleIterator($matrix);
$needle = 1337;
$found_match = false;
while ($iterator->hasNext()) {
    $current = $iterator->next();
    if ($current == $needle) {
        $found_match = true;
        break;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文