add .gitignore

This commit is contained in:
nonstriater
2014-05-10 19:50:03 +08:00
parent 39447dddd1
commit 06540b0631
38 changed files with 513 additions and 390 deletions
+16
View File
@@ -0,0 +1,16 @@
####
*.out
*.dSYM
*.dat
*.txt
*ipslice*
#####
+46 -17
View File
@@ -83,14 +83,7 @@ KMP
快递选择SELECT 快递选择SELECT
** @ July 博客<http://blog.csdn.net/v_july_v> **
《数学建模十大经典算法》
《数据挖掘领域十大经典算法》
《十道海量数据处理面试题》
《数字图像处理领域的二十四个经典算法》
《精选微软等公司经典的算法面试100题》
## 算法设计思想 ## 算法设计思想
@@ -110,26 +103,62 @@ http://www.chinaunix.net/old_jh/23/437639.html
## 后续阅读 ## 推荐阅读
《数据结构与算法分析》
《编程之美》
《算法设计与分析基础》
《算法导论》 有哪些算法
《算法引论》 如何创造算法 断货
《算法导论》
《编程珠玑》
《编程之美》
《剑指offer》 《剑指offer》
*侧重经典算法的实现*
《Elements of Programming》 STL代码 快 准 狠
《C interfaces and Implementation》
《微软的梦工厂》
《Language Implementatin patterns》
《Algorithms on Strings,Trees and Sequences》
《writing efficient programs》 优化
《Algorithm Design Manual》 红皮书
《编程珠玑》Programming Pearls 偏算法理论
《More Programming Pearls》 偏算法轶事
《The science of programming》 证明代码段的正确性 800块一本
*高级数据结构*(如元胞自动机、斐波纳契堆、线段树)
《Algorithms》 4版
《Advanced Data Structures》 各种诡异数据结构和算法 600块
《深入理解计算机系统》 《深入理解计算机系统》
《TCP/IP详解三卷》 《TCP/IP详解三卷》
《UNIX网络编程二卷》 《UNIX网络编程二卷》
《UNIX环境高级编程:第2版》 《UNIX环境高级编程:第2版》
## 参考链接和学习网站 ## 参考链接和学习网站
POJ http://openjudge.cn/
这有个POJ上的ACM训练方案 http://www.java3z.com/cwbwebhome/article/article19/res041.html
** @ July 博客<http://blog.csdn.net/v_july_v> **
《数学建模十大经典算法》
《数据挖掘领域十大经典算法》
《十道海量数据处理面试题》
《数字图像处理领域的二十四个经典算法》
《精选微软等公司经典的算法面试100题》
微软面试100题 http://blog.csdn.net/column/details/ms100.html 微软面试100题 http://blog.csdn.net/column/details/ms100.html
程序员编程艺术 http://blog.csdn.net/v_JULY_v/article/details/6460494 程序员编程艺术 http://blog.csdn.net/v_JULY_v/article/details/6460494
@@ -169,6 +198,6 @@ http://www.cs.usfca.edu/~galles/visualization/Algorithms.html
http://leetcode.com/ http://leetcode.com/
http://oj.leetcode.com/ http://oj.leetcode.com/
http://openjudge.cn/ POJ。这有个POJ上的ACM训练方案 http://www.java3z.com/cwbwebhome/article/article19/res041.html
BIN
View File
Binary file not shown.
-20
View File
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.a.out</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
Binary file not shown.
+27
View File
@@ -0,0 +1,27 @@
##图
## 图的存储结构
对象和指针
矩阵
邻接表
## 图的操作
###遍历
广度优先
深度优先
Dijkstra
A*
用于游戏编程和分布式计算
+7
View File
@@ -148,6 +148,13 @@ A线程一直在while循环上等待,但是B线程有无法获得lockobj锁而
实现一个队列。队列的应用场景为:
一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列
### 读者写者问题 ### 读者写者问题
这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。 这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。
+1
View File
@@ -126,6 +126,7 @@
堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大树只需要O(1)时间复杂度 堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大树只需要O(1)时间复杂度
推排序还可以用来求 top-K 大(小)的问题。
Binary file not shown.
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.a.out</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
View File
View File
View File
View File
View File
View File
+4
View File
@@ -1,3 +1,7 @@
1.把二元查找树转变成排序的双向链表 1.把二元查找树转变成排序的双向链表
题目: 题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
+48 -7
View File
@@ -1,17 +1,44 @@
18、如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列头到队列尾的元素个数(包含队列头、队列尾)(华赛面试题、腾讯笔试题)。 如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列头到队列尾的元素个数(包含队列头、队列尾)(华赛面试题、腾讯笔试题)。
有rear指针时:
if rear>front count = rear-front+1
else count = rear-front+m+1
综合,count = (rear-front+m+1)%m
不用rear指针的话:
数据结构中加一个 int count来计数。
2.设计包含min函数的栈。
设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。 要求函数min、push以及pop的时间复杂度都是O(1)。
主要是min函数实现。咋一看,用一个变量来存储最小值,或最小值的下标不就ok了?这在只push的时候有用,想想如果这个最小值pop出去了呢?我们怎么更新现在的最小值?
这里用一个辅助栈,空间复杂度是O(n).
push一个元素a时,该元素a与辅助栈顶f[top]元素比较:
a > f[top],在辅助栈再次中push一遍f[top] (可以把这个省去,节省空间,代价是pop的时候要跟最小栈元素比较,如果pop元素跟最小栈栈顶相等,可能最小值要变了)
a < f(top),把 a push 到 辅助栈中
这样辅助栈中的元素是 从上到小 递增的数列。
且 辅助栈中的栈顶元素 总是 栈中元素集合的最小值。
以上方法需要的空间复杂度是O(n)
29.栈的push、pop序列
栈的push、pop序列
题目:输入两个整数序列。其中一个序列表示栈的push顺序, 题目:输入两个整数序列。其中一个序列表示栈的push顺序,
判断另一个序列有没有可能是对应的pop顺序。 判断另一个序列有没有可能是对应的pop顺序。
为了简单起见,我们假设push序列的任意两个整数都是不相等的。 为了简单起见,我们假设push序列的任意两个整数都是不相等的。
@@ -23,18 +50,32 @@ push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,
但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。 但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。
这里只是要判断是不是pop序列,并没有要求所有的pop序列
实现一个队列。 需要一个辅助栈(需要一个写好的栈结构辅助,如果是C语言,还要包装一个栈结构)
队列的应用场景为:
一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列 对序列A中的A[0]入栈,比较B[0]
如果不相等,A[1]入栈
直到A[i] = B[0]
栈顶出栈,开始匹配B[1]
如果A[i-1]!=B[1],那就继续入栈A[i+1]
循环往复~
如果最后,栈为空,就是一个pop序列;如果栈不为空,或者B数组都没有遍历到尾部,就肯定不是pop序列了
66.颠倒栈。
颠倒栈
题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。 题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。
颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。 颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。
递归方法
+64 -29
View File
@@ -19,7 +19,14 @@ int string_to_integer(char *s,int length)
分析: 分析:
1. 不能使用循环,那就用递归 1. 不能使用循环,那就用递归
2. 递归需要终止递归的条件判断语句,这里也不能用if,想其他办法,可以使用 || 逻辑或运输符 2. 递归需要终止递归的条件判断语句,这里也不能用if,想其他办法,可以使用 &&逻辑与 运算符(在n>0条件满足是,才会指向后面的递归语句
int factorial(n){
int sum=0;
(n>0) && sum=n+factorial(n-1)
return sum;
}
@@ -30,8 +37,7 @@ int string_to_integer(char *s,int length)
分析: 分析:
这是一道很基本的考查位运算的面试题。 这是一道很基本的考查位运算的面试题。
包括微软在内的很多公司都曾采用过这道题。 解法1:一轮循环移位计数 (移位运算比除法运算效率要高,注意要考虑是负数的情况)
解法1:循环计数
解法2:位运算 解法2:位运算
解法3:num &= num-1 巧妙之处在于,对高位没有影响 解法3:num &= num-1 巧妙之处在于,对高位没有影响
@@ -39,6 +45,8 @@ int string_to_integer(char *s,int length)
请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句 请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
分析: 分析:
@@ -73,16 +81,6 @@ tmp[i]= tmp[i]>=0?tmp[i]:tmp[i]+16;
大整数乘法(或 大整数阶乘)
请使用代码计算1234567891011121314151617181920*2019181716151413121110987654321 。
1. 注意结果可能超出长整形的最大范围 2^64-1
2. 采用分治算法,将大整数相乘转换为小整数计算
编程实现两个正整数的除法(和取模) 编程实现两个正整数的除法(和取模)
编程实现两个正整数的除法,当然不能用除法操作符。 编程实现两个正整数的除法,当然不能用除法操作符。
// return x/y. // return x/y.
@@ -110,26 +108,23 @@ int div(const int x, const int y)
求两个或N个数的最大公约数和最小公倍数。 求两个或N个数的最大公约数和最小公倍数。
大整数乘法(或 大整数阶乘)
请使用代码计算1234567891011121314151617181920*2019181716151413121110987654321 。
1. 注意结果可能超出长整形的最大范围 2^64-1
2. 采用分治算法,将大整数相乘转换为小整数计算
规律分析:
任意位数的整数相乘,最终都可以转化为2位数相乘
40、用1、2、2、3、4、5这六个数字,写一个main函数,打印出所有不同的排列,
如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连.
给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含),
指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
比如,A=[1,0] K=21 那么输出结构应该为100。
@@ -153,7 +148,7 @@ int div(const int x, const int y)
30.在从1到n的正数中1出现的次数 在从1到n的正数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。 例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
@@ -167,8 +162,48 @@ int one_appear_count(int n);
19、判断一个自然数是否是某个数的平方
说明:当然不能使用开方运算。
判断一个自然数是否是某个数的平方。说明:当然不能使用开方运算。
square(25) YES
square(35) NO
方法1: 从1开始遍历,显然这种方法很差
方法2: 除数跟余数比较,除数从2开始,每一轮都跟结果比较;相等就是存在这个数,不相等就把除数++;时间复杂度为(根号n)。在一个数比较大时,效率不够好。如1194877489=(34567)^2,需要从2开始,一直比较到34566,做3万多次除法和比较运算。跟方法1一样。。
方法3:二分查找 O(logn)
排列组合问题
1,2,3,4,5 五个不同的数字,打印不同的排列
这就是一个无向图的遍历,把每个数字看成一个节点。
用1、2、2、3、4、5这六个数字,写一个main函数,打印出所有不同的排列,
如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连.
这是对上一题增加难度。但是需要
1. 去掉 3,5之间的联通
2. 2重复,过滤重复结果 treeset
3. 4不能在3位
给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含),
指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
比如,A=[1,0] K=21 那么输出结构应该为100。
-37
View File
@@ -1,37 +0,0 @@
#include "stdio.h"
#include "string.h"
int string_to_integer(char *s,int length){
if (length>1)
{
return s[0]=='-'?string_to_integer(s,length-1)*10-(s[length-1]-'0'):string_to_integer(s,length-1)*10+s[length-1]-'0';
}else{
return s[0]=='-'?-1/10:s[0]-'0';
}
}
/* 问题:
1. s是空字符串
2. s传参为非数字字符
3. 超出整数所能表示范围
*/
int main(){
char *s = "4323";
printf("integer == %d\n",string_to_integer(s,strlen(s)) );
printf("integer == %d\n",string_to_integer("12342",5));
printf("integer == %d\n",string_to_integer("-11",3) );
printf("integer == %d\n",string_to_integer("-5",2) );
printf("integer == %d\n", string_to_integer("3",1));
printf("integer == %d\n", string_to_integer("abcd",4));
printf("integer == %d\n", string_to_integer("a",1));
return 0;
}
-23
View File
@@ -1,23 +0,0 @@
#include "stdio.h"
int factorial(int n){
int ret=0;
(n==0) || (ret=n+factorial(n-1));
return ret;
}
int main(){
int n=10;
printf("factorial(10)= %d\n",factorial(10));
printf("factorial(5)= %d\n",factorial(5));
printf("factorial(1)= %d\n",factorial(1));
printf("factorial(0)= %d\n",factorial(0));
return 0;
}
-71
View File
@@ -1,71 +0,0 @@
#include "stdio.h"
#include "stdlib.h"
char *integer_to_bin(long integer){
int bit_num = sizeof(long)*8;
char *buffer= (char *)malloc(bit_num+1);
if (buffer==NULL)
{
return "malloc error";
}
buffer[bit_num]='\0';
for (int i = 0; i < bit_num; ++i)
{
buffer[i]= integer<<i>>(bit_num-1);
buffer[i]= buffer[i]==0?'0':'1';
}
return buffer;
}
char *integer_to_hex(long integer){
int bit_num=sizeof(long)*8/4;
char *buffer=(char *)malloc(bit_num+3);
buffer[0]='0';
buffer[1]='x';
buffer[bit_num+2]='\0';
char *tmp=&buffer[2];
for (int i = 0; i < bit_num; i++)
{
tmp[i]= integer<<(i*4)>>(bit_num*4-4);
tmp[i]= tmp[i]>=0?tmp[i]:tmp[i]+16;
tmp[i]= tmp[i]<10?(tmp[i]+48):(tmp[i]-10+'A');
}
return buffer;
}
/*
A 65
0 48
*/
int main(){
printf("b(11) = %s\n", integer_to_bin(11));
printf("b(1023) = %s\n",integer_to_bin(1023) );
printf("b(23564) = %s\n",integer_to_bin(23564) );
printf("h(11) = %s\n", integer_to_hex(11));
printf("h(1023) = %s\n",integer_to_hex(1023) );
printf("h(23564) = %s\n",integer_to_hex(23564) );
printf("b(11) = %x\n", 11);
printf("b(1023) = %x\n",1023 );
printf("b(23564) = %x\n",23564 );
return 0;
}
-7
View File
@@ -1,7 +0,0 @@
#include "stdio.h"
int main(){
printf("%ld",236432123443*33453098);
return 0;
}
-25
View File
@@ -1,25 +0,0 @@
#include "stdio.h"
/*
1 是第一个元素
序列中元素被2或3或5整除
*/
unsigned long value_in_sequence(unsigned index){
}
int main(){
return 0;
}
-70
View File
@@ -1,70 +0,0 @@
#include "stdio.h"
int binary_search_first(int *a,int length,int key){
int low=0;
int high = length-1;
int mid = 0;
while(low<high){
mid = (low+high)/2;
if (a[mid]>=key)//往左找
{
high = mid;
}else{
low = mid+1;
}
}
return high;
}
int binary_search_last(int *a,int length,int key){
int low = 0;
int high = length -1;
int mid = 0;
while(low<high){
mid = (low+high+1)/2;
if (a[mid]<=key)// 往右找
{
low=mid;
}else{
high = mid-1;
}
}
return low;
}
int element_appear_times(int *a,int length,int key){
printf("(%d) first appear at index %d\n",key,binary_search_first(a,length,key));
printf("(%d) last appear at index %d\n",key,binary_search_last(a,length,key));
return binary_search_last(a,length,key)-binary_search_first(a,length,key)+1;
}
int main(){
int a[] = {2,3,4,4,4,4,4,5,5,7,7,11,11,11,11,11,32,32,54};
printf("(2)appear times = %d\n", element_appear_times(a,sizeof(a)/sizeof(int),2) );
printf("(4)appear times = %d\n", element_appear_times(a,sizeof(a)/sizeof(int),4) );
printf("(11)appear times = %d\n", element_appear_times(a,sizeof(a)/sizeof(int),11) );
printf("(36)appear times = %d\n", element_appear_times(a,sizeof(a)/sizeof(int),36) );
printf("(54)appear times = %d\n", element_appear_times(a,sizeof(a)/sizeof(int),54) );
return 0;
}
-14
View File
@@ -1,14 +0,0 @@
#include "stdio.h"
int main(){
int j,k,m;
int i= (j=4,k=5,m=8);
printf("%d\n", i);
i= (j==4)?:0;
printf("i=%d\n", i);
return 0;
}
Binary file not shown.
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.a.out</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
+3 -2
View File
@@ -28,6 +28,9 @@ print_sum_detials(int n , int sum)
二维数组中的查找
@@ -84,8 +87,6 @@ print_minimums(int *a,int length ,int k);
2在下排出现了1次,3在下排出现了0次.... 2在下排出现了1次,3在下排出现了0次....
以此类推.. 以此类推..
昨天,花了一个下午,用c++实现了此题。(*^__^*)
+11
View File
@@ -0,0 +1,11 @@
#include "stdio.h"
int main(){
int a = 257;
unsigned char *result = (unsigned char *)&a;
printf("%d.%d.%d.%d\n", result[0],result[1],result[2],result[3] );
}
+53
View File
@@ -0,0 +1,53 @@
#include "stdio.h"
int isSquare(unsigned integer){
if (integer==1 || integer==0)
{
return integer;
}
int divider=2,result=integer/divider;
while(result>divider){
divider++;
result = integer/divider;
}
if (result!=divider)
{
return -1;
}
return result;
}
int main(int argc, char const *argv[])
{
// 243,1849(43),289(17), 64(8)
int a[] = {1849,144,243,289,64,1194877489};
for (int i = 0; i < sizeof(a)/sizeof(int); ++i)
{
int ret = isSquare(a[i]);
if (ret==-1)
{
printf("%d 不是某个数的平方\n",a[i]);
}else{
printf("%d 是 %d 的平方\n", a[i], ret);
}
}
return 0;
}
Binary file not shown.
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.a.out</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
@@ -0,0 +1,135 @@
#include "stdio.h" // fwrite
#include "unistd.h" // write
#include "stdlib.h" // itoa
#include "string.h"
#define test_file_path2 "./ip2.txt"
#define test_file_path "./ip.txt"
#define ip_count 100000000 //随机1亿个IP
#define tmp_file_count 32
#define mem_count 128*1024*1028 //128MB个IP空间
int hash(unsigned i){
return i>>27;
}
int main(){
// 模拟创建一个文件,产生测试用的IP
// FILE *fd;
// fd = fopen(tmp_file_path,"a+");
// for (int i = 0; i < ip_count;++i)
// {
// //char c[] = "this is sentence!";
// unsigned random_ip = (unsigned)rand();
// char tmp[50];
// sprintf(tmp,"%d",random_ip);
// //printf("random ip = %s\n",tmp);
// fwrite(tmp,strlen(tmp),1,fd);
// fputc('\n',fd);//加入换行符号
// }
//创建临时文件
FILE *fd[tmp_file_count];
for (int i = 0; i < tmp_file_count; ++i)
{
char file_path[128];
//s[0]=(char)(i+48);
//char *file_path = strcat("./ipslice/ipslice",s) ; // 这样写出现 bus error!!!
sprintf(file_path,"./ipslice/ipslice%d",i);
fd[i] = fopen(file_path ,"a+" );
if ( !fd[i])
{
printf("file %d open fail!! \n" ,i);
}
}
//开始读测试数据IP,按IP,映射到32个文件中
FILE *testfd = fopen(test_file_path2,"r");
if (!testfd)
{
printf("file open fail !!\n");
exit(-1);
}
unsigned tmp_data;
while( getline() ){ //能读到数据 // fread(&tmp_data,sizeof(unsigned),1,testfd) , C语言中没有getline() 这样的函数
printf("%d\n",(unsigned)tmp_data );
int key = hash((unsigned)tmp_data);// key值即为对应文件fd
int size = fwrite(&tmp_data,sizeof(unsigned),1,fd[key]);
printf("写入数据size=%d ,key=%d\n",size, key );
//跳过换行符
fseek(testfd,1,SEEK_CUR);
}
// 依次读入每个文件并统计, hash_map 统计每个区间段的最大IP
int hash_map[mem_count];
int max_ip;
int max_times;
for (int i = 0; i < tmp_file_count; ++i)
{
// hash统计
while(){}
//hash 表里找出最大的,变量一遍
for (int i = 0; i < mem_count; ++i)
{
/* code */
}
}
// 释放
for (int i = 0; i < tmp_file_count; ++i)
{
fclose(fd[i]);
}
return 0;
}
/**
关于warning
implicit declaration of function 'itoa' is invalid in C99
itoa() 函数并不是一个 standard functions ANSI C standard
inet_ntop() // 整数转换成 .分 ip地址 字符串
inet_nton() //
inet_aton() //
struct in_addr
*/
+98 -8
View File
@@ -2,23 +2,119 @@
/////////////////// 海量数据处理(千万以上量级) /////////// /////////////////// 海量数据处理(千万以上量级) ///////////
时间上:无法在较短时间内迅速解决。可以设计巧妙的算法搭配合适的数据结构解决
空间上:数据量太大,无法一次全部装入内存;针对方法是大而化小,分而治之。将规模大划分为规模小的问题,各个击破
2.有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。
1. 分而治之/Hash映射 + hash统计 + 堆排序/快速排序/归并排序
2. 双层桶划分
3. Bloom filter 、Bitmap
4. Trie树/数据库/倒排索引
5. 外排序
6. 分布处理之 Hadoop/Mapreduce
### 海量日志处理,提取某日访问百度次数最多的那个IP(或top-K IP)
分析
2^32 = 42亿九千万。。
假设一个IP一天内访问百度的次数不查过40亿次,可以用unsigned表示。用数组统计处每个IP地址出现的最大次数,就可以得到访问次数最大的IP地址
unsigned count[N],这个N=2^32=4G个IP地址 sizeof(count) = 4*N = 16G内存,原因超过32位机器所支持的4G内存大小。因此不能直接创建这个数组
第一步 分治法/文件映射
假设运行使用的内存是512MB, 512M/4 = 128M个IP地址(一个IP地址32位,占4个字节)
注意理解:`512M内存可以统计128M个不同的IP地址的访问次数`,哪怕切割的小文件中的IP总数大于128M
4G/128M = 32,也就是把IP地址划分成 32 个不同的区间段,addr[1-xx],addr[xx-xx]..分别计算每个区间中访问次数最大的IP,然后再比较32个区间段中的最大次数,就可以得到所有IP的做大值了。
一个区间段的IP地址个数任然可能撑破128M个,从而撑爆内存
具体实施:
把大文件映射到小文件,有2种方式:
1. 取模映射 。 IP%32 映射到32个小文件,把model相同的IP保存到同一个文件
2. 位运算映射。把IP的前5为作为作为区间编号,即 IP>>27 结果就是[0,31],把相同区间的IP保存到同一个文件
上面的映射中,都不会出现同一个IP映射到不同小文件的情况
第二步 统计每个小文件中的最大值
现在文件不同的IP数量达到内存承受的范文了,可以统计小文件中的IP次数了,使用常规的 hash_map(IP,count) 来 统计了
第三步 排序 堆排序/快速排序/归并排序
###top-K 找出最大的k个数
hashmap + 堆
100w个数中找出最大的100个数。
类似问题:
分析:100W个数里面是否有重复
方案1:在前面的题中,我们已经提到了,用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)。
方案2:采用快速排序的思想,每次分割之后只考虑比轴大的一部分,知道比轴大的一部分在比100多的时候,采用传统排序算法排序,取前100个。复杂度为O(100w*100)。
方 案3:采用局部淘汰法。选取前100个元素,并排序,记为序列L。然后一次扫描剩余的元素x,与排好序的100个元素中最小的元素比,如果比这个最小的要 大,那么把这个最小的元素删除,并把x利用插入排序的思想,插入到序列L中。依次循环,知道扫描了所有的元素。复杂度为O(100w*100)。
有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。
请用5分钟时间,找出重复出现最多的前10条。 请用5分钟时间,找出重复出现最多的前10条。
寻找热门查询,300万个查询字符串中统计最热门的10个查询
文件中的内容排序并去重复 文件中的内容排序并去重复
一个文件中包含了1亿个随机整数,如何快速的找到最大(小)的100万个数字?(时间复杂度:O(n lg k)) 一个文件中包含了1亿个随机整数,如何快速的找到最大(小)的100万个数字?(时间复杂度:O(n lg k))
分析: 堆排序 分析: 堆排序
3.2 在O(n lg k)时间内,将k个排序表合并成一个排序表,n为所有有序表中元素个数。 3.2 在O(n lg k)时间内,将k个排序表合并成一个排序表,n为所有有序表中元素个数。
【解析】取前100 万个整数,构造成了一棵数组方式存储的具有小顶堆,然后接着依次取下一个整数,如果它大于最小元素亦即堆顶元素,则将其赋予堆顶元素,然后用Heapify调整整个堆,如此下去,则最后留在堆中的100万个整数即为所求 100万个数字。该方法可大大节约内存。 【解析】取前100 万个整数,构造成了一棵数组方式存储的具有小顶堆,然后接着依次取下一个整数,如果它大于最小元素亦即堆顶元素,则将其赋予堆顶元素,然后用Heapify调整整个堆,如此下去,则最后留在堆中的100万个整数即为所求 100万个数字。该方法可大大节约内存。
搜索中的智能提示(如 "中国" ,"zhongguo",考虑拼音)
把2万个汉字排序,弄成一个超长的字符串
用Int16索引汉字的所有拼音
Int64 建立汉字和拼音的关联--汉字有多音字,需要把多个拼音pack到一个Int64,位操作搞定
二分+位移unpack,直接做到汉字到拼音的检索
3.大量的URL字符串,如何从中去除重复的,优化时间空间复杂度 3.大量的URL字符串,如何从中去除重复的,优化时间空间复杂度
@@ -29,6 +125,7 @@
一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数 一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数
假设一个文件中有9亿条不重复的9位整数,现在要求对这个文件进行排序。 假设一个文件中有9亿条不重复的9位整数,现在要求对这个文件进行排序。
@@ -184,13 +281,6 @@ s 求出每台电脑上的TOP10后,然后把这100台电脑上的TOP10组合
方案1:首先根据用hash并求模,将文件分解为多个小文件,对于单个文件利用上题的方法求出每个文件件中10个最常出现的词。然后再进行归并处理,找出最终的10个最常出现的词。 方案1:首先根据用hash并求模,将文件分解为多个小文件,对于单个文件利用上题的方法求出每个文件件中10个最常出现的词。然后再进行归并处理,找出最终的10个最常出现的词。
12. 100w个数中找出最大的100个数。
方案1:在前面的题中,我们已经提到了,用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)。
方案2:采用快速排序的思想,每次分割之后只考虑比轴大的一部分,知道比轴大的一部分在比100多的时候,采用传统排序算法排序,取前100个。复杂度为O(100w*100)。
方 案3:采用局部淘汰法。选取前100个元素,并排序,记为序列L。然后一次扫描剩余的元素x,与排好序的100个元素中最小的元素比,如果比这个最小的要 大,那么把这个最小的元素删除,并把x利用插入排序的思想,插入到序列L中。依次循环,知道扫描了所有的元素。复杂度为O(100w*100)。
13. 寻找热门查询: 13. 寻找热门查询: