查找算法

控制反转(IoC)与依赖注入(DI)

吃可爱长大的小学妹 提交于 2019-12-29 14:45:44
控制反转(IoC)与依赖注入(DI) 2009-01-14 22:57:47 标签: 依赖注入 职场 休闲 控制反转 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://zhangjunhd.blog.51cto.com/113473/126530 1. 控制反转 (Inversion of Control) 与依赖注入 (Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交 给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。 IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:<1>依赖查找(Dependency Lookup): 容器 提供回调接口和上下文环境给 组件 。EJB和Apache Avalon都使用这种方式。<2>依赖注入(Dependency Injection): 组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor

索引碎片的检测和整理

非 Y 不嫁゛ 提交于 2019-12-29 02:08:12
存储数据是为了查找数据,存储结构影响数据查找的性能。对无序数据进行查找,最快的查找算法是哈希查找;对有序数据进行查找,最快的查找算法是平衡树查找。在传统的关系型数据库中,聚集索引和非聚集索引都是平衡树(B-Tree)类型的存储结构,用于顺序存储数据,便于实现数据的快速查找。除了提升数据查找的性能之外,索引还能减少硬盘IO和内存消耗。通常情况下,硬盘IO是查找性能的瓶颈,由于索引是数据表的列的子集,这意味着,索引只存储部分列的数据,占用的硬盘空间比全部列少了很多,因此,数据库引擎只需要消耗相对较少的硬盘IO和内存buffer,就能把索引数据加载到内存中。 索引以B-Tree结构存储在数据文件中,分为叶子节点和非叶子节点,叶子节点用于存储数据,而非叶子节点(中间节点和根节点)用于存储索引键,节点数据按照索引键排序。理论上,一旦数据集确定下来,索引查找的时间消耗就只跟索引结构的层次有关系,层次越多,查找数据所消耗的时间越多。碎片会影响索引的层次结构,但是,碎片并不总是破坏者,碎片有利于数据的更新。 在数据的物理存储上,索引和数据存储在硬盘上的数据文件中,数据文件以页(Page)为最小单位分割,每一个Page是8KB,物理位置上连续的8个Page叫做一个区(Extent),每一个区是64KB。区是空间分配的基本单位,而页是数据存储的基本单位。 从物理存储上来看,索引是由一系列的分段

leetcode 34 在排序数组中查找元素的第一个和最后一个位置

守給你的承諾、 提交于 2019-12-28 23:20:19
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] 1、可否 直接通过二分查找 ,很容易 同时求出 目标target所在区间的左右端点? 2、若 无法同时求出 区间左右端点,将对目标target的二分查找 增加怎样的限制条件 ,就可以 分别求出 目标target所在区间的左端点和右端点? 查找区间左端点时,增加限制条件: 当target == nums[mid]时,若此时mid == 0或nums[mid - 1] < target, 则说明mid即为区间左端点,返回;否则设置区间右端点为mid - 1 查找区间右端点时,增加限制条件: 当target == nums[mid]时,若此时mid == nums.size()-1或nums[mid +1] > target, 则说明mid即为区间右端点,返回;否则设置区间左端点为mid + 1 实现代码如下: class Solution { public

数据结构与算法之PHP排序算法(快速排序)

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-28 03:47:08
一、基本思想 快速排序又称划分交换排序,是对冒泡排序的一种改进,亦是分而治之思想在排序算法上的典型应用。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列的目的。 二、算法过程 1)从数列中挑出一个元素,称为“基准值”; 2)将待排序元素进行分区,比基准值小的元素放在基准值前面,比基准值大的元素放在基准值后面。分区结束后,该基准值就处于数组的中间位置; 3)对左右两个分区重复以上步骤直到所有元素都是有序的。 三、算法图解及PHP代码实现 1、替换版 上图只给出了第1趟快速排序的流程。在第1趟排序中,设置pivot=arr[i],即pivot=3。 1) 右 → 左 查找小于pivot的数:找到满足条件的数arr[j]=2,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。 2) 左 → 右 查找大于pivot的数:找到满足条件的数arr[i]=4,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。 3) 右 → 左 查找小于pivot的数:找到满足条件的数arr[j]=1,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。 4) 左 → 右

你真的会写二分查找吗

