求解一道百度笔试题

eejacobi 2009-10-19 09:16:49
一个M*M的矩阵A,每个元素都是字符;一个字符串数组S,比较S中的字符串是否在A中的连续对角线序列中出现。对于一个4*4的矩阵:
1 2 3 4
a b c d
5 6 7 8
e f g h
其连续对角线为:
左上到右下:1 2 a 5 b 3 4 c 6 e f 7 d 8 g h 或者 1 a 2 3 b 5 e 6 c 4 d 7 f g 8 h
右上到左下:4 3 d 8 c 2 1 b 7 h g 6 a 5 f e 或者 4 d 3 2 c 8 h 7 b 1 a 6 g f 5 e

...全文
438 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
linren 2009-10-21
  • 打赏
  • 举报
回复
4楼的程序只是用strstr进行了单模式的串匹配
多模式的匹配可以使用WM或AC算法……

1楼的想法不错……
不过在某些情况下效率可能会不是很理想
比如说:
aaaa
caaa
caba
aaaa

查找:
aaaa
aab
acca
aa

当某个字符出现的频率比较高的时候……
tianya0609 2009-10-21
  • 打赏
  • 举报
回复
mark
linren 2009-10-20
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char a5[5][5]={
'a','b','c','d','e',
'1','2','3','4','5',
'f','g','h','i','j',
'6','7','8','9','0',
'k','l','m','n','o'};
char a4[4][4]={
'1','2','3','4',
'a','b','c','d',
'5','6','7','8',
'e','f','g','h'};

void find(char *a,int m,int f,char *s){
int t,i,j,k;
char *tmp;
char *p;

if(f!=1&&f!=2&&f!=3&&f!=4) return;

tmp=(char*)malloc(sizeof(char)*(m*m+1));
tmp[0]='\0';k=0;

for(t=0;t<m;t++){
if(f==1){
i=t;j=0;
while(1){
tmp[k++]=*(a+i*m+j);
if(i==0) break;
i--;j++;
}
f=2;
}else if(f==2){
j=t;i=0;
while(1){
tmp[k++]=*(a+i*m+j);
if(j==0) break;
i++;j--;
}
f=1;
}else if(f==3){
i=t;j=m-1;
while(1){
tmp[k++]=*(a+i*m+j);
if(i==0) break;
i--;j--;
}
f=4;
}else if(f==4){
i=0;j=m-1-t;
while(1){
tmp[k++]=*(a+i*m+j);
if(j==m-1) break;
i++;j++;
}
f=3;
}
}
for(t=1;t<m;t++){
if(f==1){
i=m-1;j=t;
while(1){
tmp[k++]=*(a+i*m+j);
if(j==m-1) break;
i--;j++;
}
f=2;
}else if(f==2){
j=m-1;i=t;
while(1){
tmp[k++]=*(a+i*m+j);
if(i==m-1) break;
i++;j--;
}
f=1;
}else if(f==3){
i=m-1;j=m-1-t;
while(1){
tmp[k++]=*(a+i*m+j);
if(j==0) break;
i--;j--;
}
f=4;
}else if(f==4){
i=t;j=0;
while(1){
tmp[k++]=*(a+i*m+j);
if(i==m-1) break;
i++;j++;
}
f=3;
}
}
tmp[k++]='\0';
printf("[%s] match [%s]: ",s,tmp);
p=strstr(tmp,s);
if(p==0) printf("not match!\n");
else printf("pos %d\n",p-tmp+1);

free(tmp);
}

int main(){
char s[100];

sprintf(s,"d3g");
find(&a5[0][0],5,1,s);
find(&a5[0][0],5,2,s);

sprintf(s,"i0o9h2a");
find(&a5[0][0],5,3,s);
find(&a5[0][0],5,4,s);

sprintf(s,"b5e6c");
find(&a4[0][0],4,1,s);
find(&a4[0][0],4,2,s);
find(&a4[0][0],4,3,s);
find(&a4[0][0],4,4,s);

return 0;
}

【运行结果】
[d3g] match [ab1f2cd3g6k7h4e5i8lm9j0no]: pos 7
[d3g] match [a1bc2f6g3de4h7kl8i5j9mn0o]: not match!
[i0o9h2a] match [ed5j4cb3i0o9h2a1g8nm7f6lk]: pos 9
[i0o9h2a] match [e5dc4j0i3ba2h9on8g1f7ml6k]: not match!
[b5e6c] match [12a5b34c6ef7d8gh]: not match!
[b5e6c] match [1a23b5e6c4d7fg8h]: pos 5
[b5e6c] match [43d8c21b7hg6a5fe]: not match!
[b5e6c] match [4d32c8h7b1a6gf5e]: not match!
Press any key to continue


【说明】
主要是使用了库函数strstr……
eejacobi 2009-10-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 threeleafzerg007 的回复:]
我的解法:

先做一个 字符 hashmap
hash的结点设计

typedef struct _hashnode_t
{
    int row;
    int col;
    struct _hashnode_t *next
}hashnode_t;

hashnode_t *hashmap[255];

遍历一次数组得到每个字符相应的 row,col (可重复)

然后开始遍历字符串数组,

对于每一个字符串,先找出第一个字符在hashmap中的 row,col 无则查第二个字符串。

有则分别按照 左上 左下 右下 右上 四个对角线方向遍历自身的字符串 ,直至符合或者不符合。
觉得关键在于如何优化这个搜索过程

最后依次遍历整个字符串数组。

建hashmap O(M*M)时间

遍历字符串数组 O(sizeof(array) * strlen(string))
?A中可能多个对应的起始字符

我觉得属于技巧题
[/Quote]
L_thread 2009-10-20
  • 打赏
  • 举报
回复
mask
tianya0609 2009-10-19
  • 打赏
  • 举报
回复
mark
sdn_009 2009-10-19
  • 打赏
  • 举报
回复
我也在baidu笔试中碰到这题了,不过也没想法的
threeleafzerg007 2009-10-19
  • 打赏
  • 举报
回复
我的解法:

先做一个 字符 hashmap
hash的结点设计

typedef struct _hashnode_t
{
int row;
int col;
struct _hashnode_t *next
}hashnode_t;

hashnode_t *hashmap[255];

遍历一次数组得到每个字符相应的 row,col (可重复)

然后开始遍历字符串数组,

对于每一个字符串,先找出第一个字符在hashmap中的 row,col 无则查第二个字符串。

有则分别按照 左上 左下 右下 右上 四个对角线方向遍历自身的字符串 ,直至符合或者不符合。

最后依次遍历整个字符串数组。

建hashmap O(M*M)时间

遍历字符串数组 O(sizeof(array) * strlen(string))

我觉得属于技巧题

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