04 2013 档案
摘要:当一个应用的数据量大的时候,我们用单表和单库来存储会严重影响操作速度,如mysql的myisam存储,我们经过测试,200w以下的时候,mysql的访问速度都很快,但是如果超过200w以上的数据,他的访问速度会急剧下降,影响到我们webapp的访问速度,而且数据量太大的话,如果用单表存储,就会使得系统相当的不稳定,mysql服务很容易挂掉。所以当数据量超过200w的时候,建议系统工程师还是考虑分表.以下是几种常见的分表算法: 1.按自然时间来分表/分库; 如一个应用的数据在一年后数据量会达到200w左右,那么我们就可以考虑用一年的数据来做为一个表或者库来存储,例如,表名为app,那...
阅读全文
摘要:相同点:(1)都是申请内存,释放内存,free和delete可以释放NULL指针;(2)都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就对应一个delete/free,而是指在作用域内,new/malloc所申请的内存,必须被有效释放,否则将会导致内存泄露。 new/delete的功能完全覆盖了malloc/free,为什么C++还保留malloc/free呢?因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc..
阅读全文
摘要:/**原型:extern char *strcpy(char *dest,const char *src);*用法:#include <string.h>*功能:把src所指由NULL结束的字符串复制到dest所指的数组中。*说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。*返回指向dest的指针。*编程实现strcpy*/#include<cstdio>#include<cassert>char * _strcpy(char * dest,const char * src){ if((dest != NULL)|
阅读全文
摘要:方法一:初始化最大值为a[0],次大值为a[1],遍历一次,每次比较并更新最大值和次大值,最后就可以得到次大值。代码如下:#include<stdio.h>#include<stdlib.h>int findSecond(int *a,int size){ int i,max,s_max; max=a[0]; //最大值 s_max=a[1]; //次大值 for(i=0;i<size;i++) { if(a[i]>max) { s_max=max; //更新最大值和次大值 max=...
阅读全文
摘要:第一种方法(可能越界):a=a+b;b=a-b;a=a-b;第二种写法(只适用于整数):解决方法:(a、b异或的结果 ,和a异或得b ,和b异或得a)a=a^b;b=a^b;a=a^b;写成宏替换法:#define swap(a,b) (a)^=(b)^=(a)^=(b)
阅读全文
摘要:题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。 关于中位数:数据排序后,位置在最中间的数值。即将数据分成两部分,一部分大于该数值,一部分小于该数值。中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大的数的均值了)。分析:明显是一道工程性很强的题目,和一般的查找中位数的题目有几点不同。 1. 原数据不能读进内存,不然可以用快...
阅读全文
摘要:atoi()函数原型:int atoi(const char *nptr) 用法:#include <stdlib.h> 功能:将字符串转换成整型数;atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串时('\0')才结束转化,并将结果返回。 说明:atoi()函数返回转换后的整型数。用法如下:#include<stdio.h> #include<stdlib.h> int main() { char a[] = "-100"; char b[] = "
阅读全文
摘要:题目:给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。在构造过程:不允许使用除法;要求:O(1)空间复杂度和O(n)时间复杂度;除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);请用程序实现并简单描述。方法一:首先进行一次迭代:i:1-n-1b[i]=b[i-1]*a[i-1];这样下去就是:b[1] = a[0]b[2] = a[0]a[1]…b[i] = a[0]a[1]a[2]…a[i-1]…b[n-1] = a[0]a[1]…a[n-2]…b[i] = a[0]a[1]a[2
阅读全文
摘要:什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。说白了哈希表的原理其实就是通过空间换取时间的做法。。 哈希表的做法其实很简单,就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。 而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该...
阅读全文
摘要:据说有个计算圆周率的外星人程序,如下:#include<cstdio>#include<cstdlib> int a=10000,b,c=8400,d,e,f[8401],g;int main(){ for(;b-c;) f[b++]=a/5; for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); system("pause"); return 0;}稍微整理:#include<cstdi
阅读全文
摘要:题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。10/ \6 14/ \ / \4 8 12 16转换成双向链表4=6=8=10=12=14=16。首先我们定义的二元查找树节点的数据结构如下:struct BSTreeNode{int m_nValue; // value of nodeBSTreeNode *m_pLeft; // left child of nodeBSTreeNode *m_pRight; // right child of node};思想:1.构造二叉查找树;2.中序遍历二叉查找树,因此结点按从小到大顺序访
阅读全文
摘要:二叉排序树(Binary Sort Tree)又称二叉查找树或二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)左、右子树也分别为二叉排序树。通俗地讲很简单:一句话就是左孩子比父节点小,右孩子比父节点大,还有一个特性就是”中序遍历“可以让结点有序。如下图:几种常见的操作:1、二叉树数据结构struct BSTNode{ int data; // value of node BSTNode *lchild; // left ch...
阅读全文
摘要:题意:有一个n*m大的农场,其中每一方格不是干旱就是潮湿,现在给出k个潮湿的方格信息(即每个潮湿方格的坐标),如果每个方格与其四连通的其中一个方格连通则构成一个湖泊,该湖泊所包含的方格数就是该湖泊的大小,现在要求构成的湖泊中最大的那个湖泊所包含的方格数。输入:3 4 53 22 23 12 31 1输出:4代码:#include<iostream>#include<cmath>using namespace std;#define MAX 101int n, m, k, num, G[MAX][MAX], f[MAX][MAX];int dir[4][2] = {{1,
阅读全文
摘要:/* Author:yzm 求阶乘末尾0的个数 因式分解,有多少对2和5,末尾就有多少个0 而总是2多5少,所以5的个数决定了0的个数 进位思想: 先看有多少个5 (v除以5) 再看有多少个25 (v再除以5) 再看有多少个125(v再除以5) …… (类似于筛法)*/#include <cstdio>int main(){ int n, v, cnt; scanf("%d", &n); while(n --) { scanf("%d", &v); ...
阅读全文
摘要:double的新认识:以前总听说可以用double骗过高精度小数,不知道是怎么一回事儿,而且意识上double最多可以精确6位小数(oh!我的天!这想法哪儿学来的)。现在发现,double应该用有效数字来衡量会比较好,double可以拥有17位有效数字(最后一位有效数字是小数的话接受下一位数的四舍五入),那么就是说,如果整数部分位数很小,那么,小数部分的精度就可以调得很高,像这个例子 但如果整数很大的话,小数精度就会下降了:所以,在整数部分很大而小数部分又需要比较高的精度的话(17位以内),可以把整数部分和小数部分分开处理最后分别输出就可以了。题意:根据题目给出的公式计算N从1到9的时候e的值
阅读全文
摘要:同pku1562 Oil Deposits 油田合并(简单深搜)输入:10 12W........WW..WWW.....WWW....WW...WW..........WW..........W....W......W...W.W.....WW.W.W.W.....W..W.W......W...W.......W.输出:3代码:#include<iostream>using namespace std;char map[101][101];int dir[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
阅读全文
摘要:题意:N*M的图中有一些'@',从该位置往四周8个位置延伸,求共有多少块互不连通的‘@’构成的块?简单的dfs便能搞定。。。输入:1 1*3 5*@*@***@***@*@*1 8@@****@*5 5****@*@@*@*@**@@@@*@@@**@0 0输出:0122代码:#include<iostream>using namespace std;char map[101][101]; //定义地图 map[][],标记油田状况 int dir[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1
阅读全文
摘要:递归实现:int CountNode(BiTree T) { if(T == NULL) return 0; return 1 + CountNode(T -> lchild) + CountNode(T -> rchild); }
阅读全文
摘要:分析问题:若一颗二叉树为空,其深度为0,否则,利用其深度等于max{左子树depth,右子树depth}+1,可递归实现:int depth(BiTree T) //树的深度 { if(!T) return 0; int d1 = depth(T -> lchild); int d2 = depth(T -> rchild); return (d1 > d2 ? d1 : d2) + 1; }
阅读全文
摘要:层次遍历用队列实现:方法一:int visit(BiTree T) { if(T) { printf("%c ",T->data); return 1; } else return 0; } void LeverTraverse(BiTree T) //方法一、非递归层次遍历二叉树 { queue <BiTree> Q; BiTree p; p = T; if(visit(p)==1) Q.push(p); whil...
阅读全文
摘要:如下图表示一颗二叉树,对它进行先序遍历操作,采用两种方法,递归和非递归操作。。遍历结果为:4526731。。1、递归操作:思想:若二叉树为空,返回。否则1)后序遍历右子树;2)后序遍历左子树;3)遍历根节点代码:void PostOrder(BiTree root) { if(root==NULL) return ; PostOrder(root->lchild); //递归调用,后序遍历左子树 PostOrder(root->rchild); //递归调用,后序遍历右子树 printf("%c ", root->...
阅读全文
摘要:如下图表示一颗二叉树,对它进行先序遍历操作,采用两种方法,递归和非递归操作。。遍历结果为:4251637。。1、递归操作:思想:若二叉树为空,返回。否则1)中序遍历左子树;2)访问根节点;3)中序遍历右子树代码:void InOrder(BiTree root) { if(root==NULL) return ; InOrder(root->lchild); //递归调用,中序遍历左子树 printf("%c ", root->data); //输出数据 InOrder(root->rchild); //递归调用,中序遍历右子树 }...
阅读全文
摘要:如下图表示一颗二叉树,对它进行先序遍历操作,采用两种方法,递归和非递归操作。。遍历结果为:1245367。1、递归操作:思想:若二叉树为空,返回。否则1)遍历根节点;2)先序遍历左子树;3)先序遍历右子树代码:void PreOrder(BiTree root) { if(root==NULL) return ; printf("%c ", root->data); //输出数据 PreOrder(root->lchild); //递归调用,先序遍历左子树 PreOrder(root->rchild); //递归调用,先序遍历右子树 ...
阅读全文
摘要:二叉树数据结构:typedef struct BiTNode{ char data; struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;假设要建立一颗如下的二叉树,输入为:124##5##36##7##我们采用两种方法递归和非递归1、二叉树的先序递归建立过程(递归就是调用栈进行的操作)直接上代码:void CreateBiTree(BiTree &root) { char ch; //要插入的数据 cin>>ch; if(ch=='#') root = NULL; else ...
阅读全文
摘要:题目是这样描述的:“水王”发帖的数目超过了所有帖子的一半,有各个帖子的作者ID,求这个水王的ID编程之美给出了两种巧妙的解法解法一:ID排序,那么ID列表中的N/2项即为要找的ID(还要排序,时间复杂度为O(NlogN))解法二:通过查找,每次从列表中除去两个不一样的ID,最后就可以得出这个ID,时间复杂度O(N)。写法上也有技巧,不必非要找到一个不一样的在继续下去,如果下一个一样,那么用一个变量记录这个次数,把次数+1,遇见不一样的-1。例如1,1,2,3,4 初始value =1,count =1,第二个1,value = 1,count =2,下一个2,value=1,count=1,下
阅读全文
摘要:给定整数,判断是否是2的方幂。。我们来做分析:2->10 & 1->01 == 0 4->100 & 3->011 == 0 8->1000 & 7->0111 == 0 16->10000 & 15->01111 == 0是否看到规律呢。。n&(n-1)==0代码:int judge(int n){ return (n>0&&(n&(n-1)==0));}
阅读全文
摘要:解法一:如果n!最末尾位0,则右移一位得到商,如果末尾是1,则不能被2整除,是奇数,这个问题等同与求n!中质有质因数2的个数。。最后结果再加1代码:#include<iostream>using namespace std;int main(){ int n,sum; sum=0; cin>>n; while(n) { n>>=1; sum+=n; } cout<<sum+1<<endl; system("pause"); return 0;}解法二:N减去N的二进制表示中1的数目,然后再加1。。这也是一个规律。.
阅读全文
摘要:解法一:找出n!中质数2和质数5的个数,由于能被2整除的数的个数比能被5整除的数多的多,因为只需求出质数5的个数。利用Z=[Z/5]+[Z/25]+[Z/125]+....,其中[Z/5]表示<=z的数中含有质数5的个数。。代码:#include<iostream>using namespace std;int main(){ int n,sum; sum=0; cin>>n; while(n) { n/=5; sum+=n; } cout<<sum<<endl; system("pause"); return ...
阅读全文
摘要:扩展问题:给定二进制数N,写下从1开始到N的所有二进制数,数一下其中出现的所有“1”的个数: f(1)=1 f(10)=10 (因为01,10,有两个1) f(11)=100 (因01,10,11,有四个1)解答:考虑f(1011):1,10,11,100,101,110,111,1000,1001,1010,1011 第一位上:高位数为101,每两个数就出现一个1,则出现101个1;且current位为1,低位数为0,所以5+1=6 第二位上:高位数为10,每四个数出现一个1,则出现(10)*2=4个1;且current位为1,...
阅读全文
摘要:1、给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数?解法一:从1到N遍历,将每个数中含有“1”的个数加起来。。时间复杂度:O(n)*每个整数中“1”的个数复杂度=O(N*lgN)。。随着N增大,时间超越线性增长。。#include<iostream>using namespace std;int getNum(int n){ if(n==0) return 0; int num=0; while(n!=0) { num+=(n%10==1)?1:0; n/=10; } return nu...
阅读全文
摘要:解法一:举例说明,为了减少复杂度,就使用八位二进制吧。设 A = 0010 1011, B = 0110 0101. 1. C = A & B = 0010 0001; 2. D = A | B = 0110 1111; 3. E = C ^ D = 0100 1110; 4. 结果E中有4个1,那么也就是说将A变成B,需要改变4位(bit)。 至于如何判断E的二进制表示中有几个1,可以采用快速移位与方法。 算法原理如下: 1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位; ...
阅读全文
摘要:#include<iostream>using namespace std;/* Description: 解法一:求余法,时间复杂度O(lgn) 以10100010为例: 第一次除以2时,商为1010001,余数为0; 第二次除以2时,商为101000,余数为1; ...... 故,可以利用整形数据除法的特点,通过相除判断余数的值来分析。有如下代码: */int getNum1(int n){ if(n==0) return 0; int count=0; while(n) { if(n%2==1) { ...
阅读全文