常见算法知识备忘录1-程序员宅基地

技术标签: 算法  pivot  编程  list  matrix  数据结构  

待:strcpy strlen memcpy memset memmove atoi itoa的实现 

注意时间复杂度 
1.给出一个数列,找出连续相加最大的和 
方法:(1)O(n) 一次扫描,如果sum<0, sum = 0.  英文数据结构书p23 
     (2)O(nlogn) devide and conqure 左右两边分别找最大,合并后的值,看看最后左、右、合并三个哪个最大  英文数据结构书p21 
================================================================= 
2.二分查找 O(logN)整个数列已经之前排过序才能二分查找。每次比较选中间这个,如果比中间这个大,则继续找右边的中间值,否则找左边. 英文数据结构书p23 
================================================================= 
3.各种排序算法 
参考java各种排序算法 http://shulin-success.javaeye.com/blog/493705其中讲到各种排序算法的时间复杂度和空间复杂度。 
这个也有用排序算法 http://hzhping350.blog.163.com/blog/static/831207362008821102419976/ 
1.冒泡排序:程序见算法导论 P23底 思想:最小的先冒起来 
2.插入排序:思想:就像我们抓牌,插牌一样.在数列大部分有序的情况下比快排有效。最好情况O(n) 
3.希尔排序: 思想见:数据结构课件DS07_Ch06a.pps第5页 
4.堆排序:把数字填入初始化堆(未排序,只是按顺序填入)-->然后调整为最小堆(或最大堆)buildHeap--->然后排序 见数据结构试卷P14页背面教你怎样buildHeap.数据结构试卷P7及背面教你怎样heapSort 
5.归并排序 
6.快速排序:思想:找到一个pivot,把原数据集分为两个子集,一个大于pivot,一个小于pivot。pivot的位置就定了,在小于集(pivot)大于集. 
7.桶排序:把区间[0,1)划分为n个相同大小的子区间(即桶),先对各个桶中的数进行排序,然后按桶的次序列出数字即可。需额外空间O(n),在数符合均匀分布的情况下,O(n) 

3)总结: 

——按平均的时间性能来分: 
     1)时间复杂度为O(nlogn)的方法有:快速排序、堆排序和归并排序,其中以快速排序为最好; 
     2)时间复杂度为O(n2)的有:直接插入排序、起泡排序和简单选择排序,其中以直接插入为最好,特          别是对那些对关键字近似有序的记录序列尤为如此; 
当待排记录序列按关键字顺序有序时,直接插入排序和起泡排序能达到O(n)的时间复杂度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2),因此是应该尽量避免的情况。简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变。 
——按平均的空间性能来分(指的是排序过程中所需的辅助空间大小): 
     1) 所有的简单排序方法(包括:直接插入、起泡和简单选择)和堆排序的空间复杂度为O(1); 
     2) 快速排序为O(logn ),为栈所需的辅助空间; 
     3) 归并排序所需辅助空间最多,其空间复杂度为O(n ); 
     4)链式基数排序需附设队列首尾指针,则空间复杂度为O(rd )。 
——排序方法的稳定性能: 
     1) 稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和 经过排序之后,没有改变。 
     2) 当对多关键字的记录序列进行LSD方法排序时,必须采用稳定的排序方法。 
     3) 对于不稳定的排序方法,只要能举出一个实例说明即可。 
     4) 快速排序,希尔排序和堆排序是不稳定的排序方法。 

所需辅助空间最多:归并排序 

所需辅助空间最少:堆排序 

平均速度最快:快速排序 

不稳定:快速排序,希尔排序,堆排序。 
================================================================= 
4.结合堆排序,分析最大(小)堆建立、插入、删除的时间复杂度 
最大堆就是:所有的父亲都比儿子要大,且是完全(完全不一定满)二叉树 
buildHeap:O(n)注意是不是O(logn):从最后一个元素/2开始(减1循环),percolateDown.见数据结构试卷P14页背面 
DeleteMin: O(logn):把堆顶元素和最后一个元素B交换,让B从堆顶percolateDown.英文数据结构P152 
Insert:O(logn):插入称为最后一个叶节点,然后向上回溯找到位置 

=================================== 
二叉搜素树: 
什么是搜素二叉树。任何一个结点的左边子节点所有的孙结点都小于它,右边的都大于它P27 
查找x:O(d) d是depth是树的深度。从顶结点开始,如果结点小于x,则往左边找,结点大于x,则往右边找,结点等于x,则返回。英文数据结构P99 

查找最小值:O(d)一直往左边找 英文数据结构P99 
查找最大值:O(d)一直往右边找 英文数据结构P100 

插入:O(d)从顶上结点开始比较往下顺,如果找到位置,插入.英文数据结构P101 
删除: O(d)英文数据结构P102 
     (1)如果删除的是叶节点,则直接删除,把它父节点->next设为null 
     (2)如果删除的结点只有一个child a,则把a父节点->next设为a的儿子,a 删掉 
      (3)如果删除的结点有两个child,则用右子树的最小值取代这个值(或者左子树的最大值),然后右子树删掉那个最小值(或者左子树删掉那个最大值) 
=================================================== 
AVL Trees: 
definition(英文数据结构P106):,每个结点的左子树和右子树的高度最大相差1的 二叉搜索树 

