Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP数组-独立的相同值_Php_Arrays_Algorithm_Sorting - Fatal编程技术网

PHP数组-独立的相同值

PHP数组-独立的相同值,php,arrays,algorithm,sorting,Php,Arrays,Algorithm,Sorting,有什么好的或标准的方法可以做到这一点吗 以以下为例: $values = array( 'blue' , 'blue' , 'blue' , 'blue' , 'green' , 'red' , 'yellow' , 'yellow' , 'purple' , 'purple' , 'purple' ); 我需要将它分开,这样就不会有两个相同的值相接触(除非没有可能的解决方案——在这种情况下,要么

有什么好的或标准的方法可以做到这一点吗

以以下为例:

$values = array(
    'blue'
    , 'blue'    
    , 'blue'
    , 'blue'
    , 'green'
    , 'red'
    , 'yellow'
    , 'yellow'
     , 'purple'
    , 'purple'
    , 'purple'
);
我需要将它分开,这样就不会有两个相同的值相接触(除非没有可能的解决方案——在这种情况下,要么生成错误,要么返回false,或者其他任何东西都是可以接受的)

下面是上面的数组(手工完成),但我是如何尝试更改它的:

$values = array(
    'blue'
    , 'purple'
    , 'green'
    , 'purple'
    , 'blue'
    , 'red'
    , 'blue'
    , 'yellow'
    , 'blue'
    , 'yellow'
    , 'purple'
)
这些值在一开始并不一定是有序的——这只是为了简单起见


有什么想法吗?有什么代码可以让我从正确的方向开始吗?

沿着数组走,记住你看到的最后一个值,如果它匹配,就扔掉你看到的值:

这导致:

Array
(
    [0] => blue
    [1] => green
    [2] => red
    [3] => yellow
    [4] => purple
    [5] => blue
    [6] => yellow
    [7] => purple
    [8] => blue
    [9] => purple
    [10] => blue
)
逻辑上:


打印第一个值,在打印下一个值之前,将其与上一个值进行比较,如果它们相同,则跳过下一个值,依此类推。

此函数应执行以下操作:

function uniq_sort($arr){
    if(!count($arr))
        return array();

    $counts = array_count_values($arr);
    arsort($counts);
    while(NULL !== ($key = key($counts)) && $counts[$key]){
        if(isset($prev) && $prev == $key){
            next($counts);
            $key = key($counts);
            if($key === NULL)
                return false;
        }
        $prev = $result[] = $key;

        $counts[$key]--;
        if(!$counts[$key])
            unset($counts[$key]);

        arsort($counts);
        reset($counts);
    }
    return $result;
}
用法示例:

$values = array('blue', 'blue', 'blue', 'blue', 'green', 'red', 'yellow', 'yellow', 'purple', 'purple', 'purple');
print_r(uniq_sort($values));

$values = array('a', 'b', 'b');
print_r(uniq_sort($values));

$values = array(1);
print_r(uniq_sort($values));

$values = array(1, 1, 1, 1, 2, 3, 4);
print_r(uniq_sort($values));

$values = array(1, 1, 1, 1, 2, 3);
var_dump(uniq_sort($values));
和输出:

Array
(
    [0] => blue
    [1] => purple
    [2] => blue
    [3] => yellow
    [4] => blue
    [5] => purple
    [6] => blue
    [7] => purple
    [8] => red
    [9] => yellow
    [10] => green
)
Array
(
    [0] => b
    [1] => a
    [2] => b
)
Array
(
    [0] => 1
)
Array
(
    [0] => 1
    [1] => 3
    [2] => 1
    [3] => 4
    [4] => 1
    [5] => 2
    [6] => 1
)
bool(false)

这将只输出唯一的值。我认为OP想要的是数组被“洗牌”,这样就不会有两个相同的值发生碰撞。换句话说,输出数组的大小应该与输入数组的大小相同。这实际上不起作用。它适用于示例输入数组,但不适用于许多其他数组。说
[1,1,1,2,3,4]
。解决方案可能是
[1,2,1,3,1,4,1]
,但您的代码返回的
[1,2,3,4,1,1,1]
不正确。ascii-lime正确。但是,我认为如果在计算计数后按值计数的降序排序,它应该可以正常工作。基本上,开始用具有最高值的元素填充结果数组count@mattedgod是的,应该有用。您还应该跟踪上一个添加的值,如果计数最高的值与上一个值相同,则使用计数第二高的值。如果您遇到只剩下一个唯一元素的情况,并且它也是您的前一个元素,那么您将返回false。另外,请注意:我认为,只要一个元素的值不超过(n+1)/2,就总会有一个有效的解决方案occurrences@Ascii-莱姆--你能展示一下更新后的代码吗?我实际上是想让它在多维数组中工作,一个关联数组,如果它们中的三个最终像上面的例子一样是相同的,它会跳转到下一个值,['a','b','b']会发生什么?我不认为这对你有用that@KleberS但是
['b','a','b']
是该列表的有效解决方案,并且您的算法返回false。这个(最有可能是家庭作业)问题的关键是,你需要先按最频繁的元素进行排序。@Kerry Haha我是在开硬件的玩笑,如果是一个没有代表性的人问这个问题,我会更加怀疑。这让我想起了大学里那些“有趣”的算法问题。尽管如此,我认为wecsam的排序加法答案是最好的bet@Kerry没问题,我收回了我在原始版本中说过的话,即可以通过从循环中删除
arsort
来优化它。事实证明,在一个PHP数组中交换两个键/值对的位置非常困难,解决方案可能比调用
arsort
Great要慢——对我来说很好,这是我在今天之前从未想过需要的函数之一。我觉得所使用的方法(总是先选择最高频率)可以保证找到解决方案(如果存在解决方案)。
$values = array('blue', 'blue', 'blue', 'blue', 'green', 'red', 'yellow', 'yellow', 'purple', 'purple', 'purple');
print_r(uniq_sort($values));

$values = array('a', 'b', 'b');
print_r(uniq_sort($values));

$values = array(1);
print_r(uniq_sort($values));

$values = array(1, 1, 1, 1, 2, 3, 4);
print_r(uniq_sort($values));

$values = array(1, 1, 1, 1, 2, 3);
var_dump(uniq_sort($values));
Array
(
    [0] => blue
    [1] => purple
    [2] => blue
    [3] => yellow
    [4] => blue
    [5] => purple
    [6] => blue
    [7] => purple
    [8] => red
    [9] => yellow
    [10] => green
)
Array
(
    [0] => b
    [1] => a
    [2] => b
)
Array
(
    [0] => 1
)
Array
(
    [0] => 1
    [1] => 3
    [2] => 1
    [3] => 4
    [4] => 1
    [5] => 2
    [6] => 1
)
bool(false)