PHP 在带连字符的数字数组中查找缺失的数字

Cof*_*ker 5 php arrays algorithm numbers

我有一个数字数组,这些数字有时用连字符连接起来,就像软件版本号一样。我想要做的是回声“失踪!” 或在缺少数字时运行特定功能。

例如:

$numbers = array('1', '2', '3', '5', '6', '8');
Run Code Online (Sandbox Code Playgroud)

印刷:

1
2
3
Missing!
5
6
Missing!
8
Run Code Online (Sandbox Code Playgroud)

我遇到了连字符的问题。

例如:

$numbers = array('1', '1-1', '1-3', '3-1-1', '3-1-3');
Run Code Online (Sandbox Code Playgroud)

印刷:

1
1-1
Missing!
1-3
Missing!
3-1-1
Missing!
3-1-3
Run Code Online (Sandbox Code Playgroud)

另外,我的代码看起来很长/做了太多的事情——在我看来——应该是一个简单的任务。有这种事情的方法或算法吗?

这是我的代码:

<?php

    $numbers = array(
        '1',
        '1-1',
        '1-3',
        '3-1-1',
        '3-1-3'
    );

    foreach ($numbers as $number) {
        if (isset($prev_number)) {
            $curr_number = explode('-', $number);
            $prev_levels = explode('-', $prev_number);

            if (preg_match('/-/', $number) and !preg_match('/-/', $prev_number)) {
                if (current() - $prev_levels[0] >= 1) {
                    echo 'Missing!<br>' . PHP_EOL;
                }
            }

            for ($missing = 1; ((count($curr_number) - count($prev_levels)) - $missing) >= 1; $missing++) {
                echo 'Missing!<br>' . PHP_EOL;
            }

            foreach ($curr_number as $hyphen => $part) {
                for ($missing = 1; ($part - $missing) - $prev_levels[$hyphen] >= 1; $missing++) {
                    echo 'Missing!<br>' . PHP_EOL;
                }
            }
        } else {
            if ($number != '1') {
                echo 'Missing!<br>' . PHP_EOL;

                foreach ($curr_number as $part) {
                    for ($missing = 1; $part > $missing; $missing++) {
                        echo 'Missing!<br>' . PHP_EOL;
                    }
                }
            }
        }

        echo $number . '<br>' . PHP_EOL;

        $prev_number = $number;
    }

?>
Run Code Online (Sandbox Code Playgroud)

Ja͢*_*͢ck 0

您可以迭代列表,并且对于每一对,您尝试通过对第一对应用转换来到达第二对:

  1. 增加最后一个值,例如"1"变成"2""1-1"成为"1-2"
  2. 添加一个新的子值,例如"1"become"1-1""1-1"becomes "1-1-1"

#1 可以通过从右向左增加来扩展。

如果没有一个转换匹配,则该数字被视为丢失。在代码中:

$numbers = array('1', '1-1', '1-2', '1-3', '3-1-1', '3-1-3');

$first = array_shift($numbers);
echo "$first\n";

while (($second = array_shift($numbers)) !== null) {
    if (find_next($first, $second) === false) {
        echo "Missing\n";
    }
    echo "$second\n";
    $first = $second;
}

// attempt to transform between current and next
function find_next($current, $next)
{
    if (increment_last($current) == $next) {
        return $next; // first transformation worked
    } elseif (add_suffix($current) == $next) {
        return $next; // second transformation worked
    }
    return false; // nothing worked
}

// transformation 1
function increment_last($value)
{
    if (($pos = strpos($value, '-')) !== false) {
        $last = substr($value, $pos + 1) + 1;
        return substr_replace($value, $last, $pos + 1, strlen($last));
    } else {
        return $value + 1;
    }
}

// transformation 2
function add_suffix($value)
{
    return "$value-1";
}
Run Code Online (Sandbox Code Playgroud)

这不是一种算法,而是一种启发式方法;它尽最大努力做你想做的事,但没有正式的证据表明它有效。