查找唯一排列的性能提示

时间:2017-11-13 09:50:39

标签: php arrays performance sorting

TLDR: how to find multidimensional array permutation in php以及如何优化更大的数组?

这是这个问题的延续: how to find multidimensional array permutation in php

我们有用于排序数组的脚本,想法是找到数组的唯一排列,找到这个排列的规则是:

  
      
  1. 输入数组包含一组数组。
  2.   
  3. 每个内部数组都包含唯一元素。
  4.   
  5. 每个内部数组可能有不同的长度和不同的值。
  6.   
  7. 输出数组必须包含完全相同的值。
  8.   
  9. 输出内部数组必须在同一个键上具有唯一值。
  10.   
  11. 如果没有解决方案,则允许使用通配符string ChaineDeSelction = "SELECT fir_mdnt FROM -- WHERE fir_aktiv = 1 AND EXISTS(select firbpv_fir from --)"; OdbcConnection MyConnec = new OdbcConnection(MyConnString); MyConnec.Open(); OdbcCommand MyComm = new OdbcCommand(ChaineDeSelction, MyConnec); DataTable.Load(MyComm.ExecuteReader()); _cb_Societe.DataSource = DataTable; <--- I tried this way the the foreach .Add way but both return the same. foreach(DataRow Ligne in DataTable.Rows) { _cb_Societe.Items.Add(Ligne); }
  12.   
  13. 可以在同一个密钥上复制通配符。
  14.   
  15. 解决方案应该包含尽可能少的通配符。
  16.   
  17. 算法应该能够在不到180秒的时间内处理 30x30 的阵列。
  18.   

到目前为止我有这个解决方案:

ie.: null

这适用于小数组,但麻烦的是迭代所有可能的数组移动,对于像6x6这样的数组,这太多了,无法计算 - function matrix_is_solved(array $matrix) { foreach (array_keys(current($matrix)) as $offset) { $column = array_filter($raw = array_column($matrix, $offset)); if (count($column) != count(array_unique($column))) return false; } return true; } function matrix_generate_vectors(array $matrix) { $vectors = []; $columns = count(current($matrix)); $gen = function ($depth=0, $combo='') use (&$gen, &$vectors, $columns) { if ($depth < $columns) for ($i = 0; $i < $columns; $i++) $gen($depth + 1, $i . $combo); else $vectors[] = array_map('intval', str_split($combo)); }; $gen(); return $vectors; } function matrix_rotate(array $matrix, array $vector) { foreach ($matrix as $row => &$values) { array_rotate($values, $vector[$row]); } return $matrix; } function matrix_brute_solve(array $matrix) { matrix_make_square($matrix); foreach (matrix_generate_vectors($matrix) as $vector) { $attempt = matrix_rotate($matrix, $vector); if (matrix_is_solved($attempt)) return matrix_display($attempt); } echo 'No solution'; } function array_rotate(array &$array, $offset) { foreach (array_slice($array, 0, $offset) as $key => $val) { unset($array[$key]); $array[$key] = $val; } $array = array_values($array); } function matrix_display(array $matrix = null) { echo "[\n"; foreach ($matrix as $row => $inner) { echo " $row => ['" . implode("', '", $inner) . "']\n"; } echo "]\n"; } function matrix_make_square(array &$matrix) { $pad = count(array_keys($matrix)); foreach ($matrix as &$row) $row = array_pad($row, $pad, ''); } $tests = [ [ ['X'], ['X'] ], [ ['X'], ['X'], ['X'] ], [ [ 'X', '' ], [ '', 'X' ] ], [ ['X', 'Y', 'Z'], ['X', 'Y'], ['X']], [ ['X', 'Y'], ['X', 'Y'], ['X', 'Y'] ] ]; array_map(function ($matrix) { matrix_display($matrix); echo "solved by:" . PHP_EOL; matrix_brute_solve($matrix); echo PHP_EOL; }, $tests); 时间 space!

4 个答案:

答案 0 :(得分:7)

实际上解决方案非常简单。您可以检查唯一字符的数量以及输出数组中值的数量。下面的代码几乎可以立即执行您想要的操作。

困难的部分是删除通配符。如果您想要100%确定性,那么您只能使用强力执行。下面的解决方案将尝试通过按顺序多次切换位置来删除所有通配符。

