简易的站内搜索引擎 (万字长文!!绝对值得一看!!)

搜索引擎的实现

  • 项目简介
    • 项目背景
    • 项目开始前
      • 开始前的准备
    • 四个模块
      • 预处理模块
      • 索引模块
      • 搜索模块
      • 服务器模块

项目简介

这里所实现的并非如同百度、谷歌一样的全网搜索,我们的硬件条件达不到,并且技术实力也不够,但是我们可以按照搜索引擎的基本原理,来实现一个站内搜索,实现原理也算是大同小异,此项目分为四个模块预处理模块索引模块搜索模块服务器模块
简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第1张图片

项目背景

想要写一个搜索引擎也是源于偶然,在知乎上看到一篇文章,说是百度搜索为什么可以那么快?回答里说了很多方面的技术,其中最核心的就是倒排索引,这让我产生了浓厚的兴趣,但是因为实力和设备都有欠缺,没法做一个像是百度和搜狗一样的全网搜索,但我可以做一个站内搜索,来理解相应的技术。

项目开始前

虽然我们要实现的是站内搜索,但是与全网搜索大同小异,那么我们可以看一看搜索应该要包含什么
简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第2张图片
我们可以看到当我们在上面的文本框输入关键字之后点击搜索,在下面会显示出许多具有相关性的搜索结果,而这些搜索结果中至少需要包含以下四个部分:
标题
描述(网页正文摘要出一部分)
展示url
点击url,点击标题会跳转到另外一个url中
因此我们可以仿照百度的方式,来实现我们的搜索引擎

开始前的准备

httplib
g++版本必须得是4.9以上

jieba分词的库
用这个库的时候直接用include是不够的,需要将deps目录下的limonp也拷贝到include目录下

boost: yum install boost-devel.x86_64

jsoncpp: yum install jsoncpp-devel.x86_64

简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第3张图片
创建这样的一个目录结构

四个模块

预处理模块

这里就要提一下我为什么会选择boost网站来实现站内搜索了,

  1. 我们暂时无法实现一个全网搜索,只能完成站内搜索
  2. boost官方文档没有一个搜索功能,但是boost文档很常用,没有搜索功能比较麻烦
  3. boost文档提供了两个版本,离线版本在线版本
    boost提供了离线版本,那么我们就可以基于离线版本,分析文档页面的内容,为搜索功能提供支持。点击搜索结果的标题的时候,就能够跳转到在线版本的文档上,而如果网站内容无法直接下载,就必须使用爬虫来抓取页面到本地。

boost 在线文档.

我为什么选择1.53版本的boost呢?其实主要是因为我用的Linux版本是contos7,它默认就是1.53

那么我们现在得到了boost文档的离线版本之后需要干什么呢?
我们下载下来的boost文档,其实就是一个个的html,而这些html里面是有很多内容和标签混合在一起的,而我们需要的只是其中的标题正文url,而我们预处理阶段所要做的就是读取原始的html文档内容,提取我们所要的,整理成一个行文本,以供下面的模块使用
接下来我们就开始写预处理模块的代码了
首先我们需要定义两个变量来表示从哪里读数据和要把最后生成的行文本放到哪个路径下面展示一些 内联代码片

这个变量表示从哪个目录中读取boost文档的html

string g_input_path ="../data/input";

这个变量表示预处理模块输出结果放到哪里

string g_output_path ="../data/tmp/raw_input";

我们还需要一个结构体,来表示一个个的html

struct DocInfo{
     string title;//文档的标题
     string url;//文档的url
     string content;//文档的正文
 };

既然我们要将所有的html都解析成行文件,那么我们首要做的就是将所下载的所有html都枚举加载进来,那么我们就可以封装一个函数

bool EnumFile(const string &input_path, vector<string> *file_list)

其中input_path为输入参数,file_list是输出参数,将上面定义的输入变量传进来,然后将所有的html都枚举到输出参数file_list中。我们的枚举过程中是会遇到目录的,而我们只要枚举html,C++的标准库中没有能做到这个的,但是boost库中可以。

//把boost::filesystem这个命名空间定义一个别名
 39     namespace fs = boost::filesystem;
 40     fs::path root_path(input_path);
 41     if(!fs::exists(root_path)){
 42       std::cout << "当前的目录不存在" << std::endl;
 43     }
 44
 45     //递归目录迭代器,迭代器使用循环实现的时候可以自动完成递归
 46
 47     fs::recursive_directory_iterator end_iter;
 48     for(fs::recursive_directory_iterator begin_iter(root_path); begin_iter != end_iter; ++begin_iter){
 49         //需要判定当前的路径对应的是不是一个普通文件
 50         //如果是目录直接跳过
 51         if(!fs::is_regular_file(*begin_iter))
 52         {
 53             continue;
 54         }
 55         //当前路径对应的文件是不是一个html文件,如果不是也跳过
 56         if(begin_iter->path().extension() != ".html"){
 57           continue;
 58         }
 59 
 60         //把得到的html加入到最终结果的vector中                                                                                                          
 61         file_list->push_back(begin_iter->path().string());

接下来就是遍历vector里面的html了,打开每一个html,然后解析其中的内容,解析出标题、正文、url,对应我们之前创建好的结构体
找到标题

70 //找到html中的title标签
 71 bool ParseTitle(const string& html, string *title){
 72     size_t beg = html.find(""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">73</span>     <span class="token keyword">if</span><span class="token punctuation">(</span>beg <span class="token operator">==</span> string<span class="token operator">::</span>npos<span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token number">74</span>         std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"标题未找到"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
 <span class="token number">75</span>         <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
 <span class="token number">76</span>     <span class="token punctuation">}</span>
 <span class="token number">77</span>     size_t end <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"");
 78     if(end == string::npos){
 79         std::cout <<"标签未找到" <<std::endl;
 80         return false;
 81     }
 82     beg += string(""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">83</span>     <span class="token keyword">if</span><span class="token punctuation">(</span>beg <span class="token operator">>=</span> end<span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token number">84</span>         std<span class="token operator">::</span>cout <span class="token operator"><<</span><span class="token string">"标题位置不合法"</span> <span class="token operator"><<</span>std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
 <span class="token number">85</span>         <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
 <span class="token number">86</span>     <span class="token punctuation">}</span>
 <span class="token number">87</span>     <span class="token operator">*</span>title <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>beg<span class="token punctuation">,</span> end<span class="token operator">-</span>beg<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">88</span>     <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
 <span class="token number">89</span> 
 <span class="token number">90</span> <span class="token punctuation">}</span>
</code></pre> 
  <p><em><strong>获取url</strong></em></p> 
  <pre><code class="prism language-cpp"> <span class="token number">70</span> <span class="token comment">//找到html中的title标签</span>
 <span class="token number">71</span> <span class="token keyword">bool</span> <span class="token function">ParseTitle</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> html<span class="token punctuation">,</span> string <span class="token operator">*</span>title<span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token number">72</span>     size_t beg <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"<title>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">73</span>     <span class="token keyword">if</span><span class="token punctuation">(</span>beg <span class="token operator">==</span> string<span class="token operator">::</span>npos<span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token number">74</span>         std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"标题未找到"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
 <span class="token number">75</span>         <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
 <span class="token number">76</span>     <span class="token punctuation">}</span>
 <span class="token number">77</span>     size_t end <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"");
 78     if(end == string::npos){
 79         std::cout <<"标签未找到" <<std::endl;
 80         return false;
 81     }
 82     beg += string(""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">83</span>     <span class="token keyword">if</span><span class="token punctuation">(</span>beg <span class="token operator">>=</span> end<span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token number">84</span>         std<span class="token operator">::</span>cout <span class="token operator"><<</span><span class="token string">"标题位置不合法"</span> <span class="token operator"><<</span>std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
 <span class="token number">85</span>         <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
 <span class="token number">86</span>     <span class="token punctuation">}</span>
 <span class="token number">87</span>     <span class="token operator">*</span>title <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>beg<span class="token punctuation">,</span> end<span class="token operator">-</span>beg<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">88</span>     <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
 <span class="token number">89</span> 
 <span class="token number">90</span> <span class="token punctuation">}</span>
</code></pre> 
  <p><em><strong>找到正文</strong></em></p> 
  <pre><code class="prism language-cpp"><span class="token number">101</span> <span class="token comment">//获取正文</span>