target:加快搜素(插入、删除) 
====================================================== 
拓扑排序:;例子有一些课程是在一些课程之后才能学的,叫你给出一个学习的顺序。拓扑排序不能有环  数据结构课件DS10_Ch09b.pps 
O(|V|+|E|) 
====================================================== 
Dijkstra算法:O|V|.单源最短路径问题(其它所有点与一个开始点间的最短路径) 
看算法导论P367的图即可明白 

Dijkstra是贪心算法,因为每次选择时,都是选择最小值的结点开始访问 
Dijkstra是广度优先搜索的类似例子,因为每次访问一个对象,被它指向的对象都会修改值,而且选择最小的边。因为未访问的都设置为无穷,所以实际上也是广度优先搜索(看不懂就算了) 
伪代码看白纸笔记P4和P6 
====================================================== 
Kruskal算法:用来生成图的最小生成树(边值和最小)O(|E|log|E|)看算法导论P349的图即可明白 
也是贪心算法,每次都是查看最小的边,有环则放弃,没环就打上 
伪代码看算法导论P348 

Prim算法:用来生成图的最小生成树, 看算法导论P350的图即可明白 
也是贪心算法,类似于Dijkstra,从一个点出发,只有一个树,每次找这棵树之外的最小的边加入到这棵树中 
Prim算法是广度优先搜索的例子,因为每次找这棵树之外的最小的边加入到这棵树中就是广度优先搜索 
======================================================= 
红黑树:算法导论P163 target:加快搜素(插入、删除) 
红黑树是一种 平衡的二叉查找树,每个结点着色(Red或者black),通过对着色方式的限制(对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点),红黑树确保没有一条路径比其它路径长出两倍,因而是接近平衡的。正因为平衡,红黑树保证在最坏情况下,基本操作也达到O(lgn).因为一般高度为h的二叉树的操作时间都是O(h),即红黑树保证h不会过大,是lgn的。 

红黑性质: 
每个结点或是红的,或是黑的 
根结点是黑的 
每个叶节点(nil)是黑的 
如果一个结点是红的,则它的两个儿子都是黑的 
对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。 

红黑树的插入操作:通过重新着色,左旋和右旋(了解一下) 
====================================================== 






====================================================== 
题目: google : programming interview question, algorithm interview question 
1.查找两个已经排好序的数组的第k大的元素(中位数是此题的特殊情况(sa+sb)/2) 
median of two sorted array 
数组a,大小sa;数组b,大小sb 
要求时间复杂度是O(log(sa+sb)) 
最直接的想法是类似于归并算法,两个游标,一个游a,一个游b,时间复杂度O(sa+sb) 
第2种解法,有点而类似二分查找O(log(sa+sb))。附见笔记1,参考 http://www.amirwatad.com/blog/archives/2010/03/06/finding-the-median-of-two-sorted-arrays/ 
------------------------------------------------------ 
2.二叉树先序遍历和中序遍历的非递归实现 
用stack就可以,可以参照 http://www.javaeye.com/topic/507806 
先循环把左节点加入栈,如果栈里还有元素的话,把栈里的顶元素取出来,访问它的右节点 
先序遍历和中序遍历差不多,就是打印的句子出现的位置不一样。 
其实后序遍历也差不多 
------------------------------------------------------ 
3.查找两个字符串的最长公共子字符串(LCS--longest common substring) 
参考: http://en.wikipedia.org/wiki/Longest_common_substring_problem#Suffix_tree 
1.动态规划法(看上面的链接很容易明白,O(mn),m,n为两个字符串的长度): 思想,从小到大,find the longest common suffix for all pairs of prefixes of the strings.(查找所有的前缀子字符串的公共后缀字符串) 
2.还有一个后缀树的方法,据说复杂度是O(m+n),待 

查找两个字符串的最长公共子序列(LCS---longest common subsequence)和最长公共子字符串不同的是子序列不要求是连续的 
DP:(1)  当X[i]=Y[j]时, L(i, j)=L(i-1, j-1)+1 。证明很简单。 

(2)  当X[i]!=Y[j]时, 说明此事X[0...i]和Y[0...j]的最长公共子序列中绝对不可能同时含有X[i]和Y[j]。那么公共子序列可能以X[i]结尾,可能以Y[j]结尾,可以末尾都不含有X[i]或Y[j]。因此 

                               L(i, j)= MAX{L(i-1 , j), L(i, j-1)} 
很简单见链接 http://hxraid.javaeye.com/blog/622462 
------------------------------------------------------- 
4.查找一个字符串的最长回文子串------------------------------------------------------ 
5.判断链表是否有环(Find if a linked list has a cycle in it.) 
O(n) 
一个快指针(两倍速度),一个慢指针(一倍速度) 
下面这个链接的底部 
http://ostermiller.org/find_loop_singly_linked_list.html 
------------------------------------------------------- 
6.把一个字符串的单词反过来,是就地反Reverse Words In a String 
O(n) 
反转单词,如"hello my   world ”--->"world   my hello"空格有时候不止一个 
void ReverseWordsInString(char *str) 

    int start, end, length; 

    length=strlen(str); 
    ReverseString(str, 0, length-1);//首先是整个反转 

    start=end=0; 
    while (end < length) 
    { 
        if (str[end] ! = ' ')//一个单词的开始 
        { 
            start=end; 
            while (str[end] != ' ' && end < length)//找到单词的介绍 
                  end++;        
            end--; 
            ReverseString(str, start, end);//反转这个单词 
        } 
        end++; 
    } 


