This commit is contained in:
nonstriater
2014-05-07 11:24:51 +08:00
parent bed6d32fa1
commit 3954690000
18 changed files with 729 additions and 128 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

+30
View File
@@ -0,0 +1,30 @@
#include "stdio.h"
int main(int argc, char const *argv[])
{
int length=10;
int j;
for (int i = 0; i < length; ++i)
{
for (j = i+1 ; j < length; ++j)
{
printf("i=%d,j=%d\n",i,j );
}
}
for (int i = 0; i < length; ++i)
{
for (int k = i+1 ; k < length; ++k)
{
printf("i=%d,k=%d\n",i,k );
}
}
return 0;
}
+120
View File
@@ -0,0 +1,120 @@
## 排序算法
**排序的稳定性** 对于相等的元素,排序之后,任然保存2个元素的位置没有变,就是稳定的排序,反之就是不稳定排序。
### 直接选择排序
1. 从未排序的序列中选择最小的元素,放在第一个位置
2. 依次类推,直到全部排序
在a【i,n】中最小的元素和 a[i]交换位置。空间复杂度O(1),时间复杂度 O(n^2)
### 堆排序
利用堆这种数据结构设计的一种排序算法
将待排序数列看做一颗完全二叉树的存储结构
堆总是一颗完全树,
堆也被称为`优先队列`,
堆分小根堆和大根堆
堆: 任一节点小于(或大于)其所有的孩子节点,如果是大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
按层遍历堆既可以得到一个排好顺序的序列。
堆排序主要时间花在建堆期间,找数列中最大树只需要O(1)时间复杂度
### 快速排序
1. 从数列中选择一个元素,作为基准 pivot
2. 重排数列,比 pivot 小得排左边,比pivot大的排右边,相等的随便
3. 递归的,使用相同的方式,重排左右两边的子序列
递归一次,pivot 左边都比它小,右边都比它大
这是递归,分治的思想
平均复杂度 O(n*logn)
### 冒泡排序
相邻的2各元素比较,大的向后移,经过一轮比较,做大的元素排在最后
第二轮,第二大的元素排倒数第二个位置
直到全部排好
这样,即使是排好序的拿冒泡排序排序,比较的时间复杂度O(n^2)
### 插入排序
1. 第一个元素算作已经排好
2. 取下一个元素,从已经排好的序列元素中,从后向前扫描
3. 如果排好序的元素大于 新元素,排好序的元素一道下一个位置
4. 重复3,直到直到最后的插入位置
5. 重复2
最坏的情况: 待排序的是一个逆序排放的数组,这样导致每一轮都要移动元素;此时复杂度是是0(n^2)
最好的情况: 待排序的是一已经顺序排放的数字,此时只需要做一轮比较就够了 0(n)
空间复杂度O(1)
### 希尔排序
### 归并排序
### 基数排序
### 总结
常见的排序算法都是比较排序,比较排序的时间复杂度通常为 O(n^2) 或 O(nlogn)
BIN
View File
Binary file not shown.
+117
View File
@@ -0,0 +1,117 @@
#include "stdio.h"
// 插入排序
void insert_sort(int *a,int length){
int tmp ;
int i,j;
for (i = 1; i < length; ++i)
{
for ( tmp=a[i],j=i-1 ; j>=0 && a[j] > tmp ; j--)
{
a[j+1]=a[j];
}
// j+1是插入的位置
a[j+1]=tmp;
}
}
// 选择排序
void select_sort(int *a,int length){
int min_index,tmp;
int j;
for (int i = 0; i < length; ++i)
{
for (j = i+1 ,min_index=i; j < length; ++j)// 不能写成for (int j = i+1 ,min_index=i; j < length; ++j)
{
if (a[min_index]>a[j])
{
min_index=j;
}
}
//min_index是最小的元素的index
if (min_index!=i)
{
tmp=a[i];
a[i]=a[min_index];
a[min_index]=tmp;
}
}
}
// 冒泡排序
void bubble_sort(int *a, int length){
int tmp ;
for (int i = 0; i < length-1; ++i) // 第i轮排序
{
for (int j = 0; j < length-i; ++j)
{
if (a[j] > a[j+1])
{
tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
}
// 快速排序
void fast_sort(int *a, int length){
}
// 堆排序
void heap_sort(int *a, int length){
}
int main(){
int a[] = {4,87,2,32,5,41,2,9};
//insert_sort(a,sizeof(a)/sizeof(int));
//select_sort(a,sizeof(a)/sizeof(int));
bubble_sort(a,sizeof(a)/sizeof(int));
printf("after sort:\n");
for (int i = 0; i < sizeof(a)/sizeof(int); ++i)
{
printf(" %d ",a[i]);
}
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
### 枚举迭代法
### 递归
### 动态规划
### 分治算法
### 回溯法
### 贪心算法
+136 -103
View File
@@ -1,23 +1,98 @@
字符串常见的问题:
单词反转
回文判断
字符串的压缩
字符串的排列和组合
字符串比较
是否是子串
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。
为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
分析
char *revert(const char *source,char *dest);
思路一:反向拷贝
思路二:原地逆序,字符串2边的字符逐个交换
思路三: 针对不允许临时空间的情况,也就是字符交换不用临时空间,可以使用的方法有:
1. 异或操作
2. 也就是2个整数相互交换一个道理
char a = 'a', b = 'b';
a = a + b;
b = a - b;
a = a - b;
类似的题目还有:
不开辟用于交换数据的临时空间,如何完成字符串的逆序(在技术一轮面试中,有些面试官会这样问)
用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。
按单词逆序 。如 “this is a sentence。” 逆序就是 “.sentence a is this”
判断字符粗是否是回文
分析: 2个指针,一头一尾,逐个比较,都相同就是回文
请编写能直接实现strstr()函数功能的代码。
string.h char *strstr(const char *haystack, const char * needle); //返回第一次出现子串的地址,否则返回0
编写strcpy 函数。已知strcpy 函数的原型是
char *strcpy(char *strDest, const char *strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数
在字符串中删除特定的字符。
题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。
char *delete(char *source,const char *del);
分析:这是一道微软面试题。在微软的常见面试题中,与字符串相关的题目占了很大的一部分,
因为写程序操作字符串能很好的反映我们的编程基本功。
1.不开辟用于交换数据的临时空间,如何完成字符串的逆序
(在技术一轮面试中,有些面试官会这样问)
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
分析:这道题是2006年google的一道笔试题。
char first_appear_only_once(const char *source)
思路一: 蛮力统计, O(n^2)复杂度
思路二: 使用hash表,2次扫描,第一次建立hash表 key为字符,value为出现次数;第二次扫描找到第一个value为1的key,时间复杂度O(n)
hash表长度 256,字符直接作为key值
题目扩展:这里的字符换成整数,整数数量几十TB,海量数据处理,显然hash方法不可能,没有那么大得内容
题目:匹配兄弟字符串
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。思路:判断各自素数乘积是否相等。更多方法请参见:http://blog.csdn.net/v_JULY_v/article/details/6347454。
BOOL isBrother(const char *first,const char *secd)
@@ -25,92 +100,74 @@
给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
1. 设计相应的数据结构和算法,尽量高效的统计一片英文文章(总单词数目)里出现的所有英文单词,按照在文章中首次出现的顺序打印输出该单词和它的出现次数。
设计相应的数据结构和算法,尽量高效的统计一片英文文章(总单词数目)里出现的所有英文单词,按照在文章中首次出现的顺序打印输出该单词和它的出现次数。
void statistics(FILE *fd)
用一种算法使通用字符串相匹配。
找到一个子字符串。优化速度。优化空间。
比较两个字符串,用O(n)时间和恒量空间。
54、字符串原地压缩
字符串原地压缩
题目描述:“eeeeeaaaff" 压缩为 "e5a3f2",请编程实现。
分析
char *compress(const char *src,char *dest)
3.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
1.给出一个函数来输出一个字符串的所有排列。
55、字符串匹配实现
请以俩种方法,回溯与不回溯算法实现。
56、一个含n个元素的整数数组至少存在一个重复数,
请编程实现,在O(n)时间内找出其中任意一个重复数。
实现一个挺高级的字符匹配算法:
给一串很长字符串,要求找到符合要求的字符串,例如目的串:123
1******3***2 ,12*****3这些都要找出来
其实就是类似一些和谐系统。。。。。
39、对称子字符串的最大长度
对称子字符串的最大长度
题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
分析:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加
分析:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加强版。
int max_symmetrical_char_length(const char *scr);
强版。
思路一:蛮力法,3重循环(类似 求子数组的最大和 fmax(i,j)问题), fmax(i,j)区间i,j是最长的对称字符
思路二: 遍历所有子串,然后判读是否对称 O(n^2)
35、编程实现:找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad"
思路三: 有个O(n)复杂度的 http://www.jb51.net/article/48090.htm
3、给出一个函数来输出一个字符串的所有排列。
2、写一个函数,检查字符是否是整数,如果是,返回其整数值。
(或者:怎样只用4行代码编写出一个从字符串到长整形的函数?)
17、有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在答谢字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型void proc(char *str) 也可以采用你自己熟悉的语言
有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在答谢字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型void proc(char *str) 也可以采用你自己熟悉的语言
第20题:
题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。
例如输入字符串"345",则输出整数345。
第25题:
写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,
并把这个最长数字串付给其中一个函数参数outputstr所指内存。
例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,
outputstr所指的值为123456789
26.左旋转字符串
题目:
题目:左旋转字符串
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。
@@ -119,12 +176,6 @@ outputstr所指的值为123456789
33.
实现一个挺高级的字符匹配算法:
给一串很长字符串,要求找到符合要求的字符串,例如目的串:123
1******3***2 ,12*****3这些都要找出来
其实就是类似一些和谐系统。。。。。
37.
@@ -145,33 +196,22 @@ outputstr所指的值为123456789
当用户输入中国人民的时候,要求返回与这个搭配词组相关的信息。
1 判断一字符串是不是对称的,如:abccba
1.编写strcpy 函数
已知strcpy 函数的原型是
char *strcpy(char *strDest, const char *strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请
编写函数 strcpy
24、用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。
4.删除字符串中的数字并压缩字符串。
如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。
(下面的算法只需要一次遍历,不需要开辟新空间,时间复杂度为O(N))
5.求两个串中的第一个最长子串(神州数码以前试题)。
求两个串中的第一个最长子串(神州数码以前试题)。
如"abractyeyt","dgdsaeactyey"的最大子串为"actyet"。
2.删除串中指定的字符
删除串中指定的字符
(做此题时,千万不要开辟新空间,否则面试官可能认为你不适合做嵌入式开发)
char *delete_character(char *src , char target)
@@ -183,9 +223,15 @@ char *strcpy(char *strDest, const char *strSrc);
1.给出一个函数来复制两个字符串A和B。
字符串A的后几个字节和字符串B的前几个字节重叠。
分析:记住,这种题目往往就是考你对边界的考虑情况。
2.已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,
如果没有返回0,有的话返回子字符串的个数。
char *sub_str_count(const char *src, const char *substr, int *count)
函数将字符串中的字符'*'移到串的前部分,
前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。
@@ -193,34 +239,11 @@ char *strcpy(char *strDest, const char *strSrc);
处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)
2.求最大连续递增数字串(如“ads3sl456789DF3456ld345AA”中的“456789”)
3.实现strstr功能,即在父串中寻找子串首次出现的位置。
(笔试中常让面试者实现标准库中的一些函数)
求最大连续递增数字串(如“ads3sl456789DF3456ld345AA”中的“456789”)
int continuousnum(const char *input, char *output)
73.对策字符串的最大长度。
题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
分析:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加强版。
70.给出一个函数来输出一个字符串的所有排列。
分析:简单的回溯就可以实现了。当然排列的产生也有很多种算法,去看看组合数学,
还有逆序生成排列和一些不需要递归生成排列的方法。
印象中Knuth的<TAOCP>第一卷里面深入讲了排列的生成。
这些算法的理解需要一定的数学功底,
也需要一定的灵感,有兴趣最好看看。
56.最长公共字串。
@@ -231,43 +254,53 @@ char *strcpy(char *strDest, const char *strSrc);
注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。
最长公共子串问题
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,
则输出它们的长度4,并打印任意一个子串。
如"abccade","dgcadde"的最大子串为"cad"
分析:求最长公共子串(Longest Common Subsequence, LCS)是一道非常经典的动态规划题,
因此一些重视算法的公司像MicroStrategy都把它当作面试题。
int longest_common_subsequence(const char *s1,const char *s2, char *common)
53.字符串的排列。
字符串的排列。
题目:输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。输入字符串 abcca,则输出由 a,b,c排列出来的所有字符串,字符出现个数不变
分析:这是一道很好的考查对递归理解的编程题
简单的回溯就可以实现了。当然排列的产生也有很多种算法,去看看组合数学,
还有逆序生成排列和一些不需要递归生成排列的方法。
印象中Knuth的<TAOCP>第一卷里面深入讲了排列的生成。
这些算法的理解需要一定的数学功底,
也需要一定的灵感,有兴趣最好看看。
分析:这是一道很好的考查对递归理解的编程题,
因此在过去一年中频繁出现在各大公司的面试、笔试题中。
63.在字符串中删除特定的字符。
题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。
分析:这是一道微软面试题。在微软的常见面试题中,与字符串相关的题目占了很大的一部分,
因为写程序操作字符串能很好的反映我们的编程基本功。
+8 -2
View File
@@ -10,8 +10,8 @@ int string_to_integer(char *s,int length)
1. s是空字符串
2. s传参为非数字字符
3. 超出整数所能表示范围
类似的题目还有:
请编写能直接实现int atoi(const char * pstr)函数功能的代码。 将字符串转出整数
题目:求1+2+…+n,
@@ -68,6 +68,12 @@ tmp[i]= tmp[i]>=0?tmp[i]:tmp[i]+16;
大整数乘法(或 大整数阶乘)
请使用代码计算1234567891011121314151617181920*2019181716151413121110987654321 。
+25 -5
View File
@@ -499,9 +499,16 @@ unsigned long value_in_sequence(int index)
1、有一个整数数组,请求出两两之差绝对值最小的值,
有一个整数数组,请求出两两之差绝对值最小的值,
记住,只要得出最小值即可,不需要求出是哪两个数。
如 [-1, 3, 5, 9] 绝对值最小的是2(5-3)
最短区间问题
如果是有重复元素,那最小值就是0了
12、一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
@@ -521,13 +528,17 @@ unsigned long value_in_sequence(int index)
56、一个含n个元素的整数数组至少存在一个重复数,
请编程实现,在O(n)时间内找出其中任意一个重复数。
在排序数组中,找出给定数字的出现次数
比如 [1, 2, 2, 2, 3] 中2的出现次数是3次。
1. 排序数组,可以使用二分查找
将二分操作观测到底,这样在最坏的情况下([2,2,2,2,2,2,2])都有0(lgn)复杂度
分析:
1. 因为是排序数组,可以使用二分查找
2. 将二分查找坚持到底,这样在最坏的情况下([2,2,2,2,2,2,2])都有0(lgn)复杂度
int binary_search_first(int *a,int length,int key);
int binary_search_lash(int *a,int length,int key);
@@ -543,3 +554,12 @@ Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。
Binary file not shown.
+251
View File
@@ -0,0 +1,251 @@
#include "stdio.h"
typedef int BOOL;
#define YES 1
#define NO 0
// 反序
void revert(const char *source,char *dest){
const char *s = source;
char *end = dest;
while(*s){
*end++ = *s++; //先拷贝字符串
}
*end='\0';
end--;// 指向最后一个字符
while(end>dest){
char tmp = *end;
*end = *dest;
*dest = tmp;
end--;
dest++;
}
}
// 回文,或 对称
BOOL symmetrical(const char *scr,int length){
const char *end = scr+length-1;
BOOL is=YES;
while(end>scr){
if (*scr++ != *end--)
{
is=NO;
}
}
return is;
}
//找出第一个只出现一次的字符,找不到就返回‘0’
char first_appear_only_once(const char *source){
// 建立hash表
const int length=256;
int hash_table[length];
for (int i = 0; i < length; ++i)
{
hash_table[i]=0;
}
//第一次扫描,建立hash表
const char *tmp = source;
while(*tmp){
hash_table[*tmp++]++;
}
// 第二次扫描
while(*source){
if(hash_table[*source]==1){
return *source;
}
source++;
}
// 没找到
if (!*source)
{
return '0';
}
return '0';
}
// 最大对称子串的长度
int max_symmetrical_char_length(const char *scr){
return 0;
}
// 找最大数字子串
int continumax(char *outputstr,char *intputstr){
return 0;
}
// 最大连续递增数字串
int continuousnum(const char *input, char *output){
return 0;
}
// 2个字符串的最长公共子串
int longest_common_subsequence(const char *s1,const char *s2, char *common){
return 0;
}
// 找子串
char *strstr(const char *haystack, const char * needle){
return NULL;
}
// 子串个数
char *sub_str_count(const char *src, const char *substr, int *count){
return NULL;
}
// 删除子串
char *delete(char *source,const char *del,BOOL greedy){
return NULL;
}
// 字符串拷贝
char *strcpy(char *strDest, const char *strSrc){
return NULL;
}
BOOL isBrother(const char *first,const char *secd){
return YES;
}
// 字符串压缩
char *compress(const char *src,char *dest){
return NULL;
}
// 删除其中的数字并压缩
char *filternumber(const char*src,char *dest){
return NULL;
}
// 删除指定字符
char *delete_character(char *src , char target){
return NULL;
}
// 统计文件中单词的出现的个数
void statistics(FILE *fd){
}
// 字符串中字符的所有排列
int main(int argc, char const *argv[])
{
// 反转
char *reverse = "nonstriater";
char reversed[20];
revert(reverse,reversed);
printf("%s after reverse : %s\n", reverse,reversed);
// 回文
char symmetri[] = "dacbcacbcad";
printf("%s : %d\n", symmetri, symmetrical(symmetri,sizeof(symmetri)-1) );
char unsymmetrical[] = "aaacbdaa";
printf("%s : %d\n", unsymmetrical, symmetrical(unsymmetrical,sizeof(unsymmetrical)-1) );
// 第一次出现一次的字符
printf("%s第一次出现一次的字符是:%c\n",symmetri,first_appear_only_once(symmetri) );// '0'
printf("%s第一次出现一次的字符是:%c\n",unsymmetrical,first_appear_only_once(unsymmetrical) ); // 'c'
return 0;
}
+17 -18
View File
@@ -1,6 +1,19 @@
///////////////////////// 排序 ///////////////////////////
int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少?
逗号运算符
(表达式1,表达式2,...,表达式n) 分别计算每个表达式,,最后表达式的值做为整个表达式的值
所以输出是32
@@ -23,6 +36,9 @@
3.收藏了1万条url,现在给你一条url,如何找出相似的url。(面试官不解释何为相似)
四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(())
@@ -43,10 +59,6 @@
3.请编写能直接实现strstr()函数功能的代码。
请编写实现malloc()内存分配函数功能一样的代码。
@@ -57,19 +69,6 @@
8、请编写能直接实现int atoi(const char * pstr)函数功能的代码。
int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少?
逗号运算符
(表达式1,表达式2,...,表达式n) 分别计算每个表达式,,最后表达式的值做为整个表达式的值
所以输出是32