编程之美-第3章 结构之法

3.1. 字符串移位包含问题

clip_image002

方法1:

分别对字符串进行循环移1位,2位,3位…,来判断给定的字符串是否是其中一个字串.

复杂度是O(n^3)

clip_image004

方法2:

clip_image006

这也是一种利用空间换时间的方法.

代码如下, 为了简便实现,采用了C库中的字符串操作函数:

#if 0
/** 3.1*/
bool isRotate(char *s1,char* s2){int len1=strlen(s1),len2=strlen(s2);char *ss=new char[2*len1+1];strncpy(ss,s1,len1);strncat(ss,s2,len1);char *p=strstr(ss,s2);bool flag;if(p==0)flag=false;elseflag=true;delete[] ss;return true;
}
int main(){char *s1="ABCD";char *s2="CDAB";if(isRotate(s1,s2))printf("OK");elseprintf("NO");}#endif

也可以采用KMP算法进行加快查找: http://blog.csdn.net/linyunzju/article/details/7745553

3.2 电话号码对应英语单词问题

clip_image008

这个问题可以直观的用下面的图来表示

clip_image010

这样对于一个号码所对应的单词, 可以使用对树进行搜索的方式进行.

这种情况下采用的是DFS的方式.

下面的代码中采用了两种方式, 递归和非递归的方式. 其实这就是一个组合问题, 需要遍历所有情况. 对于非递归的情况, 其实有些类似非递归的排列组合的方式.

#if 0
char *c[10]{"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ" 
};
int total[10]={0,0,3,3,3,3,3, 4,3,4};
void transform(char *number){int sz=strlen(number);int *answer=new int[sz]();while(1){for(int i=0;i<sz;i++)printf("%c",c[number[i]-'0'][answer[i]]);printf("\n");int k=sz-1;while(k>=0){if(answer[k]<total[number[k]-'0']-1){answer[k]++;break;}else{answer[k]=0;k--;}}if(k<0)break;}delete[] answer;
}
void dfs(char *number,int *answer,int k,int sz){if(k==sz){for(int i=0;i<sz;i++)printf("%c",c[number[i]-'0'][answer[i]]);printf("\n");}else{for(answer[k]=0;answer[k]<total[number[k]-'0'];answer[k]++)dfs(number,answer,k+1,sz);}}
void transform2(char *number){int sz=strlen(number);int *answer=new int[sz]();dfs(number,answer,0,sz);delete[] answer;
}
int main(){char *number="2345";transform(number);transform2(number);
}#endif

对于问题二,可以采用下面的解法:

clip_image012

3.3 计算字符串相似度问题(编辑距离问题)

clip_image014

这个问题就是编辑距离的问题.

可以有两种解决方式: 递归的方式和动态规划的方式.

方法1: 递归的方式

clip_image016

这样就得到了下面的递归程序:

#if 0
/** 3.3*/
int calc_edit_dist(char *s1,char *s2){if(*s1=='\0'||s1==0)return strlen(s2);if(*s2=='\0'||s2==0)return strlen(s1);if(*s1==*s2){return calc_edit_dist(s1+1,s2+1);}else{int ed1=calc_edit_dist(s1,s2+1);int ed2=calc_edit_dist(s1+1,s2);int ed3=calc_edit_dist(s1+1,s2+1);if(ed1<ed2)return (ed1<ed3?ed1:ed3)+1;elsereturn (ed2<ed3?ed2:ed3)+1;}
}
int main(){char *s1="ab";char *s2="bb";printf("%d\n",calc_edit_dist(s1,s2));}#endif

但是递归程序计算比较慢, 因为中间存在很多的重复计算.

clip_image018\

方法2: 动态规划

这个问题其实可以归结为寻找两个序列的最长公共子序列问题.

参考: http://blog.csdn.net/linyunzju/article/details/7747718

3.5 最短摘要生成问题

给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请说明思路并编程实现方法String extractSummary(String description,String[] key words),目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。(不限编程语言)20分。