北战南征 提交于 2019-12-27 16:42:07
1 二分查找   二分查找是一个基础的算法,也是面试中常考的一个知识点。二分查找就是将查找的键和子数组的中间键作比较,如果被查找的键小于中间键,就在左子数组继续查找;如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素。 (图片来自《算法-第4版》) /** * 二分查找,找到该值在数组中的下标,否则为-1 */ static int binarySerach(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] == key) { return mid; } else if (array[mid] < key) { left = mid + 1; } else { right = mid - 1; } } return -1; }   每次移动left和right指针的时候,需要在mid的基础上+1或者-1, 防止出现死循环, 程序也就能够正确的运行。   注意:代码中的判断条件必须是while (left <= right),否则的话判断条件不完整,比如:array[3] = {1, 3, 5};待查找的键为5,此时在(low <

leetcode_34.在排序数组中查找元素的第一个和最后一个位置

亡梦爱人 提交于 2019-12-27 14:11:16
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] 解析:二分法的应用,注意边界的判断 class Solution { public : vector < int > searchRange ( vector < int > & nums , int target ) { int left = 0 ; int right = nums . size ( ) ; int mid ; vector < int > res ( 2 , - 1 ) ; //寻找左边界 while ( left < right ) { mid = left + ( right - left ) / 2 ; if ( nums [ mid ] >= target ) right = mid ; else left = mid + 1 ; } if ( left == nums . size ( ) || nums [ left

java系统增加查找算法详解

♀尐吖头ヾ 提交于 2019-12-26 19:32:13
题干 数学老师小y 想写一个成绩查询系统,包含如下指令: insert [name] [score],向系统中插入一条信息,表示名字为name的学生的数学成绩为score。 find [name],表示查找名字为name的学生的数学成绩。 注意有些同学可能会为了刷分多次选课,查询的时候给出最大成绩即可。学生的名字是由小写字母组成。成绩是一个 0 \ldots 1000…100 的整数。 老师找到你,想你帮他完成这个系统。 输入格式 输入若干行,每行都是insert [name] [score]或者find [name]的形式,或一行end表示输入结束。输入行数不大于 10001000,每个学生名字长度不大于 2020 个字符。 输出格式 对于每个查询,输出查询的学生的最高成绩,如果系统中不存在该学生,输出 -1−1。 -------------------------------------------------------成功解决下面bug----------------------------------------------------------------------------------------- 问题总结: 中间很多输出了内容没有删掉 你没有考虑一个情况是可能有人的名字是 insert num 的 return 值显然存在问题 成功代码: import

[算法系列之三十三]杨氏矩阵

安稳与你 提交于 2019-12-26 19:09:38
即对于矩阵Table有Table[i][j] ≤Table[i][j + 1], Table[i][j] ≤ Table[i + 1][j],我们也称这样的矩阵为杨氏矩阵。 给出判定某个数是否存在该矩阵中的高效算法。 分析: 为了便于复杂度分析,我们暂时假定该矩阵为大小n*n。如下图所示为一个杨氏矩阵。 二分搜索解法: 许多人都观察到了矩阵在二维上都是有序的,所以使用在每一行(或者每一列)使用二分搜索是很自然的想法。由于每一行二分搜索需要O(lgn)时间,搜索n行需要O(nlogn)的时间。显然这个时间复杂度还是不够高效。当然这只是第一步尝试,不要让自己过早的陷入到二分搜索的泥潭中,好的方法还在后面。 一种错误的想法: 如果不细心也许会掉入一个陷阱中。有人也许认为可以先从行来判定,如果某个数位于某2行间,则只需要检查相应的2列即可,这是错误的。如下左边图所示,假定我们需要查找9是否在矩阵中,由于9位于7到11之间,所以接下来在7和11的这两列中(这2列在图中高亮显示)二分查找9,虽然能够查找到9,虽然查找9成功了,但是这个方法是错误的。因为10也位于7到11之间,但是10并不在这2列中。 即便是如下右边图示查询范围包括2行2列,尽管在查找9和10都成功,但是还是错误的,反例大家可以自己找一个。 Step-wise线性搜索解法: 从右上角开始,每次将搜索值与右上角的值比较

数据结构知识点复习(五)

好久不见. 提交于 2019-12-26 17:03:16
第七章 查找 相关概念: (1)关键字:数据元素中某个数据项的值,可以标识一个数据元素(或记录)。如果可以唯一标识: 主关键字 。不唯一不标识, 次关键字 。 (2)动态查找表和静态查找表:如果在查找的过程中有修改表的信息,那就是动态查找表,反之为静态查找表 (3)**平均查找长度:**为确定关键字在查找表中的位置,需和给定值进行比较的关键字个数的期望值,称为查找算法在查找成功时的平均查找长度。 对于含有n个记录的表,查找成功的平均查找长度为: A S L = ∑ i = 1 n P i C i ASL=\sum_{i=1}^{n}P_iC_i A S L = i = 1 ∑ n ​ P i ​ C i ​ 其中, p i p_i p i ​ 为查找表中第i个记录的概率, ∑ i = 1 n P i = 1 \sum_{i=1}^{n}P_i=1 ∑ i = 1 n ​ P i ​ = 1 . C i C_i C i ​ 为找到表中与之相等的关键字的第i个记录的时候,和给定值比较的次数。 可以用平均查找长度来衡量算法的性能 7.2.1顺序查找 顺序查找就是从头开始比较查找,如果查找到了,就成功,否则,失败。 假设以顺序表作为存储结构 typedef struct { KeyType key; //关键字域 InfoType OtherInfo; //其他域 }ElemType;

数据结构笔记:第七章 查找

寵の児 提交于 2019-12-25 21:34:04
查找基本概念: 列表:由同一类型的数据元素组成的集合。 关键码:数据元素中的某个数据项,可以标识列表中的一个或一组数据元素。 键值:关键码的值。 主关键码:可以唯一地标识一个记录的关键码。 次关键码:不能唯一地标识一个记录的关键码。 查找 :在具有相同类型的记录构成的集合中找出满足给定条件的记录。 查找的结果 :若在查找集合中找到了与给定值相匹配的记录,则称查找成功;否则,称查找失败。 静态查找 :不涉及插入和删除操作的查找 。 动态查找 :涉及插入和删除操作的查找。 查找结构 :面向查找操作的数据结构 ,即查找基于的数据结构。 线性表:适用于静态查找,主要采用顺序查找技术、折半查找技术。 树表:适用于动态查找,主要采用二叉排序树的查找技术。 散列表:静态查找和动态查找均适用,主要采用散列技术。 顺序查找: 基本思想: 从线性表的一端向另一端逐个将关键码与给定值进行比较, 若相等,则查找成功,给出该记录在表中的位置; 若整个表检测完仍未找到与给定值相等的关键码,则查找失败,给出失败信息。 改进顺序查找: 基本思想:设置“哨兵”。 哨兵就是待查值, 将哨兵放在查找方向的尽头处, 免去了在查找过程中每一次比较后都要判断查找位置是否越界,从而提高查找速度。 int LineSearch :: SeqSearch(int k) { int i = length; //从数组高端开始比较