js实现kmp算法_搜索算法 与 随机算法 (JS实现)

搜索算法

我们会发现 之前学习的 数据结构与算法 中的 BinarySearchTree 类的 search 方法(二叉搜索树中 )以及 LinkedList 类的 indexOf 方法( 链表中 )等, 都是搜索算法。当然,它们每一个都是根据其各自的数据结构来实现的。所以,我们已经熟悉两 个搜索算法了,只是还不知道它们“正式”的名称而已。

  • 顺序搜索

顺序或线性搜索是最基本的搜索算法。它的机制是,将每一个数据结构中的元素和我们要找 的元素做比较。顺序搜索是最低效的一种搜索算法。

import { DOES_NOT_EXIST } from '../models/const'

export function sequentialSearch<T>(arr: T[], value: T) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === value) {
      return i
    }
  }
  return DOES_NOT_EXIST
}

DOES_NOT_EXIST 是一个常量 = -1 表示 没有找到该值

假定有数组[5, 4, 3, 2, 1]和待搜索值 3,下图展示了顺序搜索的示意图。

50a5c6a52bd0e65689b5c4079e50ecdc.png
  • 二分搜索

二分搜索算法的原理和猜数字游戏类似,就是那个有人说“我正想着一个 1~100 的数”的 游戏。我们每回应一个数,那个人就会说这个数是高了、低了还是对了。

这个算法要求被搜索的数据结构已排序。以下是该算法遵循的步骤。

(1) 选择数组的中间值。

(2) 如果选中值是待搜索值,那么算法执行完毕(值找到了)。

(3) 如果待搜索值比选中值要小,则返回步骤 1 并在选中值左边的子数组中寻找(较小)。

(4) 如果待搜索值比选中值要大,则返回步骤 1 并在选种值右边的子数组中寻找(较大)。

import { DOES_NOT_EXIST } from '../models/const'

export function binarySearch(arr: number[], value: number) {
  //二分查找
  let low = 0
  let high = arr.length - 1
  while (low <= high) {
    const mid = Math.floor((low + high) / 2)
    const element = arr[mid]
    if (element === value) {
      return mid
    }
    if (value > element) {
      low = mid + 1
    } else {
      high = mid - 1
    }
  }
  return DOES_NOT_EXIST
}

给定下图所示数组,让我们试试搜索 2。这些是算法将会执行的步骤。

0c9a8dfd2dd24df4170c5af8705f8520.png
  • 内插搜索

内插搜索是改良版的二分搜索。二分搜索总是检查 mid 位置上的值,而内插搜索可能会根 据要搜索的值检查数组中的不同地方。

这个算法要求被搜索的数据结构已排序。以下是该算法遵循的步骤:

(1) 使用 position 公式选中一个值;(此公式的证明更多与数学相关)

(2) 如果这个值是待搜索值,那么算法执行完毕(值找到了);

(3) 如果待搜索值比选中值要小,则返回步骤 1 并在选中值左边的子数组中寻找(较小);

(4) 如果待搜索值比选中值要大,则返回步骤 1 并在选种值右边的子数组中寻找(较大)。

import { DOES_NOT_EXIST } from '../models/const'

export function interpolationSearch(arr: number[], value: number) {
  let low = 0
  let high = arr.length - 1
  let position = -1
  let delta = -1

  while (low <= high && value >= arr[low] && value <= arr[high]) {
  //delta 与position 是按照公式来计算的
    delta = (value - arr[low]) / (arr[high] - arr[low])

    position = low + Math.floor((high - low) * delta)

  //剩下的与二分搜索思想一致。
    if (arr[position] === value) {
      return position
    }
    if (arr[position] < value) {
      low = position + 1
    } else {
      high = position - 1
    }
  }
  return DOES_NOT_EXIST
}

随机算法

之前我们学习了如何将一个数组进行排序以及怎样在排序后的数组中搜索元素。不过还有 一种场景是需要将一个数组中的值进行随机排列。现实中的一个常见场景是洗扑克牌。

  • Fisher-Yates 随机

这个算法由 Fisher 和 Yates 创造,并由高德纳(Donald E. Knuth)在《计算机程序设计艺术》 系列图书①中推 , 是 随机数组的一种最有名的算法。

它的含义是迭代数组,从最后一位开始并将当前位置和一个随机位置进行交换。这个随机位 置比当前位置小。这样,这个算法可以保证随机过的位置不会再被随机一次(洗扑克牌的次数越 多,随机效果越差)。

export function shuffle(arr: number[]) {
  for (let i = arr.length - 1; i > 0; i--) {
    let index = Math.floor(Math.random() * (i + 1)) // 随机数满足区间 [0,i+1)
    ;[arr[i], arr[index]] = [arr[index], arr[i]] //交换两者值
  }
  return arr
}

为什么要逆序迭代 数组 ?

因为 维持 random 的区间 在 [0 , n ) 是最简单的,这样一定会和 arr [0 ~ n ]之间的值交换 所以要倒序 , 保证 已经随机过的值 不再随机.

下图展现了该算法的操作。

743d286a05fccc6746bde602e33a7d04.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值