<span class="token number">102</span> <span class="token keyword">bool</span> <span class="token function">ParseContent</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> html<span class="token punctuation">,</span> string<span class="token operator">*</span> content<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token number">103</span>     <span class="token comment">//这里引入一个bool变量,当进入标签之后,此值为false</span>
<span class="token number">104</span>     <span class="token comment">//判断这个变量就能知道是在标签内还是在标签外了</span>
<span class="token number">105</span>     <span class="token keyword">bool</span> is_content <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token number">106</span>     <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> c <span class="token operator">:</span> html<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token number">107</span>         <span class="token keyword">if</span><span class="token punctuation">(</span>is_content<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token number">108</span>             <span class="token comment">//当前是正文</span>
<span class="token number">109</span>             <span class="token keyword">if</span><span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token string">'<'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token number">110</span>                 is_content <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token number">111</span>             <span class="token punctuation">}</span>
<span class="token number">112</span>             <span class="token keyword">else</span><span class="token punctuation">{</span>
<span class="token number">113</span>                 <span class="token comment">//当前是普通字符,就把结果写入到content中</span>
<span class="token number">114</span>                 <span class="token keyword">if</span><span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token number">115</span>                     c <span class="token operator">=</span> <span class="token string">' '</span><span class="token punctuation">;</span>    
<span class="token number">116</span>                 <span class="token punctuation">}</span>
<span class="token number">117</span>                 content<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token number">118</span>             <span class="token punctuation">}</span>
<span class="token number">119</span>         <span class="token punctuation">}</span>
<span class="token number">120</span>         <span class="token keyword">else</span><span class="token punctuation">{</span>
<span class="token number">121</span>             <span class="token comment">//当前是在标签内</span>
<span class="token number">122</span>             <span class="token keyword">if</span><span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token string">'>'</span><span class="token punctuation">)</span>
<span class="token number">123</span>             <span class="token punctuation">{</span>
<span class="token number">124</span>                 <span class="token comment">//标签结束</span>
<span class="token number">125</span>                 is_content <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token number">126</span>             <span class="token punctuation">}</span>                                                                                                                                           
<span class="token number">127</span>             <span class="token comment">//标签里的其他内容都直接忽略掉</span>
<span class="token number">128</span>         <span class="token punctuation">}</span>
<span class="token number">129</span>     <span class="token punctuation">}</span>
<span class="token number">130</span>     <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token number">131</span> <span class="token punctuation">}</span>
</code></pre> 
  <p>最后只需要将我们解析出来的结果写入到我们最开始设置好的输出文件中就可以了,<mark>不过要记得选择一个不可见分隔符对标题、正文、url进行分割!!不然会出现粘包问题!!</mark><br> 以上就是预处理模块的全部内容了,可以编译运行一下,看看输出文件中是否如愿解析出来了。</p> 
  <h3>索引模块</h3> 
  <p>现在我们已经有了解析好的行文本了,那么我们接下来就要进入索引模块了,<mark>索引模块是最核心的部分,在这个模块我们就要引入倒排索引了!!!</mark><br> 不管是站内搜索还是全网搜索,面对大量的数据,最核心的点就是效率,我们需要在大量的数据中,快速而准确的找出我们所要的数据,那么解决这个问题,最核心的就是倒排索引。<br> 那么什么是倒排索引呢?<br> 我们来看一个经典的例子,我所学习倒排索引的时候,就是看的这个例子<br> <a href="http://img.e-com-net.com/image/info8/fdfc1ed7fde64891be9a075762a91f59.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/fdfc1ed7fde64891be9a075762a91f59.jpg" alt="简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第4张图片" width="342" height="211" style="border:1px solid black;"></a><br> 中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列所组成,然后对每个不同的单词赋予唯一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,我们可以得到最简单的倒排索引。<br> <a href="http://img.e-com-net.com/image/info8/0f7861490b1c4d8c8f7e44f215cb4f39.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/0f7861490b1c4d8c8f7e44f215cb4f39.jpg" alt="简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第5张图片" width="369" height="347" style="border:1px solid black;"></a><br> 我们可以概括性的理解为:<code>正排索引就是利用文档id来得到文本内容,倒排索引就是根据文本内容来得到文本id</code><br> 那么我们的基本逻辑就是构建出正排索引,并且对字符串进行分词切割,然后切分出来的单词,再根据切分的单词和正排索引构建倒排索引,通过倒排索引找到对应的文档id,再通过文档id查找正排索引,从正排索引找到文档的内容。<br> 因此我们现在要做的就是:<mark>构建正排索引</mark>,<mark>构建倒排索引</mark>,<mark>进行分词</mark>,<mark>查找倒排索引</mark>,<mark>查找正排索引</mark><br> 下面我们构建一下正排索引和倒排索引的基本结构体</p> 
  <pre><code class="prism language-cpp"> <span class="token number">23</span> <span class="token keyword">struct</span> <span class="token class-name">DocInfo</span> <span class="token punctuation">{</span>                                                        
 <span class="token number">24</span>     <span class="token keyword">int64_t</span> doc_id<span class="token punctuation">;</span>
 <span class="token number">25</span>     string title<span class="token punctuation">;</span>
 <span class="token number">26</span>     string url<span class="token punctuation">;</span>
 <span class="token number">27</span>     string content<span class="token punctuation">;</span>
 <span class="token number">28</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
 <span class="token number">29</span> 
 <span class="token number">30</span> <span class="token comment">// 倒排索引是给定词, 映射到包含该词的文档 id 列表. (此处不光要有文档 id,</span>
 <span class="token number">31</span> <span class="token comment">// 还得有权重信息, 以及该词的内容)</span>
 <span class="token number">32</span> <span class="token keyword">struct</span> <span class="token class-name">Weight</span> <span class="token punctuation">{</span>
 <span class="token number">33</span>     <span class="token comment">// 该词在哪个文档中出现</span>
 <span class="token number">34</span>     <span class="token keyword">int64_t</span> doc_id<span class="token punctuation">;</span>
 <span class="token number">35</span>     <span class="token comment">// 对应的权重是多少</span>
 <span class="token number">36</span>     <span class="token keyword">int</span> weight<span class="token punctuation">;</span>
 <span class="token number">37</span>     <span class="token comment">// 词是什么                                                                                                                                       </span>
 <span class="token number">38</span>     string word<span class="token punctuation">;</span>                                                                                                                            
 <span class="token number">39</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>                                                                                                                     
</code></pre> 
  <p>这就是我们需要做的所有操作</p> 
  <pre><code class="prism language-cpp"> <span class="token number">37</span> <span class="token keyword">typedef</span> vector<span class="token operator"><</span>Weight<span class="token operator">></span> InvertedList<span class="token punctuation">;</span>
 <span class="token number">38</span> 
 <span class="token number">39</span> <span class="token comment">// Index 类用于表示整个索引结构, 并且提供一些供外部调用的 API</span>
 <span class="token number">40</span> <span class="token keyword">class</span> <span class="token class-name">Index</span> <span class="token punctuation">{</span>
 <span class="token number">41</span>   <span class="token keyword">private</span><span class="token operator">:</span>
 <span class="token number">42</span>     <span class="token comment">// 索引结构</span>
 <span class="token number">43</span>     <span class="token comment">// 正排索引, 数组下标就对应到 doc_id</span>
 <span class="token number">44</span>     vector<span class="token operator"><</span>DocInfo<span class="token operator">></span> forward_index<span class="token punctuation">;</span>
 <span class="token number">45</span>     <span class="token comment">// 倒排索引, 使用一个 hash 表来表示这个映射关系</span>
 <span class="token number">46</span>     unordered_map<span class="token operator"><</span>string<span class="token punctuation">,</span> InvertedList<span class="token operator">></span> inverted_index<span class="token punctuation">;</span>
 <span class="token number">47</span> 
 <span class="token number">48</span>   <span class="token keyword">public</span><span class="token operator">:</span>
 <span class="token number">49</span>     <span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">50</span>     <span class="token comment">// 提供一些对外调用的函数</span>
 <span class="token number">51</span>     <span class="token comment">// 1. 查正排</span>
 <span class="token number">52</span>     <span class="token keyword">const</span> DocInfo<span class="token operator">*</span> <span class="token function">GetDocInfo</span><span class="token punctuation">(</span><span class="token keyword">int64_t</span> doc_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">53</span>     <span class="token comment">// 2. 查倒排</span>
 <span class="token number">54</span>     <span class="token keyword">const</span> InvertedList<span class="token operator">*</span> <span class="token function">GetInvertedList</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">55</span>     <span class="token comment">// 3. 构建索引</span>
 <span class="token number">56</span>     <span class="token keyword">bool</span> <span class="token function">Build</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input_path<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">57</span>     <span class="token comment">// 4. 分词函数</span>
 <span class="token number">58</span>     <span class="token keyword">void</span> <span class="token function">CutWord</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input<span class="token punctuation">,</span> vector<span class="token operator"><</span>string<span class="token operator">></span><span class="token operator">*</span> output<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">59</span> 
 <span class="token number">60</span>   <span class="token keyword">private</span><span class="token operator">:</span>                                                                                                                                            
 <span class="token number">61</span>     DocInfo<span class="token operator">*</span> <span class="token function">BuildForward</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">62</span>     <span class="token keyword">void</span> <span class="token function">BuildInverted</span><span class="token punctuation">(</span><span class="token keyword">const</span> DocInfo<span class="token operator">&</span> doc_info<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token number">63</span> 
 <span class="token number">64</span>     cppjieba<span class="token operator">::</span>Jieba jieba<span class="token punctuation">;</span>
 <span class="token number">65</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> 
  <p>接下来就具体实现一下,咱们先挑简单的查正排和查倒排来实现一下</p> 
  <pre><code class="prism language-cpp">   <span class="token number">28</span> <span class="token keyword">const</span> DocInfo<span class="token operator">*</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">GetDocInfo</span><span class="token punctuation">(</span><span class="token keyword">int64_t</span> doc_id<span class="token punctuation">)</span> <span class="token punctuation">{</span>                             
   <span class="token number">29</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span>doc_id <span class="token operator"><</span> <span class="token number">0</span> <span class="token operator">||</span> doc_id <span class="token operator">>=</span> forward_index<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>                                                                          
   <span class="token number">30</span>         <span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>                                                                                                               
   <span class="token number">31</span>     <span class="token punctuation">}</span>                                                                                                 
   <span class="token number">32</span>     <span class="token keyword">return</span> <span class="token operator">&</span>forward_index<span class="token punctuation">[</span>doc_id<span class="token punctuation">]</span><span class="token punctuation">;</span>                                                  
   <span class="token number">33</span> <span class="token punctuation">}</span>                                                                                                                
   <span class="token number">34</span>                                                                                 
   <span class="token number">35</span> <span class="token keyword">const</span> InvertedList<span class="token operator">*</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">GetInvertedList</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span>                
   <span class="token number">36</span>     <span class="token keyword">auto</span> it <span class="token operator">=</span> inverted_index<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                                                       
   <span class="token number">37</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> inverted_index<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>                                                                                 
   <span class="token number">38</span>         <span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>                                                                                             
   <span class="token number">39</span>     <span class="token punctuation">}</span>                                                                                                 
   <span class="token number">40</span>     <span class="token keyword">return</span> <span class="token operator">&</span>it<span class="token operator">-></span>second<span class="token punctuation">;</span>                                                             
   <span class="token number">41</span> <span class="token punctuation">}</span>                                                                                                     
