A php interview question. let's take a look.

Source: Internet
Author: User
{Code ...} define a function and input $ listData if the elements in 111, and 222333444... if the elements in 222 are repeated, false is returned... if the elements in 333 are repeated, false is returned...
$listData = [    '111' => ['a', 'b', 'c', 'a'],    '222' => ['d', 'e', 'f', 'f', 'b'],    '333' => ['g', 'h'],    '444' => ['i', 'j'],    ...];

Define a function and input $ listData
If111The elements in it are the same as those in 222/333/444..., and false is returned.
If222The elements in it are the same as those in 111/333/444..., and false is returned.
If333The elements in it are the same as those in 111/222/444..., and false is returned.
If...

Allow repeated elements in 111/222/333/444 and return true
Returns true in other cases.

Known:
$ Unknown listData length
The length of 111/222/333/444... is unknown.
The elements in 111/222/333/444... are strings and numbers.

I implemented it myself and felt that the algorithm was very bad. Is there any other way?

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

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

Define a function and input $ listData
If111The elements in it are the same as those in 222/333/444..., and false is returned.
If222The elements in it are the same as those in 111/333/444..., and false is returned.
If333The elements in it are the same as those in 111/222/444..., and false is returned.
If...

Allow repeated elements in 111/222/333/444 and return true
Returns true in other cases.

Known:
$ Unknown listData length
The length of 111/222/333/444... is unknown.
The elements in 111/222/333/444... are strings and numbers.

I implemented it myself and felt that the algorithm was very bad. Is there any other way?

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

Look, the two answers are useless. LZ is really hard ..

The sub-array is defined as a single array like ['A', 'B', 'C', 'A.

My answer:

$ Result = array (); foreach ($ listData as $ line) {// deduplication inside the subarray, then assemble it back to the original format $ result [] = array_unique ($ line );} // compare the number of results that the sub-array first duplicates and then merges the sub-array first and then duplicates. // If it is the same, it means that there are no duplicates across sub-arrays. only the sub-arrays are repeated internally, so 'true' var _ dump (count (array_merge (... $ result) = count (array_unique (array_merge (... $ listData ))));

My answer is that the number of calls to system functions is relatively large, and it looks Concise. However, a large part of PHP array_xxx functions do not have an advantage in performance. if these functions are not used, it can improve the running efficiency relatively.

Currently, @ springhack has the highest efficiency. In addition, the highest efficiency can be maintained in various situations.

Auxiliary reference information for easy understanding:

Raw data:

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

Then $ result is like this:

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

Result of re-merging the sub-array first

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

It is used to compare with the number (number of array elements) above. The so-called "first merge sub-arrays and then duplicate results ":

Array(    [0] => a    [1] => b    [2] => c    [4] => d    [5] => e    [6] => f    [9] => g    [10] => h    [11] => i    [12] => j)

Loop once. the current element and all other elements are intersection. the code is as follows:

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 = ['20140901' => ['A', 'K ', 'C', 'A'], '000000' => ['D', 'e', 'F', 'F', 'B'], '000000' => ['G', 'E'], '000000' => ['I', 'J']; $ result = isExistsInOther ($ listData ); var_dump ($ result); // true without intersection // false with intersection

/*** [CheckRepeat: Check whether the array value of each key has a duplicate value with other values] * @ param [type] $ listData [checked array] * @ return [type] [array] */function checkRepeat ($ listData) {foreach ($ listData as $ key => $ val) {$ check_arr = $ listData; // delete the current key unset ($ check_arr [$ key]); // Merge the deleted array $ check_arr = array_merge (... $ check_arr); // determines whether an intersection exists. $ rs [$ key] = count (array_intersect ($ val, $ check_arr)> 0? False: true;} return $ rs;} $ listData = ['000000' => ['A', 'B', 'C', 'A'], '000000' => ['D', 'e', 'F', 'F', 'B'], '000000' => ['G ', 'H'], '000000' => ['I', 'J'],]; $ rs = checkRepeat ($ listData );

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

The claw machine code word should be the most efficient and can be debugged by yourself.

Since the answers are given above, I will add to you that multi-dimensional array deduplication

/*** Multi-dimensional array deduplication * @ 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 ;}

Multi-dimensional array deduplication

$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 
'; } else{ echo $k.$n.'true
'; } }}

My answer (principle: cyclic intersection ):


   ['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)?>

Can you understand this way? if there is an intersection of values in the array, false is returned...
The array_intersect () function seems to be usable. But the problem is that the value in an array is converted into a small array to pass the value.


   ['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 . "
"; } } if($isUnsetFirstKey) echo $firstKey . "
"; getArr($newList);}getArr($listData);?>
Let's take a look at my answer. it's amazing.

A one-dimensional array is similar to a two-dimensional array. The following is a two-dimensional array method.
Compare the length of the array before and after array merging (then unique)

Function check_repeat ($ arr) {$ after_arr = []; // compare your foreach ($ arr as $ index => $ value) {$ arr [$ index] = $ after_arr = array_unique ($ value); if (count ($ value )! = Count ($ after_arr) {return true ;}// compare with others $ 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 = ['20160301' => ['A', 'B', 'C',], '20160301' => ['D ', 'E', 'F',], '000000' => ['G', 'H'], '000000' => ['I ', 'j'],]; var_dump (check_repeat ($ listData ));

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


   ['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!';

Few lines to meet your needs.

The
Shiji's answer

First, array_pop to get the last item. And then the union of the items array. If the Union and the last one have an intersection, true is returned (the table is repeated ). Loop execution.

I improved it according to the @ da algorithm.

Function checkRepeat2 ($ listData) {$ check_arr = $ listData; foreach ($ listData as $ key => $ val) {// The previously compared key does not need to be compared with unset ($ check_arr [$ key]); if ($ check_arr) {// merges the deleted array, determine whether there is an intersection // 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 ;}

I don't know if it is like this:

$ New_arr = []; foreach ($ listData as $ key => $ value) {foreach ($ value as $ k = >$ v) {$ kv = $ k. $ v; if (in_array ($ kv, $ new_arr) {echo 'repeated '; exit;} else {$ new_arr [] = $ kv ;}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.