#include<stdio.h> #include<stdlib.h> int maze[5][5]; int mark[5][5]={0}; typedef struct{ int x; int y; }offset; offset direct[8] = {-1,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1, 0,1, -1,1}; //8个方向 typedef struct{ int x; int y; int direct; }element; element stack[26]; void add(int *top,element position); element delete(int *top); int main() { int entry_x, entry_y; int exit_x, exit_y; printf("请输入入口:"); scanf(" %d%d",&entry_x 继续阅读 >>


陈文浩 18/01/15 22:15:32
/* * 用prim算法弄最小生成树,每次一个点都会遍历所有点,找出,两点距离最短的情况 * 再改变节点的入度和最小值 */ #include<stdio.h> #include<stdlib.h> #include<string.h> #define INFINITY 1000 struct{ int adjvex; int lowcost; }closedge[31]; typedef struct { int vexnum; int arcs[11][11]; }AdjMatrix; AdjMatrix *G; void prim(AdjMatrix *G,int start); int main() { printf("请输入矩阵:"); G = (AdjMatrix *)malloc(sizeof(AdjMatrix)); for(int i=1;i<=10;i++) for(int j=1;j<=10;j++) s 继续阅读 >>


陈文浩 18/01/15 15:14:37
kruskal算法的一点就是不能形成环路,而且是从排列好的边集合依次选出最小的边,每次选出的顶点都要放在同一个边集合中,之后在顶点集合选两个顶点的边,要求这两个顶点不能在边集合中,这样才能保障不形成环路。 一、链表表示 #include<stdio.h> #include<stdlib.h> /* kruskal,最小生成树,利用链表,并查集的知识 */ typedef struct{ int bef; int aft; int weight; }pic_node;//图中点的结构体 typedef struct find_set{ int data; struct find_set *next; }NODE;//点集合的节点 typedef struct set_head{ NODE *head; NODE *tail; int flag; }HEAD;//点集合的头 HEAD set[20];//点集合 pic_node arr[20];//开始时候数据 int edge 继续阅读 >>


陈文浩 18/01/15 15:08:38
java有可以获得数组大小的函数,但是c++没有,在写函数的时候发现了一些问题,就是传数组名的时候,会在函数中将数组退化成指针,得不到想要的结果,使用引用之后就不会有这样的问题 #include<iostream> #include<typeinfo> #include<vector> using namespace std; // 使用 int[] template <typename T> inline int get_array_len(T &p) { return sizeof(T) / sizeof(*p); } void insertsort(int arr[], int n) { int j = 0; for(int i = 2; i < n; i++) { if(arr[i] < arr[i-1]) { arr[0] = arr[i]; for(j = i-1; arr[0] < 继续阅读 >>


陈文浩 18/01/14 20:33:26
Acceptor 用于 accept 一个 TCP 连接,accept 接受成功后通知 TCP 连接的使用者。Acceptor 主要是供 TcpServer 使用的,其生命期由后者控制。一个 Acceptor 相当于持有服务端的一个 socket 描述符,该 socket 可以 accept 多个 TCP 客户连接,这个 accept 操作就是 Acceptor 实现的。 这里用到了一些封装好的 socket 和地址结构,如 class InetAddress 表示 sockaddr_in 的封装,如可以通过ip地址和port端口生成一个sockaddr_in; class Socket封装了部分关于socket套接字的操作,如Socket::bindAddress(InetAddress&) 将socket和一个sockaddr_in地址绑定,Socket::accept(InetAddress& peerAddr)将一个socket允许连接一个客户端地址peerAddr,Socket::listen()监听socket,Socket::shutdownWrite 继续阅读 >>


杜肖孟 18/01/12 22:43:03
手动管理的弊端 在简单的程序中,我们不大可能忘记释放 new 出来的指针,但是随着程序规模的增大,我们忘了 delete 的概率也随之增大。在 C++ 中 new 出来的指针,赋值意味着引用的传递,当赋值运算符同时展现出“值拷贝”和“引用传递”两种截然不同的语义时,就很容易导致“内存泄漏”。 手动管理内存带来的更严重的问题是,内存究竟要由谁来分配和释放呢?指针的赋值将同一对象的引用散播到程序各处,但是该对象的释放却只能发生一次。当在代码中用完了一个资源指针,该不该释放 delete 掉它?这个资源极有可能同时被多个对象拥有着,而这些对象中的任何一个都有可能在之后使用该资源,其余指向这个对象的指针就变成了“野指针”;那如果不 delete 呢?也许你就是这个资源指针的唯一使用者,如果你用完不 delete,内存就泄漏了。 资源的拥有者是系统,当我们需要时便向系统申请资源,当我们不需要时就让系统自己收回去(Garbage Collection)。当我们自己处理的时候,就容易出现各种各样的问题。 C++ 中的智能指针 为了让用户免去手动 delete 资源的烦恼,不少类库采用了 继续阅读 >>