clip_image020

#if 0
bool allExisted(const map<string,int>& mp){map<string,int>::const_iterator ite;for(ite=mp.begin();ite!=mp.end();++ite)if(ite->second==0)return false;return true;
}
void reset(map<string,int>& mp){map<string,int>::iterator ite;for(ite=mp.begin();ite!=mp.end();++ite)ite->second=0;
}
int find_min_len_digest(const vector<string>& vec,const vector<string>& keywords){map<string,int> mp;int len=1000000;vector<string>::const_iterator ite,pbeg,pend;for(ite=keywords.begin();ite!=keywords.end();++ite)mp[*ite]=0;pbeg=vec.begin();while(pbeg!=vec.end()){while(pbeg!=vec.end()&&mp.find(*pbeg)==mp.end())++pbeg;if(pbeg==vec.end())break;mp[*pbeg]++;pend=pbeg+1;while(pend!=vec.end()&&!allExisted(mp)){if(mp.find(*pend)==mp.end()) {++pend;}else{mp[*pend]++;++pend;}}if(allExisted(mp)){if(pend!=vec.end()){if(len>pend-pbeg){len=pend-pbeg;}for(ite=pbeg;ite!=pend;++ite)cout<<*ite<<' ';cout<<'\n';}else{if(len>vec.size()-(pbeg-vec.begin()))len=vec.size()-(pbeg-vec.begin());for(ite=pbeg;ite!=vec.end();++ite)cout<<*ite<<' ';cout<<'\n';break;}reset(mp);}pbeg=pend;}return len;
}
int main(){
//    string str[]={"i","am","a","big","boy",".","i","is","i","boy"};
//      string key[]={"i","boy"};
string key[] = { "微软", "计算机", "亚洲"};string str[] = { "微软","亚洲","研究院","成立","","1998","","","我们","","使命","","使","未来","","计算机","能够","","","","","","","","","自然语言","","人类","进行","交流","","","","基础","","","微软","亚洲","研究院","","","促进","计算机","","亚太","地区","","普及","","改善","亚太","用户","","计算","体验","",""};vector<string> keywords(key,key+sizeof(key)/sizeof(string));vector<string> vec(str,str+sizeof(str)/sizeof(string));//  copy(vec.begin(),vec.end(),ostream_iterator<string>(cout," "));
//  cout<<endl;
find_min_len_digest(vec,keywords);}#endif

3.6 判断两个链表是否相交

clip_image022

clip_image024clip_image026clip_image028clip_image030

参考: http://blog.csdn.net/linyunzju/article/details/7753548

3.7 队列中取最大值操作问题

clip_image032

clip_image034

clip_image036

参考: http://blog.csdn.net/linyunzju/article/details/7765324

解法三:

利用两个STL中的stack适配器来实现带有最大值操作的栈类, 然后利用两个新实现的栈来实现带有最大值操作的队列.

#if 0
class Stack{public:void push(int x){sta.push(x);if(stb.empty()) {stb.push(x);}else{int t=stb.top();stb.push(t>x?t:x);}}void pop(){if(!sta.empty()){sta.pop();stb.pop();}}int top(){assert(sta.empty()==false);return sta.top();}int maxV(){assert(sta.empty()==false);return stb.top();}int size(){return sta.size();}bool empty(){return sta.empty();}private:stack<int> sta;stack<int> stb;
};
class Queue{public:void push(int x){sta.push(x);}void pop(){if(stb.empty()) {while(!sta.empty()) {int t=sta.top(); sta.pop();stb.push(t);}}stb.pop();}int front(){if(stb.empty()) {while(!sta.empty()){int t=sta.top(); sta.pop();stb.push(t);}}return stb.top();}int maxV(){if(stb.empty()){return sta.maxV();}if(sta.empty()){return stb.maxV();}return max(sta.maxV(),stb.maxV());}private:Stack sta;Stack stb;
};
int main(){Queue q;  int a[] = {2, 3, 4, 9, 4, 5, 10, 6};  for(int i = 0; i < sizeof(a)/sizeof(int); ++i) {  q.push(a[i]);  }  q.push(101);cout<<q.front()<<endl;cout<<"queue maxvalue = "<<q.maxV()<<endl;  q.push(590);cout<<"queue maxvalue = "<<q.maxV()<<endl;  int deq = q.front();  cout<<"deq = "<<deq<<endl;  cout<<"queue maxvalue = "<<q.maxV()<<endl;  q.pop();cout<<"queue maxvalue = "<<q.maxV()<<endl;  
}#endif

