Eine PHP-Interviewfrage, werfen wir einen Blick darauf

WBOY
Freigeben: 2023-03-03 08:58:02
Original
1037 Leute haben es durchsucht

<code class="php">$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],
    ...
];</code>
Nach dem Login kopieren
Nach dem Login kopieren

Definieren Sie eine Funktion, übergeben Sie $listData
Wenn die Elemente in 111 mit den Elementen in 222/333/444... dupliziert werden, geben Sie false zurück
Wenn die Elemente in 222, If die Elemente in 111/333/444... werden dupliziert, geben Sie false zurück
Wenn die Elemente in 333 mit den Elementen in 111/222/444... dupliziert werden, geben Sie false zurück
wenn ..

Erlauben Sie die Wiederholung der Elemente in 111/222/333/444 und geben Sie true zurück.
Gib in anderen Fällen true zurück.


Bekannt:
Die Länge von $listData ist unbekannt.
Die Länge von 111/222/333/444... ist unbekannt.
Die Elemente in 111/222/333/444. ..sind Zeichen, Zeichenfolgen und Zahlen



Ich habe es selbst implementiert und es kommt mir so vor, als ob der Algorithmus schrecklich ist.

<code class="php">function test ($array) {

    $tempValueList  = [];
    foreach ($array as $key => $valueList) {
        
        foreach ($valueList as $value) {
            
            $tempValueList[]    = $key . '~' . $value;
        }
    }
    $result         = true;
    foreach ($array as $key => $valueList) {
        
        foreach ($valueList as $value) {
            
            foreach ($tempValueList as $_value) {
                
                $pos    = strpos($_value, '~');
                $_key   = substr($_value, 0, $pos);
                $_val   = substr($_value, $pos + 1);

                if ($key == $_key) {

                    continue;
                }
                if ($_val == $value) {

                    $result = false;
                    break 3;
                }
            }
        }
    }

    return      $result;
}</code>
Nach dem Login kopieren
Nach dem Login kopieren

Antwortinhalt:

<code class="php">$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],
    ...
];</code>
Nach dem Login kopieren
Nach dem Login kopieren

Definieren Sie eine Funktion, übergeben Sie $listData
Wenn die Elemente in 111 mit den Elementen in 222/333/444... dupliziert werden, geben Sie false zurück
Wenn die Elemente in 222, If die Elemente in 111/333/444... werden dupliziert, geben Sie false zurück
Wenn die Elemente in 333 mit den Elementen in 111/222/444... dupliziert werden, geben Sie false zurück
wenn ..

Erlauben Sie die Wiederholung der Elemente in 111/222/333/444 und geben Sie true zurück.
Gib in anderen Fällen true zurück.


Bekannt:
Die Länge von $listData ist unbekannt.
Die Länge von 111/222/333/444... ist unbekannt.
Die Elemente in 111/222/333/444. ..sind Zeichen, Zeichenfolgen und Zahlen



Ich habe es selbst implementiert und es kommt mir so vor, als ob der Algorithmus schrecklich ist.

<code class="php">function test ($array) {

    $tempValueList  = [];
    foreach ($array as $key => $valueList) {
        
        foreach ($valueList as $value) {
            
            $tempValueList[]    = $key . '~' . $value;
        }
    }
    $result         = true;
    foreach ($array as $key => $valueList) {
        
        foreach ($valueList as $value) {
            
            foreach ($tempValueList as $_value) {
                
                $pos    = strpos($_value, '~');
                $_key   = substr($_value, 0, $pos);
                $_val   = substr($_value, $pos + 1);

                if ($key == $_key) {

                    continue;
                }
                if ($_val == $value) {

                    $result = false;
                    break 3;
                }
            }
        }
    }

    return      $result;
}</code>
Nach dem Login kopieren
Nach dem Login kopieren

Nach Durchsicht sind die beiden vorherigen Antworten unbrauchbar. LZ ist wirklich unglücklich. .

Meine Definition von Subarray ist ein einzelnes Array wie ['a', 'b', 'c', 'a'].

Meine Antwort:

<code>$result = array();
foreach ($listData as $line) {
    //子数组内部去重,再组装回原来的格式
    $result[] = array_unique($line);
}

//子数组先去重再合并的结果数量 和 先合并子数组再去重的结果数量 做比较。
//如果是相同的,意味着不存在跨子数组的重复,只存在子数组内部重复,所以`True`
var_dump(count(array_merge(...$result)) === count(array_unique(array_merge(...$listData))));</code>
Nach dem Login kopieren

Meine Antwort ruft Systemfunktionen häufiger auf und sieht einfacher aus. Allerdings haben viele Funktionen wie PHP array_xxx keine Leistungsvorteile. Wenn diese Funktionen nicht verwendet werden, kann die Betriebseffizienz relativ verbessert werden.