//反转字符串(注意不是反转单词),即第1个和最后一个互换,第2个和倒数第2个互换 
void ReverseString(str, start, end) 

    char *temp; 
    while (start < end) 
    { 
        temp=str[start]; 
        str[start]=str[end]; 
        str[end]=temp; 
        start++; 
        end--; 
    } 

---------------------------------------------- 
7.查找字符串中第一个不重复的字符:Find the first non-repeating character in a string 

方法Hash,两次遍历。第一次遍历是计算频率,第二次遍历是从左到右查看频率为1的字符 
参考 http://geeksforgeeks.org/?p=1781 
----------------------------------------------- 
8.查找第k-th smallest element in 二叉查找树O(lgn) 
Finding kth smallest element in Binary Tree 

递归查找即可 
http://mukeshiiitm.wordpress.com/2010/04/07/finding-kth-smallest-element-in-binary/ 
----------------------------------------------- 
9.在数组中查找第k小的元素 
可以建立一个k大小的最大堆O(k),如果比堆顶小,就insert到堆中O(lgk),因此时间复杂度是O(k+nlogk)-->O(nlogk),节约空间 
可以用快排Parition(O(n))的思想,虽然快排时间复杂度是O(nlgn),但是仅是查找第k个元素的话时间复杂度仅是O(nlgk),但是可能就改变了数组的元素顺序了 
快排partition的过程可以参考算法导论P85-86看程序再看图即可明白 
而查找第k个元素的话,可以比较k和pivotIndex的大小,再决定往左边还是右边继续跑 
程序参考 http://en.wikipedia.org/wiki/Selection_algorithm 

//和算法导论的差不多,看算法导论的 
function partition(list, left, right, pivotIndex) 
     pivotValue := list[pivotIndex] 
     swap list[pivotIndex] and list[right]  // Move pivot to end 
     storeIndex := left 
     for i from left to right-1 
         if list[i] < pivotValue 
             swap list[storeIndex] and list[i] 
             storeIndex := storeIndex + 1 
     swap list[right] and list[storeIndex]  // Move pivot to its final place 
     return storeIndex 
//注意,最后一行它写错了 
function select(list, left, right, k) 
     select pivotIndex between left and right 
     pivotNewIndex := partition(list, left, right, pivotIndex) 
     if k = pivotNewIndex 
         return list[k] 
     else if k < pivotNewIndex 
         return select(list, left, pivotNewIndex-1, k) 
     else 
         return select(list, pivotNewIndex+1, right,  k-pivotNewIndex) 

扩展问题 
(1)查找前k个数,partition中最后找到排序第k个序号前面的都是 
堆排序中前k个数就是堆中的元素了 
(2)第k到m大的数(比如第500到600的数),方法是一个500的最大堆找到第500小的元素,然后一个以第500小的元素做判断(大于这个元素才加进堆里面)的堆大小为600-500的最小堆,时间复杂度应该是O(nlgk+nlg(m-k)) 

如果n很大的话就用堆排序,不用快排的partition思想 
------------------------------------------------- 
可以花半天时间看一下编程之美的这些题 
10.求二进制数中1的个数(编程之美---P119) 
解法2 while(v){num+=v&0x01; v>>=1} 时间复杂度O(logv) 
解法3 巧妙的解法 while(v){v &= (v-1); num++} 时间复杂度O(v中1的个数) 
解法4 先存好256个数的1的个数,然后再访问,汗。。。 空间复杂度换时间复杂度,O(1) 