3.8 求二叉树中节点的最大距离

clip_image037

计算一个二叉树的最大距离有两个情况:

情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。

情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。

只需要计算这两个情况的路径距离,并取其大者,就是该二叉树的最大距离。

clip_image038

//思路:注意指针声明了一定要赋值,否则会报错。

// 方法一:递归法

//距离相差最远的两个结点,共有以下两种情况:

// (1)路径经过根结点,所以两个结点在根结点的不同分支上

// (2)路径不经过根结点,所以两个结点应该是次根结点中相聚最远的两个结点。(递归思想)

// 递归本质上还是采用了后续遍历的方法。由于是从叶子结点开始的所以每次处理都是第一种情况。

// 方法二:非递归法

//采用后序遍历二叉树的同时对二叉树的结点进行更新,每次更新都要更新最大距离。

struct Node{char data;Node* left;Node* right;int nMaxLeft;int nMaxRight;
};
int maxLen=0;
void findMaxLength(Node* root){if(root==0)return ;if(root->left==0)root->nMaxLeft=0;if(root->right==0)root->nMaxRight=0;if(root->left!=0)findMaxLength(root->left);if(root->right!=0)findMaxLength(root->right);if(root->left!=0) {root->nMaxLeft=(root->left->nMaxLeft>root->left->nMaxRight?root->left->nMaxLeft:root->left->nMaxRight)+1;}if(root->right!=0){root->nMaxRight=(root->right->nMaxLeft>root->right->nMaxRight?root->right->nMaxLeft:root->right->nMaxRight)+1;}if(root->nMaxLeft+root->nMaxRight>maxLen)maxLen=root->nMaxLeft+root->nMaxRight;
}
void findMaxLength2(Node* root){stack<Node*> st;Node *p=root,*visited=0;while(p!=0||!st.empty()){while(p!=0){st.push(p);p=p->left;}p=st.top();if(p->right==0||visited==p->right){if(p->left!=0) {p->nMaxLeft=(p->left->nMaxLeft>p->left->nMaxRight?p->left->nMaxLeft:p->left->nMaxRight)+1;}if(p->right!=0){p->nMaxRight=(p->right->nMaxLeft>p->right->nMaxRight?p->right->nMaxLeft:p->right->nMaxRight)+1;}if(p->nMaxLeft+p->nMaxRight>maxLen)maxLen=p->nMaxLeft+p->nMaxRight;st.pop();visited=p;p=0;}elsep=p->right;}
}

这段代码有几个缺点:

算法加入了侵入式(intrusive)的资料nMaxLeft, nMaxRight

使用了全局变量 nMaxLen。每次使用要额外初始化。而且就算是不同的独立资料,也不能在多个线程使用这个函数

逻辑比较复杂,也有许多 NULL 相关的条件测试。

一种不改变树本身结构的方法:

我认为这个问题的核心是,情况A 及 B 需要不同的信息: A 需要子树的最大深度,B 需要子树的最大距离。只要函数能在一个节点同时计算及传回这两个信息,代码就可以很简单:

struct RESULT{int nMaxDistance;int nMaxDepth;
};
RESULT findMaxLength3(Node* root){if(root==0){RESULT empty={0,-1};return empty;}RESULT lhs=findMaxLength3(root->left);RESULT rhs=findMaxLength3(root->right);RESULT res;res.nMaxDepth=max(lhs.nMaxDepth,rhs.nMaxDepth)+1;res.nMaxDistance=max(max(lhs.nMaxDistance,rhs.nMaxDistance),lhs.nMaxDepth+rhs.nMaxDepth+2);return res;
}void postorder(Node* root){stack<Node*> st;Node* p=root,*visited=0;while(p!=0||!st.empty()){while(p!=0){st.push(p);p=p->left;}p=st.top();if(p->right==0||visited==p->right){cout<<(int)p->data<<' ';st.pop();visited=p;p=0;}else{p=p->right;}}cout<<endl;
}

计算 result 的代码很清楚;nMaxDepth 就是左子树和右子树的深度加1;nMaxDistance 则取 A 和 B 情况的最大值。

为了减少 NULL 的条件测试,进入函数时,如果节点为 NULL,会传回一个 empty 变量。比较奇怪的是 empty.nMaxDepth = -1,目的是让调用方 +1 后,把当前的不存在的 (NULL) 子树当成最大深度为 0。

除了提高了可读性,这个解法的另一个优点是减少了 O(节点数目) 大小的侵入式资料,而改为使用 O(树的最大深度) 大小的栈空间。这个设计使函数完全没有副作用(side effect)。

测试代码如下:

Node* initTree()  
{  Node* tree[10];  for(int i=0;i<10;i++)  {  tree[i]=(Node*)malloc(sizeof(Node));  tree[i]->nMaxLeft=0;  tree[i]->nMaxRight=0;  tree[i]->left=NULL;  tree[i]->right=NULL;  tree[i]->data=(char)i;  }  for(int i=0;i<=2;i++)  {  tree[i]->left=tree[2*i+1];  tree[i]->right=tree[2*i+2];  }  tree[3]->left=tree[7];  tree[5]->right=tree[8];  return tree[0];  
}  
int main(){findMaxLength(initTree());  printf("递归法:%d\n",maxLen); maxLen=0;findMaxLength2(initTree());  printf("非递归:%d\n",maxLen);  maxLen=0;RESULT r=findMaxLength3(initTree());printf("new Method:%d\n",r.nMaxDistance);
}

参考: http://blog.csdn.net/zuiaituantuan/article/details/6210317

http://www.cnblogs.com/miloyip/archive/2010/02/25/1673114.html

3.9 重建二叉树

主要是给出前序和中序或中序和后序来构造出二叉树.

这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。

一、已知二叉树的前序序列和中序序列,求解树。

1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

二、已知二叉树的后序序列和中序序列,求解树。

1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

举例说明:根据已知求解二叉树

中序序列 HLDBEKAFCG

后序序列 LHDKEBFGCA

1、在后序序列LHDKEBFGCA中最后出现的元素为A,HLDBEK|A|FCG

2、在后序序列LHDKEB中最后出现的元素为B,HLD|B|EK|A|FCG

3、在后序序列LHD中最后出现的元素为D,HL|D|B|EK|A|FCG

4、在后序序列LH中最后出现的元素为H,H|L|D|B|EK|A|FCG

5、在后序序列KE中最后出现的元素为E,H|L|D|B|E|K|A|FCG

5、在后序序列FGC中最后出现的元素为C,H|L|D|B|E|K|A|F|C|G

6、所有元素都已经定位,二叉树求解完成。

A

/ \

B C

/ \ / \

D E F G

/ \

H K

\

L

下面的代码中也包括了根据两个遍历结果输出另一个结果.