Derzeit ist @springhack am effizientesten. Und es kann in jeder Situation maximale Effizienz aufrechterhalten.

Leicht verständliche Zusatzreferenzinformationen:

Originaldaten:

<code>$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j']
];
</code>
Nach dem Login kopieren

Dann sieht $result so aus:

<code>$listData = [
        '111' => ['a', 'b', 'c'],
        '222' => ['d', 'e', 'f', 'b'],
        '333' => ['g', 'h'],
        '444' => ['i', 'j']
];
</code>
Nach dem Login kopieren

Das Ergebnis der Sub-Array-Deduplizierung und anschließenden Zusammenführung

<code>Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
    [6] => b
    [7] => g
    [8] => h
    [9] => i
    [10] => j
)
</code>
Nach dem Login kopieren

Wird verwendet, um die Menge (Anzahl der Array-Elemente) mit den oben genannten zu vergleichen, das sogenannte „Ergebnis der ersten Zusammenführung von Unterarrays und der anschließenden Deduplizierung“:

<code>Array
(
    [0] => a
    [1] => b
    [2] => c
    [4] => d
    [5] => e
    [6] => f
    [9] => g
    [10] => h
    [11] => i
    [12] => j
)</code>
Nach dem Login kopieren

Schleifen Sie einmal eine Schleife und finden Sie den Schnittpunkt des aktuellen Elements und aller anderen Elemente. Der Code lautet wie folgt:

<code>    function isExistsInOther($data)
    {
        $temp = [];
        $isExists = true;
        foreach ($data as $key=>$value) {
            $temp = $data;
            unset($temp[$key]);
            if(!$isExists) break;
            @array_walk($temp,function($v,$k) use($value,&$isExists){
                if($isExists) {
                    $intersect = array_intersect($v,$value);
                    if(!empty($intersect)) {
                        $isExists = false;
                    }
                }
            });
        }
        return $isExists;
    }
    
    $listData = [
        '111' => ['a', 'k', 'c', 'a'],
        '222' => ['d', 'e', 'f', 'f', 'b'],
        '333' => ['g', 'e'],
        '444' => ['i', 'j']
    ];
    $result = isExistsInOther($listData);
    var_dump($result);
    //true  无交集
    //false 有交集</code>
Nach dem Login kopieren

<code>/**
 * [checkRepeat 检查每个key的数组值是否与其它的有重复值]
 * @param  [type] $listData [检查的数组]
 * @return [type]           [array]
 */
function checkRepeat($listData) {
    foreach($listData as $key =>$val) {
        $check_arr = $listData;
        // 删除当前key
        unset($check_arr[$key]);
        // 合并删除后的数组
        $check_arr = array_merge(...$check_arr);
        // 判断是否存在交集
        $rs[$key] = count(array_intersect($val, $check_arr)) > 0 ? false : true ;
    }
    return $rs;
}

$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],

];
$rs = checkRepeat($listData);</code>
Nach dem Login kopieren

<code>function check($arr)
{
  $chk = [];
  foreach ($arr as $k => $v)
    foreach ($v as $i)
    {
      if (isset($chk[$i] && $chk[$i] != $k)
        return false;
      $chk[$i] = $k;
    }
  return true;
}</code>
Nach dem Login kopieren

Das Codewort der Klauenmaschine sollte am effizientesten sein, sodass Sie es selbst debuggen können.

Da die Antworten oben gegeben wurden, möchte ich Ihnen die mehrdimensionale Array-Deduplizierung hinzufügen

<code>/**
 * 多维数组去重
 * @param array 
 * @return array
 */
function super_unique($array)
{
    $result = array_map("unserialize", array_unique(array_map("serialize", $array)));

    foreach ($result as $key => $value)
    {
        if ( is_array($value) ) {
            $result[$key] = super_unique($value);
        }
    }

    return $result;
}</code>
Nach dem Login kopieren

Mehrdimensionale Array-Deduplizierung

<code>$listData = array_values($listData);
foreach ($listData as $k => $v) {
    foreach ($listData as $n => $m) {
        if($k == $n) continue;
        if(array_intersect($v , $m)){
            echo $k.$n.'false <br>';
        }
        else{
            echo $k.$n.'true <br>';
        }
    }
}</code>
Nach dem Login kopieren

Meine Antwort (Prinzip: Schleife zum Finden von Schnittpunkten):

<code><?php
$list = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f','b'],
    '333' => ['g', 'h','c'],
    '444' => ['i', 'j']
];
function jiaoji($array){
    $listData = array_values($array);
    $list = [];
    for ($i = 0; $i < count($listData); $i++) {
        for ($j = $i+1; $j < count($listData); $j++) {
            $list[] = array_intersect($listData[$i],$listData[$j]);
        }
    }
    $result = array_filter($list);
    return count($result)==0;
}
var_dump(jiaoji($list));//bool(false)
?></code>
Nach dem Login kopieren

