算法
realxie
网易游戏研发工程师
展开
-
正态分布随机数
时间关系暂时先不介绍啥是正态分布了,网上关于生成正态分布随机数的方法也有很多。下面是moro 逆正态累积分布函数(Moro's Inverse Cumulative Normal Distribution function) double MoroInvCND(double prob){ const double a1 = 2.50662823884; const d原创 2013-03-03 20:25:22 · 6852 阅读 · 0 评论 -
实现指数函数Power
该题目不解释了,看代码,使用二分的思想,//int Power(int base, int exponent){ int result = 1; while (exponent) { if (exponent & 1) { result *= base; } base *= base; exponent >>= 1; } return result;}原创 2012-10-03 20:06:19 · 5256 阅读 · 0 评论 -
打印所有括号匹配排列方式
对于2对左右括号,其排列方式有:( ( ) )( ) ( )4对括号的排列方式有:( ( ( ( ) ) ) )( ( ( ) ( ) ) )( ( ( ) ) ( ) )( ( ( ) ) ) ( )( ( ) ( ( ) ) )( ( ) ( ) ( ) )( ( ) ( ) ) ( )( ( ) ) ( ( ) )( ( ) ) ( ) ( )原创 2012-10-02 17:10:34 · 5713 阅读 · 0 评论 -
二叉树两个结点的最低共同父结点(树)
题目:二叉树的结点定义如下:struct TreeNode{ int m_nvalue; TreeNode* m_pLeft; TreeNode* m_pRight;};输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。解法:要想找到两个节点的最低共同父结点,其实就是找一个节点,使得它的左子树包含两个结点中的一个结点,右子树包含另原创 2012-07-30 20:11:47 · 5925 阅读 · 0 评论 -
最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
最大子序列最大子序列是要找出由数组成的一维数组中和最大的连续子序列。比如{5,-3,4,2}的最大子序列就是 {5,-3,4,2},它的和是8,达到最大;而 {5,-6,4,2}的最大子序列是{4,2},它的和是6。你已经看出来了,找最大子序列的方法很简单,只要前i项的和还没有小于0那么子序列就一直向后扩展,否则丢弃之前的子序列开始新的子序列,同时我们要记下各个子序列的和,最后找到和最大的子序转载 2012-07-28 20:52:29 · 2900 阅读 · 0 评论 -
给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数
google问题:给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。解答:假设我们要等概率生成一个3位的10进制数(000 - 999),我们可以在 随机生成整数0到9的函数 基础上,随机生成3个数字组成三位数就得到了结果。这里类似,我们首先必须认识到:任何一个数都可以用5进制的数来表示,如12 = 5进制(22) = 2*5 + 2。因此转载 2012-08-08 21:53:17 · 2934 阅读 · 0 评论 -
约瑟夫问题 大家一起来解决
本文之所以引出这个问题,是因为该问题曾经作为微软的一道面试问题出现,约瑟夫环问题原题为:已知n个人(以编号0,1,2,3...n-1分别表示)围坐在一张圆桌周围。从编号为0的人从0开始报数,数到m-1的那个人出列;他的下一个人又从0开始报数,数到m-1的那个人又出列;依此规律重复下去,给出最后一个出列的人的编号。首先该问题最简单的一个解法是采用链表进行模拟,在此不作解释。至于归纳法解决原创 2012-07-24 00:26:58 · 2905 阅读 · 0 评论 -
一道微软面试题
一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。解法:1> 求出5个数值中的最大和最小值 Max, Min.2> 如果Min = Max = 0, 则是连续的。3> 遍历整数数据将所有在Min 和 Max之间的数值求和sum, 包括min 和M原创 2012-08-05 19:32:18 · 2891 阅读 · 3 评论 -
可以用数学证明的随机洗牌算法
问题背景:有一副牌假设有N张,请设计一个随机洗牌算法。解决方案:这里只给出一个可以使用数学证明每张牌出现在任何位置概率为1/N的算法。Poker[N]for (i = 0; i {k = rand() % ( i + 1)if (i != k){switch(Poker[k], Poker[i]);}}分析:第一次取第一张牌(i=0)原创 2012-08-03 23:25:33 · 7438 阅读 · 1 评论 -
判断少了哪一张牌
问题:有一副扑克牌(没有大小天王),随机从中抽出一张牌,问抽出的是哪一张牌(不管花色)?请问,(1)如何设计一个算法能使得解决该问题的时间复杂度为O(N),空间复杂度为O(1)? (2)如果随机抽出两张不同的牌呢,如何确定?(1)提示:使用异或。这个问题其实RAID3-6等4种方式使用的数据校验方式,可以恢复任意单个磁盘失效下的数据。原创 2012-01-07 21:02:28 · 2190 阅读 · 0 评论 -
递归地反转一个栈
//// The code is used to reverse a stack recursively//#include #include using namespace std;// We can think about how we can reverse a stack with another stack.// Cause stack is a structure f原创 2012-10-03 16:18:11 · 6520 阅读 · 0 评论 -
动态散列(哈希)待续
这是一个很有意思的算法,暂时记下,以后有时间在些补上有兴趣的先参考这里http://blog.csdn.net/hintonic/article/details/7186613原创 2012-10-08 09:41:00 · 4770 阅读 · 0 评论 -
OS的进程调度算法
在多进程、多线程并发的环境里,从概念上看,有多个进程或者多个线程在同时执行,具体到单个CPU级别,实际上任何时刻只能有一个进程或者线程处于执行状态;因此OS需要决定哪个进程执行,哪些进程等待,也就是进程的调度。一、调度的目标1、首先要区分程序使用CPU的三种模式:IO密集型、计算密集型和平衡型。对于IO密集型程序来说,响应时间非常重要;对于CPU密集型来说,CPU的周转时间就比较重要;对于转载 2012-10-21 23:04:46 · 5480 阅读 · 0 评论 -
特殊的数组排序问题
问题:有一个数组A,将A排序之后,原数组中的每个元素在排序数组中位置相差不超过K. 请设计一个排序算法。解:首先对这个问题可以采用任意一种排序算法,例如使用归并排序可以在O(nLog(n))的时间内完成。题目中给出每个元素在排完序后和原来的位置相差不超过K,即其实就说明了这个数组其实对某些元素来说其实已经相对有序了,比如考虑两个元素 A[0]和 A[k+1],那么一定有A[原创 2012-10-18 10:54:48 · 5763 阅读 · 0 评论 -
再来一道概率题
桶中有M个白球,小明每分钟从桶中随机取出一个球,涂成红色(无论白或红都涂红)再放回,问小明将桶中球全部涂红的期望时间是?下面是从CSDN论坛上找到的一个解法:E(1)=1 //拿到第一个白球并将它涂红的期望时间E(2)=M/M-1 //拿到第2个白球并将它涂红的期望时间E(3)=M/M-2 //拿到第3个白球并将它涂红的期望时间...E(M)=M/1 //拿到第3个白球并将原创 2012-10-18 20:27:13 · 5532 阅读 · 0 评论 -
字符串字典顺序比较
//使用迭代器进行字典顺序比较template bool Compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2){ for (; first1 != last1 && first2 != last2; ++ first1, ++ first2) { if (*first1 < *first2)原创 2012-09-25 16:26:41 · 5385 阅读 · 0 评论 -
寻找两个有序数组中的第K个数或者中位数
假设有长度分为为M和N的两个升序数组A和B,在A和B两个数组中查找第K大的数,即将A和B按升序合并后的第K个数。解法一:使用两个指针指向A和B的开头,很容易在O(M+N)的时间内完成,此算法略过。解法二:使用二分的方法。算法思想在代码注释中#include #include #include using namespace std;//Notic原创 2012-10-16 17:25:32 · 16999 阅读 · 2 评论 -
在字符串中找出连续最长的数字串
写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)功能:在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,outputstr所指的值为1原创 2012-09-24 11:26:43 · 5921 阅读 · 1 评论 -
判断两个线段\矩形相交
如何判断两个线段\矩形相交?首先来判断两个线段的情况:假设有两个线段A和B,左右端点分别为A1,A2和B1,B2,分别考虑下面两种情况1. 线段A在线段B的左边,即A1 A22. 线段A在线段B的右边,即A1> B1,那么 A,B不相交的条件是 B1 B2那么将上面两种情况综合起来考虑就是Min(A2,B2) - Max(A1,B1) =0,那么X就是相交的区域大小。原创 2012-10-13 10:20:37 · 6121 阅读 · 0 评论 -
求正整数n所有可能的和式的组合
问题背景:求正整数n所有可能的和式的组合(如;4=1+1+1+1、1+1+2、1+3、2+1+1、2+2)对于这个题目有两种理解了:一> 如果将1+1+2和2+1+1当成不同的序列的话,这个问题会相对容易些。拿n=4这个例子,首先最长的组合肯定是4=1+1+1+1,那么最短的组合是4=4,到最后可能会将4=4这种情况排除掉,所以所有组合的长度一定为1,2,3原创 2012-10-12 17:29:31 · 8360 阅读 · 0 评论 -
动态规划求不相邻的最大子数组和
其实这个问题原题是这样描述的:有N个节点,每两个节点相邻,每个节点只与2个节点相邻,因此,N个顶点有N-1条边。每一条边上都有权值wi,定义节点i到节点i+1的边为wi。求:不相邻的权值和最大的边的集合。对于这个问题可能看起来不是很好处理,把问题更加规范化一些:给出一个数组,求出其中一个子集,使得子集中每个元素在原数组中两两都不相邻并使子集的和最大。因为不能选择两个相邻原创 2012-10-12 11:51:44 · 13367 阅读 · 6 评论 -
初窥内存管理(三)伙伴算法
假设系统的可利用内存空间容量为2m个字(地址从0到2m-1),则在开始运行时,整个内存区是一个大小为2m的空闲块,在运行了一段时间之后,被分隔成若干占用块和空闲块。为了在分配时查找方便起见,我们将所有大小相同的空闲块建于一张子表中。每个子表是一个双重链表,这样的链表可能有m+1个,将这m+1个表头指针用向量结构组织成一个表,这就是伙伴系统中的可利用空间表,如图所示:转载 2012-04-13 10:40:33 · 3785 阅读 · 0 评论 -
一道海量日志的随机选取问题
原题是这样的:假设有100G的日志存在于磁盘之上,其中每条日志占用的空间不多于100个字节,现在从日志随机选取N条日志,保证每条日志的选取概率相同。解1:最简单且严格的做法是扫描日志两遍。第一遍:统计出日志的总条数,M。第二遍:扫描每条日志以N/M的概率选择该条日志,直到满足N条日志。解法2:由于每条日志的最大长度为100字节,因此日志数量至少有K = 1G条,原创 2012-03-22 10:39:48 · 5844 阅读 · 2 评论 -
重载new和delete来防止c++工程中内存泄漏
在C/C++中指针给编码带来的极大的方便,但是同时由于分配的指针需要编程人员自行释放内存,因此容易造成内存泄漏,C++中自带的new/delete本身没有提供内存泄漏检测的功能,不过我们可以重载这两个函数来追踪内存的分配和释放,以此来检测程序是否出现了内存泄漏。算法的思想是在new一块内存时将该块内存的地址以及出现的文件和行号信息记录到一个map数据结构中,以内存地址作为key。释放该内存时将ma原创 2012-04-08 15:29:54 · 7965 阅读 · 0 评论 -
寻找无序数组中的第K大数
利用快速排序的思想,其中K从1开始int quicksort(int * x , int l , int r , int k){ if(l == r && k==1)return x[l]; int i , j ; for(i=l-1 , j=l;j<r;j++) if(x[j]<x[r])std::swap(x[++i] , x[j]);原创 2012-02-08 23:07:19 · 2256 阅读 · 0 评论 -
布隆过滤器在网页去重中的应用
//关于布隆过滤器在URL去重中的应用//问题背景/**假设你想从网上(新浪新闻)去下载一批网页,做信息检索(搜索引擎)的第一步.你已经从网上下载下来了一批网页,并且有这批网页的URL,不过你还有一批需要下载的网页的URL,问题是这样的,如果有些URL已经被下载过了,你就不必要再次下载了,现在让你快速的识别出哪些URL上的是还没被下载的,可以有一定的误差,但是不能超过1%。.**/原创 2012-02-08 16:18:56 · 2580 阅读 · 0 评论 -
C++内存池的实现实例
本节分析在某个大型应用程序实际应用到的一个内存池实现,并详细讲解其使用方法与工作原理。这是一个应用于单线程环境且分配单元大小固定的内存池,一般用来为执行时会动态频繁地创建且可能会被多次创建的类对象或者结构体分配内存。本节首先讲解该内存池的数据结构声明及图示,接着描述其原理及行为特征。然后逐一讲解实现细节,最后介绍如何在实际程序中应用此内存池,并与使用普通内存函数申请内存的程序性能作比较。转载 2012-02-02 13:29:19 · 4929 阅读 · 0 评论 -
判断是否为欧拉图的并行算法
欧拉图:一个图为欧拉图,当且公当有一条回路经过图的每一条边且恰好经过一次。欧拉定理表明:一个图为欧拉图,当且仅当不含有奇度数的顶。假设图G大小为M * N和邻接矩阵A。 判断一个图是否为欧拉图,很容易在O(M*N)的时间内完成。为了说明方便,下面设M = N下面给出复杂度为O(Log(N)) 并行算法,注意这里只给出理论上可行的算法。1. 计算每个点原创 2012-02-01 00:17:09 · 5951 阅读 · 1 评论 -
读写锁算法
背景:在多线程编程中经常面临这样一个问题,同一个数据可以被多个线程同时读取,但是同一时间只能有一个线程对共享变量进行写操作。对该问题常用的解决方法时声明一个锁(互斥量)来对共享变量进行保护,这样每次只能有一个线程来对数据进行读写,会导致读取的效率低下。读写锁:读写锁算法主要实现对共享资源访问时,可以在多个线程间同时进行读操作,但是在同一时间内只能有一个线程对共享资源进行修改,并且在原创 2012-01-29 17:04:24 · 4141 阅读 · 0 评论 -
一个简单问题的并行算法
设一个数列S[N], 其中S[0] = 0; S[k] = S[k - 1] + k ( 1 对于这个问题的求解串行算法相当简单,O(N)时间复杂度,不再解释。并行:假设有 M 个线程, 其中 M S[K] = S[K - 1] + K = S[K - 2] + K - 1 + K= S[K - 3] + K - 2 + K - 1 + k...= S[K原创 2012-01-30 16:48:19 · 1898 阅读 · 1 评论 -
有序数组合并的并行算法(有一定限制)
如果A=(a1,a2,...,am)和B=(b1,b2,...,bn)是两个有序的升序数组,合并数组A和B就行形成一个新的升序数组包含A和B的有所有元素,假设A=(2,4,11,12,14,35,95,99),B=(6,7,9,25,26,31,42,85,87,102,105).如果合并A和B的数组,串行算法会遍历两个数组,然后将数组元素存到数组C中,开始时设置两个指针,分别指向数组A和B的原创 2012-01-28 16:03:34 · 2954 阅读 · 0 评论 -
一组字符串散列函数
unsigned int RSHash(const std::string& str){ unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; for(std::size_t i = 0; i { hash = hash * a +原创 2012-01-07 17:17:31 · 669 阅读 · 0 评论 -
小量压缩简单算法
本方介绍一种简单的数据压缩算法:SB (simple block)作者:realxie在对文档进行倒排的时候经常涉及到对倒排文档的压缩,例如假设有单词instance 出现的文档有<1,3 ,4 , 6 ,9 ,10,... >,即倒排表以升充排列,这样我们就可以在倒排文件中只保存前后两个文档位置的差量,即转变之后结果为<1 ,2 , 1 , 2 , 3 , 1 , ...>,原创 2012-02-08 23:05:03 · 3773 阅读 · 2 评论 -
TBB(intel threading building blocks)内存分配算法(一)
开篇:最近研究了一下TBB的内存分配算法,发现设计的非常优雅,故和大家分析一下它的算法思想。既然是开篇,那么我们就先从最基本的入手来看一下TBB基于Cache对齐的内存管理算法。首先来明确几个概念。cache: 现代的cpu都引入的cache的概念,即cpu在参与运算时并非每次都去内存中取得数据的,而是将内存中的一部分数据直接存储在cpu的cache中,cpu中的cache采用的静态随机存原创 2012-02-11 15:14:46 · 6809 阅读 · 0 评论 -
c++/cpp中auto_ptr用法分析
本文将分析一下c++中自带的auto_ptr在使用中需要注意的一个问题。首先看一段代码:// auto_ptr example#include #include using namespace std;int main () { auto_ptr p1 (new int); *p1.get()=10; { auto_p原创 2012-04-08 11:30:02 · 6021 阅读 · 1 评论 -
判断一段文件是UTF-8编码还是GB2312的编码方式
对于只包含中文和英文的文本中判断编码方式是非常简单的,中文的编码方式最常用的是GBK,字符集更大的如GBK向下兼容GB2312,其中包含的的很多一部分字符是我们在日常生活中用不到的,因此在实际中我们一般只需要区分GB2312和UTF8编码。这里我只是提供一种可行的方法,如果判断GBK也可以采用类似的方式首先分析一下汉字在GB2312中的编码方式,gb2312规则汉字采用双字节编码其中第一字节161原创 2012-03-10 16:01:18 · 17865 阅读 · 1 评论 -
一道网易笔试题目-几何相关
两个圆相交,交点是A1,A2。现在过A1点做一直线与两个圆分别相交另外一点B1,B2。B1B2可以绕着A1点旋转。问在什么情况下,B1B2最长?当A1A2⊥B1B2时B1B2最长设弦A1B1、A1B2所在圆分别为⊙O1、⊙O2,取A1B1、A1B2的中点C、D,连结O1C、O2D则B1B2=A1B1+A1B2=2A1C+2A1D=2CD当A1A2与B1B2不垂直时,四边形O1O2DC原创 2012-03-24 15:32:21 · 4447 阅读 · 0 评论 -
浅谈Intel QPI的MESIF协议和Home,Source Snoop
Intel的Nehalem一出,CPU江湖顿时失色。其中北桥FSB被灭,CSI/QPI兴起是一个重要因素。也正式宣告了Parallel Bus在处理器领域的王牌地位退出,和Serial Bus或者Point2Point互联的统治地位的诞生。。。:走的快(Parallel Bus)不如走的远(Serial Bus)。QPI的互联,其中Cache的一致性是一个关键。其协议是什么?MES转载 2012-03-04 11:29:29 · 8808 阅读 · 1 评论 -
MESI-CPU缓存一致性协议
MESI(Modified Exclusive Shared Or Invalid)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出)是一种广泛使用的支持写回策略的缓存一致性协议,该协议被应用在Intel奔腾系列的CPU中,详见“support the more efficient write-back cache in addition to the write-through ca翻译 2012-03-04 13:39:30 · 21480 阅读 · 10 评论 -
cpp程序性能优化
1. 重中之重 - 算法优化: 程序性能优化最显著的优化方法是算法上的优化,算法的优化对性能的提升往往是一个数量级的,例如排序,冒泡的时间复杂度为O(N^2),而快速排序的时间复杂度为O(Nlog(N)),这种性能的提供是非常明显的。 2. 消除冗余的循环: 我们先看一下for循环生成的汇编代码for (int N = 4原创 2012-02-18 18:55:53 · 2951 阅读 · 0 评论