#if 0
//查找根节点的位置
char* find_root(char *start,char *end,char c){while(start<=end){if(*start==c)return start;start++;}return NULL;
}
//根据前序和中序来输出后序:核心函数
void pre_in_post_(char *pre_start,char*pre_end,char* in_start,char *in_end){if(in_start>in_end)return;if(in_start==in_end) {printf("%c",*in_start);return ;}char c=*pre_start++;char *p=find_root(in_start,in_end,c);if(p!=NULL){int len=p-in_start;pre_in_post_(pre_start,pre_start+len-1,in_start,p-1);pre_in_post_(pre_start+len,pre_end,p+1,in_end);}printf("%c",c);
}
//调用上面的递归函数
void pre_in_post(char*pre,char *in){int len1=strlen(pre);int len2=strlen(in);char *pre_end=pre+len1-1;char *in_end=in+len2-1;pre_in_post_(pre,pre_end,in,in_end);
}
//根据后序和中序来输出前序
void post_in_pre_(char *post_start,char*post_end,char* in_start,char *in_end){if(in_start>in_end)return;if(in_start==in_end) {printf("%c",*in_start);return ;}char c=*post_end--;char *p=find_root(in_start,in_end,c);printf("%c",c);if(p!=NULL){int len=p-in_start;post_in_pre_(post_start,post_start+len-1,in_start,p-1);post_in_pre_(post_start+len,post_end,p+1,in_end);}}
//调用上面的递归函数
void post_in_pre(char*post,char *in){int len1=strlen(post);int len2=strlen(in);char *post_end=post+len1-1;char *in_end=in+len2-1;post_in_pre_(post,post_end,in,in_end);
}
//二叉树节点定义
struct Node{char data;Node* left;Node* right;Node(){};Node(char c,Node* l=0,Node* r=0):data(c),left(l),right(r){}
};
//根据前序和中序来重建二叉树
Node* rebuild_pre_in_post_(char *pre_start,char*pre_end,char* in_start,char *in_end){if(in_start>in_end)return 0;if(in_start==in_end)return new Node(*in_start);char c=*pre_start++;char *p=find_root(in_start,in_end,c);Node* r=new Node(c);if(p!=NULL){int len=p-in_start;r->left=rebuild_pre_in_post_(pre_start,pre_start+len-1,in_start,p-1);r->right=rebuild_pre_in_post_(pre_start+len,pre_end,p+1,in_end);}return r;
}
//
Node* rebuild_pre_in_post(char*pre,char *in){int len1=strlen(pre);int len2=strlen(in);char *pre_end=pre+len1-1;char *in_end=in+len2-1;Node* root=rebuild_pre_in_post_(pre,pre_end,in,in_end);return root;
}
//根据后序和中序来重建二叉树
Node* rebuild_post_in_pre_(char *post_start,char*post_end,char* in_start,char *in_end){if(in_start>in_end)return 0;if(in_start==in_end)return new Node(*in_start);char c=*post_end--;char *p=find_root(in_start,in_end,c);Node* r=new Node(c);if(p!=NULL){int len=p-in_start;r->left=rebuild_post_in_pre_(post_start,post_start+len-1,in_start,p-1);r->right=rebuild_post_in_pre_(post_start+len,post_end,p+1,in_end);}return r;
}
//
Node* rebuild_post_in_pre(char*post,char *in){int len1=strlen(post);int len2=strlen(in);char *post_end=post+len1-1;char *in_end=in+len2-1;Node* root=rebuild_post_in_pre_(post,post_end,in,in_end);return root;
}
//前序遍历函数
void PreOrder(Node* root){if(root!=0) {printf("%c ",root->data);PreOrder(root->left);PreOrder(root->right);}
}
//后序变量函数
void PostOrder(Node* root){if(root!=0) {PostOrder(root->left);PostOrder(root->right);printf("%c ",root->data);}
}
int main(){char *pre="ACBGEDF";char *in="GBCEADF";char *post="GBECFDA";pre_in_post(pre,in);printf("\n");post_in_pre(post,in);printf("\n");PreOrder(rebuild_pre_in_post(pre,in));printf("\n");PostOrder(rebuild_post_in_pre(post,in));
}#endif

参考: http://www.cnblogs.com/bmrs/archive/2010/08/19/SloveTree.html

转载于:https://www.cnblogs.com/xkfz007/archive/2012/11/07/2758363.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每天学习一点点(2010年二月)

