一道腾讯笔试的压轴题

SmallBoat2000 2010-03-26 10:18:10
有一个江洋大盗,他每次写信都是从一张报纸上剪下单词,再把单词贴在信上。假如某张报纸的单词保存在vector<string>paper 中,而信的单词保存在vector<string>letter 中,写一个算法程序判别该报纸可不可以生成该信?
...全文
1829 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
fanster28_ 2010-05-12
  • 打赏
  • 举报
回复
上面的release 忘了调了,恩
fanster28_ 2010-05-12
  • 打赏
  • 举报
回复
我来一个trie树的,其实实现非常简单,这里约定单词都是由26个小写之母构成(其他的自己改)
对于单词来说一般不会很长,所以空间开销可以接受。
下面的代码考虑了单词个数的问题,上代码吧


#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct node
{
node *next[26]; //这里假设单词都是26小写字母组成
int cnt;
node () : cnt(0)
{
memset(next,0,sizeof(next));
}
};
node *root;
vector<node*> de; //记录待delete的指针

void insert_str(const char *str)
{
node *p=root;
int i=0,j;
while (str[i])
{
j=str[i]-'a';
if (p->next[j]==0)
{
p->next[j]=new node;
de.push_back(p->next[j]);
}
p=p->next[j];
i++;
}
p->cnt++; //记录单词出现的次数
}

int find(const char *str)
{
node *p=root;
int i=0,j;
while (str[i])
{
j=str[i]-'a';
if (p->next[j]==0)
return 0;
p=p->next[j];
i++;
}
if (p->cnt==0)
return 0;
else
p->cnt--;
return 1;
}

void release()
{
size_t i;
for (i=0;i<de.size();++i)
delete de[i];
}

int main()
{
vector<string> paper(3);
paper[0]="abc";
paper[1]="cde";
paper[2]="def";
vector<string> letter(1);
letter[0]="cde";

size_t i;
//这里可以做一些预处理
//下面针对查找的情况
root=new node;
de.push_back(root);
for (i=0;i<paper.size();++i)
insert_str(paper[i].c_str());
for (i=0;i<letter.size();++i)
if (find(letter[i].c_str())==0)
{
printf("failed!\n");
break;
}
if (i==letter.size())
printf("succeed!\n");
}
luo6620378xu 2010-05-01
  • 打赏
  • 举报
回复
跟这个有点像不?
http://acm.hdu.edu.cn/showproblem.php?pid=3198
Java2King 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 java2king 的回复:]

归纳比较或者用hash
[/Quote]
是归并~
Java2King 2010-05-01
  • 打赏
  • 举报
回复
归纳比较或者用hash
lz3771 2010-05-01
  • 打赏
  • 举报
回复
学习中
lirg8405 2010-05-01
  • 打赏
  • 举报
回复
我是来学习的
zsxcn 2010-04-30
  • 打赏
  • 举报
回复
mark
japt88_115656292 2010-04-29
  • 打赏
  • 举报
回复
kmp算法
psysj 2010-04-29
  • 打赏
  • 举报
回复
效率问题
Carmack Jiang 2010-04-28
  • 打赏
  • 举报
回复

#include <string>
#include <iostream>
#include <vector>
#include <set>
using namespace std;

bool IsLetterInPaper(vector<string> paper,vector<string> letter)
{
set<string> set_string;
for(vector<string>::iterator vc_it = paper.begin();vc_it != paper.end();vc_it ++)
{
set_string.insert(*vc_it);
}
for(vector<string>::iterator lt_it = letter.begin();lt_it != letter.end();lt_it ++)
{
if(set_string.insert(*lt_it).second)
return false;
}
return true;
}
int main(int argc, char* argv[])
{
string p[4] = {"I","love","swimming","hate"};
string l[3] = {"I","love","swimming"};
vector<string> paper(p,p + 4);
vector<string> letter(l,l+3);
if(IsLetterInPaper(paper,letter))
cout << "in paper";
else
cout <<"not in paper";
cout <<endl;
while(1);
return 0;
}
sxdxiaodong000 2010-04-28
  • 打赏
  • 举报
回复
此题要求是剪下
不是copy
likee003 2010-04-28
  • 打赏
  • 举报
回复
用图论算法来查找效率比较高。
public static boolean Check(Vector v1, Vector v2)
for(String str : v2)
{
if(!v1.contains(str))
return false;
}
return true;
}
pmars 2010-04-24
  • 打赏
  • 举报
回复

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>

using namespace std ;

vector<string> paper ; //已经初始化好了的
vector<string> letter ; //同上
map<string,int> result ;

int main()
{
bool flag = true ;
vector<string>::iterator p = paper.begin() , l = letter.begin() ;
while (p!=paper.end()) ++result[*p++] ;
while (l!=paper.end())
{
if (result[*l++]<1) { flag = false ; break ; } //就是说paper里没有这个词
}
if (flag) cout<<"可以"<<endl ;
else cout<<"不可以"<<endl ;
return 0 ;
}
pmars 2010-04-24
  • 打赏
  • 举报
回复
两个数组先排序一下,之后,归并匹配一下就行了吧


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

using namespace std ;

vector<string> paper ; //已经初始化好了的
vector<string> letter ; //同上

int main()
{
sort(paper.begin(),paper.end()) ;
sort(letter.begin(),letter.end()) ;
vector<string>::iterator p = paper.begin() , l = letter.begin() ;
bool flag = true ; //标志位
while (l!=letter.end())
{
if (*p<*l) ++p ; //不匹配paper指针++
if (*p==*l) { ++p ; ++ l ; } //匹配,两个指针都加
if (*p>*l) { flag = false ; break ; } //没有找到与*l匹配的字符,所以不能实现所需
}
if (flag) cout<<"可以"<<endl ;
else cout<<"不可以"<<endl ;
return 0 ;
}
SmallBoat2000 2010-04-24
  • 打赏
  • 举报
回复
可以贴个完整代码吗?
_千鸟 2010-04-02
  • 打赏
  • 举报
回复
我把报纸上的单词按字母剪开后,就成了一堆字母了,要组成什么样的信都可以啊!
把vector<string>paper中的所有字符映射到map<char,int>A
把vector<string>letter中的所有字符映射到map<char,int>B

A,B中也就A-Za-z的字符,伪代码如下:

foreach(char x:A-Za-z)
{
if(B[x]>A[x])
return false;
}
retuen true;

我一个个字母的剪,这样思考问题么?
WizardOz 2010-04-01
  • 打赏
  • 举报
回复
先对信中各个单词做哈希,在哈希表相应位置 +1,总数+1.

对报纸各个单词做哈希,如果哈希表相应位置不等于0,则 -1, 总数-1,等于0则continue。

最后看总数是不是等于0,等于0则可生成,否则不能。
WizardOz 2010-04-01
  • 打赏
  • 举报
回复
哈希 + 信号量
ac1985482 2010-04-01
  • 打赏
  • 举报
回复
先把报纸做成一个树或者是Hash表 然后对信做一个遍历
Hash表的效率应该要高一点
加载更多回复(41)

33,009

社区成员

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

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