我试图解决这个问题:
这个想法非常简单,你的程序会继续从一个流中读取新单词不断被输入你的程序,但由于存储空间有限,你的程序只能记住最新的K字。因此,当第(K + 1)个单词到达时,你的程序会忘记第一个单词,当第(k + 2)个单词到达时,你的程序会忘记第二个单词,依此类推。
我们希望您在每次新单词到达时找到最新的K
字词。我尝试使用map(作为哈希表)deque解决问题(以维护输入流)。下面是我尝试过的代码,但在某些情况下,它没有给出所需的结果。
#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
答案 0 :(得分:0)
以下可能会有所帮助:
class Counter
{
public:
Counter(std::size_t size) : max_size(size) {}
void AddWord(const std::string& word)
{
if (words.size() == max_size) {
auto it = counts.find(words.front());
--it->second;
if (it->second == 0) {
counts.erase(it);
}
words.pop();
}
words.push(word);
++counts[word];
}
const std::pair<const std::string, std::size_t>& getMax() const
{
return *std::max_element(counts.begin(), counts.end(),
[](const std::pair<const std::string, std::size_t>& lhs, const std::pair<const std::string, std::size_t>& rhs)
{
return std::tie(lhs.second, rhs.first) < std::tie(rhs.second, lhs.first);
});
}
private:
std::size_t max_size;
std::queue<std::string> words;
std::map<std::string, std::size_t> counts;
};
答案 1 :(得分:0)
我已经修改了Jarod42的解决方案,以便与g ++ 4.3.2一起使用,但方法是 max_element函数太慢了。需要更快的算法。
#include <algorithm>
#include <iostream>
#include <string>
#include <cstdio>
#include <map>
#include <queue>
using namespace std;
int max_size;
string words[100000];
map<string, size_t> counts;
int ifrontword,ilastword;
bool mycmp( pair<const string, size_t>& lhs, pair<const string, size_t>& rhs){
if (lhs.second==rhs.second) return rhs.first<lhs.first;
else return lhs.second<rhs.second;
}
map<string, size_t>::iterator it;
void AddWord(string& word){
if (ilastword-ifrontword == max_size) {
counts[words[ifrontword]]--;
if (counts[words[ifrontword]]==0)
counts.erase(words[ifrontword]);
ifrontword++;
}
words[ilastword++]=word;
counts[word]++;
}
pair<const string, size_t>& getMax() {
return *max_element(counts.begin(), counts.end(), mycmp);
}
int main(){
ios_base::sync_with_stdio(false);
int n,k;
int tc,cs=0;
string word;
scanf("%d",&tc);
while(tc--){
cout<<"Case "<<++cs<<":"<<endl;
scanf("%d%d",&n,&k);
max_size=k;
counts.clear();
ilastword=ifrontword=0;
while(n--){
cin>> word;
AddWord(word);
pair<const string, size_t> &p = getMax();
cout << p.first << " " << p.second << endl;
}
}
return 0;
}