목차
답글 내용:
수정 없는 정적 쿼리
순서를 변경하지 않고 추가 작업만 수행하는 동적 쿼리
추가 및 삭제 작업이 포함된 동적 쿼리(더 큰 숫자)
백엔드 개발 PHP 튜토리얼 해당 값을 빠르게 검색하는 방법

해당 값을 빠르게 검색하는 방법

Dec 01, 2016 am 01:27 AM
php 연산

PHP 인덱스 배열입니다. 배열의 값은 1부터 100까지의 정수(비반복)이며 값이 간헐적으로 나타날 수 있습니다. 즉, 7과 9는 있을 수 있지만 8은 없을 수 있습니다. 그리고 순서가 어긋나는 것, 즉 1부터 100까지 배열되어 있지 않은 것입니다

이제 $a=50이라고 가정하면 ==$a 또는 $a에 가장 가까운 두 값을 빠르게 꺼내는 방법은 무엇일까요?

그런데 배열의 값이 반드시 $a와 같지 않을 수도 있습니다

답글 내용:

PHP 인덱스 배열입니다. 배열의 값은 1부터 100까지의 정수(비반복)이며 값이 간헐적으로 나타날 수 있습니다. 즉, 7과 9는 있을 수 있지만 8은 없을 수 있습니다. 그리고 순서가 어긋나는 것, 즉 1부터 100까지 배열되어 있지 않은 것입니다

이제 $a=50이라고 가정하면 ==$a 또는 $a에 가장 가까운 두 값을 빠르게 꺼내는 방법은 무엇일까요?

그런데 배열의 값이 반드시 $a와 같지 않을 수도 있습니다

  1. array_search — 배열에서 주어진 값을 검색하고 성공하면 해당 키 이름을 반환합니다.

  2. 은 키 이름을 가져옵니다. $arr[$key-1], $arr[$key+1]

  3. 일 수 있습니다.

위의 것은 매우 간단하지만, 숫자를 찾지 못하면 가장 가까운 것을 찾으세요. 원래 배열의 순서가 엉망이므로 위쪽과 아래쪽이 반드시 가장 가까운 것은 아닙니다. , 2점 검색도 아이디어입니다. 제 아이디어는 먼저 배럴 정렬(현재 알고 있는 양의 정수를 정렬하는 가장 빠른 방법)을 사용하는 것입니다.

<code>//这个是要求的数组
$arr = [1,2,3...];

//填充一个1-100范围的数组
$search_arr = array_fill(0 , 99 , 0);

//遍历数组
foreach($search_arr as $k=>$v){
    if(in_array($k , $arr)){
        ++ $v;
    }
}

//此时search_arr数组里面值是1的就是要找的,同时已经排序好了
foreach($search_arr as $k=>$v){
    if($v >= 1){
        $new_arr[] = $k;
    }
}

//此时的new_arr就是一个键从0自增,同时值是排序的数组,然后再结合楼上的写法,便可求出。
</code>
로그인 후 복사

얼마나 효율적인지 모르겠습니다

<code>$arr = range(1, 100); // 要求的数组
$target = 10; // 目标值
shuffle($arr); // 打乱顺序

$val_key = array_search($target, $arr);
// 测试 $target 不存在的情况去掉以下注释
// array_splice($arr, $val_key, 1);
// $val_key = '';
if ($val_key) {
    echo "这个值是:{$arr[$val_key]}";
} else {
    sort($arr);
    foreach ($arr as $key => $value) {
        if (($value < $target) && ($arr[$key+1] > $target)) {
            echo "左边:{$value} <br/>";
            echo "右边:{$arr[$key+1]}";
            exit;
        }
    }
}</code>
로그인 후 복사

수정 없는 정적 쿼리

  • 정렬(오름차순), 복잡도 nlogn(1개 정렬)

  • 두 지점으로 빠른 위치 지정, 복잡도 logn(쿼리 1개)

// 在有序数组$arr中得到大于等于$val的第一个下标
// 如果想要获得离$val最近的值,通过返回值判断
// 如果大于最大的值,返回数组的长度
function binary_search($arr, $val){
    $n = count($arr) - 1;
    $ans = $n + 1;
    $l = 0; $r = $n; 
    while($l <= $r){
        $mid = ($l + $r) >> 1;
        if($arr[$mid] >= $val){
            $ans = $mid;
            $r = $mid -1;
        }
        else $l = $mid + 1;
    }
    return $ans;
}

$arr = [1,5,9,3,8,7,10,12];
sort($arr);
foreach($arr as $key => $val){
    printf("%d ", $val);
}
printf("\n");

$search_num = 6;

printf("%d\n", binary_search($arr, $search_num));
로그인 후 복사

순서를 변경하지 않고 추가 작업만 수행하는 동적 쿼리

1-100에는 100개의 숫자가 있고, 그 값도 1-100입니다. 69의 위치에 대한 첨자를 구하면 69를 중심으로 하고 이진 탐색을 통해 그 근처 지점의 첨자를 찾을 수 있습니다. 특정 위치에 숫자가 있으면 1로 표시하고 그렇지 않으면 0으로 표시한 다음 69를 중심으로 왼쪽으로 이등분하여 가장 긴 간격을 찾고 합은 0이 되며 오른쪽으로 이등분하여 숫자를 찾습니다. 가장 긴 간격이고 합계는 0입니다. 트리를 사용하면 간격 합계를 빠르게 찾을 수 있습니다. 배열과 마찬가지로 업데이트 쿼리의 복잡도는 로그이고 숫자 추가의 복잡도는 로그입니다.
요구사항 및 목적:

  • 트리 배열은 간격 플래그 합계(특정 간격의 값이 나타나는지 여부)를 저장하고 업데이트 및 쿼리 복잡도는 로그됩니다

  • 특정 값에 가장 가까운 값을 중심으로 찾아 첨자, 이진 탐색, 복잡도 로그 반환

  • 시간에 맞춰 공간을 교환하고 값->첨자 매핑을 저장합니다.

  • 배열 끝에 숫자를 추가할 수 있으며 순서대로 추가할 필요는 없습니다.