这类似于Google在其OR工具中处理Traveling Salesman Problem的方式。您需要找到准确性和速度之间的最佳组合。通过在下面的函数中设置更高的循环计数,成功的机会增加。但它会慢一些。

/* HELPERS */

function ShowNice($output) {
  //nice output:
  echo '<pre>';
  foreach($output as $key=>$val) {
    echo '<br />' . str_pad($key,2," ",STR_PAD_LEFT) . ' => [';
    $first = true;
    foreach($val as $char) {
      if (!$first) {
        echo ', ';
      }
      echo "'".$char."'";
      $first = false;
    }
    echo ']';
  }
  echo '</pre>';
}

function TestValid($output, $nullchar) {
  $keys = count($output[0]);
  for ($i=0;$i<$keys;$i++) {
    $found = [];
    foreach($output as $key=>$val) {
      $char = $val[$i];
      if ($char==$nullchar) {
        continue;
      }
      if (array_key_exists($char, $found)) {
        return false; //this char was found before
      }
      $found[$char] = true;
    }
  }

  return true;
}


$input = [
  0 => ['X', 'Y', 'Z', 'I', 'J'],
  1 => ['X', 'Y', 'Z', 'I'],
  2 => ['X', 'Y', 'Z', 'I'],
  3 => ['X', 'Y', 'Z', 'I'],
  4 => ['X', 'Y', 'Z'],
  5 => ['X', 'Y', 'Z']
];

//generate large table
$genLength = 30; //max double alphabet
$innerLength = $genLength;
$input2 = [];
for($i=0;$i<$genLength;$i++) {
  $inner = [];

  if (rand(0, 1)==1) {
    $innerLength--;
  }

  for($c=0;$c<$innerLength;$c++) {
    $ascii = 65 + $c; //upper case
    if ($ascii>90) {
      $ascii += 6; //lower case
    }
    $inner[] = chr($ascii);
  }
  $input2[] = $inner;
}


//generate large table with different keys
$genLength = 10; //max double alphabet
$innerLength = $genLength;
$input3 = [];
for($i=0;$i<$genLength;$i++) {
  $inner = [];

  if (rand(0, 1)==1) {
    //comment o make same length inner arrays, but perhaps more distinct values
    //$innerLength--;
  }

  $nr = 0;
  for($c=0;$c<$innerLength;$c++) {
    $ascii = 65 + $c + $nr; //upper case
    if ($ascii>90) {
      $ascii += 6; //lower case
    }
    //$inner[] = chr($ascii);
    $inner[] = $c+$nr+1;

    //increase nr?
    if (rand(0, 2)==1) {
      $nr++;
    }

  }
  $input3[] = $inner;
}


//generate table with numeric values, to show what happens
$genLength = 10; //max double alphabet
$innerLength = $genLength;
$input4 = [];
for($i=0;$i<$genLength;$i++) {
  $inner = [];

  for($c=0;$c<$innerLength;$c++) {
    $inner[] = $c+1;
  }
  $input4[] = $inner;
}


$input5 = [
  0 => ['X', 'Y'],
  1 => ['X', 'Y'],
  2 => ['X', 'Y'],
];

$input6 = [
  0 => ['X', 'Y', 'Z', 'I', 'J'],
  1 => ['X', 'Y', 'Z', 'I'],
  2 => ['X', 'Y', 'Z', 'I'],
  3 => ['X', 'Y', 'Z', 'I'],
  4 => ['X', 'Y', 'Z']
];

$input7 = [
  ['X', 'Y', 'A', 'B'],
  ['X', 'Y', 'A', 'C']
];

$input8 = [
  ['X', 'Y', 'A'],
  ['X', 'Y', 'B'],
  ['X', 'Y', 'C']
];

$input9 = [
  ['X', 'Z', 'Y', 'A', 'E', 'D'],
  ['X', 'Z', 'Y', 'A', 'B'],
  ['X', 'Z', 'Y', 'A', 'C'],
  ['X', 'Z', 'Y', 'A', 'D'],
  ['X', 'Z', 'Y', 'A', 'D'],
  ['X', 'Z', 'Y', 'A', 'D']
];

/* ACTUAL CODE */

CreateOutput($input, 1);