2010/2/8号 星期一 1.决定记录下每天学到的东西和感悟 2.看老赵的博客&#xff0c;学到一句话&#xff1a;Apple告诉我们的铁律是&#xff1a;表面功夫一定要做足。 3.看到一个笑话&#xff1a;你属什么&#xff1f;我属 于你。 2010/2/9号 星期二 1.减少页面中独立的请求数&…

InnoDB一棵B+树可以存放多少行数据?

一个问题&#xff1f; InnoDB一棵B树可以存放多少行数据&#xff1f;这个问题的简单回答是&#xff1a;约2千万。为什么是这么多呢&#xff1f;因为这是可以算出来的&#xff0c;要搞清楚这个问题&#xff0c;我们先从InnoDB索引数据结构、数据组织方式说起。 我们都知道计算…

调整路由的AD值

实验&#xff1a;调整路由的AD值【实验名称】调整路由的AD值 (注意&#xff1a;PT有可能不支持distance 99 192.168.1.2 0.0.0.0这条命令&#xff0c;所以我们做实验的时候最好用小凡模拟器)【实验目的】通过调整路由的管理距离值&#xff0c;实现路由的管理和控制【实验背景】…

C#学习日志三(流程控制语句)

if条件语句&#xff1a;根据某个条件对成都的执行进行两路分支。语法&#xff1a;if(条件){语句块1}else{语句块2}*else部分并不是必须存在的。 switch...case条件选择语句&#xff1a;当分支条件很多时&#xff0c;使用。语法&#xff1a;switch(控制表达式){case 常量表达式1…

MySQL索引的一些问题

MySQL索引的一些问题 注意&#xff1a;本文基于MySQL的InnoDB引擎说明。 一、什么是最左前缀原则 对于该表&#xff0c;如果按照name字段来建立索引的话&#xff0c;采用B树结构&#xff0c;大概的索引如下&#xff1a; 如果要进行模糊查找&#xff0c;查找name 以“张"…

线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析...

最近&#xff0c;在做一个使用线程控制下载文件的小程序&#xff08;使用进度条控件显示下载进度&#xff09;时&#xff0c;遇到这样的问题&#xff0c; 错误显示&#xff1a; 未处理的“System.InvalidOperationException”类型的异常出现在 System.Windows.Forms.dll 中。 其…

大家狂欢吧,我的Google帐号悲剧了

大家狂欢吧&#xff0c;我的Google帐号悲剧了 今早开始&#xff0c;鄙人在Google Code上突然被强行杯具&#xff0c;出现如下图。 最无奈的是询问Google Code管理组后得到回复如下。 然后管理员就睡觉去了|||…… 继续等待中&#xff0c;能恢复的话我会发个解决心得以警后人&am…

Hive简单实际操作(二)

两个常用的交互命令 不用启动hive就可以执行的命令 1. bin/hive -e "select * from default.animal;" 可以直接显示指定命令后的内容 2. 创建一个sql文件 vi hivef.sql 在文件内部添加你希望执行的命令例如: select * from default.animal; bin/hive -f /opt/module/…

在数据库中, 不用max()/min()找出一个列中最大/最小值的记录

不用max()/min()找出c1列中最大/最小值的记录 // 找出c1列中&#xff0c;c1是最小值的那条记录&#xff0c;不能用min() select * from t1 where c1 < all(select c1 from t1); // 找出c1列中&#xff0c;c1是最大值的那条记录&#xff0c;不能用max() select * from t1 …

C眼看J - 初窥JAVA

最近一直在学习JAVA&#xff0c;出发点并不是像当初学C那样&#xff0c;而只是想把JAVA作为下学期参加比赛的工具&#xff0c;带着这种“浮躁”的心态&#xff0c;使得我总是在想“这个用看么&#xff1f;”、“那个用看么&#xff1f;”。 这是第一次在掌握了一门语言&#xf…

为Mac OS X添加用Firefox搜索服务

