代码改变世界

随笔分类 -  算法

位运算

2014-03-09 14:42 by 夜与周公, 300 阅读, 收藏, 编辑
摘要: 有关位运算(与运算,或运算,异或运算,左移和右移)是C/C++语言偏向底层的操作。市面上有很多有关位运算的算法技巧,特在此做了整理。 1.Bitmap 什么事Bitmap? Bitmap的核心思想就是“索引”技术,某个比特位作为key,而该比特上的值作为value(可以理解为状态位:0 or 1)。Bitmap既然利用了索引的思想,那么Bitmap这种数据结果的核心就是如何取到某个索引(即定位到某个bit)。 实现手段上肯定是利用位运算,如果想索引到第 i 比特,可以用如下代码:(p + i /8) | (0x1 > 1) a & b,则取出了a与b中相同的位,a与b相同位的平均 阅读全文

二分查找排序

2013-10-30 22:08 by 夜与周公, 556 阅读, 收藏, 编辑
摘要: 二分查找算法,是在大学阶段学习的基础性算法。算法思想简单,但要写出一个正确的二分查找算法并不简单,从1946年提出,到1962年才完成一个正确的二分查找排序算法。二分查找排序算法的变种,也常常出现在各个IT公司的面试题中。本文总结资料尝试给出一个“正确”的二分查找算法,最后给出一个二分查找排序的变种问题。 1. 经典二分查找排序的算法: 1 int BinarySearch(int* array, int n, int x) 2 { 3 assert((array != NULL) && (0 > 1);11 if (array[mid] == x)12 ... 阅读全文

在链表中漫游

2013-08-29 16:10 by 夜与周公, 338 阅读, 收藏, 编辑
摘要: 链表数据结构操作灵活,经常出现在各大公司的面试题中,因此,本文总结了常见的有关链表的面试题。 首先定义链表的数据结构:templatestruct Node{ T data; Node* next;}; 1.基本操作 虽然将其命名成“基本操作”,因为这些对链表的操作与我们正常接触的对链表的操作,完成的功能是一样的,如删除一个节点,增加一个节点。但与正常操作不一样的地方是,增加了一些限制条件。 1)删除节点:只给定单链表中某个结点p(并非最后一个结点,即p->next!=NULL)指针,删除该结点 因为不知道头节点的位置,因此,无法遍历获得节点p的前一个节点指针,采用传统的删... 阅读全文

Levenshtein距离

2013-08-22 15:46 by 夜与周公, 597 阅读, 收藏, 编辑
摘要: Levenshtein Distance,又称Edit Distance,在自然语言处理中有着广泛的应用。Levenshtein Distance 指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。编辑操作包括:1)删除一个字符;2)插入一个字符;3)替换一个字符 Example: 两个字符串a = "kitten", b = "ssitting",编辑过程如下:kitten →sitten (substitution of "s" for "k")sitten → sittin (substitut 阅读全文

动态规划(dynamic programming)

2013-08-20 23:37 by 夜与周公, 391 阅读, 收藏, 编辑
摘要: 动态规划(dynamic programming)是一种高效的程序设计技术,一般应用与最优化问题,即当我们面临多组选择时,选择一个可行解让问题达到最优。动态规划的一个显著特点是:原问题可以划分成更小的子问题的最优化问题,而这些子问题的解往往有着重叠的部分。 动态规划算法的解决一个问题,可以分成四个步骤: 1)描述最优解结构,需找最优子结构 2)递归定义最优值的解 3)自底向上的求解问题 4)依据计算过程,构造一个最优解 1)与 2)是这个问题可以用动态规划解决的理论基础,3)可以看出是动态规划算法的编程实践,4)是算法输出,依赖于3)。下面分别用三个经典的动态规划案例,阐释动态... 阅读全文

数组中子数组之和最大问题

2013-08-19 00:34 by 夜与周公, 348 阅读, 收藏, 编辑
摘要: 问题描述:给定一个包含N个元素的数据A(A[0], A[1], A[2]...A[N-1]),这个数组自然有很多子数组,那么,这些子数组之和的最大值是什么? Example: 数组[1, -2, 3, 5, -3, 2],最大的子数据是[3, 5],和为8。 解法一:穷举法 最直接,也是最简单的方法,穷举子数组A[i:j]的和,找出一个最大的,算法的时间复杂度O(N2),算法的代码如下:#include #include using namespace std;int max_sub_sum(const int* A, int n){ int max_sum = INT_MIN... 阅读全文

求二进制数中1的个数

