新浪微博热门话题 (30 分)

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值