다음 코드는 다음 문제를 해결합니다

[5,9,3,8,7,10,12] 배열이 있다고 가정합니다.
12에 가장 가까운 좌표를 요청하고 6을 반환합니다
2에 가장 가까운 좌표를 요청하고, 반환 2
고유번호 15 추가
고유번호 18 추가
고유번호 16 추가
고유번호 13 추가
13에 가장 가까운 좌표를 물어보고 10을 반환
17에 가장 가까운 좌표를 요청하고 9를 반환합니다

// 树状数组初始化长度为106,赋空值为0
$arr_bit = array();
for($i = 0;$i <= 105;$i ++){
    $arr_bit[$i] = 0;
}

// 查询1-$x之间的和
function query($x){
    global $arr_bit;
    $sum = 0;
    while($x > 0){
        $sum += $arr_bit[$x];
        $x -= $x & -$x;
    }
    return $sum;
}

// 更新第$x位的标志
function add($x, $val){
    global $arr_bit;
    while($x <= 105){
        $arr_bit[$x] += $val;
        $x += $x & -$x; 
    }
}

$arr = [5,9,3,8,7,10,12];
$arr_tmp = array();
foreach($arr as $key => $val){
    $arr_tmp[$val] = $key;
    printf("%d ",$val);
    add($val, 1);
}
printf("\n");

// 查找离某值最近的下标
// 先查找左边 然后再找右边,若不存在,返回-1
function find_val_pos($val){
    if($val < 1 || $val > 100){
        return -1;
    }
    global $arr_tmp;
    $n = count($arr);
    $l = 1; $r = $val; $ans_l = -1;
    // 得到$val左边最靠近的
    while($l <= $r){
        $mid = ($l + $r) >> 1;
        // 获得$val到$mid的标志区间和
        $mid_val = query($val) - query($mid - 1);
        // 若标志区间和大于1,记录答案,l往右移继续查
        if($mid_val >= 1){
            $ans_l = $mid;
            $l = $mid + 1;
        }
        else $r = $mid - 1;
    }
    $l = $val; $r = 101; $ans_r = -1;
    // 得到$val右边最靠近的
    while($l <= $r){
        $mid = ($l + $r) >> 1;
        // 获得$mid到$val的标志区间和
        $mid_val = query($mid) - query($val - 1);
        if($mid_val >= 1){
            $ans_r = $mid;
            $r = $mid - 1;
        }
        else $l = $mid + 1;
    }
    if($ans_l == -1) return $arr_tmp[$ans_r];
    elseif ($ans_r == -1) return $arr_tmp[$ans_l];
    else {
        if($val - $ans_l > $ans_r - $val)
            return $arr_tmp[$ans_r];
        else
            return $arr_tmp[$ans_l];
    }
}

function add_num($val){
    if($val < 1 || $val > 100) return false;
    global $arr_tmp;
    if(isset($arr_tmp[$val])){
        return false;
    }
    else {
        global $arr;
        $arr_n = count($arr);
        $arr_tmp[$val] = $arr_n;
        $arr[$arr_n] = $val;
        add($val, 1);
        return true;
    }
}

// 查询12最近的坐标
printf("%d\n",find_val_pos(12)); // 结果为6
// 查询2最近的坐标
printf("%d\n",find_val_pos(2));  // 结果为2

add_num(15); // 15位于7
add_num(18); // 18位于8
add_num(16); // 16位于9
add_num(13); // 13位于10

// 查询13最近的坐标
printf("%d\n",find_val_pos(13)); // 结果为10

// 查询17最近的坐标
printf("%d\n",find_val_pos(17)); // 结果为9

// 查询15最近的坐标
printf("%d\n",find_val_pos(15)); // 结果为7

printf("hh\n");
// 查询100最近的坐标
printf("%d\n",find_val_pos(100)); // 结果为8,因为第8个位置是18,是最大的数
로그인 후 복사

추가 및 삭제 작업이 포함된 동적 쿼리(더 큰 숫자)

첨자가 차지하는 추가 간격 값을 유지한 다음 균형 이진 트리를 설정하고 복잡성 로그n을 쿼리하고 복잡성 로그n을 추가 및 삭제해야 합니다.

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

cakephp4에서 날짜와 시간을 다루기 위해 사용 가능한 FrozenTime 클래스를 활용하겠습니다.

CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

파일 업로드 작업을 위해 양식 도우미를 사용할 것입니다. 다음은 파일 업로드의 예입니다.

CakePHP 유효성 검사기 만들기 CakePHP 유효성 검사기 만들기 Sep 10, 2024 pm 05:26 PM

컨트롤러에 다음 두 줄을 추가하면 유효성 검사기를 만들 수 있습니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

CakePHP 빠른 가이드 CakePHP 빠른 가이드 Sep 10, 2024 pm 05:27 PM

CakePHP는 오픈 소스 MVC 프레임워크입니다. 이를 통해 애플리케이션 개발, 배포 및 유지 관리가 훨씬 쉬워집니다. CakePHP에는 가장 일반적인 작업의 과부하를 줄이기 위한 여러 라이브러리가 있습니다.

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

See all articles