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

Posted

技术标签:

【中文标题】PHP在连字符数字数组中查找缺失的数字【英文标题】:PHP find missing numbers in array of hyphenated numbers 【发布时间】:2014-04-19 17:56:33 【问题描述】:

我有一个数字数组,这些数字有时带有连字符,例如软件版本号。我想做的是回显“失踪!”或在缺少数字时运行特定函数。

例如:

$numbers = array('1', '2', '3', '5', '6', '8');

打印:

1
2
3
Missing!
5
6
Missing!
8

我遇到了连字符的问题。

例如:

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

打印:

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-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:当然 :-) 欢迎使用伪代码解释此类构建块和策略。 【参考方案1】:

只是部分答案。

另外,我的代码似乎非常长/做了太多的事情——在我看来——应该是一项简单的任务。

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

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

【讨论】:

已修复。 explode 现在只调用了两次,一次用于当前号码,一次用于前一个号码。【参考方案2】:

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

    增加最后一个值,例如"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";

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

【讨论】:

我认为有几个更有效的转换。但是,是的,这是一个很好的策略。

以上是关于PHP在连字符数字数组中查找缺失的数字的主要内容,如果未能解决你的问题,请参考以下文章

在分布式阵列系统中查找缺失的数字

在未排序的数组 1 到 100 中查找 2 个缺失的数字。(Java)[重复]

剑指offer-面试题53_2-0~n-1中缺失的数字-二分查找

剑指Offer面试题53 - II. 0~n-1中缺失的数字

每日一题 - 剑指 Offer 53 - II. 0~n-1中缺失的数字

在线性时间和恒定空间中查找数组中缺失和重复的元素