Können Sie das so verstehen? Solange sich die Werte in diesem Array überschneiden, wird false zurückgegeben. . .
Die Funktion array_intersect() scheint zu funktionieren. Das Problem besteht jedoch darin, die Werte in einem Array in ein kleines Array umzuwandeln, um Werte zu übergeben.

<code><?php
$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],
    ...
];

function getArr($listData){
    $isUnsetFirstKey = false;
    $len = count($listData);
    if($len<=1) return false;
    $firstKey = key($listData);
    $firstArr = array_unique($listData[$firstKey]);
    $newList = $listData;
    unset($newList[$firstKey]);
    foreach ($newList as $key => $val) {
        $arr = array_unique($val);
        $newarr = array_merge($firstArr,$arr);
        if(count($newarr) != count(array_unique($newarr))){
            $isUnsetFirstKey = true;
            unset($newList[$key]);
            echo $key . "<br>";
        }
    }
    if($isUnsetFirstKey) echo $firstKey . "<br>";
    getArr($newList);
}

getArr($listData);
?></code>
Nach dem Login kopieren

Schauen Sie sich meine Antwort an, sie ist erstaunlich

Eindimensionale Arrays ähneln zweidimensionalen Arrays. Die folgende Methode wird für zweidimensionale Arrays übersprungen.
Vergleichen Sie die Array-Länge davor und danach das Array wird zusammengeführt (dann wird es eindeutig angenommen)

<code class="php">function check_repeat($arr){
    $after_arr = [];
    // 对比自身
    foreach($arr as $index => $value){
        $arr[$index] = $after_arr = array_unique($value);
        if(count($value) !== count($after_arr)){
            return true;
        }
    }
    // 对比其他
    $temp = array_shift($arr);
    $cnt  = count($temp);
    foreach ($arr as $index => $value) {
        $cnt += count($value);
        $temp = array_merge($temp, $value);
    }

    return $cnt !== count(array_unique($temp)) ? true : false;
}

$listData = [
    '111' => ['a', 'b', 'c',],
    '222' => ['d', 'e', 'f',],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],
];

var_dump(check_repeat($listData));
</code>
Nach dem Login kopieren

<code>function test($listData) {
    $result = array_map('array_unique', $listData);
    foreach ($result as $key => $value) {
        $keys = array_values(array_diff(array_keys($result),[$key]));
        for($i = 0; $i <= count($keys); $i ++) {
            $data = array_merge_recursive($data,$result[$keys[$i]]);
            if ($i == (count($keys) -1) ) {
                $res = array_intersect($value, $data);
            }
        }
        $data = [];
    }
    return !empty($res) === true ? false : true;
}</code>
Nach dem Login kopieren

<code><?php

$listData = [
    '111' => ['a', 'b', 'c', 'a'],
    '222' => ['d', 'e', 'f', 'f', 'b'],
    '333' => ['g', 'h'],
    '444' => ['i', 'j'],
];

$temp = array();
foreach ($listData as $key => $xxx) {
    foreach ($xxx as $value) {
        if (in_array($value, $temp)) {
            echo $value.' from '.$key.' is in array';
            exit();
        }
    }
    $temp = array_merge($temp, $xxx);
}
echo 'You should get a True!';
</code>
Nach dem Login kopieren

没几行,满足需求。

Eine PHP-Interviewfrage, werfen wir einen Blick darauf

还原之前那个
shiji 的答案

先array_pop,取出最后一项。再取items数组的并集。if并集与最后一项有交集则返回true(表重复)。循环执行。

根据 @大呜 的算法改良了一下。

<code>function checkRepeat2($listData)
{
    $check_arr = $listData;
    foreach ($listData as $key => $val) {
        //之前比较过的key无需再比较
        unset($check_arr[$key]);
        if ($check_arr) {
            // 合并删除后的数组,判断是否存在交集
            //As PHP 5.6 you can use array_merge + "splat" operator to reduce a bidimensonal array to a simple array:
            if (array_intersect($val, array_merge(...$check_arr))) {
                return false;
            }
        }
    }
    return true;
}</code>
Nach dem Login kopieren

不知道是不是这样:

<code>$new_arr = [];
foreach ($listData as $key => $value) {
    foreach ($value as $k => $v) {
        $kv = $k . $v;
        if (in_array($kv, $new_arr)) {
            echo '有重复';exit;
        } else {
            $new_arr[] = $kv;
        }
    }
}</code>
Nach dem Login kopieren
Verwandte Etiketten:
php
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage