0. 写在前面

本文记录了一个AC自动机的诞生!

之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的。。

感觉他们的代码过于冗长,而且AC率也不是很理想。

刚好在回宿舍的路上和学弟聊起这个事

随意想了想思路,觉得还是蛮简单的,就顺手写了一个,效果,还可以接受。

先上个图吧:

最后应该还可以继续刷,如果修改代码或者再添加以下其他搜索引擎可以AC更多题,

不过我有意控制在3000这个AC量,也有意跟在五虎上将之后。

1. 爬虫思路

思路其实非常清晰:

  1. 模拟登录HDU
  2. 针对某一道题目
    • 搜索AC代码

      • 通过正则表达式进行代码的提取
      • 通过htmlparser进行代码的处理
    • 提交
      • 若AC,返回2
      • 否则,继续提交代码(这里最多只提交10份代码)
      • 10次提交后还未AC,放弃此题

2. 简单粗暴的代码

#coding='utf-8'
import requests, re, os, HTMLParser, time, getpass host_url = 'http://acm.hdu.edu.cn'
post_url = 'http://acm.hdu.edu.cn/userloginex.php?action=login'
sub_url = 'http://acm.hdu.edu.cn/submit.php?action=submit'
csdn_url = 'http://so.csdn.net/so/search/s.do'
head = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36' }
html_parser = HTMLParser.HTMLParser()
s = requests.session() def login(usr,psw):
s.get(host_url);
data = {'username':usr,'userpass':psw,'login':'Sign In'}
r = s.post(post_url,data=data) def check_lan(lan):
if 'java' in lan:
return '5'
return '0' def parser_code(code):
return html_parser.unescape(code).encode('utf-8') def is_ac(pid,usr):
tmp = requests.get('http://acm.hdu.edu.cn/userstatus.php?user='+usr).text
accept = re.search('List of solved problems</font></h3>.*?<p align=left><script language=javascript>(.*?)</script><br></p>',tmp,re.S)
if pid in accept.group(1):
print '%s was solved' %pid
return True
else:
return False def search_csdn(PID,usr):
get_data = { 'q':'HDU ' + PID, 't':'blog', 'o':'', 's':'', 'l':'null' }
search_html = requests.get(csdn_url,params=get_data).text
linklist = re.findall('<dd class="search-link"><a href="(.*?)" target="_blank">',search_html,re.S)
for l in linklist:
print l
tm_html = requests.get(l,headers=head).text;
title = re.search('<title>(.*?)</title>',tm_html,re.S).group(1).lower()
if PID not in title:
continue
if 'hdu' not in title:
continue
tmp = re.search('name="code" class="(.*?)">(.*?)</pre>',tm_html,re.S)
if tmp == None:
print 'code not find'
continue
LAN = check_lan(tmp.group(1))
CODE = parser_code(tmp.group(2))
if r'include' in CODE:
pass
elif r'import java' in CODE:
pass
else:
continue
print PID, LAN
print '--------------'
submit_data = { 'check':'0', 'problemid':PID, 'language':LAN, 'usercode':CODE }
s.post(sub_url,headers=head,data=submit_data)
time.sleep(5)
if is_ac(PID,usr):
break if __name__ == '__main__':
usr = raw_input('input your username:')
psw = getpass.getpass('input your password:')
login(usr,psw)
pro_cnt = 1000
while pro_cnt <= 5679:
PID = str(pro_cnt)
if is_ac(PID,usr):
pro_cnt += 1
continue
search_csdn(PID,usr)
pro_cnt += 1

代码不长,仅仅只有78行,是的,就是这样!

3. TDDO

目前没有打算完善这篇博客,也不推荐去研究这个东西,推荐的是去学习真正的算法,哈哈!