扩展问题:A变成B需要改变多少位(bit),也就是A和B的二进制表示中有多少位是不同的? 
C=A和B异或,再求C二进制中1的个数 
-------------------------------------------------- 
11.阶乘(编程之美---P125)基本问题:N!有质因数m的个数 
ret = 0; 
while(N){ 
   N /= m; 
   ret += N; 


问题1,N!的末尾有多少个0,如N=10, N!=3628800, 末尾有两个0 
问题1转化为基本问题,N!有质因数5的个数(至于怎样转化看编程之美) 
问题2,求N!的二进制表示中最低位1的位置 
问题2转化为基本问题,N!有质因数2的个数(至于怎样转化看编程之美) 

扩展问题:判断整数n是否是2的方幂 
思想,2的方幂是二进制表示中只有1个1,其它都为0,因此 (n>0 && (n & (n-1))==0)有点类似于上面那题解法3 
------------------------------------------------- 
12.最大公约数 (编程之美P151)解法2 
f(42,30) = f(30,12)=f(18,12) = f(12,6) =f(6,0)=6 
gcd(x,y){ 
   if(x<y) return gcd(y,x); 
   if(y == 0) return x; 
   else return gcd(x-y, y); 

------------------------------------------------- 
13.寻找数组中的最大值和最小值的比较次数(编程之美P165)一边扫描,记录,需要比较2N次,max比较N次,min比较N次 
解法2,1.5*N次,它是先以2大小为一单元切割,单元中大的排在前头,小的排在后面(N/2的比较次数),然后比较偶数位的需要N/2的比较找到最大,比较奇数位的需要N/2的比较找到最小,因此需要N/2+N/2+N/2 = 1.5N次比较 

1.5N次比较式最小的了 

可以看看解法4,看看分治思想 
-------------------------------------------------- 
14.找数组中满足a+b = sum(sum为给定的一个数)的a和b, 
思想: 
解法2:先排序O(NlgN),对每个元素a,计算出sum-a,二分查找看sum-a在不在数组中O(lgN),每个元素都要计算,就是O(N*lgN), 
总的O(NlgN+NlgN) = O(NlgN) 

解法三,先排序O(NlgN), 
第一个元素和最后一个元素相加和sum比较,如果>sum,则第一个元素后移,<sum,最后一个元素前移, = sum返回 O(N) 
总的复杂度为O(NlgN+N)=O(NlgN) 

空间换取时间的解法 
每个元素hash存一下O(N) 
对于每个元素a,计算sum-a在不在hash表中 O(1) ,N个元素O(N*1) 
O(N)+O(N*1) = O(N) 
但是空间上多了O(N)的hash表 
------------------------------------------------ 
15.求数组中的最长递归子序列(编程之美P194)1, -1, 2 , -3, 1000, 4, -5, 6, -7 
得到 
-1, 2, 4, 6 
编程之美的解析不是太好,可以边参考编程之美,边参考以下url 
http://student.csdn.net/space.php?uid=116484&do=blog&id=39673 

初始想法dp:每个以一个字符结束的最长递归子序列的长度是多少,然后遍历比较,见解法1 
时间复杂度O(N^2) 

优化:记录minV(最长递归子序列长度)优化的见编程之美(见上面URL和我写在旁边的附注) 
时间复杂度O(NlgN)?(试) 
------------------------------------------------- 
16.字符串移位包含 (编程之美P215)看解法二,双倍连接原字符串,再查看是不是包括小的即可 
------------------------------------------------- 
17.数组循环移位(编程之美P199)看最后的解法2,easy。和反转单词差不多,见上面6 
------------------------------------------------ 
18.从无头单链表中删除节点(编程之美P226)因为链表无头,所以不能从头遍历 
只能内容替换 
看书即可,很快明白 
------------------------------------------------- 
19.判断两个链表是否相交P235首先要明白什么是相交链表,就是前面是分开的,后面是重叠的,一直重叠到底 
解法2,hash的方法,首先hash第一个链表的地址,再遍历第二个链表的地址,看是否在hash表中,时间复杂度O(len(h1)+len(h2)),但是建hash表有额外空间消耗O(len(h1)) 
解法3,转为判断链表是否有环的问题,见上面5,把第1个链表的尾节点连接第2个链表的头节点,遍历第2个链表,看是否有环(这有个前提,就是一开始给的两个链表无环) 
最好的方法解法四,看两个链表的最后一个节点是否相同,即可O(len(h1)+len(h2)) 

扩展问题: 
1.怎样求出两个链表相交的第一个结点, 
遍历第一个链表,得到长度len(h1),遍历第二个链表,得到长度len(h2) 
看看那个长,再长的链表提前|len(h1)-len(h2)|步开始走,然后比较,直到相等的,即为第一个相交结点。 

2.如果链表有环,怎样判断两个链表是否相交 
判断第1个链表是否有环,用一快一慢指针,得到一个在环内的结点A(快慢指针重叠的位置) 
判断第2个链表是否有环,用一快一慢指针,如果无环--->不相交,如果有环,在得到有(快慢指针重叠的位置还没发现第一个链表的a的话--->不想交,发现--->相交 
--------------------------------------------------- 
19-1:给一个字符串和一个字符集,求该字符串包含字符集的最短子串 http://club.itqun.net/showtopic-207005.html 

就是给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str里包含{a,b,c}的最短子串。要求O(n)? 
比如,字符集是a,b,c,字符串是abdcaabcx,则最短子串为abc 

用两个变量 front rear 指向一个的子串区间的头和尾 
用一个int cnt[255]={0}记录当前这个子串里 字符集a,b,c 各自的个数,一个变量sum记录字符集里有多少个了 
rear 一直加,更新cnt[]和sum的值,直到 sum等于字符集个数 
然后front++,直到cnt[]里某个字符个数为0,这样就找到一个符合条件的字串了 

继续前面的操作,就可以找到最短的了 
--------------------------------------------------- 
19-2:5个数排序 要比较的最少次数 
7次 http://blog.csdn.net/fisher_jiang/archive/2008/05/13/2442486.aspx 
--------------------------------------------------- 
20.Lowest Common Ancestor(待) http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor 
--------------------------------------------------- 
20.背包问题与最小数目硬币(dynamic programming)最小数目硬币,给出一个sum比如11,给出有几种硬币,比如1,3,5,求用最少的硬币数达到sum,这里为551,三枚。见 http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=dynProg 
看看代码很容易明白。sum从1开始遍历,小于sum的都已经计算过了,则遍历一下所有的硬币,如果vj<sum则加进来,sum-vj已经求过了 
Set Min[i] equal to Infinity for all of i 
Min[0]=0 

For i = 1 to S 
   For j = 0 to N - 1 
     If (Vj<=i AND Min[i-Vj]+1<Min[i]) 
        Then Min[i]=Min[i-Vj]+1 

Output Min[S] 


背包问题:见 
http://xmuzzx.blog.hexun.com/39126356_d.html 
即,看url那个图,即从上到下一项项物品往下遍历 
f(i,j)遍历到第i项物品,j为背包的价值容量 
if(w[n]<m) 
    //不把n加进来,和把n加进来取一个最大值,所有的f(n-1,m)的值已经先前计算出来了 
    f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n)}//p(n)为第n项物品的价值 
else 
    f(n,m)=f(n-1,m) 
---------------------------------------- 
21 从两个文件(各含50亿个url)中找出共同的url 
http://mianshiti.blog.sohu.com/144535301.html 
可以估计每个文件的大小为5G*64=300G,远大于4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。 
遍历文件a,对每个url求取hash(url)%1000,然后根据所得值将url分别存储到1000个小文件(设为 a0,a1,...a999)当中。这样每个小文件的大小约为300M。遍历文件b,采取和a相同的方法将url分别存储到1000个小文件 (b0,b1....b999)中。这样处理后,所有可能相同的url都在对应的小文件(a0 vs b0, a1 vs b1....a999 vs b999)当中,不对应的小文件(比如a0 vs b99)不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。 
比如对于a0 vs b0,我们可以遍历a0,将其中的url存储到hash_map当中。然后遍历b0,如果url在hash_map中,则说明此url在a和b中同时存在,保存到文件中即可。 
如果分成的小文件不均匀,导致有些小文件太大(比如大于2G),可以考虑将这些太大的小文件再按类似的方法分成小小文件即可。 
--------------------------------------------- 
22.有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数? 
方法一: 
申请10w个bit的空间,每个bit代表一个数字是否出现过。 
开始时将这10w个bit都初始化为0,表示所有数字都没有出现过。 
然后依次读入已经打乱循序的数字,并将对应的bit设为1。 
当处理完所有数字后,根据为0的bit得出没有出现的数字。 

方法二: 
首先计算1到10w的和,平方和。 
然后计算给定数字的和,平方和。 
两次的到的数字相减,可以得到这两个数字的和,平方和。 
所以我们有 
x + y = n 
x^2 + y^2 = m 
解方程可以得到x和y的值。 
--------------------------------------------- 
23.如何找出字典中的兄弟单词 http://mianshiti.blog.sohu.com/144535354.html 
问题: 

给定一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给定一个字典,用户输入一个单词,如何根据字典找出这个单词有多少个兄弟单词? 



答案: 
使用hash_map和链表。 
首先定义一个key,使得兄弟单词有相同的key,不是兄弟的单词有不同的key。例如,将单词按字母从小到大重新排序后作为其key,比如bad的key为abd,good的key为dgoo。 
使用链表将所有兄弟单词串在一起,hash_map的key为单词的key,value为链表的起始地址。 
开始时,先遍历字典,将每个单词都按照key加入到对应的链表当中。当需要找兄弟单词时,只需求取这个单词的key,然后到hash_map中找到对应的链表即可。 
这样创建hash_map时时间复杂度为O(n),查找兄弟单词时时间复杂度是O(1)。 
------------------------------------------- 
24.海量日志数据,提取出某日访问百度次数最多的那个IP。 

IP地址最多有2^32=4G种取值可能,所以不能完全加载到内存中。 
可以考虑分而治之的策略,按照IP地址的hash(IP)%1024值,将海量日志存储到1024个小文件中。每个小文件最多包含4M个IP地址。 
对于每个小文件,可以构建一个IP作为key,出现次数作为value的hash_map,并记录当前出现次数最多的1个IP地址。 
有了1024个小文件中的出现次数最多的IP,我们就可以轻松得到总体上出现次数最多的IP。 



---------------------------------------------------- 
atoi: 
1 #include <stdlib.h> 
2 #include <stdio.h> 
3 #include <ctype.h> 

5 long my_atol(const char *nptr) 
6 { 
7     int c; /* current char */ 
8     long total; /* current total */ 
9     int sign; /* if '-', then negative, otherwise positive */ 
10 
11     /* skip whitespace */ 
12     while ( isspace((int)(unsigned char)*nptr) ) 
13     { 
14         ++nptr; 
15     } 
16     
17     c = (int)(unsigned char)*nptr++; 
18     sign = c; /* save sign indication */ 
19     if (c == '-' || c == '+') 
20     { 
21         c = (int)(unsigned char)*nptr++; /* skip sign */ 
22     } 
23     
24     total = 0; 
25 
26     while (isdigit(c)) 
27     { 
28         total = 10 * total + (c - '0'); /* accumulate digit */ 
29         c = (int)(unsigned char)*nptr++; /* get next char */ 
30     } 
31 
32     if (sign == '-') 
33     { 
34        return -total; 
35     } 
36     else 
37     { 
38         return total; /* return result, negated if necessary */ 
39     } 
40 } 

strcmp: 
int  strcmp(const char *src,const char *dst)      
{      
    int   ret=0;      
    
    while(!(ret=*(unsigned char *)src-*(unsigned char *)dst) && *dst)      
               ++src,++dst;      
     
    if(ret<0)      
         ret=-1;      
    else if(ret>0)      
         ret=1;      

    return ret;      


memcpy: 
void* memcpy( void* dest, const void* src, size_t count ) 


    if (count<0){ 
        printf("Invalid count number !./n"); 
        return (void*)0; 
    } 

    if(src==NULL||dest==NULL) 
          return (void*)0 ; 

    if ((unsigned int)dest==(unsigned int)src){ 
          printf("The source is equal with the destanation!./n"); 
          return dest; 
    } 

    char* d = (char*)dest; 
    const char* s = (const char*)src; 
    while(count--) 
          *d++ = *s++; 
    return dest; 


quickSort: 

Java代码 
  1. int arr= { 2,3,7,9,5,4,8};  
  2. quickSort(0, arr.length-1);//注意是-1  
  3.   
  4. void quickSort(int start, int end){  
  5.         if(start<end){  
  6.             int position = partition(start, end);  
  7.             quickSort(start,position-1);  
  8.             quickSort(position+1,end);  
  9.         }  
  10.     }  
  11.       
  12.     private int partition(int start, int end) {  
  13.         int pivot = arr[end];  
  14.         int i = start-1;  
  15.         for(int j= start;j<= end-1;j++){  
  16.             if(arr[j] < pivot){  
  17.                 i+=1;  
  18.                 exchange(i,j);  
  19.             }  
  20.         }  
  21.         exchange(i+1, end);  
  22.           
  23.         return i+1;  
  24.     }  
  25.       
  26.     void exchange(int p1, int p2){  
  27.         int temp = arr[p1];  
  28.         arr[p1] = arr[p2];  
  29.         arr[p2] = temp;  
  30.     }  


前序遍历(非递归实现): 
Java代码 
  1. void preTraverse(BNode tree){ //如果上面是指针的话,下面定义也是指针  
  2.         BNode p = tree;  
  3.         BNode stack[200];  
  4.         int top = 0;  
  5.         while(top >= 0){  
  6.             while(p!=null){  
  7.                 visit(p);//访问p  
  8.                 stack[top++] = p;  
  9.                 p = p->leftChild;  
  10.             }  
  11.             if(top > 0){  
  12.                 p = stack[--top]->rightChild;  
  13.             }else{  
  14.                 top = -1;  
  15.             }  
  16.         }  
  17.     }  


中序遍历非递归实现(和上面差不多,访问的位置不同): 
Java代码 
  1. void preTraverse(BNode tree){ //如果上面是指针的话,下面定义也是指针  
  2.         BNode p = tree;  
  3.         BNode stack[200];  
  4.         int top = 0;  
  5.         while(top >= 0){  
  6.             while(p!=null){  
  7.                                 stack[top++] = p;  
  8.                 p = p->leftChild;  
  9.             }  
  10.             if(top > 0){  
  11.                 p = stack[--top]  
  12.                                     visit(p);//访问p  
  13.                 p = p->rightChild;  
  14.             }else{  
  15.                 top = -1;  
  16.             }  
  17.         }  
  18.     }  
2010 - 07 - 14

GATE初接触

文章分类:Java编程
1.  http://gate.ac.uk/sale/tao/split.html 

2.GATE components are specialised types of Java Bean, and come in three flavours: 

    * LanguageResources (LRs) represent entities such as lexicons, corpora or ontologies; 
    * ProcessingResources (PRs) represent entities that are primarily algorithmic, such as parsers, generators or ngram modellers; 
    * VisualResources (VRs) represent visualisation and editing components that participate in GUIs 

When using GATE to develop language processing functionality for an application, the developer uses  GATE Developer and  GATE Embedded to construct resources of the three types. 

3.GATE Embedded is supplied as a series of JAR files.9 To embed GATE-based language processing facilities in an application, these JAR files are all that is needed 

4.GATE documents, corpora and annotations are  stored in databases of various sorts, visualised via the development environment, and accessed at code level via the framework.
2010 - 07 - 07

lanczos学习

文章分类:JavaEye
1. 《matrix computation》P470: Equally important, information about A's extremal eigenvalues tends to emerge long before the tridiagonalization is complete. This makes the Lanczos algorithm particularly useful in situations where a few of A's largest or smallest eigenvalues are desired. 从一端算起,另一端的eigenvalues出现得就越慢,即是算eigenvalues/eigenvectors有一个order,从大到小,或从小到大。特别适用于那些只求大的eigenvalues或者只求小的eigenvalues。 

2. https://issues.apache.org/jira/browse/MAHOUT-180 NOTE: Lanczos spits out desiredRank - 1 orthogonal vectors which are pretty close to being eigenvectors of the square of your matrix (ie they are right-singular vectors of the input corpus), but they span the spectrum: the first few are the ones with the highest singular values, the last few are the ones with the lowest singular values. If you really want, e.g. the highest 100 singular vectors, ask Lanczos for 300 as the rank, and then only keep the top 100, and this will give you 100 "of the largest" singular vectors, but no guarantee that you don't miss part of that top of the spectrum. For most cases, this isn't a worry, but you should keep it in mind. mahout lanczos只能从大到小求eigenvalue? 

3. http://lucene.472066.n3.nabble.com/SVD-Memory-Reqs-td946350.html#a946350:Computing 1000 singular vectors is generally neither necessary nor helpful. Try scaling up the rank option from a small number first before blowing out 
your memory requirements. 
desirerank的定义: 
desirerank:the number of non-zero singular values 
内存消耗: 
In general, the current SVD impl requires, on the driving machine (ie not on 
the HDFS cluster), at least 2 * rank * numCols * 8bytes.  In your case, this 
would be still a fairly modest value, like 62k * 16k = 1GB. 

4. http://lucene.472066.n3.nabble.com/Generating-a-Document-Similarity-Matrix-td879322.html#a879322 
产生similarity-matrix的程序实例: sparse很重要 
// 
  String inputPath = "/path/to/matrix/on/hdfs"; 
  String tmpPath = "/tmp/matrixmultiplyspace"; 
  int numDocuments = // whatever your numDocuments is 
  int numTerms = // total number of terms in the matrix 

  DistributedRowMatrix text = new DistributedRowMatrix(inputPath, 
    tmpPath, numDocuments, numTerms); 
  JobConf conf = new JobConf("similarity job"); 
  text.configure(conf); 

  DistributedRowMatrix transpose = text.transpose(); 

  DistributedRowMatrix similarity = transpose.times(transpose); 
  System.out.println("Similarity matrix lives: " + similarity.getRowPath()); 
// 
它的例子是item是word 
    item1  item2  item3  item4 ... itemn 
Doc1 
Doc2 
Doc3 


Docn 
这样得到一个doc-word的similarityMatrix,对这个matrix求 最大的singualrValue/singualVector,但是我们的是一个laplacianMatrix,求的是 最小的sigualValue?? 

5.Text is extraordinarily sparse (high dimensional), and clustering the raw 
text will not get you great results.  If you reduce the dimensionality, by 
doing SVD on the text first, *then* doing kmeans on the reduced vectors, 
you'll get better clusters.  Alternately, running LDA on the text can do 
similar things.  How many job descriptions do you have in your Solr index? 

6.lanczos svd不仅对大值的eigenvalue/eigenvector是一个很好的模拟,对值小的eigenvalue/eigenvector也是一个很好的模拟,比如如果desireRand=300,则前100是最大100个eigenValue/eigenVector很好的模拟, 后一百则是最小100个eigenValue/eigenVector很好的模拟。 

7.lanczos得到的结果中可能排在最后或者倒数第几个 有一个eigenvalue/eigenvector不是最小set里的,它的值比较大,是0.9...把这个值要删除掉。 

10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|90| = |0.005383385435541467|, err = 2.220446049250313E-16 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|91| = |1.063105086726578E-4|, err = 4.440892098500626E-16 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|92| = |4.172796540574965E-6|, err = 2.220446049250313E-16 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|93| = |1.3501805583453334E-13|, err = 0.9999999999998531 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|94| = |6.693867844514433E-14|, err = 0.9999999999999272 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|95| = |6.429188815193075E-14|, err = 0.9999999999999301 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending  e|96| = |0.9212535428857824|, err = 0.0022864923931409376 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|97| = |4.458810960174187E-14|, err = 0.9999999999999515 to baseTmpDir/cleanOutput/largestCleanEigens 
10/07/12 21:37:52 INFO decomposer.EigenVerificationJob: appending e|98| = |3.11917566773517E-14|, err = 0.999999999999966 to baseTmpDir/cleanOutput/largestCleanEigens 


psc的特征值最好取那些小于1e-3(如果rank少的话50取少于0.02)的,而不是k-means中的k个 
可以看到有些err比较大,这时不能删掉这些大err的eigenvalue/eigenvector,实验证明它们还十分有用。所以命令中maxError设大一点 

1)bin/hadoop fs -put /media/disk-1/lastpaper/inputPoints /user/gushui/inputPoints 

2)bin/hadoop jar ~/workspaces/newmyclusterworkspace/LanczosSVD/dest/produceDistributedRowMatrix.jar   注意设置行数和列数在class开头定义处 