为Mac OS X添加用Firefox搜索服务 在Mac OS X上&#xff0c;Firefox这种移植过来的程序往往不提供服务&#xff0c;比如只有safari才能利用服务搜索&#xff0c;经过一番实验终于自己做了一个服务&#xff1a; 第一步&#xff0c;打开Automator 第二部&#xff0c;新建一个服务…

jmeter持续集成测试中mongodb版本问题

jmeter测试mongodb&#xff0c;采用的是JSR223 Sampler脚本连接数据库&#xff0c;其中连接数据库用到了SCRAM-SHA1认证机制&#xff0c;代码如下&#xff1a; MongoCredential credential MongoCredential.createScramSha1Credential("username", "databaseN…

速度之王 — LZ4压缩算法与其他算法的比较

LZ4 (Extremely Fast Compression algorithm) 项目&#xff1a;http://code.google.com/p/lz4/ 作者&#xff1a;Yann Collet 本文作者&#xff1a;zhangskd csdn blog 简介 LZ4 is a very fast lossless compression algorithm, providing compression speed at 400MB/…

我用过的DOS命令

我用过的DOS命令 1、进入当前目录的子目录&#xff1a;cd xxx 2、放回到当前目录的上一子目录&#xff1a;cd.. 3、返回到根目录&#xff1a;cd/ 5、进入到指定目录&#xff1a;先键入指定目录的本目录如D盘&#xff1a;D: 然后回车键入cd xxx\xxx\xxx\xxx\xxx 如图&#xf…

XAMPP 无法启动解决

当安装完XAMPP后&#xff0c;在XAMPP Control Panel 里面无法启动apache,网上找了很多都是关于apache端口冲突问题&#xff0c;但我的不是&#xff0c;解决步骤如下&#xff1a;1&#xff1a;进入apache目录 conf/httpd.conf 改变监听端口&#xff1a;Listen 8080--启动任然失败…

lz4压缩算法--速度之王

简介 lz4是目前综合来看效率最高的压缩算法&#xff0c;更加侧重压缩解压速度&#xff0c;压缩比并不是第一。在当前的安卓和苹果操作系统中&#xff0c;内存压缩技术就使用的是lz4算法&#xff0c;及时压缩手机内存以带来更多的内存空间。本质上是时间换空间。 压缩原理 lz…

Mac OS defaults命令(Access the Mac OS user defaults system)

defaults命令: 用于访问和修改Mac 上一些系统的默认设置&#xff08;Access the Mac OS user defaults system&#xff09; 仅修改当前用户设置&#xff0c;所以不应加sudo。 用法&#xff1a; 读取所有默认配置&#xff1a; defaults read 读取某项配置&#xff1a; defaults …

推荐12个绚丽的CSS3图片悬停效果

CSS3为我们开发提供了很多特效&#xff0c;如鼠标悬停&#xff0c;线性渐变&#xff0c;在web开发早期常用的是鼠标悬停&#xff0c;他是网页制作的常用特效之一&#xff0c;早期使用Flash可以制作非常炫的效果&#xff0c;后来慢慢演变成现在的是图片悬停效果&#xff0c;现在…

SAP和ABAP内存的区别

1、读取哈使用方法不同SAP内存使用SET/GET parameters方法&#xff1b;ABAP内存使用 EXPORT 和 IMPORT 方法&#xff1b;2、共享范围不同SAP内存可以被所有的主session访问&#xff0c;内存数据可以同一个session中不同程序之间&#xff0c;或者不同session之间&#xff1b;AB…

RocksDB事务实现TransactionDB分析

基本概念 1. LSN (log sequence number) RocksDB中的每一条记录(KeyValue)都有一个LogSequenceNumber(后面统称lsn)&#xff0c;从最初的0开始&#xff0c;每次写入加1。该值为逻辑量&#xff0c;区别于InnoDB的lsn为redo log物理写入字节量。 我有几张阿里云幸运券分享给你&…