您的位置:首页 > 理论基础 > 计算机网络

各类 HTTP 返回状态代码详解

2014-11-03 17:16 344 查看
大众点评网的两道笔试题

因为白师兄的缘故,偶然看他做大众点评网网上的笔试题,总共有两个编程题。
第一个题目大意是:给定两个字符串,将凡是在第二个字符串出现过的字符从字符串一中删除,即删除字符串一和字符串二相同字符(只对字符串一执行删除操作)。这个看到题目是觉得很简单,最常规的方法是依次遍历字符串一,然后用此时的字符与字符串二依次比较,相同则删除。这是大家最常想到的方法了。但是有没有更高效的算法呢,这样才能在笔试中脱颖而出,下面是我和师兄的想法:第一步:开辟一个128(或者256)的字符标记数组flag,并将其初始化为为零,每个数组元素的索引值即为当前表示的字符(49表示字符‘1’)。第二步:然后遍历字符串二,并将相应的flag对应的字符位置置一。遍历完成后,flag数组会将字符串二出现过的字符的相应位置置一。第三步:遍历字符串一,检查flag数组的相应位置是否为一,如果是一则执行删除操作,不为一则继续执行,直到数组最后一个元素。上边算法对比于最常想到的方法,对字符串二的遍历次数会明显减少(字符串一长度越长,节约的时间就越多)。不足之处就是借助了一个标记数组,在空间复杂度上不如常用算法。注意:执行完删除操作后,要注意此时字符串长度已经发生改变,因此利用for循环使用的变量索引要做一定改变,才能正常完成功能。至于程序代码,我就不给出了,大家自己可以实现试试。

第二个题目大意如下:现在的智能手机都是触屏,而且都有智能的锁屏软件,一般是如下的这个样子