杜肖孟 18/01/11 23:39:30
使用公历类GregorianCalendar 使用公历类 GregorianCalendar,公历类 GregorianCalendar有方法setTimeInMillis(long);可以用它来设置从1970年1月1日算起的一个特定时间。请编程从键盘输入一个长整型的值,然后输出对应的年、月和日。例如输入:1234567898765,输出:2009-1-14 输入格式: 输入 1234567898765 (毫秒数) 输出格式: 输出 2009-1-14 (输出年、月和日,实际应该是2月,因为Java API 从0开始计算月份) 输入样例: 1450921070108 输出样例: 2015-11-24 import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Scanner; public class Main { public static void main(String[] args) { GregorianCalendar date 继续阅读 >>


陈文浩 18/01/10 17:15:07
主要涉及到的类和实现文件有: Endian.h 提供了字节序转换的函数。 Socket.h/Socket.cc socketfd 的封装,提供了绑定地址、开始listen、接受连接等操作,并可设置套接字选项。 InetAddress.h/InetAddress.cc 套接字地址的封装,提供了多种方式初始化一个地址,还提供方法从地址中拿到 ip 和 port。 SocketsOps.h/SocketsOps.cc 封装了 socket 相关的一些操作,提供给 Socket 和 InetAddress 用。 这部分就是基本的 TCP 套接字编程和套接字选项的知识,代码逻辑也很简单,推荐看下 UNP卷一 的相关章节。 下面逐一看下这几个相关的文件。 字节序转换部分(Endian.h) #ifndef MUDUO_NET_ENDIAN_H #define MUDUO_NET_ENDIAN_H #include <stdint.h> #include <endian.h> namespace muduo { namespace net { na 继续阅读 >>


杜肖孟 18/01/09 15:14:11
  首先我们先来看一下淘宝搜索商品的页面,这里以糖炒板栗为例:   可以看到搜索到了很多糖炒板栗,显示有100页,但真正搜索到的商品超过了100页,给用户只显示前100页,后面编写的爬虫只爬取前50页,url构造这里就不讲了,之前的博客已经讲过了,需要更多可以自己更改页数,然后我们检查网页元素,找到商品链接并复制,然后在网页源代码里查找,结果如下:   发现并没有找到,说明该数据是动态加载的,那我们是不是应该去js动态加载的数据中去找呢?答案是没必要,虽然可以这样找,但是效率很低。这里介绍另一种方法,仔细观察商品详情页的链接,你会发现有一个参数是id,如果搜索结果页的网页源码里有这些商品的id,那我们不就可以直接构造url了,带着这种思路,我们进行如下操作:   我们发现,这种思路是正确的,在网页源代码里确实找到了该商品的id,然后我们进行如下操作: 按照这种规则可以找到44个搜索结果,正好是淘宝搜索结果页一页的商品数,于是,我们就可以构造出商品详情页的url,仔细观察搜索结果,你会发现在淘宝网搜索的结果里面,包含了大量天猫商城的商品,而这两个 继续阅读 >>


何攀 18/01/07 14:14:09
本文分析一下Reactor模式的实现,关键是三个类:Channel、Poller、EventLoop。 事件分发类 Channel Channel 是 selectable IO channel,负责注册与响应IO事件,包括注册给Poller的 fd 及其监听的事件,以及事件发生了所调的回调函数。 每个Channel对象自始至终只负责一个 fd 的事件分发,封装了一系列该 fd 对应的操作,使用了回调函数,包括可读、可写、关闭和错误处理四个。 首先给定Channel所属的 loop,及其要处理的 fd;接着注册 fd 上需要监听的事件,如果是常用的读写事件的话,可以直接调用接口函数enableReading或enableWriting来注册对应fd上的事件,disable*是销毁指定的事件;然后通过 set*Callback 来设置事件发生时的回调。 注册事件时函数调用关系,如下:Channel::update()->EventLoop::updateChannel(Channel*)->Poller::updateChannel(Channel*),最终向 继续阅读 >>


杜肖孟 18/01/06 18:36:02