</code></pre> 
  <p>这俩就是查找正排和倒排,查不到就返回nullptr,查到了就返回对应的指针即可<br> 接下来要做的就是构建索引了</p> 
  <pre><code class="prism language-cpp">   <span class="token number">43</span> <span class="token keyword">bool</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">Build</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input_path<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">44</span>     <span class="token comment">// 1. 按行读取输入文件内容(上个环节预处理模块生成的 raw_input 文件)</span>
   <span class="token number">45</span>     <span class="token comment">//    每一行又分成三个部分, 使用 \3 来切分, 分别是标题, url, 正文</span>
   <span class="token number">46</span>     std<span class="token operator">::</span>cerr <span class="token operator"><<</span> <span class="token string">"开始构建索引"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
   <span class="token number">47</span>     std<span class="token operator">::</span>ifstream <span class="token function">file</span><span class="token punctuation">(</span>input_path<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">48</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>file<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 
   <span class="token number">49</span>         std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"raw_input 文件打开失败"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
   <span class="token number">50</span>         <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>      
   <span class="token number">51</span>     <span class="token punctuation">}</span>                      
   <span class="token number">52</span>     string line<span class="token punctuation">;</span>           
   <span class="token number">53</span>     <span class="token keyword">while</span> <span class="token punctuation">(</span>std<span class="token operator">::</span><span class="token function">getline</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">54</span>         <span class="token comment">// 2. 解析成 正排结构的DocInfo 对象, 并构造为正排索引</span>
   <span class="token number">55</span>         DocInfo<span class="token operator">*</span> doc_info <span class="token operator">=</span> <span class="token function">BuildForward</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">56</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span>doc_info <span class="token operator">==</span> <span class="token keyword">nullptr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">57</span>             std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"构建正排失败!"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
   <span class="token number">58</span>             <span class="token keyword">continue</span><span class="token punctuation">;</span>      
   <span class="token number">59</span>         <span class="token punctuation">}</span>                  
   <span class="token number">60</span>         <span class="token comment">// 3.构造成倒排索引.</span>
   <span class="token number">61</span>         <span class="token function">BuildInverted</span><span class="token punctuation">(</span><span class="token operator">*</span>doc_info<span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">62</span>                            
   <span class="token number">63</span>         <span class="token comment">//此时需要知道进度是多少,但是如果每一个都进行打印</span>
   <span class="token number">64</span>         <span class="token comment">//每个数据都进行I/O操作的话过于影响效率</span>
   <span class="token number">65</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span>doc_info<span class="token operator">-></span>doc_id <span class="token operator">%</span> <span class="token number">100</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>                                                                                                            
   <span class="token number">66</span>             std<span class="token operator">::</span>cerr <span class="token operator"><<</span> doc_info<span class="token operator">-></span>doc_id <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
   <span class="token number">67</span>         <span class="token punctuation">}</span>
   <span class="token number">68</span>     <span class="token punctuation">}</span>
   <span class="token number">69</span>     std<span class="token operator">::</span>cerr <span class="token operator"><<</span> <span class="token string">"结束构建索引"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
   <span class="token number">70</span>     file<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">71</span>     <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
   <span class="token number">72</span> <span class="token punctuation">}</span>
</code></pre> 
  <p>这是整体的构建思路,我们接下来就分别完成倒排索引和正排索引<br> =<mark>正排索引</mark>=<br> 我们要做的核心操作: 按照 <code>设定的分隔符</code> 对 <code>行文本</code> 进行切分, 第一个部分就是<code>标题</code>, 第二个部分就是 <code>url</code>, 第三个部分就是<code>正文</code>,然后将这三个部分填充到正排索引对应的结构体中即可。</p> 
  <pre><code class="prism language-cpp">   <span class="token number">77</span> DocInfo<span class="token operator">*</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">BuildForward</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> line<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">78</span>     <span class="token comment">// 1. 先把 line 按照 \3 切分成 3 个部分</span>
   <span class="token number">79</span>     vector<span class="token operator"><</span>string<span class="token operator">></span> tokens<span class="token punctuation">;</span>
   <span class="token number">80</span>     common<span class="token operator">::</span><span class="token class-name">Util</span><span class="token operator">::</span><span class="token function">Split</span><span class="token punctuation">(</span>line<span class="token punctuation">,</span> <span class="token string">"\3"</span><span class="token punctuation">,</span> <span class="token operator">&</span>tokens<span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">81</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span>tokens<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">82</span>         <span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>                                                                                                                               
   <span class="token number">83</span>     <span class="token punctuation">}</span>                         
   <span class="token number">84</span>     <span class="token comment">// 2. 把切分结果填充到 DocInfo 对象中</span>
   <span class="token number">85</span>     DocInfo doc_info<span class="token punctuation">;</span>                    
   <span class="token number">86</span>     doc_info<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> forward_index<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">87</span>     doc_info<span class="token punctuation">.</span>title <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>            
   <span class="token number">88</span>     doc_info<span class="token punctuation">.</span>url <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>              
   <span class="token number">89</span>     doc_info<span class="token punctuation">.</span>content <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
   <span class="token number">90</span>     forward_index<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token operator">::</span><span class="token function">move</span><span class="token punctuation">(</span>doc_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">91</span>     <span class="token keyword">return</span> <span class="token operator">&</span>forward_index<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                
   <span class="token number">92</span> <span class="token punctuation">}</span>                                                