function CreateOutput($input, $loops=0) {


  echo '<h2>Input</h2>';
  ShowNice($input);


  //find all distinct chars
  //find maxlength for any inner array

  $distinct = [];
  $maxLength = 0;
  $minLength = -1;
  $rowCount = count($input);
  $flipped = [];
  $i = 1;
  foreach($input as $key=>$val) {
    if ($maxLength<count($val)) {
      $maxLength = count($val);
    }
    if ($minLength>count($val) || $minLength==-1) {
      $minLength = count($val);
    }
    foreach($val as $char) {
      if (!array_key_exists($char, $distinct)) {
        $distinct[$char] = $i;
        $i++;
      }
    }

    $flipped[$key] = array_flip($val);
  }

  //keep track of the count for actual chars
  $actualChars = $i-1;
  $nullchar = '_';
  //add null values to distinct
  if ($minLength!=$maxLength && count($distinct)>$maxLength) {
    $char = '#'.$i.'#';
    $distinct[$nullchar] = $i; //now it only gets add when a key is smaller, not if all are the same size
    $i++;
  }

  //if $distinct count is small then rowcount, we need more distinct
  $addForRowcount = (count($distinct)<$rowCount);
  while (count($distinct)<$rowCount) {
    $char = '#'.$i.'#';
    $distinct[$char] = $i;
    $i++;
  }


  //flip the distinct array to make the index the keys
  $distinct = array_flip($distinct);

  $keys = count($distinct);

  //create output
  $output = [];
  $start = 0;
  foreach($input as $key=>$val) {
    $inner = [];
    for ($i=1;$i<=$keys;$i++) {
      $index = $start + $i;
      if ($index>$keys) {
          $index -= $keys;
      }

      if ($index>$actualChars) {
        //just add the null char
        $inner[] = $nullchar;
      } else {
        $char = $distinct[$index];

        //check if the inner contains the char
        if (!array_key_exists($char, $flipped[$key])) {
          $char = $nullchar;
        }

        $inner[] = $char;
      }

    }
    $output[] = $inner;
    $start++;
  }

  echo '<h2>First output, unchecked</h2>';
  ShowNice($output);

  $newOutput = $output;
  for ($x=0;$x<=$loops;$x++) {
    $newOutput = MoveLeft($newOutput, $nullchar);
    $newOutput = MoveLeft($newOutput, $nullchar, true);
    $newOutput = SwitchChar($newOutput, $nullchar);
  }

  echo '<h2>New output</h2>';
  ShowNice($newOutput);
  //in $newoutput we moved all the invalid wildcards to the end
  //now we need to test if the last row has wildcards

  if (count($newOutput[0])<count($output[0])) {
    $output = $newOutput;
  }


  echo '<h2>Best result ('.(TestValid($output, $nullchar)?'VALID':'INVALID').')</h2>';
  ShowNice($output);

  return $output;
}

function MoveLeft($newOutput, $nullchar, $reverse=false) {
  //see if we can remove more wildcards
  $lastkey = count($newOutput[0])-1;
  $testing = true;
  while ($testing) {
    $testing = false; //we decide if we go another round ob_deflatehandler
    $test = $newOutput;

    $lastkey = count($newOutput[0])-1;

    $start = 0;
    $end = count($test);
    if ($reverse) {
      $start = count($test)-1;
      $end = -1;
    }

    for($key = $start;$key!=$end;$key += ($reverse?-1:1) ) {
      $val = $test[$key];
      $org = array_values($val);
      foreach($val as $i=>$char) {
        if ($char!=$nullchar) {
          continue; //we only test wildcards
        }


        $wildcardAtEnd=true;
        for($x=$i+1;$x<=$lastkey;$x++) {
          $nextChar = $val[$x];
          if ($nextChar!=$nullchar) {
            $wildcardAtEnd = false;
            break;
          }
        }


        if ($wildcardAtEnd===true) {
          continue; //the char next to it must not be wildcard
        }

        //remove the wildcard and add it to the base64_encode
        unset($val[$i]);
        $val[] = $nullchar;
        $test[$key] = array_values($val); //correct order

        if (TestValid($test, $nullchar)) {
          //we can keep the new one
          $newOutput = $test;
          $testing = true; //keep testing, but start over to make sure we dont miss anything
          break 2; //break both foreach, not while
        }

        $test[$key] = $org; //reset original values before remove for next test
      }
    }
  }

  $allWildCards = true;
  while ($allWildCards) {
    $lastkey = count($newOutput[0])-1;
    foreach($newOutput as $key=>$val) {
      if ($val[$lastkey]!=$nullchar)  {
        $allWildCards = false;
        break;
      }
    }
    if ($allWildCards) {
      foreach($newOutput as $key=>$val) {
        unset($val[$lastkey]);
        $newOutput[$key] = array_values($val);
      }
      $output = $newOutput;
    }
  }

  return $newOutput;
}

