Codeforces Gym 100338B Spam Filter 字符串哈希+贝叶斯公式
原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-andrew-stankevich-contest-22-asc-22-en.pdf
题意
这是一个过滤垃圾邮件的算法,叫贝叶斯算法。这个算法的第一步是训练过程,通过人工给定的邮件,来确定每个词语在垃圾邮件中的概率和在普通邮件的概率。然后通过贝叶斯公式来计算每个邮件是否为垃圾邮件。具体过程可以看题,或者维基百科。
题解
模拟题目的过程即可,不过要注意的是,为了避免超时,必须哈希,使用 最小表示来记录字符串。
代码
//#include<iostream>
#include<cstring>
#include<fstream>
#include<vector>
#include<map>
#include<algorithm>
#include<string>
#include<set>
#include<cmath>
#include<queue>
#define eps 1e-10
#define MAX_N 1234
#define Pr 131
#define mod 1000000009
using namespace std; typedef long long ll; int s,g,n,t;
string sp[MAX_N];
string go[MAX_N];
string ma[MAX_N]; set<ll> spam[MAX_N];
set<ll> good[MAX_N];
set<ll> mail[MAX_N]; set<ll> allWord; string bankLine; map<ll, double> wordIsSpam;
map<ll, double> wordIsGood; double pSpam;
double pGood; ll Hash(string ss) {
ll tmp = Pr;
ll res = ;
for (auto c:ss) {
res = (res + c * tmp) % mod;
tmp = (tmp * Pr) % mod;
}
return res;
} string changeToSmall(string ss) {
string res = "";
for (auto c:ss) {
if (c <= 'Z' && c >= 'A')c = c - 'A' + 'a';
res = res + c;
}
return res;
} bool isAl(char c) {
if (c <= 'Z' && c >= 'A')return true;
return (c <= 'z' && 'a' <= c);
} void divi(string v[],set<ll> G[],int x) {
for (int i = ; i < x; i++) {
int p = ;
while ((!isAl(v[i][p])) && p < v[i].length())p++;
bool flag = true;
for (int j = p; j < v[i].length(); j++) {
if ((!isAl(v[i][j])) && flag) {
flag = false;
string tmp;
tmp.assign(v[i].begin() + p, v[i].begin() + j);
tmp = changeToSmall(tmp);
allWord.insert(Hash(tmp));
G[i].insert(Hash(tmp));
}
else if (isAl(v[i][j]) && flag == false) {
p = j;
flag = true;
}
}
}
} double divide(double a,double b) {
if (fabs(b)<eps)return ;
return a / b;
} double P(ll word) {
double ws, wg; if (wordIsSpam.find(word) == wordIsSpam.end())ws = ;
else ws = wordIsSpam[word]; if (wordIsGood.find(word) == wordIsGood.end())wg = ;
else wg = wordIsGood[word]; return divide(ws * pSpam, ws * pSpam + wg * pGood);
} int main() {
ifstream cin("spam.in");
ofstream cout("spam.out");
cin.sync_with_stdio(false);
cin >> s >> g >> n >> t;
pSpam = divide(s, s + g);
pGood = divide(g, s + g);
getline(cin, bankLine);
for (int i = ; i < s; i++) {
getline(cin, sp[i]);
sp[i] = sp[i] + " ";
}
for (int i = ; i < g; i++) {
getline(cin, go[i]);
go[i] = go[i] + " ";
}
for (int i = ; i < n; i++) {
getline(cin, ma[i]);
ma[i] = ma[i] + " ";
}
divi(sp, spam, s);
divi(go, good, g);
divi(ma, mail, n); for (auto word:allWord) {
int cnt = ;
for (int i = ; i < s; i++)
if (spam[i].find(word) != spam[i].end())cnt++;
wordIsSpam[word] = divide(cnt, s);
cnt = ;
for (int i = ; i < g; i++)
if (good[i].find(word) != good[i].end())cnt++;
wordIsGood[word] = divide(cnt, g);
}
for (int i = ; i < n; i++) {
double ans = ;
for (auto word:mail[i]) {
double p = P(word);
//cout<<word<<": "<<p<<endl;
if (p > 0.5 || fabs(p - 0.5) < eps)ans++;
}
if (ans * / mail[i].size() < t)cout << "good" << endl;
else cout << "spam" << endl;
}
return ;
}
Codeforces Gym 100338B Spam Filter 字符串哈希+贝叶斯公式的更多相关文章
- codeforces Gym 100338F Spam Filter 垃圾邮件过滤器(模拟,实现)
阅读题, 概要:给出垃圾邮件和非垃圾邮件的集合,然后按照题目给出的贝叶斯公式计算概率一封邮件是垃圾邮件的概率. 逐个单词判断,将公式化简一下就是在垃圾邮件中出现的次数和在总次数的比值,大于二分之一就算 ...
- 【CodeForces】961 F. k-substrings 字符串哈希+二分
[题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} ...
- codeforces gym 100286 I iSharp (字符串模拟)
题目链接 给定一个字符串.输入是int& a*[]&, b, c*; 输出是 int&&[]* a;int& b;int&* c; 输入格式里逗号后面一 ...
- codeforces gym 101164 K Cutting 字符串hash
题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...
- Codeforces Gym 100338B Geometry Problem 计算几何
Problem B. Geometry ProblemTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudg ...
- Codeforces Round #543 (Div. 2) F dp + 二分 + 字符串哈希
https://codeforces.com/contest/1121/problem/F 题意 给你一个有n(<=5000)个字符的串,有两种压缩字符的方法: 1. 压缩单一字符,代价为a 2 ...
- CodeForces Gym 100213F Counterfeit Money
CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...
- HDU 1880 魔咒词典(字符串哈希)
题目链接 Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一 ...
- 洛谷P3370 【模板】字符串哈希
P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...
随机推荐
- Python学习笔记:PyInstaller(exe程序打包)
PyInstaller可以将Python程序打包成一个exe程序来独立运行,用户使用时只需要执行这个exe文件即可,不需要在机器上再安装Python及其他包就可运行了.另外,PyInstaller相较 ...
- nordic芯片开发——烧写方法记录
在开发nordic芯片的时候,分为存外设开发和结合softdevice开发,另外还有结合mbr的开发(这个暂时没有深究)在裸机开发的时候,sdk里面称为blank,把芯片的程序erase之后,直接下载 ...
- javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)
原博客地址:https://blog.csdn.net/weixin_37766296/article/details/80044000 将多个文件压缩并下载下来:(绿色为修改原博客的位置) 注意:需 ...
- BZOJ 5442: [Ceoi2018]Global warming
[l,r]+x不如[l,n]+x [l,r]-x不如(r,n)+x 所以等价于只有[l,n]+x 枚举断点树状数组合并 难度在于想到这个贪心 #include<cstdio> #inclu ...
- c++ dll 创建
建立一个C++的Win32DLL,这里要注意选择"Export symbols"导出符号.点击完成. 如下图所示: 由于项目的名称是"TestCPPDLL" ...
- Python 基础(一)
本章内容 1.编译和解释型语言的区别 2.Python的解释器 3.pyc文件 4.运行环境 5.变量 6.数据类型 7.字符编码 8.三元运算 编译和解释型语言的区别 编译器是把源程序的每一条语句都 ...
- loj2032 「SDOI2016」游戏
做了 [JSOI2008]Blue Mary开公司 以后发现这 tm 不就是个傻逼树剖+李超线段树吗,做了以后发现我才是傻逼--树剖竟然写错了--这题是我目前写过最长的代码了qwq #include ...
- python常用方法总结
1.os模块的路径拼接: import os now_path=os.path.abspath(__file__)#当前运行文件的路径 print(now_path) uppeer_path=os.p ...
- session的工作原理、django的超时时间设置及session过期判断
1.session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 session服务端中存在的数据为: session = { 随机字符串1:{ 用户1的相关信 ...
- PHP下mysql驱动概述
Overview of the MySQL PHP drivers 什么是API? 一 个应用程序接口(Application Programming Interface的缩写),定义了类,方法,函数 ...