【发布时间】:2014-09-24 07:11:05
【问题描述】:
我试图解决这个问题:
这个想法很简单,你的程序会不断地从流中读取新单词,但由于存储空间有限,你的程序只能记住最近的 K 个单词。因此,当第 (K+1) 个单词到达时,您的程序会忘记第 1 个单词,当第 (k+2) 个单词到达时,您的程序会忘记第 2 个单词,依此类推。
我们希望您在每次出现新词时,在最新的K 词中找到最常用的词。我尝试使用映射(作为哈希表)双端队列(以维护输入流)来解决问题。下面是我尝试过的代码,但在某些情况下它没有给出预期的结果。
#include <bits/stdc++.h>
#include <string>
using namespace std;
#define ps pair<string,int>
map<string,int>dir;
int lookup( string name)
{
map<string,int>::iterator it;
dir[name]+=1;
it=dir.find(name);
return it->second;
}
void update(string name)
{
map<string,int>::iterator it;
it=dir.find(name);
if(it!=dir.end()&& it->second>=1)
dir[name]-=1;
else dir[name]=0;
}
string small(string s1,string s2)
{
int l=min(s1.size(),s2.size());
if(s1==s2)return s1;
else
{
for(int i=0;i<l;i++)if(s1[i]>s2[i])return s2;
return s1;
}
}
int main()
{
ios_base::sync_with_stdio(false);
int n,k;
int tc,cs=0;
cin >> tc;
while(tc--){cout<<"Case "<<++cs<<":"<<endl;
cin >> n >> k;
string words;
deque<ps>Q;
deque<ps>::iterator it;
Q.clear();
dir.clear();
int max =-1;
string mf;
while(n--)
{
cin>> words;
if(Q.size()<k)
{
int c = lookup(words);
Q.push_back(ps(words,c));
it=Q.end()-1;
if(it->second > max)
{
max = it->second;
mf = it->first;
}
else if(max==it->second)
{
max = it->second;
mf = small(mf,it->first);
}
cout <<mf<<" "<<max<<endl;
}
else
{
map<string,int>::iterator itm;
if(Q.size() >= k)
{
it=Q.begin();
update(it->first);
itm=dir.find(it->first);
if(itm->second>0)
max-=1;
Q.pop_front();
int c = lookup(words);
Q.push_back(ps(words,c));
it=Q.end()-1;
itm=dir.find(mf);
if(it->second > itm->second)
{
max = it->second;
mf = it->first;
}
else if(it->second == itm->second)
{
max = it->second;
mf = small(itm->first,it->first);
}
cout <<mf<<" "<<max<<endl;
}
}
}
}
return 0;
}
和测试用例:
Sample test cases:
1
8 3
hello
hi
who
hi
hi
hello
who
when
correct output
Case 1:
hello 1
hello 1
hello 1
hi 2
hi 2
hi 2
hello 1
hello 1
Mine code output
Case 1:
hello 1
hello 1
hello 1
hi 2
hi 2
hi 2
who 1
when 1
【问题讨论】:
-
基本思想:维护一个单词图来计数。还要维护一个 k 大小的单词数组。当输入一个新单词时,检查数组的大小。如果数组已满,则删除最旧的单词,将元素下移,添加新元素;减少地图中(现在已删除的)最旧单词的计数,增加地图中新单词的计数。打印地图中值最大的单词。继续
-
@inspectorG4dget 我尝试了同样的想法,我使用地图来存储单词及其频率,当新单词出现时。我正在使用 deque 来存储单词,当它达到限制 k 时,我将删除旧单词并通过降低它的频率再次维护地图。我正在做同样的事情,但得到错误的答案。这里是问题链接[link]spoj.com/problems/WORDCNT2
-
您不需要双端队列 - 具有最大大小的队列就足够了。我无法提供实现细节,因为我没有 C++ 所需的专业知识
-
“它有时不符合我的要求”。 “当输入是 XYZ 时,输出是 ABC,而我期望 IJK”。哪种措辞可能会吸引更多答案?你决定。
-
#include <bits/stdc++.h>不是标准的,可能会阻止使用其他实现的潜在贡献者。首选可移植代码。
标签: c++ data-structures stl