#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAXLENTH 1000000
typedef struct node *Node;
struct node {
char* KTitle;//整理后的话题
int Times;//提到次数,这个我之前想错了,以为把一句中提到的重复计算了,实际上他的次数是看句子的
int LastTimeWhoPost;//最近一次提及它的是哪条微博(用于去重)
};
void Scan(int);
int HashKey(char*);
int Mod(int);
void Insert(int,char*);
Node Hash[MAXLENTH];//散列存储
Node Titles[MAXLENTH]; // 建立双索引
int SumofTitles=0;//话题总数
int main() {
int n;
scanf("%d",&n);
getchar();
for(int i=0; i<n; i++) {
Scan(i);
}
Node MostTimes=Titles[0];
int NumofMost=0;
for(int i=1; i<SumofTitles; i++) {
if(Titles[i]->Times>MostTimes->Times) {
MostTimes=Titles[i];
NumofMost=0;
} else if(Titles[i]->Times==MostTimes->Times) {//找小的
if(strcmp(Titles[i]->KTitle,MostTimes->KTitle)<0) {
MostTimes=Titles[i];
}
++NumofMost;
}
}
//话题首字母应该大写
if(MostTimes->KTitle[0]>='a'&&MostTimes->KTitle[0]<='z')MostTimes->KTitle[0]+='A'-'a';
printf("%s\n%d",MostTimes->KTitle,MostTimes->Times);
if(NumofMost) {
printf("\nAnd %d more ...",NumofMost);
}
return 0;
}
void Scan(int NumofWeibo) {
char temp[141];//每行给出一条英文微博,其长度不超过140个字符
gets(temp);
int Flag_Jin=0;
char title[141];
int Flag_Space=1;
for(char*i=temp,*j=title; *i!='\0'; i++) {
//遇到第一个#
if(Flag_Jin==1) {
switch(*i) {
//第二次遇到了
case '#':
while(*(j-1)==' ')--j;
*j='\0';
if(strlen(title)>0)//两个连续的#是空话题,不予计数
Insert(NumofWeibo,title);
Flag_Jin=0;
j=title;//从头开始
break;
case 'a'...'z':
case '0'...'9':
*j++=*i;
Flag_Space=0;
break;
case 'A'...'Z':
*j++=*i-'A'+'a';
Flag_Space=0;
break;
//遇到空格
default:
//即使出现两个空格也变成一个 ,统一空格形式 ;也防止其他符号造成干扰
if(Flag_Space==0) {
*j++=' ';
Flag_Space=1;
}
break;
}
} else if(*i=='#') {
Flag_Jin=1;
Flag_Space=1;
}
}
}
int HashKey(char*K) {
int n=0;
while(*K) {
n+=*K-'a';
n<<=5;
K++;
}
return n;
}
int Mod(int n) {
while(n<0)n+=MAXLENTH;
return n%MAXLENTH;
}
void Insert(int NumofWeibo,char*t) {//比较后插入散列表并更新话题原型
int Key=HashKey(t);
int i=0,j=0;
for( ; i<=MAXLENTH/2; i++)
{
j=Mod(Key+i);
if(Hash[j])
{
if(strcmp(t,Hash[j]->KTitle)==0)
{
if(Hash[j]->LastTimeWhoPost==NumofWeibo)return;
++Hash[j]->Times;
Hash[j]->LastTimeWhoPost=NumofWeibo;
}
}
else break;
j=Mod(Key-i);
if(Hash[j])
{
if(strcmp(t,Hash[j]->KTitle)==0)
{
if(Hash[j]->LastTimeWhoPost==NumofWeibo)return;
++Hash[j]->Times;
Hash[j]->LastTimeWhoPost=NumofWeibo;
}
}
else break;
}
//超出范围退出
if(i>MAXLENTH/2)
{
exit(1);
}
Hash[j]=(Node)malloc(sizeof(struct node));
Hash[j]->KTitle=(char*)malloc(strlen(t));
strcpy(Hash[j]->KTitle,t);
Hash[j]->Times=1;
Hash[j]->LastTimeWhoPost=NumofWeibo;
Titles[SumofTitles++]=Hash[j];//把新加入的元素在哈希表中的地址保存进数组。方便遍历。
}
下面是第二种
#include <stdio.h>
#include <string.h>
#define Max 1000000
#define MaxLen 200
typedef struct {
char s[MaxLen];
int all;
int cnt;
int flag;
} Topic;
Topic f[Max];
int t=0;
int IsChar(char c) {
if((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z'))
return 1;
return 0;
}
void GetTopic(char s[],int tag) {
int i=0,flag=0,j=0,cnt=0,k;
char c[MaxLen];
while(s[i]!='\0') {
if(s[i]=='#'&&!flag) {
flag=1;
i++;
}
if(flag) {
if(IsChar(s[i])) {
if(!j) {
if(s[i]>='a'&&s[i]<='z')
s[i]=s[i]-'a'+'A';
} else {
if(s[i]>='A'&&s[i]<='Z')
s[i]=s[i]-'A'+'a';
}
c[j++]=s[i];
cnt=0;
} else {
if(s[i]!='#') {
s[i]=' ';
if(!cnt) {
if(s[i-1]!='#'&&s[i+1]!='#')
c[j++]=s[i];
cnt++;
}
} else {
flag=0;
c[j]='\0';
for(k=0; k<t; k++) {
if(!strcmp(f[k].s,c)) {
f[k].all++;
if(f[k].flag!=tag) {
f[k].cnt++;
f[k].flag=tag;
}
break;
}
}
if(k==t) {
strcpy(f[t].s,c);
f[t].all=1;
f[t].cnt=1;
f[t].flag=tag;
t++;
}
j=0;
}
}
}
i++;
}
}
char MIN[MaxLen];
int count;
int Find() {
int i,max=0,pos=0;
for(i=0; i<t; i++) {
if(f[i].cnt>max) {
max=f[i].all;
strcpy(MIN,f[i].s);
pos=i;
count=1;
}
else if(f[i].cnt==max) {
count++;
if(strcmp(f[i].s,MIN)<0) {
strcpy(MIN,f[i].s);
pos=i;
}
}
}
return pos;
}
int main() {
char s[MaxLen];
int n,i;
scanf("%d",&n);
getchar();
for(i=0; i<n; i++) {
gets(s);
GetTopic(s,i);
}
int pos=Find();
printf("%s\n",MIN);
printf("%d\n",f[pos].cnt);
if(count-1>0)
printf("And %d more ...",count-1);
return 0;
}