</code></pre> 
  <p>这里的切分,在C++的标准库中并没有,但是boost库中是有的,因此我们用boost库中的split函数,不过这里我将split封装了一下,比boost库中的split函数少了一个参数,也就是boost::token_compress_on:将连续多个分隔符当一个,默认没有打开,当用的时候一般是要打开的。<br> boost:: token_compress_off:不会压缩分割结果,连续的分隔符时会返回 ""字符串<br> 我默认选择了compress_off因为也许有的html中的字段是空的,那我们也不能将其压缩。<br> <code>并且最后我选择了将doc_info转化成了右值(将亡值)进行了右值引用(效率就是一点点省出来的哦)</code><br> 接下来就是构建倒排索引了,而我们构建倒排索引要做的首先就是构建正排和分词,现在正排已经构建完毕了,那我们就需要分词了,分词我们选择了<code>cppjieba分词库</code>来帮我们完成</p> 
  <pre><code class="prism language-cpp">  <span class="token number">147</span> <span class="token keyword">void</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">CutWord</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input<span class="token punctuation">,</span> vector<span class="token operator"><</span>string<span class="token operator">></span><span class="token operator">*</span> output<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">148</span>     jieba<span class="token punctuation">.</span><span class="token function">CutForSearch</span><span class="token punctuation">(</span>input<span class="token punctuation">,</span> <span class="token operator">*</span>output<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">149</span> <span class="token punctuation">}</span>
</code></pre> 
  <p>那么我们现在终于可以开始期待已久的倒排索引了</p> 
  <pre><code class="prism language-cpp">   <span class="token number">97</span> <span class="token keyword">void</span> <span class="token class-name">Index</span><span class="token operator">::</span><span class="token function">BuildInverted</span><span class="token punctuation">(</span><span class="token keyword">const</span> DocInfo<span class="token operator">&</span> doc_info<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">98</span>     <span class="token comment">// 创建专门用于统计词频的结构</span>
   <span class="token number">99</span>     <span class="token keyword">struct</span> <span class="token class-name">WordCnt</span> <span class="token punctuation">{</span>       
  <span class="token number">100</span>         <span class="token keyword">int</span> title_cnt<span class="token punctuation">;</span>     
  <span class="token number">101</span>         <span class="token keyword">int</span> content_cnt<span class="token punctuation">;</span>   
  <span class="token number">102</span>         <span class="token function">WordCnt</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">title_cnt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">content_cnt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">103</span>         <span class="token punctuation">}</span>                  
  <span class="token number">104</span>     <span class="token punctuation">}</span><span class="token punctuation">;</span>                     
  <span class="token number">105</span>     unordered_map<span class="token operator"><</span>string<span class="token punctuation">,</span> WordCnt<span class="token operator">></span> word_cnt_map<span class="token punctuation">;</span>
  <span class="token number">106</span>     <span class="token comment">// 针对标题进行分词    </span>
  <span class="token number">107</span>     vector<span class="token operator"><</span>string<span class="token operator">></span> title_token<span class="token punctuation">;</span>
  <span class="token number">108</span>     <span class="token function">CutWord</span><span class="token punctuation">(</span>doc_info<span class="token punctuation">.</span>title<span class="token punctuation">,</span> <span class="token operator">&</span>title_token<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">109</span>     <span class="token comment">// 遍历分词结果, 统计每个词出现的次数</span>
  <span class="token number">110</span>     <span class="token keyword">for</span> <span class="token punctuation">(</span>string word <span class="token operator">:</span> title_token<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">111</span>         <span class="token comment">//将只是大小写不同的词当作同一个词来处理</span>
  <span class="token number">112</span>         <span class="token comment">//因此都转化成小写                                                                                                                            </span>
  <span class="token number">113</span>         boost<span class="token operator">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>                                        
  <span class="token number">114</span>         <span class="token operator">++</span>word_cnt_map<span class="token punctuation">[</span>word<span class="token punctuation">]</span><span class="token punctuation">.</span>title_cnt<span class="token punctuation">;</span>                               
  <span class="token number">115</span>     <span class="token punctuation">}</span>                                                                 
  <span class="token number">116</span>     <span class="token comment">// 针对正文进行分词                                               </span>
  <span class="token number">117</span>     vector<span class="token operator"><</span>string<span class="token operator">></span> content_token<span class="token punctuation">;</span>                                     
  <span class="token number">118</span>     <span class="token function">CutWord</span><span class="token punctuation">(</span>doc_info<span class="token punctuation">.</span>content<span class="token punctuation">,</span> <span class="token operator">&</span>content_token<span class="token punctuation">)</span><span class="token punctuation">;</span>                        
  <span class="token number">119</span>     <span class="token comment">// 遍历分词结果, 统计每个词出现的次数     </span>
  <span class="token number">120</span>     <span class="token keyword">for</span> <span class="token punctuation">(</span>string word <span class="token operator">:</span> content_token<span class="token punctuation">)</span> <span class="token punctuation">{</span>                            
  <span class="token number">121</span>         boost<span class="token operator">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">122</span>         <span class="token operator">++</span>word_cnt_map<span class="token punctuation">[</span>word<span class="token punctuation">]</span><span class="token punctuation">.</span>content_cnt<span class="token punctuation">;</span>
  <span class="token number">123</span>     <span class="token punctuation">}</span>
  <span class="token number">124</span>     <span class="token comment">// 填充Weight对象</span>
  <span class="token number">125</span>     <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span><span class="token operator">&</span> word_pair <span class="token operator">:</span> word_cnt_map<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">126</span>         <span class="token comment">// 构造 Weight 对象</span>
  <span class="token number">127</span>         Weight weight<span class="token punctuation">;</span>
  <span class="token number">128</span>         weight<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> doc_info<span class="token punctuation">.</span>doc_id<span class="token punctuation">;</span>
  <span class="token number">129</span>         <span class="token comment">// 权重 = 标题出现次数 * 10 + 正文出现次数</span>
  <span class="token number">130</span>         weight<span class="token punctuation">.</span>weight <span class="token operator">=</span> <span class="token number">10</span> <span class="token operator">*</span> word_pair<span class="token punctuation">.</span>second<span class="token punctuation">.</span>title_cnt <span class="token operator">+</span> word_pair<span class="token punctuation">.</span>second<span class="token punctuation">.</span>content_cnt<span class="token punctuation">;</span>
  <span class="token number">131</span>         weight<span class="token punctuation">.</span>word <span class="token operator">=</span> word_pair<span class="token punctuation">.</span>first<span class="token punctuation">;</span>
  <span class="token number">132</span> 
  <span class="token number">133</span>         <span class="token comment">// 把 weight 对象插入到倒排索引中                                                                                                             </span>
  <span class="token number">134</span>         InvertedList<span class="token operator">&</span> inverted_list <span class="token operator">=</span> inverted_index<span class="token punctuation">[</span>word_pair<span class="token punctuation">.</span>first<span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token number">135</span>         inverted_list<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token operator">::</span><span class="token function">move</span><span class="token punctuation">(</span>weight<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                   
  <span class="token number">136</span>     <span class="token punctuation">}</span>                                                                 
  <span class="token number">137</span> <span class="token punctuation">}</span>                                                  
</code></pre> 
  <p>整体思路就是将倒排索引设置成一个hash表,key是关键词,value 是倒排拉链 (包含若干个 Weight 对象),同时设置一个hash表,来统计词频key是关键词,value是WordCnt结构体,因此统计出标题的词频和正文的词频,根据这两者的词频算出权重,将权重和分词结果、文档id填入Weight对象,再将Weight对象填入到第一个hash表中。</p> 
  <p>以上就是索引部分的全部内容了。</p> 
  <h3>搜索模块</h3> 
  <p>上面我们构建好了索引模块,现在我们的搜索模块就是要利用上面的索引,首先我们还是将这个模块进行一个封装</p> 
  <pre><code class="prism language-cpp">   <span class="token number">68</span> <span class="token keyword">class</span> <span class="token class-name">Searcher</span> <span class="token punctuation">{</span>                                                                                                                       
   <span class="token number">69</span>   <span class="token keyword">private</span><span class="token operator">:</span>                                                                                                                                 
   <span class="token number">70</span>     Index<span class="token operator">*</span> index<span class="token punctuation">;</span>                                                                                                  
   <span class="token number">71</span>                                                                                                                                           
   <span class="token number">72</span>   <span class="token keyword">public</span><span class="token operator">:</span>                                                               
   <span class="token number">73</span>     <span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>                                                                          
   <span class="token number">74</span>     <span class="token punctuation">}</span>                                                                                                                                     
   <span class="token number">75</span>     <span class="token keyword">bool</span> <span class="token function">Init</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input_path<span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                                               
   <span class="token number">76</span>     <span class="token keyword">bool</span> <span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> query<span class="token punctuation">,</span> string<span class="token operator">*</span> results<span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                                    
   <span class="token number">77</span>                                                                                                                                             
   <span class="token number">78</span>   <span class="token keyword">private</span><span class="token operator">:</span>                                                              
   <span class="token number">79</span>     string <span class="token function">GenerateDesc</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> content<span class="token punctuation">,</span> <span class="token keyword">const</span> string<span class="token operator">&</span> word<span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                         
   <span class="token number">80</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> 
</code></pre> 
  <p>这里的对象是Index的一个指针,因为我们要使用到上一个类,而Init初始化也是这个用处</p> 
  <pre><code class="prism language-cpp">  <span class="token number">145</span> <span class="token keyword">bool</span> <span class="token class-name">Searcher</span><span class="token operator">::</span><span class="token function">Init</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> input_path<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">146</span>     <span class="token keyword">return</span> index<span class="token operator">-></span><span class="token function">Build</span><span class="token punctuation">(</span>input_path<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">147</span> <span class="token punctuation">}</span>
</code></pre> 
  <p>也就是将所有的正排索引和倒排索引都建立好,以便我们接下来使用,接下来就是查询倒排了,并且按照权重进行排序了</p> 
  <pre><code class="prism language-cpp">  <span class="token number">149</span> <span class="token comment">// 搜索查询词, 得到搜索结果.                                                                                                                          </span>
  <span class="token number">150</span> <span class="token keyword">bool</span> <span class="token class-name">Searcher</span><span class="token operator">::</span><span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> query<span class="token punctuation">,</span> string<span class="token operator">*</span> output<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">151</span>     <span class="token comment">// 针对查询词进行分词 </span>
  <span class="token number">152</span>     vector<span class="token operator"><</span>string<span class="token operator">></span> tokens<span class="token punctuation">;</span>
  <span class="token number">153</span>     index<span class="token operator">-></span><span class="token function">CutWord</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span> <span class="token operator">&</span>tokens<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">154</span>     <span class="token comment">// 根据分词结果, 查倒排, 把相关的文档都获取到</span>
  <span class="token number">155</span>     vector<span class="token operator"><</span>Weight<span class="token operator">></span> all_token_result<span class="token punctuation">;</span>
  <span class="token number">156</span>     <span class="token keyword">for</span> <span class="token punctuation">(</span>string word <span class="token operator">:</span> tokens<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">157</span>         boost<span class="token operator">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">158</span>         <span class="token keyword">auto</span><span class="token operator">*</span> inverted_list <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetInvertedList</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">159</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span>inverted_list <span class="token operator">==</span> <span class="token keyword">nullptr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">160</span>             <span class="token keyword">continue</span><span class="token punctuation">;</span>
  <span class="token number">161</span>         <span class="token punctuation">}</span>
  <span class="token number">162</span>         <span class="token comment">//  将搜索到的结果都合并到一起进行统一的排序</span>
  <span class="token number">163</span>         all_token_result<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>all_token_result<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> inverted_list<span class="token operator">-></span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> inverted_list<span class="token operator">-></span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">164</span>     <span class="token punctuation">}</span>
  <span class="token number">165</span>     std<span class="token operator">::</span><span class="token function">sort</span><span class="token punctuation">(</span>all_token_result<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> all_token_result<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> Weight<span class="token operator">&</span> w1<span class="token punctuation">,</span> <span class="token keyword">const</span> Weight<span class="token operator">&</span> w2<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">166</span>         <span class="token keyword">return</span> w1<span class="token punctuation">.</span>weight <span class="token operator">></span> w2<span class="token punctuation">.</span>weight<span class="token punctuation">;</span>
  <span class="token number">167</span>     <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> 
  <p>然后用得到的文档id,去查找正排,再将正排查到的行文本转化成json格式以便我们使用,使用 jsoncpp 这个库来实现 json 的操作.</p> 
  <pre><code class="prism language-cpp">  <span class="token number">170</span>     Json<span class="token operator">::</span>Value results<span class="token punctuation">;</span> 
  <span class="token number">171</span>     <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span><span class="token operator">&</span> weight <span class="token operator">:</span> all_token_result<span class="token punctuation">)</span> <span class="token punctuation">{</span>                                                                                                     
  <span class="token number">172</span>         <span class="token comment">// 根据 weight 中的 doc_id 查正排        </span>
  <span class="token number">173</span>         <span class="token keyword">const</span> DocInfo<span class="token operator">*</span> doc_info <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetDocInfo</span><span class="token punctuation">(</span>weight<span class="token punctuation">.</span>doc_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">174</span>         <span class="token comment">// 把这个 doc_info 对象再进一步的包装成一个 JSON 对象      </span>
  <span class="token number">175</span>         Json<span class="token operator">::</span>Value result<span class="token punctuation">;</span>                                        
  <span class="token number">176</span>         result<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc_info<span class="token operator">-></span>title<span class="token punctuation">;</span>                   
  <span class="token number">177</span>         result<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc_info<span class="token operator">-></span>url<span class="token punctuation">;</span>    
  <span class="token number">178</span>         result<span class="token punctuation">[</span><span class="token string">"desc"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">GenerateDesc</span><span class="token punctuation">(</span>doc_info<span class="token operator">-></span>content<span class="token punctuation">,</span> weight<span class="token punctuation">.</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">179</span>         results<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>                                       
  <span class="token number">180</span>     <span class="token punctuation">}</span>                                                                 
  <span class="token number">181</span>     <span class="token comment">// 把得到的 results 这个 JSON 对象序列化成字符串. 写入 output 中</span>
  <span class="token number">182</span>     Json<span class="token operator">::</span>FastWriter writer<span class="token punctuation">;</span>                                        
  <span class="token number">183</span>     <span class="token operator">*</span>output <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>results<span class="token punctuation">)</span><span class="token punctuation">;</span>                                
  <span class="token number">184</span>     <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>                    
  <span class="token number">185</span> <span class="token punctuation">}</span>                            
</code></pre> 
  <p>而这里的desc,就是在网页上所显示的,文本的部分摘要的内容,而我们要用多少文本来作为摘要呢?<br> 我们先根据正文, 找到 word 出现的位置. 以该位置为中心, 往前找 80 个字节, 作为描述的起始位置.<br> 再从起始位置开始往后找 160 个字节, 作为整个描述. 这里的取值完全根据个人自定义就行</p> 
  <pre><code class="prism language-cpp">  <span class="token number">187</span> string <span class="token class-name">Searcher</span><span class="token operator">::</span><span class="token function">GenerateDesc</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> content<span class="token punctuation">,</span> <span class="token keyword">const</span> string<span class="token operator">&</span> word<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">188</span>     <span class="token comment">// 1. 先找到 word 在正文中出现的位置.</span>
  <span class="token number">189</span>     size_t first_pos <span class="token operator">=</span> content<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">190</span>     size_t desc_beg <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token number">191</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span>first_pos <span class="token operator">==</span> string<span class="token operator">::</span>npos<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">192</span>         <span class="token comment">// 如果找不到, 就直接从头开始作为起始位置.</span>
  <span class="token number">193</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span>content<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">160</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">194</span>             <span class="token keyword">return</span> content<span class="token punctuation">;</span>
  <span class="token number">195</span>         <span class="token punctuation">}</span>
  <span class="token number">196</span>         string desc <span class="token operator">=</span> content<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">160</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">197</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>
  <span class="token number">198</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>
  <span class="token number">199</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>
  <span class="token number">200</span>         <span class="token keyword">return</span> desc<span class="token punctuation">;</span>
  <span class="token number">201</span>     <span class="token punctuation">}</span>
  <span class="token number">202</span>     <span class="token comment">// 2. 找到了 first_pos 位置, 以这个位置为基准, 往前找一些字节.</span>
  <span class="token number">203</span>     desc_beg <span class="token operator">=</span> first_pos <span class="token operator"><</span> <span class="token number">80</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token operator">:</span> first_pos <span class="token operator">-</span> <span class="token number">80</span><span class="token punctuation">;</span>
  <span class="token number">204</span>     <span class="token keyword">if</span> <span class="token punctuation">(</span>desc_beg <span class="token operator">+</span> <span class="token number">160</span> <span class="token operator">>=</span> content<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token number">205</span>         <span class="token comment">// desc_beg 后面的内容不够 160 了, 直接到末尾结束即可                                                                                         </span>
  <span class="token number">206</span>         <span class="token keyword">return</span> content<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>desc_beg<span class="token punctuation">)</span><span class="token punctuation">;</span>                     
  <span class="token number">207</span>     <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>                            
  <span class="token number">208</span>         string desc <span class="token operator">=</span> content<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>desc_beg<span class="token punctuation">,</span> <span class="token number">160</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token number">209</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>                
  <span class="token number">210</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>
  <span class="token number">211</span>         desc<span class="token punctuation">[</span>desc<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'.'</span><span class="token punctuation">;</span>
  <span class="token number">212</span>         <span class="token keyword">return</span> desc<span class="token punctuation">;</span>                
  <span class="token number">213</span>     <span class="token punctuation">}</span>               
  <span class="token number">214</span> <span class="token punctuation">}</span>    