很久很久以前自己写过的AC自动机,,,,贴一发:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define clr( a, b ) memset( a, b, sizeof(a) )
const int SIGMA_SIZE = 26;
const int NODE_SIZE = 500000 + 10; struct ac_automaton{
int ch[ NODE_SIZE ][ SIGMA_SIZE ];
int f[ NODE_SIZE ], val[ NODE_SIZE ], last[ NODE_SIZE ];
int sz;
void init(){
sz = 1;
clr( ch[0], 0 ), clr( val, 0 );
}
void insert( char *s ){
int u = 0, i = 0;
for( ; s[i]; ++i ){
int c = s[i] - 'a';
if( !ch[u][c] ){
clr( ch[sz], 0 );
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u]++;
}
void getfail(){
queue<int> q;
f[0] = 0;
for( int c = 0; c < SIGMA_SIZE; ++c ){
int u = ch[0][c];
if( u ) f[u] = 0, q.push(u), last[u] = 0;
}
while( !q.empty() ){
int r = q.front(); q.pop();
for( int c = 0; c < SIGMA_SIZE; ++c ){
int u = ch[r][c];
if( !u ){
ch[r][c] = ch[ f[r] ][c];
continue;
}
q.push( u );
int v = f[r];
while( v && !ch[v][c] ) v = f[v];
f[u] = ch[v][c];
last[u] = val[ f[u] ] ? f[u] : last[ f[u] ];
}
}
}
int work( char* s ){
int res = 0;
int u = 0, i = 0, e;
for( ; s[i]; ++i ){
int c = s[i] - 'a';
u = ch[u][c];
e = u;
while( val[e] ){
res += val[e];
val[e] = 0;
e = last[e];
}
}
return res;
}
}ac;

python爬虫学习(11) —— 也写个AC自动机的更多相关文章

  1. python爬虫学习 —— 总目录

    开篇 作为一个C党,接触python之后学习了爬虫. 和AC算法题的快感类似,从网络上爬取各种数据也很有意思. 准备写一系列文章,整理一下学习历程,也给后来者提供一点便利. 我是目录 听说你叫爬虫 - ...

  2. python爬虫学习(1) —— 从urllib说起

    0. 前言 如果你从来没有接触过爬虫,刚开始的时候可能会有些许吃力 因为我不会从头到尾把所有知识点都说一遍,很多文章主要是记录我自己写的一些爬虫 所以建议先学习一下cuiqingcai大神的 Pyth ...

  3. Python爬虫学习:二、爬虫的初步尝试

    我使用的编辑器是IDLE,版本为Python2.7.11,Windows平台. 本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:二.爬虫的初步尝试 1.尝试抓取指定网页 ...

  4. 《Python爬虫学习系列教程》学习笔记

    http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ...

  5. python爬虫学习笔记(一)——环境配置(windows系统)

    在进行python爬虫学习前,需要进行如下准备工作: python3+pip官方配置 1.Anaconda(推荐,包括python和相关库)   [推荐地址:清华镜像] https://mirrors ...

  6. [转]《Python爬虫学习系列教程》

    <Python爬虫学习系列教程>学习笔记 http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多. ...

  7. Python爬虫学习02--pyinstaller

    Python爬虫学习02--打包exe可执行程序 1.上一次做了一个爬虫爬取电子书的Python程序,然后发现可以通过pyinstaller进行打包成exe可执行程序.发现非常简单好用 2.这是上次写 ...

  8. Python爬虫学习第一记 (翻译小助手)

    1 # Python爬虫学习第一记 8.24 (代码有点小,请放大看吧) 2 3 #实现有道翻译,模块一: $fanyi.py 4 5 import urllib.request 6 import u ...

  9. Python爬虫学习:三、爬虫的基本操作流程

    本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:三.爬虫的基本操作与流程 一般我们使用Python爬虫都是希望实现一套完整的功能,如下: 1.爬虫目标数据.信息: 2.将 ...

随机推荐

  1. c 线程(平行世界)

    我们已经知道如何使用进程来做一些事情了,然而 它并不是在什么地方都是最适合的. 我们看看进程的缺点是什么: 线程隆重登场 1. 如何创建线程 创建线程可以使用多种线程库,在此我们使用最流行的一种:PO ...

  2. 读书笔记--SQL必知必会12--联结表

    12.1 联结 联结(join),利用SQL的SELECT在数据查询的执行中联结表. 12.1.1 关系表 关系数据库中,关系表的设计是把信息分解成多个表,一类数据一个表,各表通过某些共同的值互相关联 ...

  3. C#泛型方法解析

    C#2.0引入了泛型这个特性,由于泛型的引入,在一定程度上极大的增强了C#的生命力,可以完成C#1.0时需要编写复杂代码才可以完成的一些功能.但是作为开发者,对于泛型可谓是又爱又恨,爱的是其强大的功能 ...

  4. nodejs中使用http请求返回值为html时乱码问题

    今天用nodejs进行http请求时返回的数据是一个html文件,然后我还是按照以前解析json数据的方法.果不其然报错了:SyntaxError: Unexpected token  in JSON ...

  5. ASP.NET Core 中文文档 第三章 原理(1)应用程序启动

    原文:Application Startup 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程 ...

  6. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  7. ASP.NET MVC View 和 Web API 的基本权限验证

    ASP.NET MVC 5.0已经发布一段时间了,适应了一段时间,准备把原来的MVC项目重构了一遍,先把基本权限验证这块记录一下. 环境:Windows 7 Professional SP1 + Mi ...

  8. APNS 远程推送通知 PUSH deviceToken

    服务器向客户端推送消息:      当应用程序推到后台,或者根本就没有运行(我们的代码无能为力)      如果这种情况之下,应用程序想和用户交互(传统的做法 不可能)      推送 APNS:Ap ...

  9. 我是如何进行Spring MVC文档翻译项目的环境搭建、项目管理及自动化构建工作的

    感兴趣的同学可以关注这个翻译项目 . 我的博客原文 和 我的Github 前段时间翻译的Spring MVC官方文档完成了第一稿,相关的文章和仓库可以点击以下链接.这篇文章,主要是总结一下这个翻译项目 ...

  10. cin.ignore()函数的用法

    cin.ignore(a,ch)方法是从输入流(cin)中提取字符,提取的字符被忽略(ignore),不被使用.每抛弃一个字符,它都要计数和比较字符:如果计数值达到a或者被抛弃的字符是ch,则cin. ...