【问题标题】:Optimise search in JSON with strings in ascending order使用升序排列的字符串优化 JSON 中的搜索
【发布时间】:2017-09-12 13:45:19
【问题描述】:

我这里有这个JSON

在根目录下,有一个命令(属性)为wp,它有 39 个子命令(子属性)为cachecapchecksum...等,每个子命令都有自己的自己的子命令,这最多 4 级

更好的部分是所有子命令都按升序排列,即;字符串按升序排列。

我想遍历并搜索像wp site createwp term delete这样的命令是否存在于JSON树中。由于巨大的时间复杂度,我不想使用for 循环进行迭代。我完成工程已经太久了,如果我没有记错的话,树形结构会大大缩短搜索时间。

谁能指出我实现这一目标的正确方向?我使用 PHP 作为我的语言。

【问题讨论】:

  • commandssub-commands?你的意思是propertiesnested properties
  • 是的,正确的@Script47
  • 在使用树之前,您应该先构建它。
  • 问题是要构建一棵树,您必须遍历您的数组。但你不想。
  • 如果项目已经排序 - 使用二进制搜索,有什么问题。

标签: php json search tree


【解决方案1】:

这是一个二进制搜索解决方案,您需要将 json 放入文件中...
注意:因为wp 不在subcommands 数组中,所以您无法搜索它

<?php
function binarySearch(&$myArray, $search, $start, $end)
{
    $middle = ($start + $end) >> 1; // divide by 2
    if ($middle >= $start) {
        if ($search > $myArray[$middle]['name']) { // $search must be in top half of array
            $result = binarySearch($myArray, $search, $middle + 1, $end);
        } elseif ($search < $myArray[$middle]['name']) { // $search must be in bottom half of array
            $result = binarySearch($myArray, $search, $start, $middle - 1);
        } else { // $search is here
            $result = $middle;
        }
    } else {
        $result = false; // $search not found
    }
    return $result;
}

function findCommand($arrFound, $strFind)
{
    $arrFind = explode(' ', $strFind);
    while ($arrFound !== false and list($key, $strCommand) = each($arrFind)) {
        $arrSearch = $arrFound['subcommands'];
        if (($key = binarySearch($arrSearch, $strCommand, 0, count($arrSearch) - 1)) === false) {
            $arrFound = false;
        } else {
            $arrFound = $arrSearch[$key];
        }
    }
    return $arrFound;
}

// get json from file and convert it to an array
$arrJson = json_decode(file_get_contents('items.json'), true);

$arrCommand = findCommand($arrJson, 'site create');
var_dump($arrCommand);

$arrCommand = findCommand($arrJson, 'term delete');
var_dump($arrCommand);

【讨论】:

    【解决方案2】:

    虽然使用原生函数 array_search()array_column() 可能会更快

    <?php
    function findCommand($arrFound, $strFind)
    {
        $arrFind = explode(' ', $strFind);
        while ($arrFound !== false and list($key, $strCommand) = each($arrFind)) {
            $arrSearch = $arrFound['subcommands'];
            if (($key = array_search($strCommand, array_column($arrSearch, 'name'))) === false) {
                $arrFound = false;
            } else {
                $arrFound = $arrSearch[$key];
            }
        }
        return $arrFound;
    }
    
    // get json from file and convert it to an array
    $arrJson = json_decode(file_get_contents('items.json'), true);
    
    $arrCommand = findCommand($arrJson, 'site create');
    var_dump($arrCommand);
    
    $arrCommand = findCommand($arrJson, 'term delete');
    var_dump($arrCommand);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多