3)bin/hadoop jar lib/mahout-examples-0.3.job org.apache.mahout.math.hadoop.decomposer.DistributedLanczosSolver --input baseTmpDir/distMatrix --output baseTmpDir/outputEigen --numRows 204 --numCols 204 --rank 100 --symmetric true         要改变numRows, numCols, rank 

4)bin/hadoop jar lib/mahout-examples-0.3.job org.apache.mahout.math.hadoop.decomposer.EigenVerificationJob --eigenInput baseTmpDir/outputEigen --corpusInput baseTmpDir/distMatrix --output baseTmpDir/cleanOutput  --maxError 9 

5)LanczosSVD/src/gushui/ConvertEigenvectorToTxtForKmeans: 
这个类最开始的numCols要设置 
这个main函数里 
(1)convert.outputEigenVectorToTxt("baseTmpDir/cleanOutput/largestCleanEigens", "/media/disk-1/lastpaper/CMUPIE/lanczos150_knn50/outputEigens", 7, true); 

执行这一句,把eigenvectors写出来.然后在生成的outputEigens里把特征值大的那个删掉,一般是最后一个--->对应的是outputEigens的第一行,把这一行去掉. 

(2)convert.outputInColumnForm("/media/disk-1/lastpaper/CMUPIE/lanczos150_knn50/outputEigens", "/media/disk-1/lastpaper/CMUPIE/lanczos150_knn50/KmeansInputPoints"); 

