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

PHP在连字符数字数组中查找缺少的数字,php,arrays,algorithm,numbers,Php,Arrays,Algorithm,Numbers,我有一个数字数组,这些数字有时连字符,即软件版本号。我要做的是回显“Missing!”或者在缺少一个数字时运行一个特定的函数 例如: $numbers = array('1', '2', '3', '5', '6', '8'); $numbers = array('1', '1-1', '1-3', '3-1-1', '3-1-3'); 印刷品: 1 2 3 Missing! 5 6 Missing! 8 1 1-1 Missing! 1-3 Missing! 3-1-1 Missing!

我有一个数字数组,这些数字有时连字符,即软件版本号。我要做的是回显“Missing!”或者在缺少一个数字时运行一个特定的函数

例如:

$numbers = array('1', '2', '3', '5', '6', '8');
$numbers = array('1', '1-1', '1-3', '3-1-1', '3-1-3');
印刷品:

1
2
3
Missing!
5
6
Missing!
8
1
1-1
Missing!
1-3
Missing!
3-1-1
Missing!
3-1-3
我遇到了连字符的问题

例如:

$numbers = array('1', '2', '3', '5', '6', '8');
$numbers = array('1', '1-1', '1-3', '3-1-1', '3-1-3');
印刷品:

1
2
3
Missing!
5
6
Missing!
8
1
1-1
Missing!
1-3
Missing!
3-1-1
Missing!
3-1-3
加上我的代码似乎太长了/做了太多的事情——在我看来——应该是一项简单的任务。对于这类事情有什么方法或算法吗

这是我的密码:

<?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;
    }

?>

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

  • 增加最后一个值,例如,
    “1”
    变为
    “2”
    “1-1”
    变为
    “1-2”
  • 添加新的子值,例如,
    “1”
    变为
    “1-1”
    “1-1”
    变为
    “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";
    }
    
    这不是一种算法,而是一种启发式算法;它尽最大努力做你想做的事,但没有正式的证据证明它有效。

    只有部分答案

    加上我的代码似乎太长了/做了太多的事情——在我看来——应该是一项简单的任务

    正确的观察。如果它做的事情太多,试着把任务分成几部分。模块化


    例如:我在代码中看到6个
    explode
    调用。您一直在努力将输入转换为可用的数据格式。进行预处理阶段,使用
    分解一次将字符串转换为数组,然后处理该数据格式。

    连字符数字的预期输出是什么?或者您确实在尝试改进现有代码?如果列表以
    1-3-5-7
    开头,然后是
    1-4
    ,该怎么办。。是否有遗漏?显然,没有“遗漏连字符数字”的算法。有共同的构建块和策略。你必须想一想它们是如何有用的,并以一种解决问题的方式组合在一起。杰克:是的“1”应该被认为是缺失的,还有“1-1”、“1-2”、“1-3-1”、“1-3-2”、“1-3-3”、“1-3-4”、“1-3-5-1”、“1-3-5-2”、“1-3-5-3”、“1-3-5-4”、“1-3-5-5”和“1-3-5-6”。Karoly Horvath:当然:-)解释这种构建块和策略的伪代码是受欢迎的。我认为有几个更有效的转换。但是是的,这是一个很好的策略<代码>分解
    现在只调用两次,一次用于当前号码,另一次用于上一个号码。