2013-08-08 17:05 by 夜与周公, 489 阅读, 收藏, 编辑
摘要: >中有这么个题目:对于一个字节的无符号整形变量,求其二进制表达形式中“1”的个数。 基础算法:辗转相除法 辗转相除法是十进制采用的算法,该算法如下:int count_one_cnt(int value){ int cnt = 0; while (value) { if (value % 2 == 1) { cnt += 1; } value /= 2; } return cnt;} 上述算法的时间复杂度O(logV)(V是value比特数),上述算法的操作对象的级别是“数”级... 阅读全文

亲和数问题

2013-08-06 17:14 by 夜与周公, 1001 阅读, 收藏, 编辑
摘要: 求500万以内的亲和数 “朋友是你灵魂的倩影,要像220与284一样亲密。”——毕达哥拉斯 首先需要知道什么事亲和数?亲和数是指,两个数a和b,如果a的所有真因子之和等于b,而b所有的真因子之和也等于a,那么着两个数被称为亲和数(真因子包括1,但不包括自身)。 Example: 220的真因子: 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 284的真因子: 1, 2, 4, 71, 142 284 =1+2+4+5+10+1... 阅读全文

寻找序列中满足条件的元素

2013-07-16 22:11 by 夜与周公, 630 阅读, 收藏, 编辑
摘要: 一、基础篇 在>这本书中,给出了这样的一个问题:快速找出一个数组中的两个元素,让这两个元素之和等于一个给定的值,假设数组中至少存在一对这样的元素。 对于这个问题有两种解决思路: 思路一:首先想到的解法是穷举法,即判断序列中任意的两个元素之和是否等于给定的数值。算法的时间复杂度O(N2),显然这种蛮力解法不是我们想要的,需要继续寻找更高效的解法。 思路二:假设预定的两个元素的和等于SUM,对于某个原始array[i],实际上就是要判断SUM- array[i]是否在数组中。如果元素是无序的,算法的复杂度仍然是O(N2),没有任何改进。但如果先进行排序,算法的复杂度是O(NlogN),... 阅读全文

寻找最大(小)的K个数

2013-07-02 20:37 by 夜与周公, 1077 阅读, 收藏, 编辑
摘要: >一书中提到了寻找最大的K个数的问题,问题可以简单描述为:在长度为N的数组中,寻找第K(K#include #include using namespace std;int _tmain(int argc,_TCHAR* argv[]){ int myints[] = {10, 20, 30, 5, 15}; vector v(myints, myints+5); make_heap (v.begin(),v.end()); //构建堆 cout #include #include #include using namespace std;const int... 阅读全文

寻找发帖水王

2013-06-09 21:18 by 夜与周公, 292 阅读, 收藏, 编辑
摘要: 在<<编程之美>>这本书中提到了发帖水王的问题。 原始问题:Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗? 扩展版本:随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找 阅读全文

字符串相关操作

2013-05-30 21:38 by 夜与周公, 194 阅读, 收藏, 编辑
摘要: 接下来,总结一些常见的字符串操作算法,第一个介绍字符串拷贝操作。字符串拷贝算法比较著名的资料是林锐的<<高质量的C、C++>>,网上的很多文章都借鉴了里面有关字符串拷贝的论述。虽然字符串拷贝操作看起来很简单,但是如果仔细考虑,不禁觉得原来写代码真是件细工活,一个模板化的C++字符串拷贝代码如下:char* str_copy(const char* pSource, char* pDest){ assert((pSource!=NULL) && (pDest!=NULL)); char* address = pDest; while ((*pDest++ 阅读全文

字符串包含判断

2013-05-30 13:28 by 夜与周公, 372 阅读, 收藏, 编辑
摘要: 本节总结编程的艺术(CSDN)字符串包含操作。 算法描述:假设有两个由字母组合的字符串A和字符串B,字符串A的长度要大于字符串B的长度。算法如何判断出现在字符串B中的字母也出现在字符串A呢? 算法举例:StringA = "ABCDEFG", 若StringB = "DCEFG",则StringA与StringB之间算法判断是true;若StringB = "DCEFM"。 而StringA与StringC之间算法判读是false。 我们首先可以想到的办法是:遍历StringB,对于B中每一个字母,遍历字符串A,判断当前字母是出现在字 阅读全文

数组循环移位

2013-05-25 20:16 by 夜与周公, 275 阅读, 收藏, 编辑
摘要: 从本节开依据网上的一些资料学习总结常见的一些算法问题(CSDN程序员编程艺术),第一个总结的是“数组循环移位”算法。 算法问题:设计一个算法,把一个含有N个元素的数据,循环左移(右移)K个位置,要求时间复杂度O(N),且只允许使用两个附件的变量。 算法示例:abc1234循环左移3位abc1234->1234abc。 最先想到的办法,每次想做移动一个位置,循环K次,算法的时间复杂度O(K*N):void LeftShift(char* arr, int N, int k){ while(k--) { char temp = arr[0]; f... 阅读全文