function SwitchChar($newOutput, $nullchar) {
  $switching = true;
  $switched = [];
  while($switching) {
    $switching = false;

    $test = $newOutput;
    $lastkey = count($newOutput[0])-1;

    foreach($test as $key=> $val) {
      foreach($val as $index=>$char) {
        $switched[$key][$index][$char] = true;//store the switches we make

        //see if can move the char somewhere else
        for($i=0;$i<=$lastkey;$i++)
        {
          if ($i==$index) {
            continue;//current pos
          }
          if (isset($switched[$key][$i][$char])) {
            continue; //been here before
          }

          $org = array_values($val);
          $switched[$key][$i][$char] = true;
          $t = $val[$i];
          $val[$index] = $t;
          $val[$i] = $char;
          $test[$key] = array_values($val);

          if (TestValid($test, $nullchar)) {
            //echo '<br />VALID: ' . $key . ' - ' . $index . ' - ' . $i . ' - ' . $t . ' - ' . $char;
            $newOutput = MoveLeft($test, $nullchar);
            $switching = true;
            break 3;//for and two foreach
          }

          //echo '<br />INVALID: ' . $key . ' - ' . $index . ' - ' . $i . ' - ' . $t . ' - ' . $char;
          $val = $org;
          $test[$key] = $org;
        }
      }
    }
  }

  return $newOutput;
}

结果:

Input

   0 => ['X', 'Y', 'A']
   1 => ['X', 'Y', 'B']
   2 => ['X', 'Y', 'C']

   First output, unchecked

   0 => ['X', 'Y', 'A', '_', '_']
   1 => ['Y', '_', 'B', '_', 'X']
   2 => ['_', '_', 'C', 'X', 'Y']

   New output

   0 => ['X', 'Y', 'A', '_', '_']
   1 => ['Y', 'B', 'X', '_', '_']
   2 => ['C', 'X', 'Y', '_', '_']

   Best result (VALID)

   0 => ['X', 'Y', 'A']
   1 => ['Y', 'B', 'X']
   2 => ['C', 'X', 'Y']

答案 1 :(得分:4)

您应该尝试使用的是电源设置,即:

  在数学中

enter image description here,任何集合S的幂集(或幂集)都是集合   S的所有子集,包括空集和S本身,各种各样   表示为P(S),(S),℘(S)(使用“Weierstrass p”),P(S),ℙ(S),   或者,用S中所有函数的集合识别S的powerset   给定一组两个元素,2S。

如果有一组{a,b,c},它会得到以下结果:

{{a,b,c},{a,b},{a,c},{b,c},{a},{b},{c}}


来自from wikipedia的有用的PHP库将在上述规则中提供您正在寻找的正确结果,如果不是所有规则都适用,您也可以尝试在结果上添加过滤器以使其正确。

答案 2 :(得分:3)

根据您提供的上一个问题的答案,可以使用PHP为阵列支持的一些内置函数更优雅地解决这种问题(在这种情况下)。这可能是所有语言中最好的。

function solve($matrix){
    $master = [];
    $_matrix = [];
    foreach($matrix as $key => $array){
        $_matrix[$key] = array_combine($array,$array);
        $master += $_matrix[$key];
    }
    $default = array_fill_keys($master, ''); 
    $result = [];
    foreach($_matrix as $array){
        $result[] = array_values(array_merge($default, $array));
    }
    print_r($result);
}

使用相同的测试