然后将数字连接即可生成不同的密码。当然连接数字有一个约束条件:相连数字之间不能有第三个数字。即不能出现上图中直线的那种情况。编程实现,找出符合约束条件的所有密码的(密码长度为3~9)组合。
解答:刚看到题目,有点晕,不知道如何下手。但是静下心,通过分析对比,可以发现,当相连的两个字符的水平距离为2(且在同一垂直线上)者垂直距离(且在同一个水平距离)为2,亦或水平距离和垂直距离都为2的时候会满足约束条件。上边的约束条件其实就是密码长度为2时应该满足的要求,那么代码长度为3时,其实可以用密码长度为2的来模拟,先确定一个数字,然后寻找满足约束条件的数字,那么剩下就是密码长度为2的寻找,既然密码长度为3的找到了,密码长度为4的也就不在话下,利用相同方法…依次类推可以得到密码长度为9的密码。这时是不是有点感觉了,这就是递归嘛。
第一步:开辟一个标记数组,用来标记不同密码长度时对应的长度,当为一时会终止递归。如果发现相应数字处已经有数字,则直接返回(即一个密码不能有两个相同数字)。第二步:建立邻接矩阵,即将每个数字能够满足约束条件的数字放在该数字后边比如对于数字1 。建立邻接矩阵后为1-> 2 -> 4 -> 5 ->6 ->8第三步:对于不同的密码长度调用代码生成函数(递归函数)
下边是代码实现
#include<stdio.h>#include<stdlib.h>#include<time.h>#defineNUM_NODE 9 //定义数字节点个数
typedefstruct LIST{ int index; struct LIST * next;}node,*pnode;//设立数字节点
intnode_num[10];//保存每个邻接矩阵的后边的节点个数,比如数字1它的邻接矩阵为1->2 -> 4 -> 5 ->6 ->8,所以个数为5intflag[10];//标记数组,记录密码长度的迭代变化
int sum=0;pnode code_node[NUM_NODE+1];//之所以定义为NUM_NODE+1是因为保持索引值和数字大小一致voidgetxy(int num,int *x,int *y);//将数字转化成坐标,以进行判断是否满足约束标准
intcom_dist(int x1,int y1,int x2,int y2);//利用getxy得到的坐标,计算不同数字的距离
intinsert_node(pnode node,int num);//邻接矩阵的初始化过程,节点插入
voidcode_gen(pnode node,int len);//密码生成
FILE *f;
int main(){ int begin_x,begin_y; int end_x,end_y; int i,j; int num; clock_t start,end; for(i=0;i<=NUM_NODE;i++)// 标记数组初始化 { flag[i]=0; } for(i=0;i<=NUM_NODE;i++)//邻接矩阵的头结点初始化 { code_node[i]=(pnode)malloc(sizeof(node)*1); code_node[i]->index=i; code_node[i]->next=NULL; } for(i=1;i<=NUM_NODE;i++)//邻接矩阵的生成 { num=0; printf("%d->",i); getxy(i,&begin_x,&begin_y); for(j=1;j<=NUM_NODE;j++) { getxy(j,&end_x,&end_y); if(begin_x==end_x&& begin_y==end_y) { continue; } if(1==com_dist(begin_x,begin_y,end_x,end_y)) { insert_node(code_node[i],j); printf("%d->",j); num++; } } node_num[i]=num; printf("\n"); }
// f=fopen("result.txt","w"); start=clock(); for(i=3;i<=9;i++)//密码长度的变化 {
for(j=1;j<=NUM_NODE;j++)//选取不同密码起始数字时的密码情况 { flag[j]=i;// printf("%d->",code_node[j]->index); code_gen(code_node[j],i); flag[j]=0; } } end=clock(); printf("%d",end-start);// fclose(f); return 0;}//获取不同数字的坐标voidgetxy(int num,int *x,int *y){
if(num>=1 && num<=3) { x[0]=1; y[0]=num%4; } if(num>=4 && num<=6) { x[0]=2; y[0]=(num-3)%4; } if(num>=7 && num<=9) { x[0]=3; y[0]=(num-6)%4; }}//计算不同数字的距离,水平和垂直距离intcom_dist(int x1,int y1,int x2,int y2){
int absx=abs(x1-x2); int absy=abs(y1-y2); if((absx==2 && absy==0) ||(absy==2 && absx==0) || (absx==2 && absy==2)) { return -1; } else { return 1; }}//邻接矩阵初始化,使用的插入函数intinsert_node(pnode node,int num){ pnode new_node; pnode temp=node; new_node=(pnode)malloc(sizeof(node)*1);
if(new_node==NULL) { return 0; }
while(temp->next != NULL) { temp=temp->next; } new_node->index=num; new_node->next=NULL; temp->next=new_node; return 1;}//打印密码voidprint_code(){ int i=0; int j; int max=0;
for(i=0;i<=NUM_NODE;i++) { if (max<flag[i]) max=flag[i]; } for(i=max;i>0;i--) { for(j=0;j<=NUM_NODE;j++) { if(i==flag[j]) { fprintf(f,"%d->",j); printf("%d->",j); } } } fprintf(f,"\n");}//密码生成voidcode_gen(pnode node,int len){ int num; int i,j; pnode temp;

if(len==1) // 迭代终止条件,当长度为一时,进行输出和sum自增 { // print_code();// printf("\n"); sum++; return; } else { num=node->index; for(i=0;i<node_num[num];i++)//遍历邻接矩阵 { temp=node; for(j=0;j<=i;j++)//邻接矩阵 { temp=temp->next; } if(flag[temp->index]==0) {// printf("%d->",temp->index); flag[temp->index]=len-1; } else { continue; } code_gen(code_node[temp->index],len-1);//密码长度为len-1 flag[temp->index]=0; } }}

上边注释掉的语句为输出语句(包括命令行输出和文件输出),如果要观察输出,可以去掉注释,但是运行时间会较长。(因为命令行输出很占时间)
还有一个问题是,主函数中没有添加邻接矩阵的释放函数,可以自己添加。

其实,要想验证这一方法的正确性,可以使用实现全排列(网上代码多),然后利用约束条件进行判断,然后将满足的条件的加一。对比与上边的结果是否一致。由于时间问题,我就没有实现了比较了,谁如果比较了发现不对,请留言。

本文出自 “大叔” 博客,请务必保留此出处http://zjd1988.blog.51cto.com/2180707/1346326
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: