codeforces Gym 100338F Spam Filter 垃圾邮件过滤器(模拟,实现)

阅读题,

概要:给出垃圾邮件和非垃圾邮件的集合,然后按照题目给出的贝叶斯公式计算概率一封邮件是垃圾邮件的概率。

逐个单词判断,将公式化简一下就是在垃圾邮件中出现的次数和在总次数的比值,大于二分之一就算是垃圾邮件的单词。

如果一个邮件里的垃圾邮件的单词出现次数超过给定比例就算是垃圾邮件。

需要注意的地方是:一个邮件里单词只能统计一次,用set保证不重复。

因为sstream会很慢,容易T,所以手写了一个类似的sstream的函数

#include<bits/stdc++.h>
using namespace std;

typedef long double ld;
map<string,int> spam,good;
set<string> once;
int s,g,n,T;
const int maxn = 205;
char str[maxn],word[maxn];

int sscan_l(char *w,char *&s)
{
    while(isalpha(*s) == 0){
        if(!*s) return 0;
        s++;
    }
    int j = 0;
    for(int t; s[j] && (t = isalpha(s[j])) !=0; j++){
        w[j] = s[j];
        if(t == 1) w[j] += 'a'-'A';
    }
    w[j] = '\0'; s += j;
    return j;
}

bool judge()
{
    gets(str); char *p = str;
    int cnt = 0;
    once.clear();
    while(sscan_l(word,p)){
        string s0 = word;
        if(once.count(s0) == 0){
            once.insert(s0);
            int wS = spam[s0];
            int wTot = wS + good[s0];
            if(wTot && wS*2 >= wTot) cnt++;
        }
    }

    return cnt*100>=T*once.size();
}

int main()
{
    freopen("spam.in","r",stdin);
    freopen("spam.out","w",stdout);
    scanf("%d%d%d%d\n",&s,&g,&n,&T);
    for(int i = 0; i < s; i++){
        gets(str); char *p = str;
        once.clear();
        while(sscan_l(word,p)){
            string s0 = word;
            if(once.count(s0) == 0){
                once.insert(s0);
                spam[s0]++;
            }
        }
    }
    for(int i = 0; i < g; i++){
        gets(str); char *p = str;
        once.clear();
        while(sscan_l(word,p)){
            string s0 = word;
            if(once.count(s0) == 0){
                once.insert(s0);
                good[s0]++;
            }
        }
    }
    for(int i = 0; i < n; i++){
        if(judge()) puts("spam");
        else puts("good");
    }
    return 0;
}

 

posted @ 2015-08-21 19:06  陈瑞宇  阅读(370)  评论(0编辑  收藏  举报