
程序设计
文章平均质量分 65
songuooo
Make easy things easy & hard things possible.
展开
-
About python encoding
文件开头编码注释:# -*- coding:utf-8 -*-原创 2013-05-23 10:25:17 · 843 阅读 · 0 评论 -
n 个数中最小的 k 个数
1. 描述输入 n 个整数,输出其中最小的 k 个。2. 解法一般的方法是用选择排序,直到k个最小的数产生。时间复杂度为O(nk),空间复杂度为O(n)。或者是对这n个数用快速排序从小到大排好序后,输出前k个数,时间复杂度为O(nlogn),空间复杂度为O(n)。但若数据量非常庞大,以至于整个内存空间都放不下,上面两种方法就无能为力了。利用堆排序可以解决原创 2012-08-15 20:45:19 · 1958 阅读 · 0 评论 -
和为 n 的连续正整数序列
1. 描述输入一个正整数n,输出所有和为n的连续正整数序列。例如输入15,输出4个序列:1 2 3 4 5,4 5 6, 7 8, 15据说这是一道网易的面试题。2. 思路用start和end分别表示序列的起始和结束,sum为从start到end序列的和。end的值不大于(n+1)/2。开始时令sum = start = end = 0,判断sum的值是否等于n:(原创 2012-08-20 09:49:39 · 1230 阅读 · 0 评论 -
动态规划基础
众所周知,动态规划(Dynamic Programming)常用于解决最优化问题。能采用动态规划的问题具有两个重要的性质:最优子结构和子问题重叠性。下面就温习一下吧。1. 最优子结构(Optimal substructure)如果问题的一个最优解中包含了子问题的最优解,即原问题的最优解可以通过子问题的最优解构造,或者说可以利用子问题的最优解来构造原问题的一个最优解,则问题具有最优子原创 2012-08-19 19:35:58 · 687 阅读 · 0 评论 -
递归算法颠倒栈中的元素
1. 描述利用递归颠倒一个栈,例如栈[1, 2, 3, 4, 5], 顺序为从栈底到栈顶。颠倒之后的栈为[5, 4, 3, 2, 1]。2. 思路颠倒栈后原先处于栈底的元素现在处于栈顶,如果预先得到初始栈中栈底元素,然后在颠倒剩余的元素之后,把此元素入站,那么就完成了栈的颠倒工作,如图所示:显然是一个递归的过程,算法递归的调整栈底元素到栈顶。代码如下:原创 2012-08-28 19:08:13 · 1949 阅读 · 0 评论 -
定位单向链表某个结点
1. 描述输入一个单向链表(可带表头), 输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表的尾指针,即链表的最后一个结点。结点定义如下:typedef struct BiNode { int data; struct BiNode *next;}BiNode;2. 思路在遍历时维持两个指针,第一个指针从链表的头指针开始遍历, 在第 k-1原创 2012-08-17 18:35:25 · 819 阅读 · 0 评论 -
逆转句子中的单词
1. 描述输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。2. 思路方法和数组循环移位的思想是差不多的。代码如下:void transfer(char *words){ char *p, *q, temp; char *w = words; while (*w) {原创 2012-08-17 16:02:29 · 908 阅读 · 0 评论 -
数组循环移位
问题描述:n个元素存储于数组A[0..n-1]中,求向右或向左循环移位 k (k >= 0)位得到的新数组A[]。1. 循环右移步骤:(1) k = k % n;(2) 把序列分成前(n-k)个数和后k个数两组分别进行逆转操作,如下图:代码如下:void rightShift(char A[], int n, int k){ k = k原创 2012-08-08 16:07:12 · 421 阅读 · 0 评论 -
特殊方法求 1 到 n 的和
1. 描述求 1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句(A?B:C)。这道题其实没什么意思,但是可以温习一下解决的方法所用到的知识。2. 解法一可以用递归做,但是什么时候停止的,如果用if语句那肯定是很用以了,当n = 0时停止递归。还可以用另外一种办法,就是当 n = 0 时调用另一个函数原创 2012-08-14 22:23:28 · 1170 阅读 · 0 评论 -
O(1)时间求出栈中最小的元素
1. 描述定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及pop 的时间复杂度都是O(1)。这是2010年Google的一道面试题。2. 求解思路是这样的, 定义另外一个辅助栈,不妨叫MinStack,栈中存放数据栈(不妨叫Stack)中当前最小元素在数据栈中的标号。当向数据栈中push 元素(不妨叫ele)的时候:若原创 2012-08-12 21:32:32 · 1763 阅读 · 0 评论 -
二叉排序树转化成双向链表
二叉排序树。将二叉排序树转化成双向链表,不创建新的节点。下面是非递归的算法。BiNode* BSTtoList(BiNode *T){ BiNode *p, *q; BiNode *stack[50]; int top = 0; if (! T) return NULL; p = T; q = NULL; while原创 2012-08-12 20:02:51 · 1268 阅读 · 0 评论 -
字符串中对称子串的最大长度
1. 描述输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“goooogle”, 由于该字符串里最长的对称子字符串是“goooog”, 因此输出 6。2. 思路方法一:判断字符串的每一个子串,若是对称的,则求出它的长度即可。这种办法对每一个子串,从两头向中间判断是不是子串。总的时间复杂度为O(n^3),下面给出时间复杂度是O(n^2)的思路。方法二原创 2012-08-30 21:32:38 · 6992 阅读 · 3 评论 -
装配线调度(动态规划)
1. 问题描述公司在有两条装配线的工厂内生产汽车,如下图所示。一个汽车底盘在进入每一条装配线后,在一些装配站中会在底盘上安装部件,然后完成的汽车在装配站的末端离开。每一条装配线上有n个装配站,编号为j=1,2...n。装配线i(i=1,2)的第j个装配站表示为Sij。装配线1的第j个站和装配线2的第j个站执行相同的功能。然而这些装配站是在不同的时间建造的,并且采用了不同的技术,一次每个站上所需原创 2012-08-20 16:38:20 · 1377 阅读 · 1 评论 -
字符串的排列与组合
求字符串的排列和组合是递归很典型的应用,是很好的考查对递归理解程度的一类问题。下面的求字符串的排列、组合的算法全部用递归实现。1. 字符串的排列(1) 描述输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串 abc,则输出由字符 a、b、c 所能排列出来的所有字符串 abc、acb、bac、bca、cab 和 cba。(2) 字符串中没有重复字符先不考虑原创 2012-08-21 22:12:18 · 786 阅读 · 0 评论 -
筛选素数
筛选素数:打印出1, 2, 3, ..., n中所有的素数。“筛子法”:2是第一个素数,保留下来,筛掉所有的2的倍数;3被保留下来,则3是素数,筛掉所有的3的倍数;...直至筛选完毕。代码如下:void prime(int n){ int num[n + 1]; int i, j; for (i = 2; i <= n; i++) num[i] = 1;原创 2012-09-14 22:21:54 · 525 阅读 · 0 评论 -
给定1到N的随机数函数,产生1到M的随机数
给定能随机生成整数 1 到 n 的函数,写出能随机生成整数 1 到 m 的函数(m > n)。设 n = 5, m = 7关键是让生成的 1 到 7 的数出现概率相同。调用 n 次给定函数,生成 n 个 1 到 5之间的随机数,选取最大数所在位置,直到剩下最后一个。如:初始的 7 个数 [1, 2, 3, 4, 5, 6, 7]。(1)7 个 1 到 5 的随机数,如 [5,原创 2012-09-16 17:09:09 · 5069 阅读 · 3 评论 -
最长公共子序列LCS(动态规划)
1. 描述给定两个序列X = { x1 , x2 , ... , xm },Y = { y1 , y2 , ... , yn }求X和Y的一个最长公共子序列。2. 分析设最长子序列 Z = { z1 , ... , zk }则1、若 xm = yn , 则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列;2原创 2012-09-01 22:51:44 · 832 阅读 · 0 评论 -
最优二叉查找树(动态规划)
1. 描述给定一个有序序列K={k12. 分析(1)最优子结构一个最优二叉树的子树必定包含连续范围的关键字ki~kj,1 如果一棵最优二叉查找树T有一棵含有关键字ki~kj的子树T',那么,T'也是一棵最优查找树,这通过剪贴思想可以证明。构造最优子结构:在ki~kj中,选定一个r,i (2)递推公式定义e[i,j]为一棵包含关键字ki~kj的最优二叉树的期望原创 2012-09-08 21:56:59 · 1571 阅读 · 0 评论 -
输出0到最大的n位数
1. 描述输入数字 n,按顺序输出从 0 最大的 n 位 10 进制数。比如输入 3,则输出 0、1、2、3 一直到最大的 3位数,即 999。2. 思路方法一,求出最大的n位数(10^3 - 1),然后由一个循环控制输出。方法二,当n很大时,方法一不再适用,此时可用字符串模拟数字运算,代码较长。方法三,由字符串的排列和组合>的递归算法得到启示,可以利用递归求解。原创 2012-08-28 11:11:38 · 1323 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面
1. 不要求相对顺序输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n),不要求奇数的相对顺序和偶数的相对顺序。思路:维护两个指针,第一个指针(设为firstEven)初始化为数组的第一个数字,它只向后移动;第二个指针(设为lastdd)初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总原创 2012-08-25 22:41:09 · 865 阅读 · 1 评论 -
海量数据处理
1、海量日志数据,提取出某日访问百度次数最多的那个IP。IP位数为32位,最多可以有2^32个不同的IP,每个IP占4B,共占2^32 * 4B = 16GB。因此一般情况下,内存放不下这些不同的IP,因此用维护一个堆的方法是不行的。思想:把大文件分成多个小文件,对每个小文件进行处理,再综合之。如何把大文件分成多个大小基本一致的多个小文件,如果IP分布均匀的话,可以采用Hash的方法,原创 2012-09-05 20:46:55 · 687 阅读 · 0 评论 -
删除字符串中某些特定的字符
1. 描述输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。2. 思路字符的个数是有限的(不考虑Unicode字符),一个char型字符为一个字节占八位,共有 2^8 = 256个字符,除去ASCII为零的字符'\0'外共有255个字符,原创 2012-08-27 10:23:52 · 2395 阅读 · 0 评论 -
矩阵链乘法(动态规划)
1. 描述给定由n个要相乘的矩阵构成的序列,要计算乘积 A1A2...An 矩阵的乘法满足结合率,然而不同的结合虽然运算结果一样,但需要运算的次数是不相同的,例如:设3个矩阵的维数分别为10x100,100x5,5x50。如果按((A1A2)A3)的次序相乘,共要做10x100x5原创 2012-08-24 19:10:05 · 1280 阅读 · 0 评论 -
顺时针打印方阵
1. 描述给定一方阵,顺时针打印方阵的值,如方阵: 1, 2, 3, 4 5, 6, 7, 8 9,10,11,12原创 2012-08-31 10:14:21 · 756 阅读 · 0 评论 -
二叉树中根到叶子路径中节点和等于给定值的路径
1. 描述输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如输入整数 22 和如下二元树 10 / \ 5 12 / \原创 2012-08-12 22:38:06 · 5115 阅读 · 0 评论 -
最长递增子序列(动态规划)
1. 问题描述设n个元素的序列存储在数组A[0..n-1]中,求序列中最长递增子序列(不要求连续)的长度。2. 递推公式设LIS[i]为序列A[0..i]中最长递增子序列的长度。则:LIS[i] = 1 i = 0,LIS[i] = max{1, LIS[k] + 1}A[i] > A[k]且0代码如下:int maxLIS(int A[], int n原创 2012-08-08 15:01:00 · 748 阅读 · 0 评论 -
不要效仿这个程序
C语言中定义字符串时:char str1[] = "EFG";char str2[] = {'A', 'B', 'C', 'D', '\0'}; //末尾一定要加'\0'第二种方法中一定要加'\0'。strlen函数、puts函数等都是寻找'\0',以'\0'为字符串的结束标志。Now, hold on to your hat !下面代码:#inc原创 2012-08-03 22:40:39 · 1170 阅读 · 0 评论 -
二叉树操作
最近在温习数据结构,把书中的代码写了一遍,下面是二叉树的基本操作,包括:(1) 四种遍历二叉树的方法: 前序遍历、中序遍历、后序遍历和层序遍历,其中又包括了递归的和非递归;(2) 两种创建二叉树的方法: 根据二叉树的前序和中序序列创建二叉树和根据二叉树的中序后序序列创建二叉树。1. 二叉树的存储结构/* headfiles/BiNode.h*/#ifndef BINODE原创 2012-08-03 09:48:13 · 761 阅读 · 0 评论 -
C语言中函数参数压入栈的顺序
1. 调用惯例C调用惯例规定的方面之一是函数参数的传递顺序和方式,函数参数压入栈的顺序是从右向左还是从左向右,传递方式是使用栈还是使用寄存器以提高性能,还是两者都使用,等。在C语言里,存在这多个调用惯例,如cdecl,stdcall,fastcall,pascal等。其中cdecl是C语言默认的调用惯例,其调用惯例规定的出栈方为函数调用方,参数压入栈的顺序为从右向左,名字修饰为原创 2012-08-02 22:17:59 · 1605 阅读 · 0 评论 -
图的搜索算法
图的存储结构定义见。图的遍历一般可分为深度优先搜索(Depth First Search)和广度优先搜索(Breadth First Search)。分别对应二叉树的前序遍历算法和层序遍历算法,尽管有些不同之处。1. 深度优先搜索邻接表作为存储结构。搜索算法如下:/* sharedSource/DFS.c */ArcNode * firstAdjvex(ALGraph原创 2012-08-03 10:38:13 · 949 阅读 · 0 评论 -
C语言在main前调用函数
在 gcc编译器下使用__attribute__ ((constructor))如下例子:/* BeforeMain.c */#include void beforeMain(void) __attribute__ ((constructor));int main(void){ printf("6, 7, 8, 9, 0\n");原创 2012-08-02 22:27:13 · 827 阅读 · 0 评论 -
图的生成算法
为了测试图的搜索算法、拓扑排序、关键路径、最小生成树、最短路径等算法,特意写了图的生成算法,包括以邻接表和邻接矩阵两种存储结构的图的生成算法。1. 存储结构定义/* headfiles/graph.h */#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDED#include #define NUM 20//matrix g原创 2012-08-03 10:26:10 · 1873 阅读 · 0 评论 -
最小生成树
普里姆(Prime)算法和克鲁斯卡尔(Kruskal)算法是两个利用最小生成树(MST)性质构造最小生成树的经典算法。下面是普里姆算法构造最小生成树。图的存储结果采用邻接矩阵。1. MST性质假设N = (V, {E})是一个连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则比存在一条包含边(u, v)的最小生成树。原创 2012-08-03 16:22:26 · 553 阅读 · 0 评论 -
最短路径
1. 问题描述单源点最短路径:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径。2. 迪杰斯特拉(Dijkstra)算法迪杰斯特拉算法按照最短路径递增的次序产生最短路径。具体参见数据结构。3. 算法实现采用邻接矩阵作为其存储结构。void dijkstra(MGraph *G, int v0, int (*P)[G->vexnum], int D[原创 2012-08-03 16:48:38 · 445 阅读 · 0 评论 -
关键路径
关键路径与活动的完成有关,总之路径长度最长的路径叫关键路径。在AOE-网中只有一个入度为0的顶点(源点)和只有一个出度为零的顶点(汇点)。图的存储结构为邻接表。算法用到拓扑排序和逆拓扑排序。算法如下:(1) 算法用到的拓扑排序算法void topoOrder(ALGraph *G, int ve[], int instack[]){ int i, v, indeg原创 2012-08-03 15:47:28 · 586 阅读 · 0 评论 -
拓扑排序
采用邻接表为图的存储结构。邻接表的定义见。算法如下:void topoSort(ALGraph *G) { int i, v, indegree[G->vexnum]; ArcNode *p; int stack[50], top = 0; memset(indegree, 0, sizeof(indegree)); //find indegree原创 2012-08-03 15:23:55 · 484 阅读 · 0 评论 -
KMP字符串匹配算法
KMP算法是一种改进的字符串匹配算法。KMP算法的关键是根据给定的模式串sub,定义一个next函数。next函数包含了模式串本身局部匹配的信息。1. 算法实现(1) 计算next函数算法如下void getNext(char sub[], int next[]) { int i = -1, j= 0, len = strlen(sub);原创 2012-08-03 18:23:53 · 748 阅读 · 0 评论 -
顶点着色问题应用
1. n个学生对m个宣讲会中的若干个感兴趣,如何安排宣讲会的时间(每个宣讲会持续的时间相同),使得每个学生对自己感兴趣的宣讲会时间不冲突,且宣讲会的总时间最短?此问题可以转化成顶点着色问题。把每个宣讲会看作是一些散布的点,对于每个学生,把他感兴趣的宣讲会之间两两相连,如:学生A希望参加宣讲会1、2、3学生B希望参加宣讲会1、3、4 则: 设宣讲会1原创 2012-08-04 16:24:22 · 8656 阅读 · 0 评论 -
一整数是否为2的方幂
位操作又有用武之地了。代码如下:int isPower(long n){ if (n > 0 && (n & (n - 1)) == 0) return 1; //n是2的方幂 return 0; //n不是2的方幂}原创 2012-08-04 16:45:17 · 1504 阅读 · 0 评论 -
插入排序、快速排序、堆排序
1. 直接插入排序算法如下:void insertSort(int A[], int n) //A[1..n], A[0]用作哨兵{ int i, j; for (i = 2;i <= n;i++) { if (A[i] >= A[i - 1]) continue; A[0] = A[i]; /原创 2012-08-08 20:16:00 · 831 阅读 · 0 评论