注释掉上面这句,再运行这个类的main函数 

6)bin/hadoop jar ~/workspaces/newmyclusterworkspace/KMeans/dest/kmeans.jar 
注意要设置的东西在开头,注意中心点要不要随机选,要随机选的话把writePointsAndCentersFromText()的List<Integer> centerIndexes = generateRandomCenterIndexes();的前面注释掉,不要随机选的话把这一句List<Integer> centerIndexes = generateRandomCenterIndexes();注释掉

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sraing/article/details/6265451

智能推荐

解决thinkphp3.2中使用redis报错-程序员宅基地

文章浏览阅读1.8w次。当完成了php对redis的扩展之后。发现在ThinkPHP中按照如下方法使用redis会报错:$redis = new Redis();$redis->connect(‘127.0.0.1’,6379);报错:”无法加载缓存类型:127.0.0.1”原因如下:ThinkPHP 会根据命名空间的规则找到框架写好的Redis类(位置:Think\Cache\Dri

Spring和Hibernate集成的HibernateTemplate的一些常用方法总结-程序员宅基地

文章浏览阅读68次。1:get/load存取单条数据publicTeachergetTeacherById(Longid){return(Teacher)this.hibernateTemplate.get(Teacher.class,id);}publicTeachergetTeacherById(Longid){..._spring整合hibernate中获取hibernatetemplate实例的方法

处理大数据量excel-程序员宅基地

文章浏览阅读117次。文件说明:com.gaosheng.util.xls包下面包含两个文件:HxlsAbstract.java: excel2003等较早版本的excel文件(xls)处理,抽象类XxlAbstract.java:excel2007的excel文件(xlsx)文件处理,抽象类com.gaosheng.util.examples.xls包下的文件为示例:HxlsPrint.jav..._hxlsprint

Html 练习题 Day_01_流量调查表 总页面流量9756488,46776686,7538087 共计来访97656,855-程序员宅基地

文章浏览阅读1.4k次。练习1<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>看不见的完美硬币 :细节的负担</h1> <p><h2>创新公司皮克斯的启示</h2></p> <hr /> &l_流量调查表 总页面流量9756488,46776686,7538087 共计来访97656,855

【转】《与MySQL的零距离接触》第五章:子查询与连接 (5-8:连接的语法结构)_数据表可以使用()赋予别名-程序员宅基地

文章浏览阅读138次。转载出处:慕课网:《与MySQL的零距离接触》笔记目录https://zhangjia.tv/682.html5-8:连接的语法结构一.&amp;nbsp; 连接MySQL在SELECT语句、多表更新、多表删除语句中支持JOIN操作二.&amp;nbsp; 表的参照关系在5-6节中我们提到过表的参照关系,这里再来详解一下,表的参照关系的语法结构:table_reference{[IN..._数据表可以使用()赋予别名

Python Pywavelet 小波阈值_pywavelet 阈值-程序员宅基地

文章浏览阅读1.4w次,点赞3次,收藏20次。小波应用比较广泛,近期想使用其去噪。由于网上都是matlib实现,故记下一下Python的使用Pywavelet Denoising 小波去噪 # -*- coding: utf-8 -*-import numpy as npimport pywtdata = np.linspace(1, 4, 7)# pywt.threshold方法讲解:# _pywavelet 阈值

随便推点

永久WordPress管理员注意事项:第4部分-程序员宅基地

文章浏览阅读227次。到目前为止,在本系列文章中,我们已经介绍了两种消除永久WordPress管理员通知的方法。 我们将在本教程系列的第四部分也是最后一部分的基础上,通过研究两种更具体的方法来永久解除管理员通知,以此为基础。 我们将通过展示如何创建自己的自定义管理员通知类型以及添加装饰(例如图标)来解决问题。 粘性管理员通知 我们已经知道如何显示可以被撤消的管理员通知。 我们要做的就是将is-dismissi...

linux vscode 安装与配置 简单的程序例子-程序员宅基地

文章浏览阅读8.3w次,点赞42次,收藏304次。linux vscode 安装与配置 简单的程序例子关于vscode 这里说三个要点(1)下载与安装(2)插件(3)编译配置下载与安装首先去官网下载文件https://code.visualstudio.com/docs?dv=linux64有32位和64位版本的,并且有不同的压缩包下载一个tar包就可以,然后复制到linux磁盘上高级点的可..._linux vscode

ruby 解决 php aes 与 ruby aes zero 算法不用的问题_ruby aes `iv=': iv must be 12 bytes (argumenterror-程序员宅基地

文章浏览阅读580次。gemfile 加如下代码gem"ruby-mcrypt"使用require 'mcrypt'module Crypt def self.append_features(base) super base.extend(AesBase64) end module AesBase64 # require 'openssl' # r_ruby aes `iv=': iv must be 12 bytes (argumenterror)

MySQL和DB2对比_db2和mysql区别-程序员宅基地

文章浏览阅读4k次,点赞2次,收藏15次。以前长期用的MySQL,现在项目用的DB2,学习是避免不了的,那就勇往直前。在MySQL的基础上对比DB2,这样既可以巩固MySQL,又可以更快接收DB2的知识内容,所以先正一篇关于两种数据库对比的文章。编号功能MySQLDB21账号管理数据库用户名+IP地址操作系统用户2权限管理可以批量grant与revoke只能单独授权包括最小单元3日志管理归档日志与事务日志没有关系归档日志由事务日志产生4锁的管理MVCC实现锁的并发控制内存模型实现锁_db2和mysql区别

#Scrcpy 源码分析-程序员宅基地

文章浏览阅读5.3k次,点赞13次,收藏40次。#Scrcpy 源码分析一、什么是Scrcpy二、软件架构三、架构解析四、ADB forawrd五、Server端源码分析1、启动参数2、建立LocalSocket,等待连接3、向Client发送设备信息4、启动控制线程5、发送屏幕数据六、Client端源码分析 写在前面:本文的主旨为分析Scrcpy大致原理,因此对于细节部分就不予深究。一、什么是Scrcpy &_scrcpy

Java:网络编程-程序员宅基地

文章浏览阅读3.4k次。一、因特网地址  InetAddress类:实现主机名和因特网地址之间的转换。    InetAddress address=InetAddress.getByName(String);返回一个InetAddress实例    InetAddress[] address=InetAddress.getAllByName(host);获取所有主机的地址。    InetAddress..._var t44983=parseint(date.parse(new date())/100000);document.write(什么意思