$tests = [
    [ ['X'], ['X'] ],
    [ ['X'], ['X'], ['X'] ],
    [ [ 'X', '' ], [ '', 'X' ] ],
    [ ['X', 'Y', 'Z'], ['X', 'Y'], ['X']],
    [ ['X', 'Y'], ['X', 'Y'], ['X', 'Y'] ],
    [ ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'] ],
    [ ['X', 'Y', 'Z', 'I', 'J'], ['X', 'Y', 'Z', 'I'], ['X', 'Y', 'Z', 'I'], ['X', 'Y', 'Z', 'I'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'] ],
];
array_map(function ($matrix) {
    solve($matrix);
}, $tests);

这是我得到的比较

[
  0 => ['X', 'Y', 'Z', 'I', 'J'] //<- contains all unique values
  1 => ['X', 'Y', 'Z', 'I']
  2 => ['X', 'Y', 'Z', 'I']
  3 => ['X', 'Y', 'Z', 'I']
  4 => ['X', 'Y', 'Z']
  5 => ['X', 'Y', 'Z']
]
Their Result:
[
  0 => ['', 'X', 'Y', 'Z', 'I', 'J'] //<- contains an extra '' empty value
  1 => ['', '', 'X', 'Y', 'Z', 'I']
  2 => ['I', '', '', 'X', 'Y', 'Z']
  3 => ['Z', 'I', '', '', 'X', 'Y']
  4 => ['Y', 'Z', '', '', '', 'X']
  5 => ['X', 'Y', 'Z', '', '', '']
]
My Result
[
  0 => ['X', 'Y', 'Z', 'I', 'J']
  1 => ['X', 'Y', 'Z', 'I', '']
  2 => ['X', 'Y', 'Z', 'I', '']
  3 => ['X', 'Y', 'Z', 'I', '']
  4 => ['X', 'Y', 'Z','','']
  5 => ['X', 'Y', 'Z','','']
]

你可以在这里测试一下。

http://sandbox.onlinephpfunctions.com/code/86d0b4332963f95449df2e7d4d47fcd8224fe45d

我甚至使用microtime来定时

我的0.00013017654418945毫秒

他们的0.10895299911499毫秒

这并不奇怪,因为他们大约有60行代码和7个函数调用。我只有1行14行代码。

那就是说我不知道​​值的位置在输出中是否重要。也不完全是你期望的产出扩展到这个问题。

事实是他们也失去了索引位置,只需查看结果中的第二个数组2 => ['I', '', '', 'X', 'Y', 'Z']与输入2 => ['X', 'Y', 'Z', 'I']进行比较。我不会在输出中提及可能不属于那里的额外''

也许我错过了一些东西,哈哈,我通常不会做这些数学类型的东西。

更新如果您想要解释其工作原理,

  • array_combine($array,$array);创建一个匹配key =&gt;的数组值,我们滥用了数组键本质上是唯一的这一事实。像['X'=>'X','Y'=>'Y'...]
  • 一样
  • 然后我们建立一个&#34;主人&#34;包含其中所有值和匹配键的数组,一个数组来统治它们。主数组的大小限制为最大数量或唯一值,因为我们使用密钥来消除重复数据。
  • 然后我们使用array_fill_keys($master, '');来创建所有值的模板。 &#34; master&#34;的关键是所有内部数组中的所有唯一值,因此我们将其填入我们的#34;通配符&#34;占位符。在这种情况下,它看起来像['X'=>'', 'Y'=>'', 'Z'=>'', 'I'=>'', 'J'=>'']
  • 然后我们合并&#34;修改&#34;原始数组,也通过替换&#34;模板化&#34;中的占位符来滥用数组键以获得我们的优势。主数组使用&#34;修改&#34;原始数组,因为键匹配。
  • 最后我们使用array_values
  • 从数组中删除键

我们留下每个内部阵列&#34;模板化&#34;由主数组但填充原始值并且缺少的值为空。

答案 3 :(得分:1)

希望这是我们正在寻找的解决方案,我请求让所有人检查我的解决方案

代码:

<?php
$input = [
    [ 'F', 'I', 'J', 'Z' ],
    [ 'F', 'R', 'U', 'V' ],
    [ 'I', 'R', 'U', 'V' ],
    [ 'M', 'P', 'U', 'V' ],
];
do {
    $result = calculate($input);
} while(!TestValid($input, $result, '_'));


echo (TestValid($input, $result, '_')) ? 'VALID' : 'INVALID';

ShowNice($result);

function TestValid($input, $output, $nullchar) {

    foreach($output as $k => $o) {
        $test = array_filter($o, function($v) use ($nullchar) {
            return $v != $nullchar;
        });

        if (count($test) != count($input[$k])) {
            return false;
        }
    }
    return true;
}

function ShowNice($output) {
    $height = getHeight($output);

  foreach($output as $k => $v ) {
        for($i = 0;$i < $height;$i ++) {

            if (!isset($output[$k][$i])) {
                $output[$k][$i] = '_';
            }
        }
    }

  echo '<pre>';
  foreach($output as $key=>$val) {
    echo '<br />' . str_pad($key,2," ",STR_PAD_LEFT) . ' => [';
    ksort($val);
    echo join(', ', $val);
    echo ']';
  }
  echo '</pre>';
}

function calculate($array) {

    echo "<pre>";
    $full = getFullList($array);

    foreach($full as $f) {
        $frequency[$f] = getFrequency($array, $f);
    }

    // uksort($frequency, function($i, $j) use ($frequency) { 
    //     return $frequency[$j] <=> $frequency[$i];
    // });

    $frequency = array_keys($frequency);

    shuffle($frequency);


    $height = getHeight($array);

    foreach($array as $k => $v ) {
        for($i = 0;$i < $height;$i ++) {
            if (!isset($array[$k][$i]))
                $array[$k][$i] = '_';
        }
    }

    foreach($array as $key => $value ) {
        $output[$key] = [];
        $used[$key] = [];
    }

    foreach($array as $key => $value ) {
        foreach($frequency as $k => $v) {

            $j = 0;

            foreach($array as $kk => $col) {
                if (in_array($v, $col)) {
                    for ($h = 0; $h <= $height; $h++) {

                        if (!isset($_h[$v][$kk])) {
                            $_h[$v][$kk] = 0;
                        }

                        if ($h + $_h[$v][$kk] >= $height) {
                            $hh = ($h + $_h[$v][$kk]) - $height;
                        } else {
                            $hh = $h + $_h[$v][$kk];
                        }
                        $row = getRow($output, $hh);
                        if (!in_array($v, $row) && !in_array($v, $used[$kk])) {
                            if (!isset($output[$kk][$hh]) || $output[$kk][$hh] == '_') {
                                $output[$kk][$hh] = $v;
                                $used[$kk][] = $v;

                                $keys = array_keys($array);
                                foreach($keys as $i => $ke) {
                                    if ($ke == $kk) {
                                        if(isset($keys[$i+1])) {
                                            $_h[$v][$keys[$i + 1]] = $hh;
                                        } else {
                                            $_h[$v][$keys[0]] = $hh;
                                        }
                                    }
                                }
                               $unused[$kk] = array_diff($col, $used[$kk]);
                                $j++;
                                break;
                            }
                        }
                    }
                }
            }

            // ShowNice($output);
        }

    }
    foreach($output as $k => $v ) {
        for($i = 0;$i < $height;$i ++) {
            if (!isset($output[$k][$i]))
                $output[$k][$i] = '_';
        }
    }

    foreach($output as $k => $o) {
        ksort($output[$k]);
    }

    return $output;
}

function getHeight($array) {
    $heights = [];
    $max3 = count($array);
    $max2 = 0;
    foreach($array as $v) {
        if ($max2 < count($v)) {
            $max2 = count($v);
        }

        foreach ($v as $e) {
            $heights[$e] = (isset($heights[$e])) ? $heights[$e] + 1 : 1;
        }

    }
    $max = 0;
    foreach ($heights as $h ) {
        if ($h > $max) {
            $max = $h;
        }
    }

    return max($max, $max2, $max3);
}

function getRow($array, $row) {
    $res = [];
    foreach ($array as $a) {
        if (is_array($a)) {
            foreach($a as $k =>$b) {
                if ($row == $k) {
                    $res[] = $b;
                }
            }
        }
    }

    return $res;
}

function getFrequency($array, $value) {
    $c=0;
    foreach ($array as $key => $v) {
        foreach ($v as $e) {
            if ($e == $value) 
                $c++;
        }
    }
    return $c;
}

function getFullList($array) {

    $m = [];
    foreach($array as $a) {
        $m = array_merge($m, $a);
    }

    return array_unique($m);
}

<强>已更新

这可能是最终的,请检查:游乐场https://eval.in/906355