求搜索相邻单词的算法
问题描述:
定义结构体struct WORD
{
string word; //单词
int [100]; //在文章中的位置,每个单词长度不等
int wordFreq; //单词在文章中出现的次数
};
例如:
我;(0,11,20,90,120);5
爱;(1,21,121,200,300);5
你;(2;22;80,301);4
目标:
找出所有相邻的词组,如:我爱你(0,1,2;20,21,22);我爱(0,1;20,21;120,121);爱你(1,2;21,22;300,301)。
请求您帮忙给出一个算法。如能提供较详细的C++代码,本人感激不尽!
万分感谢!
定义结构体struct WORD
{
string word; //单词
int [100]; //在文章中的位置,每个单词长度不等
int wordFreq; //单词在文章中出现的次数
};
例如:
我;(0,11,20,90,120);5
爱;(1,21,121,200,300);5
你;(2;22;80,301);4
目标:
找出所有相邻的词组,如:我爱你(0,1,2;20,21,22);我爱(0,1;20,21;120,121);爱你(1,2;21,22;300,301)。
请求您帮忙给出一个算法。如能提供较详细的C++代码,本人感激不尽!
万分感谢!
作者: superyangtze 发布时间: 2011-06-11
/*
前提假设所有的页码已经是递增序列,如果没有此限定,自己排序即可
输入
3 //代表3个单词
我
5 //代表5个pos
0 11 20 90 120
爱
5
1 21 121 200 300
你
4
2 22 80 30
主要思路按照索引依次填入相应位置,相邻的话紧挨着,不相邻中间插入隔断符号以节省空间
完成后顺序扫描即可
*/
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include<map>
#include<utility>
using namespace std;
typedef struct WORD{
string word;
int pos[100];
int wordFreq;
}WORD;
class Essay{
public:
Essay(int n,WORD* w):wordNum(n),words(w){
essay.empty();
index.empty();
ans.empty();
}
void printAdjacencyWords(){
essay.empty();
index.empty();
ans.empty();
int* pos=new int[wordNum];
memset(pos,0,4*wordNum);
bool find=true;
int prepos;
int count=1;
while(find){
find=false;
int p=0x7fffffff;
int min;
for(int i=0;i<wordNum;++i)
if(pos[i]<words[i].wordFreq&&p>words[i].pos[pos[i]]){
find=true;
p=words[i].pos[pos[i]];
min=i;
}
if(find){
if(count==1){
prepos=p;
index.push_back(p);
essay.push_back(min);
}
else{
if(p==prepos+1){
index.push_back(p);
essay.push_back(min);
}
else{
index.push_back(-1);
index.push_back(p);
essay.push_back(-1);
essay.push_back(min);
}
prepos=p;
}
++count;
pos[min]=pos[min]+1;
}
}
/*
{
for(int i=0;i<essay.size();++i)
if(essay[i]!=-1)
cout<<words[essay[i]].word;
else cout<<" ";
cout<<endl;
}*/
int l=essay.size();
int bpos=0,epos=0;
for(int i=0;i<l;++i){
if(essay[i]==-1){
if((epos-bpos)>=1)
cal(bpos,epos);
bpos=i+1,epos=i+1;
continue;
}
else{
epos=i;
}
}
if(epos-bpos>=1)
cal(bpos,epos);
string t="";
count=1;
for(multimap<string,string>::iterator p=ans.begin();p!=ans.end();++p){
if(t!=p->first){
if(count!=1)
cout<<")"<<endl;
++count;
t=p->first;
cout<<t<<"("<<p->second;
}
else{
cout<<";"<<p->second;
}
}
cout<<")"<<endl;
}
private:
void cal(int bpos,int epos){
for(int from=bpos;from<epos;++from){
string w=words[essay[from]].word;
string pos=numToString(index[from]);
for(int end=from+1;end<=epos;++end){
w+=words[essay[end]].word;
pos+=",";
pos+=numToString(index[end]);
ans.insert(make_pair(w,pos));
}
}
}
string numToString(int n){
string s="";
do{
char t=n%10+'0';
s=t+s;
n/=10;
}while(n);
return s;
}
int wordNum;
WORD* words;
vector<int> essay;
vector<int> index;
multimap<string,string> ans;
};
int main(){
int wordsNum;
cin>>wordsNum;
WORD *words=new WORD[wordsNum];
for(int i=0;i<wordsNum;++i){
cin>>words[i].word;
cin>>words[i].wordFreq;
for(int j=0;j<words[i].wordFreq;++j)
cin>>words[i].pos[j];
}
Essay essay(wordsNum,words);
essay.printAdjacencyWords();
return 0;
}
结贴给分吧
前提假设所有的页码已经是递增序列,如果没有此限定,自己排序即可
输入
3 //代表3个单词
我
5 //代表5个pos
0 11 20 90 120
爱
5
1 21 121 200 300
你
4
2 22 80 30
主要思路按照索引依次填入相应位置,相邻的话紧挨着,不相邻中间插入隔断符号以节省空间
完成后顺序扫描即可
*/
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include<map>
#include<utility>
using namespace std;
typedef struct WORD{
string word;
int pos[100];
int wordFreq;
}WORD;
class Essay{
public:
Essay(int n,WORD* w):wordNum(n),words(w){
essay.empty();
index.empty();
ans.empty();
}
void printAdjacencyWords(){
essay.empty();
index.empty();
ans.empty();
int* pos=new int[wordNum];
memset(pos,0,4*wordNum);
bool find=true;
int prepos;
int count=1;
while(find){
find=false;
int p=0x7fffffff;
int min;
for(int i=0;i<wordNum;++i)
if(pos[i]<words[i].wordFreq&&p>words[i].pos[pos[i]]){
find=true;
p=words[i].pos[pos[i]];
min=i;
}
if(find){
if(count==1){
prepos=p;
index.push_back(p);
essay.push_back(min);
}
else{
if(p==prepos+1){
index.push_back(p);
essay.push_back(min);
}
else{
index.push_back(-1);
index.push_back(p);
essay.push_back(-1);
essay.push_back(min);
}
prepos=p;
}
++count;
pos[min]=pos[min]+1;
}
}
/*
{
for(int i=0;i<essay.size();++i)
if(essay[i]!=-1)
cout<<words[essay[i]].word;
else cout<<" ";
cout<<endl;
}*/
int l=essay.size();
int bpos=0,epos=0;
for(int i=0;i<l;++i){
if(essay[i]==-1){
if((epos-bpos)>=1)
cal(bpos,epos);
bpos=i+1,epos=i+1;
continue;
}
else{
epos=i;
}
}
if(epos-bpos>=1)
cal(bpos,epos);
string t="";
count=1;
for(multimap<string,string>::iterator p=ans.begin();p!=ans.end();++p){
if(t!=p->first){
if(count!=1)
cout<<")"<<endl;
++count;
t=p->first;
cout<<t<<"("<<p->second;
}
else{
cout<<";"<<p->second;
}
}
cout<<")"<<endl;
}
private:
void cal(int bpos,int epos){
for(int from=bpos;from<epos;++from){
string w=words[essay[from]].word;
string pos=numToString(index[from]);
for(int end=from+1;end<=epos;++end){
w+=words[essay[end]].word;
pos+=",";
pos+=numToString(index[end]);
ans.insert(make_pair(w,pos));
}
}
}
string numToString(int n){
string s="";
do{
char t=n%10+'0';
s=t+s;
n/=10;
}while(n);
return s;
}
int wordNum;
WORD* words;
vector<int> essay;
vector<int> index;
multimap<string,string> ans;
};
int main(){
int wordsNum;
cin>>wordsNum;
WORD *words=new WORD[wordsNum];
for(int i=0;i<wordsNum;++i){
cin>>words[i].word;
cin>>words[i].wordFreq;
for(int j=0;j<words[i].wordFreq;++j)
cin>>words[i].pos[j];
}
Essay essay(wordsNum,words);
essay.printAdjacencyWords();
return 0;
}
结贴给分吧
作者: wocaoqwer 发布时间: 2011-06-11
C/C++ code
结贴给分吧
/* 前提假设所有的页码已经是递增序列,如果没有此限定,自己排序即可 输入 3 //代表3个单词 我 5 //代表5个pos 0 11 20 90 120 爱 5 1 21 121 200 300 你 4 2 22 80 30 主要思路按照索引依次填入相应位置,相邻的话紧挨着,不相邻中间插入隔断符号以节省空间 完成后顺序扫描即可 */ #include<iostream> #include<string> #include<cstdlib> #include<vector> #include<map> #include<utility> using namespace std; typedef struct WORD{ string word; int pos[100]; int wordFreq; }WORD; class Essay{ public: Essay(int n,WORD* w):wordNum(n),words(w){ essay.empty(); index.empty(); ans.empty(); } void printAdjacencyWords(){ essay.empty(); index.empty(); ans.empty(); int* pos=new int[wordNum]; memset(pos,0,4*wordNum); bool find=true; int prepos; int count=1; while(find){ find=false; int p=0x7fffffff; int min; for(int i=0;i<wordNum;++i) if(pos[i]<words[i].wordFreq&&p>words[i].pos[pos[i]]){ find=true; p=words[i].pos[pos[i]]; min=i; } if(find){ if(count==1){ prepos=p; index.push_back(p); essay.push_back(min); } else{ if(p==prepos+1){ index.push_back(p); essay.push_back(min); } else{ index.push_back(-1); index.push_back(p); essay.push_back(-1); essay.push_back(min); } prepos=p; } ++count; pos[min]=pos[min]+1; } } /* { for(int i=0;i<essay.size();++i) if(essay[i]!=-1) cout<<words[essay[i]].word; else cout<<" "; cout<<endl; }*/ int l=essay.size(); int bpos=0,epos=0; for(int i=0;i<l;++i){ if(essay[i]==-1){ if((epos-bpos)>=1) cal(bpos,epos); bpos=i+1,epos=i+1; continue; } else{ epos=i; } } if(epos-bpos>=1) cal(bpos,epos); string t=""; count=1; for(multimap<string,string>::iterator p=ans.begin();p!=ans.end();++p){ if(t!=p->first){ if(count!=1) cout<<")"<<endl; ++count; t=p->first; cout<<t<<"("<<p->second; } else{ cout<<";"<<p->second; } } cout<<")"<<endl; } private: void cal(int bpos,int epos){ for(int from=bpos;from<epos;++from){ string w=words[essay[from]].word; string pos=numToString(index[from]); for(int end=from+1;end<=epos;++end){ w+=words[essay[end]].word; pos+=","; pos+=numToString(index[end]); ans.insert(make_pair(w,pos)); } } } string numToString(int n){ string s=""; do{ char t=n%10+'0'; s=t+s; n/=10; }while(n); return s; } int wordNum; WORD* words; vector<int> essay; vector<int> index; multimap<string,string> ans; }; int main(){ int wordsNum; cin>>wordsNum; WORD *words=new WORD[wordsNum]; for(int i=0;i<wordsNum;++i){ cin>>words[i].word; cin>>words[i].wordFreq; for(int j=0;j<words[i].wordFreq;++j) cin>>words[i].pos[j]; } Essay essay(wordsNum,words); essay.printAdjacencyWords(); return 0; }
结贴给分吧
作者: wocaoqwer 发布时间: 2011-06-11