</code></pre> 
  <p>这就是搜索模块所实现的所有功能了,像是测试,我就不在这里写了,不过完成每一个模块的时候都要测试一下,不要最后发现出错了都不知道去哪里找</p> 
  <h3>服务器模块</h3> 
  <p>接下来就是最后的一个模块了,服务器模块,这里我们就用cpp-httplib库来搭建服务器了,就不自己手动用stocket套接字搭建了,根据项目文档来使用即可,这里我就不多介绍了</p> 
  <pre><code class="prism language-cpp">   <span class="token number">25</span>     Server server<span class="token punctuation">;</span>
   <span class="token number">26</span>     server<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/searcher"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&</span>searcher<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> Request<span class="token operator">&</span> req<span class="token punctuation">,</span> Response<span class="token operator">&</span> resp<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">27</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>req<span class="token punctuation">.</span><span class="token function">has_param</span><span class="token punctuation">(</span><span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token number">28</span>             resp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span><span class="token string">"您发的请求参数错误"</span><span class="token punctuation">,</span> <span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">29</span>             <span class="token keyword">return</span><span class="token punctuation">;</span>
   <span class="token number">30</span>         <span class="token punctuation">}</span>
   <span class="token number">31</span>         string query <span class="token operator">=</span> req<span class="token punctuation">.</span><span class="token function">get_param_value</span><span class="token punctuation">(</span><span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">32</span>         string results<span class="token punctuation">;</span>
   <span class="token number">33</span>         searcher<span class="token punctuation">.</span><span class="token function">Search</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span> <span class="token operator">&</span>results<span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token number">34</span>         resp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span>results<span class="token punctuation">,</span> <span class="token string">"application/json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                                                
   <span class="token number">35</span>     <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                                                              

</code></pre> 
  <p>先创建Server对象,然后调用Get函数,这个函数有两个参数,第一个表示的是,你要用哪个http路径来触发get操作,第二个参数是一个lambda表达式,是一个回调函数,也就是当服务器收到第一个参数的请求的时候,会触发回调函数的操作,Request就是请求,Response就是相应,我们收到请求之后就可以解析请求,根据请求内容,来完成响应。set_content就是将我们的结果写到响应的body中,然后返回,他的第二个参数就是返回的body的数据格式,text/plain就是纯文本,application/json就是json格式。<br> 最后将我们的所做的前端页面,也就是静态资源挂载就可以了。</p> 
  <pre><code class="prism language-cpp">   <span class="token number">36</span>     <span class="token comment">// 告诉服务器, 静态资源存放在 wwwroot 目录下. (html, css, js, 图片....)          </span>
   <span class="token number">37</span>     server<span class="token punctuation">.</span><span class="token function">set_mount_point</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token string">"./ShySearcher"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                    
   <span class="token number">38</span>     <span class="token comment">// 3. 启动服务器                                                                 </span>
   <span class="token number">39</span>     server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> <span class="token number">10001</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                                 
</code></pre> 
  <p>我前端做的不太好,也就不给大家展示了。<br> 咱们的站内搜索引擎也基本就结束了。<br> <a href="http://img.e-com-net.com/image/info8/15747abf027d4f0fb26b95ace0490e0f.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/15747abf027d4f0fb26b95ace0490e0f.jpg" alt="简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第6张图片" width="255" height="255" style="border:1px solid black;"></a><a href="http://img.e-com-net.com/image/info8/5d8f7b668c684c11b1c3dd62c273043c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/5d8f7b668c684c11b1c3dd62c273043c.jpg" alt="简易的站内搜索引擎 (万字长文!!绝对值得一看!!)_第7张图片" width="500" height="499" style="border:1px solid black;"></a></p> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1592317582126456832"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(c++,http,linux)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835513699826233344.htm"
                           title="android系统selinux中添加新属性property" target="_blank">android系统selinux中添加新属性property</a>
                        <span class="text-muted">辉色投像</span>

                        <div>1.定位/android/system/sepolicy/private/property_contexts声明属性开头:persist.charge声明属性类型:u:object_r:system_prop:s0图12.定位到android/system/sepolicy/public/domain.te删除neverallow{domain-init}default_prop:property</div>
                    </li>
                    <li><a href="/article/1835511912843014144.htm"
                           title="理解Gunicorn:Python WSGI服务器的基石" target="_blank">理解Gunicorn:Python WSGI服务器的基石</a>
                        <span class="text-muted">范范0825</span>
<a class="tag" taget="_blank" href="/search/ipython/1.htm">ipython</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico</div>
                    </li>
                    <li><a href="/article/1835511030260789248.htm"
                           title="c++ 的iostream 和 c++的stdio的区别和联系" target="_blank">c++ 的iostream 和 c++的stdio的区别和联系</a>
                        <span class="text-muted">黄卷青灯77</span>
<a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/iostream/1.htm">iostream</a><a class="tag" taget="_blank" href="/search/stdio/1.htm">stdio</a>
                        <div>在C++中,iostream和C语言的stdio.h都是用于处理输入输出的库,但它们在设计、用法和功能上有许多不同。以下是两者的区别和联系:区别1.编程风格iostream(C++风格):C++标准库中的输入输出流类库,支持面向对象的输入输出操作。典型用法是cin(输入)和cout(输出),使用>操作符来处理数据。更加类型安全,支持用户自定义类型的输入输出。#includeintmain(){in</div>
                    </li>
                    <li><a href="/article/1835509770287673344.htm"
                           title="swagger访问路径" target="_blank">swagger访问路径</a>
                        <span class="text-muted">igotyback</span>
<a class="tag" taget="_blank" href="/search/swagger/1.htm">swagger</a>
                        <div>Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip</div>
                    </li>
                    <li><a href="/article/1835509391361667072.htm"
                           title="Linux下QT开发的动态库界面弹出操作(SDL2)" target="_blank">Linux下QT开发的动态库界面弹出操作(SDL2)</a>
                        <span class="text-muted">13jjyao</span>
<a class="tag" taget="_blank" href="/search/QT%E7%B1%BB/1.htm">QT类</a><a class="tag" taget="_blank" href="/search/qt/1.htm">qt</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/sdl2/1.htm">sdl2</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>需求:操作系统为linux,开发框架为qt,做成需带界面的qt动态库,调用方为java等非qt程序难点:调用方为java等非qt程序,也就是说调用方肯定不带QApplication::exec(),缺少了这个,QTimer等事件和QT创建的窗口将不能弹出(包括opencv也是不能弹出);这与qt调用本身qt库是有本质的区别的思路:1.调用方缺QApplication::exec(),那么我们在接口</div>
                    </li>
                    <li><a href="/article/1835504596898902016.htm"
                           title="linux sdl windows.h,Windows下的SDL安装" target="_blank">linux sdl windows.h,Windows下的SDL安装</a>
                        <span class="text-muted">奔跑吧linux内核</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/sdl/1.htm">sdl</a><a class="tag" taget="_blank" href="/search/windows.h/1.htm">windows.h</a>
                        <div>首先你要下载并安装SDL开发包。如果装在C盘下,路径为C:\SDL1.2.5如果在WINDOWS下。你可以按以下步骤:1.打开VC++,点击"Tools",Options2,点击directories选项3.选择"Includefiles"增加一个新的路径。"C:\SDL1.2.5\include"4,现在选择"Libaryfiles“增加"C:\SDL1.2.5\lib"现在你可以开始编写你的第</div>
                    </li>
                    <li><a href="/article/1835504218178416640.htm"
                           title="Google earth studio 简介" target="_blank">Google earth studio 简介</a>
                        <span class="text-muted">陟彼高冈yu</span>
<a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a>
                        <div>GoogleEarthStudio是一个基于Web的动画工具,专为创作使用GoogleEarth数据的动画和视频而设计。它利用了GoogleEarth强大的三维地图和卫星影像数据库,使用户能够轻松地创建逼真的地球动画、航拍视频和动态地图可视化。网址为https://www.google.com/earth/studio/。GoogleEarthStudio是一个基于Web的动画工具,专为创作使用G</div>
                    </li>
                    <li><a href="/article/1835503712899002368.htm"
                           title="linux中sdl的使用教程,sdl使用入门" target="_blank">linux中sdl的使用教程,sdl使用入门</a>
                        <span class="text-muted">Melissa Corvinus</span>
<a class="tag" taget="_blank" href="/search/linux%E4%B8%ADsdl%E7%9A%84%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/1.htm">linux中sdl的使用教程</a>
                        <div>本文通过一个简单示例讲解SDL的基本使用流程。示例中展示一个窗口,窗口里面有个随机颜色快随机移动。当我们鼠标点击关闭按钮时间窗口关闭。基本步骤如下:1.初始化SDL并创建一个窗口。SDL_Init()初始化SDL_CreateWindow()创建窗口2.纹理渲染存储RGB和存储纹理的区别:比如一个从左到右由红色渐变到蓝色的矩形,用存储RGB的话就需要把矩形中每个点的具体颜色值存储下来;而纹理只是一</div>
                    </li>
                    <li><a href="/article/1835502578050363392.htm"
                           title="PHP环境搭建详细教程" target="_blank">PHP环境搭建详细教程</a>
                        <span class="text-muted">好看资源平台</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a>
                        <div>PHP是一个流行的服务器端脚本语言,广泛用于Web开发。为了使PHP能够在本地或服务器上运行,我们需要搭建一个合适的PHP环境。本教程将结合最新资料,介绍在不同操作系统上搭建PHP开发环境的多种方法,包括Windows、macOS和Linux系统的安装步骤,以及本地和Docker环境的配置。1.PHP环境搭建概述PHP环境的搭建主要分为以下几类:集成开发环境:例如XAMPP、WAMP、MAMP,这</div>
                    </li>
                    <li><a href="/article/1835501948011376640.htm"
                           title="使用 FinalShell 进行远程连接(ssh 远程连接 Linux 服务器)" target="_blank">使用 FinalShell 进行远程连接(ssh 远程连接 Linux 服务器)</a>
                        <span class="text-muted">编程经验分享</span>
<a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/1.htm">开发工具</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/ssh/1.htm">ssh</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>目录前言基本使用教程新建远程连接连接主机自定义命令路由追踪前言后端开发,必然需要和服务器打交道,部署应用,排查问题,查看运行日志等等。一般服务器都是集中部署在机房中,也有一些直接是云服务器,总而言之,程序员不可能直接和服务器直接操作,一般都是通过ssh连接来登录服务器。刚接触远程连接时,使用的是XSHELL来远程连接服务器,连接上就能够操作远程服务器了,但是仅用XSHELL并没有上传下载文件的功能</div>
                    </li>
                    <li><a href="/article/1835499615491813376.htm"
                           title="四章-32-点要素的聚合" target="_blank">四章-32-点要素的聚合</a>
                        <span class="text-muted">彩云飘过</span>

                        <div>本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.</div>
                    </li>
                    <li><a href="/article/1835499052125483008.htm"
                           title="Git常用命令-修改远程仓库地址" target="_blank">Git常用命令-修改远程仓库地址</a>
                        <span class="text-muted">猿大师</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                        <div>查看远程仓库地址gitremote-v返回结果originhttps://git.coding.net/*****.git(fetch)originhttps://git.coding.net/*****.git(push)修改远程仓库地址gitremoteset-urloriginhttps://git.coding.net/*****.git先删除后增加远程仓库地址gitremotermori</div>
                    </li>
                    <li><a href="/article/1835497537369370624.htm"
                           title="利用Requests Toolkit轻松完成HTTP请求" target="_blank">利用Requests Toolkit轻松完成HTTP请求</a>
                        <span class="text-muted">nseejrukjhad</span>
<a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/1.htm">网络协议</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>RequestsToolkit的力量:轻松构建HTTP请求Agent在现代软件开发中,API请求是与外部服务交互的核心。RequestsToolkit提供了一种便捷的方式,帮助开发者构建自动化的HTTP请求Agent。本文旨在详细介绍RequestsToolkit的设置、使用和潜在挑战。引言RequestsToolkit是一个强大的工具包,可用于构建执行HTTP请求的智能代理。这对于想要自动化与外</div>
                    </li>
                    <li><a href="/article/1835496402042580992.htm"
                           title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a>
                        <span class="text-muted">bigbig猩猩</span>
<a class="tag" taget="_blank" href="/search/github/1.htm">github</a>
                        <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div>
                    </li>
                    <li><a href="/article/1835494258262503424.htm"
                           title="【JS】执行时长(100分) |思路参考+代码解析(C++)" target="_blank">【JS】执行时长(100分) |思路参考+代码解析(C++)</a>
                        <span class="text-muted">l939035548</span>
<a class="tag" taget="_blank" href="/search/JS/1.htm">JS</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a>
                        <div>题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围</div>
                    </li>
                    <li><a href="/article/1835493373906087936.htm"
                           title="libyuv之linux编译" target="_blank">libyuv之linux编译</a>
                        <span class="text-muted">jaronho</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>文章目录一、下载源码二、编译源码三、注意事项1、银河麒麟系统(aarch64)(1)解决armv8-a+dotprod+i8mm指令集支持问题(2)解决armv9-a+sve2指令集支持问题一、下载源码到GitHub网站下载https://github.com/lemenkov/libyuv源码,或者用直接用git克隆到本地,如:gitclonehttps://github.com/lemenko</div>
                    </li>
                    <li><a href="/article/1835493247179386880.htm"
                           title="Faiss Tips:高效向量搜索与聚类的利器" target="_blank">Faiss Tips:高效向量搜索与聚类的利器</a>
                        <span class="text-muted">焦习娜Samantha</span>

                        <div>FaissTips:高效向量搜索与聚类的利器faiss_tipsSomeusefultipsforfaiss项目地址:https://gitcode.com/gh_mirrors/fa/faiss_tips项目介绍Faiss是由FacebookAIResearch开发的一个用于高效相似性搜索和密集向量聚类的库。它支持多种硬件平台,包括CPU和GPU,能够在海量数据集上实现快速的近似最近邻搜索(AN</div>
                    </li>
                    <li><a href="/article/1835491859351302144.htm"
                           title="Python 实现图片裁剪(附代码) | Python工具" target="_blank">Python 实现图片裁剪(附代码) | Python工具</a>
                        <span class="text-muted">剑客阿良_ALiang</span>

                        <div>前言本文提供将图片按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。环境依赖ffmpeg环境安装,可以参考我的另一篇文章:windowsffmpeg安装部署_阿良的博客-CSDN博客本文主要使用到的不是ffmpeg,而是ffprobe也在上面这篇文章中的zip包中。ffmpy安装:pipinstallffmpy-ihttps://pypi.douban.com/simple代码不废话了,上代码</div>
                    </li>
                    <li><a href="/article/1835489588169240576.htm"
                           title="ARM驱动学习之5 LEDS驱动" target="_blank">ARM驱动学习之5 LEDS驱动</a>
                        <span class="text-muted">JT灬新一</span>
<a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a><a class="tag" taget="_blank" href="/search/C/1.htm">C</a><a class="tag" taget="_blank" href="/search/%E5%BA%95%E5%B1%82/1.htm">底层</a><a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E7%89%87%E6%9C%BA/1.htm">单片机</a>
                        <div>ARM驱动学习之5LEDS驱动知识点:•linuxGPIO申请函数和赋值函数–gpio_request–gpio_set_value•三星平台配置GPIO函数–s3c_gpio_cfgpin•GPIO配置输出模式的宏变量–S3C_GPIO_OUTPUT注意点:DRIVER_NAME和DEVICE_NAME匹配。实现步骤:1.加入需要的头文件://Linux平台的gpio头文件#include//三</div>
                    </li>
                    <li><a href="/article/1835489207716507648.htm"
                           title="基于CODESYS的多轴运动控制程序框架:逻辑与运动控制分离,快速开发灵活操作" target="_blank">基于CODESYS的多轴运动控制程序框架:逻辑与运动控制分离,快速开发灵活操作</a>
                        <span class="text-muted">GPJnCrbBdl</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>基于codesys开发的多轴运动控制程序框架,将逻辑与运动控制分离,将单轴控制封装成功能块,对该功能块的操作包含了所有的单轴控制(归零、点动、相对定位、绝对定位、设置当前位置、伺服模式切换等等)。程序框架由主程序按照状态调用分归零模式、手动模式、自动模式、故障模式,程序状态的跳转都已完成,只需要根据不同的工艺要求完成所需的动作即可。变量的声明、地址的规划都严格按照C++的标准定义,能帮助开发者快速</div>
                    </li>
                    <li><a href="/article/1835489081480540160.htm"
                           title="C++ | Leetcode C++题解之第409题最长回文串" target="_blank">C++ | Leetcode C++题解之第409题最长回文串</a>
                        <span class="text-muted">Ddddddd_158</span>
<a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/Leetcode/1.htm">Leetcode</a><a class="tag" taget="_blank" href="/search/%E9%A2%98%E8%A7%A3/1.htm">题解</a>
                        <div>题目:题解:classSolution{public:intlongestPalindrome(strings){unordered_mapcount;intans=0;for(charc:s)++count[c];for(autop:count){intv=p.second;ans+=v/2*2;if(v%2==1andans%2==0)++ans;}returnans;}};</div>
                    </li>
                    <li><a href="/article/1835488955101966336.htm"
                           title="C++菜鸟教程 - 从入门到精通 第二节" target="_blank">C++菜鸟教程 - 从入门到精通 第二节</a>
                        <span class="text-muted">DreamByte</span>
<a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a>
                        <div>一.上节课的补充(数据类型)1.前言继上节课,我们主要讲解了输入,输出和运算符,我们现在来补充一下数据类型的知识上节课遗漏了这个知识点,非常的抱歉顺便说一下,博主要上高中了,更新会慢,2-4周更新一次对了,正好赶上中秋节,小编跟大家说一句:中秋节快乐!2.int类型上节课,我们其实只用了int类型int类型,是整数类型,它们存贮的是整数,不能存小数(浮点数)定义变量的方式很简单inta;//定义一</div>
                    </li>
                    <li><a href="/article/1835486185015832576.htm"
                           title="【无标题】达瓦达瓦" target="_blank">【无标题】达瓦达瓦</a>
                        <span class="text-muted">JhonKI</span>
<a class="tag" taget="_blank" href="/search/%E8%80%83%E7%A0%94/1.htm">考研</a>
                        <div>博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️‍111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️‍111❤️111111111111111总结11</div>
                    </li>
                    <li><a href="/article/1835486185468817408.htm"
                           title="上图为是否色发" target="_blank">上图为是否色发</a>
                        <span class="text-muted">JhonKI</span>
<a class="tag" taget="_blank" href="/search/%E8%80%83%E7%A0%94/1.htm">考研</a>
                        <div>博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️‍111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️‍111❤️111111111111111总结11</div>
                    </li>
                    <li><a href="/article/1835485681187647488.htm"
                           title="【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面" target="_blank">【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面</a>
                        <span class="text-muted">一个射手座的程序媛</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BAod/1.htm">华为od</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA%E5%92%8C%E5%8F%91%E5%B1%95/1.htm">职场和发展</a>
                        <div>最后的话最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!资料预览给大家整理的视频资料:给大家整理的电子书资料:如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以点击这里获</div>
                    </li>
                    <li><a href="/article/1835483159140069376.htm"
                           title="143234234123432" target="_blank">143234234123432</a>
                        <span class="text-muted">JhonKI</span>
<a class="tag" taget="_blank" href="/search/%E8%80%83%E7%A0%94/1.htm">考研</a>
                        <div>博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️‍111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️‍111❤️111111111111111总结11</div>
                    </li>
                    <li><a href="/article/1835482277870661632.htm"
                           title="简介Shell、zsh、bash" target="_blank">简介Shell、zsh、bash</a>
                        <span class="text-muted">zhaosuningsn</span>
<a class="tag" taget="_blank" href="/search/Shell/1.htm">Shell</a><a class="tag" taget="_blank" href="/search/zsh/1.htm">zsh</a><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a>
                        <div>Shell是Linux和Unix的外壳,类似衣服,负责外界与Linux和Unix内核的交互联系。例如接收终端用户及各种应用程序的命令,把接收的命令翻译成内核能理解的语言,传递给内核,并把内核处理接收的命令的结果返回给外界,即Shell是外界和内核沟通的桥梁或大门。Linux和Unix提供了多种Shell,其中有种bash,当然还有其他好多种。Mac电脑中不但有bash,还有一个zsh,预装的,据说</div>
                    </li>
                    <li><a href="/article/1835479000600899584.htm"
                           title="Linux MariaDB使用OpenSSL安装SSL证书" target="_blank">Linux MariaDB使用OpenSSL安装SSL证书</a>
                        <span class="text-muted">Meta39</span>
<a class="tag" taget="_blank" href="/search/MySQL/1.htm">MySQL</a><a class="tag" taget="_blank" href="/search/Oracle/1.htm">Oracle</a><a class="tag" taget="_blank" href="/search/MariaDB/1.htm">MariaDB</a><a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/Windows/1.htm">Windows</a><a class="tag" taget="_blank" href="/search/ssl/1.htm">ssl</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/mariadb/1.htm">mariadb</a>
                        <div>进入到证书存放目录,批量删除.pem证书警告:确保已经进入到证书存放目录find.-typef-iname\*.pem-delete查看是否安装OpenSSLopensslversion没有则安装yuminstallopensslopenssl-devel开启SSL编辑/etc/my.cnf文件(没有的话就创建,但是要注意,在/etc/my.cnf.d/server.cnf配置了datadir的,</div>
                    </li>
                    <li><a href="/article/1835477362700021760.htm"
                           title="Python中深拷贝与浅拷贝的区别" target="_blank">Python中深拷贝与浅拷贝的区别</a>
                        <span class="text-muted">yuxiaoyu.</span>

                        <div>转自:http://blog.csdn.net/u014745194/article/details/70271868定义:在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复</div>
                    </li>
                    <li><a href="/article/1835476350190841856.htm"
                           title="ExpRe[25] bash外的其它shell:zsh和fish" target="_blank">ExpRe[25] bash外的其它shell:zsh和fish</a>
                        <span class="text-muted">tritone</span>
<a class="tag" taget="_blank" href="/search/ExpRe/1.htm">ExpRe</a><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>文章目录zsh基础配置实用特性插件`autojump`语法高亮自动补全fish优点缺点时效性本篇撰写时间为2021.12.15,由于计算机技术日新月异,博客中所有内容都有时效和版本限制,具体做法不一定总行得通,链接可能改动失效,各种软件的用法可能有修改。但是其中透露的思想往往是值得学习的。本篇前置:ExpRe[10]Ubuntu[2]准备神秘软件、备份恢复软件https://www.cnblogs</div>
                    </li>
                                <li><a href="/article/20.htm"
                                       title="矩阵求逆(JAVA)初等行变换" target="_blank">矩阵求逆(JAVA)初等行变换</a>
                                    <span class="text-muted">qiuwanchi</span>
<a class="tag" taget="_blank" href="/search/%E7%9F%A9%E9%98%B5%E6%B1%82%E9%80%86%EF%BC%88JAVA%EF%BC%89/1.htm">矩阵求逆(JAVA)</a>
                                    <div>package gaodai.matrix;

import gaodai.determinant.DeterminantCalculation;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 矩阵求逆(初等行变换)
 * @author 邱万迟
 *</div>
                                </li>
                                <li><a href="/article/147.htm"
                                       title="JDK timer" target="_blank">JDK timer</a>
                                    <span class="text-muted">antlove</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/schedule/1.htm">schedule</a><a class="tag" taget="_blank" href="/search/code/1.htm">code</a><a class="tag" taget="_blank" href="/search/timer/1.htm">timer</a>
                                    <div>1.java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后执行任务 
2.java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务 
3.java.util.Timer.schedule(TimerTask task, long delay,longperiod</div>
                                </li>
                                <li><a href="/article/274.htm"
                                       title="JVM调优总结 -Xms -Xmx -Xmn -Xss" target="_blank">JVM调优总结 -Xms -Xmx -Xmn -Xss</a>
                                    <span class="text-muted">coder_xpf</span>
<a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a>
                                    <div>堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。 
 
典型设置:   
 
  
   
    java -Xmx</div>
                                </li>
                                <li><a href="/article/401.htm"
                                       title="JDBC连接数据库" target="_blank">JDBC连接数据库</a>
                                    <span class="text-muted">Array_06</span>
<a class="tag" taget="_blank" href="/search/jdbc/1.htm">jdbc</a>
                                    <div>package Util; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
 
 
public class JDBCUtil { 
 
 //完</div>
                                </li>
                                <li><a href="/article/528.htm"
                                       title="Unsupported major.minor version 51.0(jdk版本错误)" target="_blank">Unsupported major.minor version 51.0(jdk版本错误)</a>
                                    <span class="text-muted">oloz</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>java.lang.UnsupportedClassVersionError: cn/support/cache/CacheType : Unsupported major.minor version 51.0 (unable to load class cn.support.cache.CacheType) 
 at org.apache.catalina.loader.WebappClassL</div>
                                </li>
                                <li><a href="/article/655.htm"
                                       title="用多个线程处理1个List集合" target="_blank">用多个线程处理1个List集合</a>
                                    <span class="text-muted">362217990</span>
<a class="tag" taget="_blank" href="/search/%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">多线程</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/list/1.htm">list</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E5%90%88/1.htm">集合</a>
                                    <div>  昨天发了一个提问,启动5个线程将一个List中的内容,然后将5个线程的内容拼接起来,由于时间比较急迫,自己就写了一个Demo,希望对菜鸟有参考意义。。 
 
 


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public c</div>
                                </li>
                                <li><a href="/article/782.htm"
                                       title="JSP简单访问数据库" target="_blank">JSP简单访问数据库</a>
                                    <span class="text-muted">香水浓</span>
<a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a>
                                    <div>学习使用javaBean,代码很烂,仅为留个脚印 
 
 

public class DBHelper {

	private String driverName;
	private String url;
	private String user;
	private String password;
	private Connection connection;
	privat</div>
                                </li>
                                <li><a href="/article/909.htm"
                                       title="Flex4中使用组件添加柱状图、饼状图等图表" target="_blank">Flex4中使用组件添加柱状图、饼状图等图表</a>
                                    <span class="text-muted">AdyZhang</span>
<a class="tag" taget="_blank" href="/search/Flex/1.htm">Flex</a>
                                    <div>1.添加一个最简单的柱状图       
?       1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28      
<?xml version= 
"1.0"&n</div>
                                </li>
                                <li><a href="/article/1036.htm"
                                       title="Android 5.0 - ProgressBar 进度条无法展示到按钮的前面" target="_blank">Android 5.0 - ProgressBar 进度条无法展示到按钮的前面</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>在低于SDK < 21 的版本中,ProgressBar 可以展示到按钮前面,并且为之在按钮的中间,但是切换到android 5.0后进度条ProgressBar 展示顺序变化了,按钮再前面,ProgressBar 在后面了我的xml配置文件如下: 
     
[html]  
view plain 
copy       
 
 <RelativeLa</div>
                                </li>
                                <li><a href="/article/1163.htm"
                                       title="查询汇总的sql" target="_blank">查询汇总的sql</a>
                                    <span class="text-muted">baalwolf</span>
<a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a>
                                    <div>select   list.listname, list.createtime,listcount from dream_list as list ,   (select listid,count(listid) as listcount  from dream_list_user  group by listid  order by count(</div>
                                </li>
                                <li><a href="/article/1290.htm"
                                       title="Linux du命令和df命令区别" target="_blank">Linux du命令和df命令区别</a>
                                    <span class="text-muted">BigBird2012</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>        1,两者区别      
       du,disk usage,是通过搜索文件来计算每个文件的大小然后累加,du能看到的文件只是一些当前存在的,没有被删除的。他计算的大小就是当前他认为存在的所有文件大小的累加和。 
       </div>
                                </li>
                                <li><a href="/article/1417.htm"
                                       title="AngularJS中的$apply,用还是不用?" target="_blank">AngularJS中的$apply,用还是不用?</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a><a class="tag" taget="_blank" href="/search/%24apply/1.htm">$apply</a>
                                    <div>        在AngularJS开发中,何时应该调用$scope.$apply(),何时不应该调用。下面我们透彻地解释这个问题。 
        但是首先,让我们把$apply转换成一种简化的形式。 
        scope.$apply就像一个懒惰的工人。它需要按照命</div>
                                </li>
                                <li><a href="/article/1544.htm"
                                       title="[Zookeeper学习笔记十]Zookeeper源代码分析之ClientCnxn数据序列化和反序列化" target="_blank">[Zookeeper学习笔记十]Zookeeper源代码分析之ClientCnxn数据序列化和反序列化</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a>
                                    <div>ClientCnxn是Zookeeper客户端和Zookeeper服务器端进行通信和事件通知处理的主要类,它内部包含两个类,1. SendThread 2. EventThread, SendThread负责客户端和服务器端的数据通信,也包括事件信息的传输,EventThread主要在客户端回调注册的Watchers进行通知处理 
  
ClientCnxn构造方法 
  
&</div>
                                </li>
                                <li><a href="/article/1671.htm"
                                       title="【Java命令一】jmap" target="_blank">【Java命令一】jmap</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/Java%E5%91%BD%E4%BB%A4/1.htm">Java命令</a>
                                    <div>jmap命令的用法: 
  
[hadoop@hadoop sbin]$ jmap
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a </div>
                                </li>
                                <li><a href="/article/1798.htm"
                                       title="Apache 服务器安全防护及实战" target="_blank">Apache 服务器安全防护及实战</a>
                                    <span class="text-muted">ronin47</span>

                                    <div>此文转自IBM. 
Apache 服务简介 
Web 服务器也称为 WWW 服务器或 HTTP 服务器 (HTTP Server),它是 Internet 上最常见也是使用最频繁的服务器之一,Web 服务器能够为用户提供网页浏览、论坛访问等等服务。 
由于用户在通过 Web 浏览器访问信息资源的过程中,无须再关心一些技术性的细节,而且界面非常友好,因而 Web 在 Internet 上一推出就得到</div>
                                </li>
                                <li><a href="/article/1925.htm"
                                       title="unity 3d实例化位置出现布置?" target="_blank">unity 3d实例化位置出现布置?</a>
                                    <span class="text-muted">brotherlamp</span>
<a class="tag" taget="_blank" href="/search/unity%E6%95%99%E7%A8%8B/1.htm">unity教程</a><a class="tag" taget="_blank" href="/search/unity/1.htm">unity</a><a class="tag" taget="_blank" href="/search/unity%E8%B5%84%E6%96%99/1.htm">unity资料</a><a class="tag" taget="_blank" href="/search/unity%E8%A7%86%E9%A2%91/1.htm">unity视频</a><a class="tag" taget="_blank" href="/search/unity%E8%87%AA%E5%AD%A6/1.htm">unity自学</a>
                                    <div>问:unity 3d实例化位置出现布置? 
答:实例化的同时就可以指定被实例化的物体的位置,即 position   
Instantiate (original : Object, position : Vector3, rotation : Quaternion) : Object 
这样你不需要再用Transform.Position了, 
  
如果你省略了第二个参数(</div>
                                </li>
                                <li><a href="/article/2052.htm"
                                       title="《重构,改善现有代码的设计》第八章 Duplicate Observed Data" target="_blank">《重构,改善现有代码的设计》第八章 Duplicate Observed Data</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%87%8D%E6%9E%84/1.htm">重构</a>
                                    <div>
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusE</div>
                                </li>
                                <li><a href="/article/2179.htm"
                                       title="struts2更改struts.xml配置目录" target="_blank">struts2更改struts.xml配置目录</a>
                                    <span class="text-muted">chiangfai</span>
<a class="tag" taget="_blank" href="/search/struts.xml/1.htm">struts.xml</a>
                                    <div>struts2默认是读取classes目录下的配置文件,要更改配置文件目录,比如放在WEB-INF下,路径应该写成../struts.xml(非/WEB-INF/struts.xml) 
web.xml文件修改如下: 
  
<filter>
<filter-name>struts2</filter-name>
<filter-class&g</div>
                                </li>
                                <li><a href="/article/2306.htm"
                                       title="redis做缓存时的一点优化" target="_blank">redis做缓存时的一点优化</a>
                                    <span class="text-muted">chenchao051</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a><a class="tag" taget="_blank" href="/search/pipeline/1.htm">pipeline</a>
                                    <div>  
      最近集群上有个job,其中需要短时间内频繁访问缓存,大概7亿多次。我这边的缓存是使用redis来做的,问题就来了。 
      首先,redis中存的是普通kv,没有考虑使用hash等解结构,那么以为着这个job需要访问7亿多次redis,导致效率低,且出现很多redi</div>
                                </li>
                                <li><a href="/article/2433.htm"
                                       title="mysql导出数据不输出标题行" target="_blank">mysql导出数据不输出标题行</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%87%BA/1.htm">数据导出</a><a class="tag" taget="_blank" href="/search/%E5%8E%BB%E6%8E%89%E7%AC%AC%E4%B8%80%E8%A1%8C/1.htm">去掉第一行</a><a class="tag" taget="_blank" href="/search/%E5%8E%BB%E6%8E%89%E6%A0%87%E9%A2%98/1.htm">去掉标题</a>
                                    <div>当想使用数据库中的某些数据,想将其导入到文件中,而想去掉第一行的标题是可以加上-N参数 
 
如通过下面命令导出数据: 
mysql -uuserName -ppasswd -hhost -Pport -Ddatabase -e " select * from tableName"  > exportResult.txt 
 
结果为: 
 
studentid</div>
                                </li>
                                <li><a href="/article/2560.htm"
                                       title="phpexcel导出excel表简单入门示例" target="_blank">phpexcel导出excel表简单入门示例</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/Excel/1.htm">Excel</a><a class="tag" taget="_blank" href="/search/phpexcel/1.htm">phpexcel</a>
                                    <div>先下载PHPEXCEL类文件,放在class目录下面,然后新建一个index.php文件,内容如下 
<?php 
error_reporting(E_ALL); 
ini_set('display_errors', TRUE); 
ini_set('display_startup_errors', TRUE); 
  
if (PHP_SAPI == 'cli') 
 die('</div>
                                </li>
                                <li><a href="/article/2687.htm"
                                       title="爱情格言" target="_blank">爱情格言</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/%E6%A0%BC%E8%A8%80/1.htm">格言</a>
                                    <div> 1) I love you not because of who you are, but because of who I am when I am with you.    我爱你,不是因为你是一个怎样的人,而是因为我喜欢与你在一起时的感觉。   2) No man or woman is worth your tears, and the one who is, won‘t</div>
                                </li>
                                <li><a href="/article/2814.htm"
                                       title="转 Activity 详解——Activity文档翻译" target="_blank">转 Activity 详解——Activity文档翻译</a>
                                    <span class="text-muted">e200702084</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/UI/1.htm">UI</a><a class="tag" taget="_blank" href="/search/sqlite/1.htm">sqlite</a><a class="tag" taget="_blank" href="/search/%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86/1.htm">配置管理</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%BA%94%E7%94%A8/1.htm">网络应用</a>
                                    <div>activity 展现在用户面前的经常是全屏窗口,你也可以将 activity 作为浮动窗口来使用(使用设置了 windowIsFloating 的主题),或者嵌入到其他的 activity (使用 ActivityGroup )中。 当用户离开 activity 时你可以在 onPause() 进行相应的操作 。更重要的是,用户做的任何改变都应该在该点上提交 ( 经常提交到 ContentPro</div>
                                </li>
                                <li><a href="/article/2941.htm"
                                       title="win7安装MongoDB服务" target="_blank">win7安装MongoDB服务</a>
                                    <span class="text-muted">geeksun</span>
<a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a>
                                    <div>1.  下载MongoDB的windows版本:mongodb-win32-x86_64-2008plus-ssl-3.0.4.zip,Linux版本也在这里下载,下载地址: http://www.mongodb.org/downloads 
  
2.  解压MongoDB在D:\server\mongodb, 在D:\server\mongodb下创建d</div>
                                </li>
                                <li><a href="/article/3068.htm"
                                       title="Javascript魔法方法:__defineGetter__,__defineSetter__" target="_blank">Javascript魔法方法:__defineGetter__,__defineSetter__</a>
                                    <span class="text-muted">hongtoushizi</span>
<a class="tag" taget="_blank" href="/search/js/1.htm">js</a>
                                    <div>转载自: http://www.blackglory.me/javascript-magic-method-definegetter-definesetter/ 
在javascript的类中,可以用defineGetter和defineSetter_控制成员变量的Get和Set行为 
例如,在一个图书类中,我们自动为Book加上书名符号: 
function Book(name){  </div>
                                </li>
                                <li><a href="/article/3195.htm"
                                       title="错误的日期格式可能导致走nginx proxy cache时不能进行304响应" target="_blank">错误的日期格式可能导致走nginx proxy cache时不能进行304响应</a>
                                    <span class="text-muted">jinnianshilongnian</span>
<a class="tag" taget="_blank" href="/search/cache/1.htm">cache</a>
                                    <div>昨天在整合某些系统的nginx配置时,出现了当使用nginx cache时无法返回304响应的情况,出问题的响应头:    Content-Type:text/html; charset=gb2312   Date:Mon, 05 Jan 2015 01:58:05 GMT   Expires:Mon , 05 Jan 15 02:03:00 GMT   Last-Modified:Mon, 05</div>
                                </li>
                                <li><a href="/article/3322.htm"
                                       title="数据源架构模式之行数据入口" target="_blank">数据源架构模式之行数据入口</a>
                                    <span class="text-muted">home198979</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/%E8%A1%8C%E6%95%B0%E6%8D%AE%E5%85%A5%E5%8F%A3/1.htm">行数据入口</a>
                                    <div>注:看不懂的请勿踩,此文章非针对java,java爱好者可直接略过。 
  
一、概念 
行数据入口(Row Data Gateway):充当数据源中单条记录入口的对象,每行一个实例。 
  
二、简单实现行数据入口 
为了方便理解,还是先简单实现: 
<?php
/**
 * 行数据入口类
 */
class OrderGateway {
    /*定义元数</div>
                                </li>
                                <li><a href="/article/3449.htm"
                                       title="Linux各个目录的作用及内容" target="_blank">Linux各个目录的作用及内容</a>
                                    <span class="text-muted">pda158</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a>
                                    <div>1)根目录“/”     根目录位于目录结构的最顶层,用斜线(/)表示,类似于 
Windows 
操作系统的“C:\“,包含Fedora操作系统中所有的目录和文件。     2)/bin     /bin     目录又称为二进制目录,包含了那些供系统管理员和普通用户使用的重要 
linux命令的二进制映像。该目录存放的内容包括各种可执行文件,还有某些可执行文件的符号连接。常用的命令有:cp、d</div>
                                </li>
                                <li><a href="/article/3576.htm"
                                       title="ubuntu12.04上编译openjdk7" target="_blank">ubuntu12.04上编译openjdk7</a>
                                    <span class="text-muted">ol_beta</span>
<a class="tag" taget="_blank" href="/search/HotSpot/1.htm">HotSpot</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/OpenJDK/1.htm">OpenJDK</a>
                                    <div>获取源码  
 从openjdk代码仓库获取(比较慢) 
 
 安装mercurial Mercurial是一个版本管理工具。   sudo apt-get install mercurial    
 将以下内容添加到$HOME/.hgrc文件中,如果没有则自己创建一个: [extensions] forest=/home/lichengwu/hgforest-crew/forest.py fe</div>
                                </li>
                                <li><a href="/article/3703.htm"
                                       title="将数据库字段转换成设计文档所需的字段" target="_blank">将数据库字段转换成设计文档所需的字段</a>
                                    <span class="text-muted">vipbooks</span>
<a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a>
                                    <div>        哈哈,出差这么久终于回来了,回家的感觉真好! 
        PowerDesigner的物理数据库一出来,设计文档中要改的字段就多得不计其数,如果要把PowerDesigner中的字段一个个Copy到设计文档中,那将会是一件非常痛苦的事情。</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>