-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
211 lines (99 loc) · 123 KB
/
local-search.xml
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>xb</title>
<link href="/2023/03/21/xb/"/>
<url>/2023/03/21/xb/</url>
<content type="html"><![CDATA[<p>你好,hyx</p>]]></content>
</entry>
<entry>
<title>光照归一化</title>
<link href="/2023/03/20/%E5%85%89%E7%85%A7%E5%BD%92%E4%B8%80%E5%8C%96/"/>
<url>/2023/03/20/%E5%85%89%E7%85%A7%E5%BD%92%E4%B8%80%E5%8C%96/</url>
<content type="html"><![CDATA[<h1 id="时序光照化处理"><a href="#时序光照化处理" class="headerlink" title="时序光照化处理"></a>时序光照化处理</h1><blockquote><p>不同时序采集同一地点的图片,并对不同的光照条件下的照片进行归一化处理。无标准图时就采集三分量分别进行处理,有标准图时需要将前景背景分离,对背景进行标准图的归一化,并且将前景图做相同的映射,之后将背景前景结合</p></blockquote><h2 id="函数接口"><a href="#函数接口" class="headerlink" title="函数接口"></a>函数接口</h2><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs matlab">rgb = gammaadapter(im)<br>功能:预处理、光照均一化<br>im:输入原图像<br>rgb:输出光照均一化图像,RGB格式<br><br>[dectResult,imageResult ]= imageRecognize( forImage,nowImage )<br>功能:前景识别<br>forImage为已知确定的标准图(或者为空) H*L*<span class="hljs-number">3</span><br>nowImage为当前帧图像 H*L*<span class="hljs-number">3</span><br>dectResult为识别结果(<span class="hljs-number">1</span>为有前景帧,<span class="hljs-number">0</span>无前景帧) <br>imageResult为做差结果图像(仅当dectResult为<span class="hljs-number">0</span>时有值)H*L*<span class="hljs-number">3</span> 若dectResult为<span class="hljs-number">1</span>则时第一帧<br><br>objIm= getObj(isObj, subIm)<br>功能:分离前景与背景,构造表示前景的二值图像<br>isObj为是否有前景,subIm为差值图像<br>objIm为表示前景的二值图像,<span class="hljs-number">1</span>为前景,<span class="hljs-number">0</span>为背景<br><br>outIm = HistogramSpecification(I,withObj,Obj,StdIm)<br>功能:图像光照的规定化<br>I:光照均一化后的目标图像(RGB格式,h*l*<span class="hljs-number">3</span> uint8类型矩阵)<br>withObj:前景指示变量,有前景为<span class="hljs-number">1</span>,无前景为<span class="hljs-number">0</span>,逻辑型变量;<br>Obj:前景二值图像,前景为<span class="hljs-number">1</span>,背景为<span class="hljs-number">0</span>;<br>StdIm:标准图像(RGB格式,h*l*<span class="hljs-number">3</span> uint8类型矩阵)<br>outIm:规定化输出<br></code></pre></td></tr></table></figure><h2 id="归一化-基于二维伽马函数的光照不均匀图像自适应矫正算法"><a href="#归一化-基于二维伽马函数的光照不均匀图像自适应矫正算法" class="headerlink" title="归一化-基于二维伽马函数的光照不均匀图像自适应矫正算法"></a>归一化-基于二维伽马函数的光照不均匀图像自适应矫正算法</h2><h3 id="算法描述"><a href="#算法描述" class="headerlink" title="算法描述"></a>算法描述</h3><p>利用多尺度高斯函数提取出场景的光照分量,构造一种二维伽马函数,利用光照分量的分布特征调整二维伽马函数的参数,降低光照过强区域图像的亮度值,提高地区域的亮度值,实现对光照不均匀图像的自适应矫正出处理</p><h3 id="算法具体描述"><a href="#算法具体描述" class="headerlink" title="算法具体描述"></a>算法具体描述</h3><h4 id="基于多尺度高斯函数的光照分量的提取"><a href="#基于多尺度高斯函数的光照分量的提取" class="headerlink" title="基于多尺度高斯函数的光照分量的提取"></a><strong>基于<em>多尺度高斯函数</em>的光照分量的提取</strong></h4><p>做出如下假设:真实场景中光照分量主要集中在图像的低频部分并且整体变化平缓;反射分量主要集中在图像高频部分,如边缘纹理,变化比较剧烈</p><p>希望提取出的场景的光照分量只包含光照变化信息,不包含图像细节,多尺度的高斯函数可以压缩动态范围并且准确估计场景的照射分从量,所以我们选择了这个方法</p><p>用高斯函数和原图像做卷积,得到光照分量的估计值</p><p><strong>高斯函数的尺度因子c</strong></p><p>c越大,卷积核范围越大,色调保持能力增强</p><p>为了兼顾光照值得全局特性和局部特性,本实验选择了多尺度高斯函数,不同尺度的高斯函数分别提取出场景的光照分量后进行加权,最终可以得到光照分量的估计值</p><p>考虑到光照分量提取的精度和运算量之间的均衡,本实验N=3,用三个不同尺度的高斯函数提取光照分量的值,并且权值都为1/3</p><p><strong>高斯卷积核尺寸</strong></p><p>卷积核尺寸取图像的宽和高中较小的,根据提取光照分量的模糊程度</p><h4 id="基于二维伽马函数的自适应亮度调整"><a href="#基于二维伽马函数的自适应亮度调整" class="headerlink" title="基于二维伽马函数的自适应亮度调整"></a><strong>基于二维<em>伽马函数</em>的自适应亮度调整</strong></h4><p>提取出场景的光照分量后,根据光照分量的分布特性,构造光照不均匀矫正函数。二维伽马函数就是求校正后输出图像的亮度值。为了避免RGB通道的影响,此处需要转换成HSV色彩空间进行,然后对分量V进行处理,最后HSV格式转换回RGB</p><img src="http://rrtf9ky5u.hn-bkt.clouddn.com/%E5%85%89%E7%85%A7%E5%A4%84%E7%90%86/01.jpg?e=1679311200&token=-yM0p6PmumD5CJ6pZXN2SSy0Cp3oEs90-FVlB7rQ:SLxQHub78ZivzkDjSftTKOjnRNc=" alt="光照均一化算法流程图" style="zoom: 50%;" /><h2 id="前景检测"><a href="#前景检测" class="headerlink" title="前景检测"></a>前景检测</h2><blockquote><p>对于当前图像和采集的时序相邻的前一图像,进行三通道做差,之后将差的结果作为输出结果传出,并继续对做差结果进行处理。</p></blockquote><p>首先进行三通道的中值滤波,去除一些噪声;然后对三通道分别求均值;之后去除有最大均值的通道,将两通道与均值先做差再进行绝对值相加;最后得到的值与预先设定的阈值进行比较,判断是否为前景图像</p><h2 id="物体分离"><a href="#物体分离" class="headerlink" title="物体分离"></a>物体分离</h2><blockquote><p>对得到的差值图像进行分割前景与背景,由于前景是变化的物体,背景为不变的物体,因此差值图像中背景所在的像素差值比较小,通过这个可以采用全局分割的方法。</p></blockquote><p><em>ps:阈值处理在图像分割中占有非常重要的地位,一般而言我们可以选择的阈值处理方式有两种,分别是基本的全局阈值处理和利用Otsu方法进行最佳全局阈值处理。前者采用了迭代的思想进行阈值处理,后者则利用了方差最大化的思想进行处理。当图像直方图中具有明显的波谷或者说波峰之间的分界十分明显时,采用基本的全局阈值处理往往可以很好的解决问题;但是如果直方图不能满足上述需求,则应采用Otsu方法进行最佳的全局阈值处理。</em></p><p>对差值图像RGB三个通道采用<strong>otsu最佳全局阈值处理进行图像分割</strong>,此处选择分别对三通道进行分割,而不是转换成灰度图。因为转换成灰度图可能颜色完全不同的两个物品灰度类似,难以区分。</p><p>otsu找到<strong>一个阈值k使得类间方差最大</strong>,遍历灰度值2-255求对应的类间方差,找到类间方差最大的一个或者多个k,对于一个k直接将其作为分割阈值,多个就找最小的k,保证前景分割彻底。</p><p>获得三通道的分割阈值后<strong>分别对三通道图像进行二值化处理</strong>,将处理后的结果进行<strong>或运算</strong>得到最终表示<strong>前景的二值图像</strong></p><img src="http://rrtf9ky5u.hn-bkt.clouddn.com/%E5%85%89%E7%85%A7%E5%A4%84%E7%90%86/02.png?e=1679311216&token=-yM0p6PmumD5CJ6pZXN2SSy0Cp3oEs90-FVlB7rQ:abMSpFEN83THYpJuA3K8s9k0bjo=" alt="物体分离框图" style="zoom: 67%;" /><h2 id="光照恒定"><a href="#光照恒定" class="headerlink" title="光照恒定"></a>光照恒定</h2><blockquote><p>对于前景和背景,光照分布不同,采用分离处理的方式。提取标准图背景,学习输入图像到标准图背景的像素映射函数;再将输入图像的前景进行相同映射,将前景背景合并得到最终结果</p></blockquote><h3 id="直方图规定化步骤"><a href="#直方图规定化步骤" class="headerlink" title="直方图规定化步骤"></a>直方图规定化步骤</h3><p>1.初始化数据</p><p>2.根据前景检测和前景分离的结果,从目标图像上分离前景、背景</p><p>3.计算背景直方图分布,处理目标背景</p><p>4.计算背景各通道直方图规定变换,处理前景RGB三通道像素亮度值</p><p>5.合并前景、背景</p><h3 id="图像规定化"><a href="#图像规定化" class="headerlink" title="图像规定化"></a>图像规定化</h3><p>将一幅图像的直方图变换成规定形状的直方图,从而间接实现图像灰度变换。</p><p>统计灰度分布概率密度函数,根据直方图规定化,找到原始图像到目标图像的变换关系:</p><p>1.对原始图像进行均衡化处理</p><p>2.对目标图像也进行同样方法的均衡化处理</p><p>3.找到目标图像变换的逆变换</p><p>4.通过同样的变换就可以找到原始图像到目标图像的灰度级</p><h2 id="其他分析"><a href="#其他分析" class="headerlink" title="其他分析"></a>其他分析</h2><h3 id="对最大均值通道去除的必要性"><a href="#对最大均值通道去除的必要性" class="headerlink" title="对最大均值通道去除的必要性"></a>对最大均值通道去除的必要性</h3><p>去除最大均值通道后,对背景的敏感度下降,降低了误判的风险,并且可以保证对前景物体有较高的识别能力</p><h3 id="中值滤波处理"><a href="#中值滤波处理" class="headerlink" title="中值滤波处理"></a>中值滤波处理</h3><p>未进行中值滤波的图像,差值图像会因为抖动或者光照在边缘的特殊影响导致会出现“白边”,也就是响应值较高的点,这也是噪声的一种,会容易导致识别的结果出错。</p><h3 id="前景提取对三通道分别进行阈值切割"><a href="#前景提取对三通道分别进行阈值切割" class="headerlink" title="前景提取对三通道分别进行阈值切割"></a>前景提取对三通道分别进行阈值切割</h3><p>采用阈值分割对两幅图像的差值图像提取出前景,即变化的像素</p><p>由于阈值分割不能直接对彩色图像进行处理,因此,第一个想法就是将彩色图转成灰度图,但是这样做会损失细节,在彩色图像中,黑色的电视与红色的上衣颜色明显不同,但转成灰度图像后,二者的灰度值差距较小</p><p>因此为了尽可能利用图像的细节,对RGB三通道分别进行阈值分割,并将三通道的结果做或运算得出最终的结果。分别采用对灰度图进行阈值分割和对RGB三通道进行阈值分割进行对比,对灰度图进行阈值分割,可以看到电视部分被认为与上衣类似,为对RGB三通道分别进行阈值分割(再结合),效果优于灰度图的效果</p>]]></content>
<tags>
<tag>课设</tag>
</tags>
</entry>
<entry>
<title>离散数学</title>
<link href="/2023/03/14/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/"/>
<url>/2023/03/14/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/</url>
<content type="html"><![CDATA[<h4 id="什么是偏序,什么是等价"><a href="#什么是偏序,什么是等价" class="headerlink" title="什么是偏序,什么是等价"></a>什么是偏序,什么是等价</h4><p>偏序是指自反,反对称,传递的关系;等价是指自反,对称,传递的关系</p><h4 id="偏序,全序,良序的定义"><a href="#偏序,全序,良序的定义" class="headerlink" title="偏序,全序,良序的定义"></a>偏序,全序,良序的定义</h4><p>偏序:关系满足自反性,反对称性,传递性</p><p>全序:特殊的偏序,要求集合中所有元素都满足关系R</p><p>良序:任一偏序集合,假如它的每一非空子集存在最小元素,这种偏序集叫良序</p><h4 id="公理系统包括什么"><a href="#公理系统包括什么" class="headerlink" title="公理系统包括什么"></a>公理系统包括什么</h4><p>公理系统,或称作公理化系统,公理体系,公理化体系,是一个公理的集合,从中一些或全部公理可以用来一起逻辑的导出定理</p><p>公理系统是指从事先给定的公理出发,根据推理规则推导出一系列定理,由此而形成的演绎系统</p><h4 id="一阶逻辑可判定吗"><a href="#一阶逻辑可判定吗" class="headerlink" title="一阶逻辑可判定吗"></a>一阶逻辑可判定吗</h4><p>不可以 如所有人都会呼吸,无法判断正确与否</p><h4 id="关系和函数"><a href="#关系和函数" class="headerlink" title="关系和函数"></a>关系和函数</h4><p>函数是不完全关系,它可以表示一对一和多对一关系,由于函数对于一个有效的x只能有一个确定的输出y,因此函数不能表示关系中的一对多关系</p><h4 id="偏序关系和全序关系,举例"><a href="#偏序关系和全序关系,举例" class="headerlink" title="偏序关系和全序关系,举例"></a>偏序关系和全序关系,举例</h4><p>偏序关系是具有自反反对称和传递性的关系</p><p>全序关系是非空集合A中任意两个元素都可比,都满足关系R</p><p>比如在大小关系中,实数集满足全序,复数集满足偏序</p><h4 id="离散数学中的二元关系是什么"><a href="#离散数学中的二元关系是什么" class="headerlink" title="离散数学中的二元关系是什么"></a>离散数学中的二元关系是什么</h4><p>如果一个集合为空集或者它的元素都是有序对,那么这个集合是一个二元关系</p><h4 id="真命题怎么判断"><a href="#真命题怎么判断" class="headerlink" title="真命题怎么判断"></a>真命题怎么判断</h4><p>陈述句+成真</p><h4 id="命题的逆否命题是什么"><a href="#命题的逆否命题是什么" class="headerlink" title="命题的逆否命题是什么"></a>命题的逆否命题是什么</h4><p>若p则q,若非q则非p</p><h4 id="介绍一下公理系统"><a href="#介绍一下公理系统" class="headerlink" title="介绍一下公理系统"></a>介绍一下公理系统</h4><p>公理系统是指从事先给定的公理出发,根据推理规则推导出一系列定理,由此而形成的演绎系统</p><p>公理系统具有完备性,自洽性,独立性</p><h4 id="命题逻辑中的完备和可靠"><a href="#命题逻辑中的完备和可靠" class="headerlink" title="命题逻辑中的完备和可靠"></a>命题逻辑中的完备和可靠</h4><p>|-推理出 |=推理正确</p><p>1-可靠性(Soundness):【|-】的存在,是【|=】存在的充分条件。这样,其逆反定理是:如果【|=】的不存在,则【|-】的不存在。逆反定理用于证明【|-】不存在。</p><p>可靠性定理:令 φ1, φ2, …, φn 和 ψ 为命题逻辑中的公式,如果 φ1, φ2, …, φn |- ψ 是有效的, 那么 φ1, φ2, …, φn |= ψ 是有效的。</p><p>2-完备性(Completeness):【|=】的存在,是【|-】存在的充分条件。通过【|=】的存在,证明【|-】的存在。</p><p>完备性定理:令 φ1, φ2, …, φn 和 ψ 为命题逻辑中的公式,如果 φ1, φ2, …, φn |= ψ 是有效的, 那么 φ1, φ2, …, φn |- ψ 是有效的。</p><p>3-可靠性(Soundness)用于证明【|-】不存在,完备性(Completeness)用于证明【|-】存在。</p><h4 id="命题的可判定性"><a href="#命题的可判定性" class="headerlink" title="命题的可判定性"></a>命题的可判定性</h4><p>存在一种算法能给出该命题成立与否的结论</p><h4 id="什么是集合"><a href="#什么是集合" class="headerlink" title="什么是集合"></a>什么是集合</h4><p>集合是一些对象的主体,对象有时也可以看作元素或成员</p><h4 id="笛卡尔积的性质"><a href="#笛卡尔积的性质" class="headerlink" title="笛卡尔积的性质"></a>笛卡尔积的性质</h4><p>不满足交换律,结合律,对并和交运算满足分配律</p><h4 id="主析取范式是什么"><a href="#主析取范式是什么" class="headerlink" title="主析取范式是什么"></a>主析取范式是什么</h4><p>若干个极小项的析取。极小项就是包含全部数目的命题变元的合取表达式,每个命题变元都出现并只出现一次</p><h4 id="数理逻辑在计算机学科中的应用"><a href="#数理逻辑在计算机学科中的应用" class="headerlink" title="数理逻辑在计算机学科中的应用"></a>数理逻辑在计算机学科中的应用</h4><p>专家系统和知识工程的出现使人们认识到仅仅研究那些从真前提得出真结果的那种古典逻辑推理的方法是不够的,因为人类生活在一个充满不确定信息的环境里,进行着有效的推理。因此,为了建立真正的智能系统,研究那些更接近人类思维方式的非单调推理、模糊推理等就变得越来越必要了,非经典逻辑应运而生。<strong>非经典逻辑</strong>一般指直觉逻辑、模糊逻辑、多值逻辑等。这些可以用计算机程序设计语言实现。计算机程序设计语言的理论基础是形式语言、自动机和形式语义学,数理逻辑的推理理论为二者提供了主要的思想和方法,程序设计语言中的许多机制和方法,如子程序调用中的参数代换,赋值等都出自数理逻辑的方法。推理是人工智能研究的主要工作,逻辑的思想就是通过一些已知的前提推理出未知的结论。</p><p>著名的n皇后问题,就是一个很好的例子,数理逻辑可以把计算机科学中表面上看似不相干的内容通过找出其内在逻辑作为前提,利用数理逻辑中的推理理论得到结论。</p><h4 id="离散数学中的最短路径算法?这两种算法的时间复杂度?存在负边时应该选用哪种算法?"><a href="#离散数学中的最短路径算法?这两种算法的时间复杂度?存在负边时应该选用哪种算法?" class="headerlink" title="离散数学中的最短路径算法?这两种算法的时间复杂度?存在负边时应该选用哪种算法?"></a>离散数学中的最短路径算法?这两种算法的时间复杂度?存在负边时应该选用哪种算法?</h4><p>dijkstra floyd算法</p><p>前者为n平方,后者n立方</p><p>floyd算法</p><h4 id="无穷集合的势,如何判定两个集合等势"><a href="#无穷集合的势,如何判定两个集合等势" class="headerlink" title="无穷集合的势,如何判定两个集合等势"></a>无穷集合的势,如何判定两个集合等势</h4><p>阿列夫0与自然数一一兑现,阿列夫1与实数一一对应,等势就是构成双射</p><h4 id="一一对应在数学中怎么体现"><a href="#一一对应在数学中怎么体现" class="headerlink" title="一一对应在数学中怎么体现"></a>一一对应在数学中怎么体现</h4><p>双射</p><h4 id="最小生成树是什么"><a href="#最小生成树是什么" class="headerlink" title="最小生成树是什么"></a>最小生成树是什么</h4><p>在一给定的无向图G=(V,E)中,(u,v)代表连接顶点u与顶点v的边,而w(u,v)代表此边的权重,若存在T为E的子集且无循环图,使得w(T)最小,则此T为G的最小生成树</p><h4 id="公理系统的两个性质"><a href="#公理系统的两个性质" class="headerlink" title="公理系统的两个性质"></a>公理系统的两个性质</h4><p>公理系统是指从事先给定的公理出发,根据推理规则推导出一系列定理,由此形成的演绎系统</p><p>公理系统由符号集,公式集,公理集,推理规则集,定理集组成</p><p><strong>可靠性</strong>和<strong>完备性</strong>是公理系统的两个重要性质,如果公理系统的每个定理都是公设集的逻辑推论,就是只要公设都为真,每个定理就为真,那么公理系统是可靠的</p><p>如果公设集的每个逻辑推论都是公理系统的定理,能用推理规则由逻辑公理和公设推出,那么公理系统是完备的</p><p>还有<strong>协调性</strong>和<strong>独立性</strong>,能推出所有公式的公理系统称为不协调的公理系统。公理系统的协调性是基本要求</p><p>如果一个公理系统没有多余的公理模型和推理规则,去掉任何一个,定理都会减少,称这个公理系统是独立的。</p><h4 id="什么是偏序集"><a href="#什么是偏序集" class="headerlink" title="什么是偏序集"></a>什么是偏序集</h4><p>满足自反,反对称,传递性的关系</p><h4 id="用关系图怎么表示对称性,自反性"><a href="#用关系图怎么表示对称性,自反性" class="headerlink" title="用关系图怎么表示对称性,自反性"></a>用关系图怎么表示对称性,自反性</h4><p>自反性:有一个从自己出发到自己结束的箭头</p><p>对称性:如果a元素指向b,则也会有一个箭头从b指向a</p><h4 id="等价关系"><a href="#等价关系" class="headerlink" title="等价关系"></a>等价关系</h4><p>一个关系如果是自反的,对称,传递的,那么这个关系是等价</p><h4 id="单射,满射,双射"><a href="#单射,满射,双射" class="headerlink" title="单射,满射,双射"></a>单射,满射,双射</h4><p>从集合到集合的映射方面讨论</p><p>满射:值域y是满的,每个y都有x对应,不存在某个y没有x对应的情况</p><p>单射:一对一函数</p><p>双射:既是单射,也是满射</p><h4 id="偏序和全序关系的区别"><a href="#偏序和全序关系的区别" class="headerlink" title="偏序和全序关系的区别"></a>偏序和全序关系的区别</h4><p>全序是特殊的偏序,要求集合中所有元素都满足关系R</p><h4 id="等价关系的性质"><a href="#等价关系的性质" class="headerlink" title="等价关系的性质"></a>等价关系的性质</h4><p>自反 对称 传递</p><h4 id="什么是团"><a href="#什么是团" class="headerlink" title="什么是团"></a>什么是团</h4><p>团是图的完全子图</p><h4 id="单射双射与同态同构的关系"><a href="#单射双射与同态同构的关系" class="headerlink" title="单射双射与同态同构的关系"></a>单射双射与同态同构的关系</h4><p>两个代数具有相同的构成成分,两个代数的运算和常数必须遵循相同的规则,两个代数的载体有相同的基数,这种结构上的一致性称为同构</p><p>A和A’是具有相同成分的代数,h是一个函数,在h作用下,A的每一种运算都保持,h是A到A’的同态</p><h4 id="什么是欧拉图"><a href="#什么是欧拉图" class="headerlink" title="什么是欧拉图"></a>什么是欧拉图</h4><p>欧拉图是指通过图(无向图或者有向图)中所有边且每边仅通过一次,相应的回路称为欧拉回路,具有欧拉回路的图称为欧拉图,具有欧拉通路没有欧拉回路的图称为半欧拉图</p><h4 id="合取范式是什么"><a href="#合取范式是什么" class="headerlink" title="合取范式是什么"></a>合取范式是什么</h4><p>是命题公式的一种标准型,一些析取式合取</p><h4 id="归结法"><a href="#归结法" class="headerlink" title="归结法"></a>归结法</h4><p>把评论的结果进行概括和归纳的方法</p>]]></content>
</entry>
<entry>
<title>E</title>
<link href="/2023/03/11/E/"/>
<url>/2023/03/11/E/</url>
<content type="html"><![CDATA[<h3 id="英语部分"><a href="#英语部分" class="headerlink" title="英语部分"></a>英语部分</h3><p>keep secret for a while:)</p>]]></content>
</entry>
<entry>
<title>STL</title>
<link href="/2023/03/10/STL/"/>
<url>/2023/03/10/STL/</url>
<content type="html"><![CDATA[<h1 id="C-标准模板库介绍STL"><a href="#C-标准模板库介绍STL" class="headerlink" title="C++标准模板库介绍STL"></a>C++标准模板库介绍STL</h1><h2 id="vector"><a href="#vector" class="headerlink" title="vector"></a>vector</h2><p>向量,也是变长数组,该数组的长度会根据需要自动改变;vector还会用邻接表的方式存储图,这对于无法使用邻接矩阵(结点数太多),又不想使用邻接表的读者非常友好。</p><p>需要使用vector时,要添加</p><p><code>#include<vector></code></p><p><code>using namespace std;</code></p><h4 id="vector的定义"><a href="#vector的定义" class="headerlink" title="vector的定义"></a>vector的定义</h4><p><code>vector <typename> name;</code></p><p>其中的typename可以是任何基本类型,也可以是stl标准容器,例如vector、set、queue等,<strong>如果typename也是一个stl容器,定义的时候要在>>符号之间加上空格</strong>,因为有的编译器会把符号当成移位操作</p><p>如<code>vector<vector<int>> name;</code></p><p>定义vector数组</p><p><code>vector <typename> ArrayName[arraysize]</code></p><p>这种定义方法不同的是,外面的一维已经是定长arraysize了,只有内部才是变长</p><h4 id="vector容器内元素的访问"><a href="#vector容器内元素的访问" class="headerlink" title="vector容器内元素的访问"></a>vector容器内元素的访问</h4><h5 id="通过下标访问"><a href="#通过下标访问" class="headerlink" title="通过下标访问"></a>通过下标访问</h5><p>和普通一维数组相同</p><h5 id="通过迭代器访问"><a href="#通过迭代器访问" class="headerlink" title="通过迭代器访问"></a>通过迭代器访问</h5><p>迭代器(iterator)类似指针</p><p><code>vector<typename>::iterator it;</code>可以通过*it来访问vector内的元素</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs c++">vector<<span class="hljs-type">int</span>> vi;<br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = i; i <= <span class="hljs-number">5</span>;i++){<br> vi.<span class="hljs-built_in">push_back</span>(i);<br>}<br>vector<<span class="hljs-type">int</span>>::iterator it = vi.<span class="hljs-built_in">begin</span>();<br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">5</span>;i++){<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d"</span>, *(it + i));<br>}<br></code></pre></td></tr></table></figure><p>vi[i]和*(vi.begin()+i)是等价的</p><p>begin()函数取首元素的地址;end()函数取尾元素的下一个地址</p><p>迭代器还有两种自加操作</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">for</span>(vector<<span class="hljs-type">int</span>>::iterator it=vi.<span class="hljs-built_in">begin</span>();it!=vi.<span class="hljs-built_in">end</span>();it++){<br><span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d"</span>,*it);<br>}<span class="hljs-comment">//不支持it<vi.end()的写法,只能用不等于</span><br></code></pre></td></tr></table></figure><p>在常用的STL容器中,只有在vector和string中,才允许使用vi.begin()+3这种加整数的写法</p><h4 id="vector常用函数"><a href="#vector常用函数" class="headerlink" title="vector常用函数"></a>vector常用函数</h4><h5 id="push-back"><a href="#push-back" class="headerlink" title="push_back()"></a>push_back()</h5><p>push_back(x)就是在vector后面添加一个元素x</p><h5 id="pop-back"><a href="#pop-back" class="headerlink" title="pop_back()"></a>pop_back()</h5><p>用来删除vector的尾元素</p><h5 id="size"><a href="#size" class="headerlink" title="size()"></a>size()</h5><p>用来获得vector中元素的个数,返回的是unsigned类型</p><h5 id="clear"><a href="#clear" class="headerlink" title="clear()"></a>clear()</h5><p>用来清空所有元素</p><h5 id="insert"><a href="#insert" class="headerlink" title="insert()"></a>insert()</h5><p>用来向vector的任意迭代器it处插入一个元素<code>vi.insert(vi.begin()+2,-1)</code></p><h5 id="erase"><a href="#erase" class="headerlink" title="erase()"></a>erase()</h5><p>删除单个元素<code>vi.erase(vi,begin()+3)</code></p><p>删除一个区间内的所有元素<code>vi.erase(vi.begin()+1,ivi.begin()+4)</code></p><h4 id="vector的常见用途"><a href="#vector的常见用途" class="headerlink" title="vector的常见用途"></a>vector的常见用途</h4><p>存储数据;用邻接表存储图</p><h2 id="set的常见用法"><a href="#set的常见用法" class="headerlink" title="set的常见用法"></a>set的常见用法</h2><p>set是一个内部自动有序且不含重复元素的容器</p><p><code>#include<set></code></p><p><code>using namespace std;</code></p><h4 id="set的定义"><a href="#set的定义" class="headerlink" title="set的定义"></a>set的定义</h4><p><code>set<typename> name;</code>和vector类似</p><h4 id="set常用函数"><a href="#set常用函数" class="headerlink" title="set常用函数"></a>set常用函数</h4><h5 id="insert-1"><a href="#insert-1" class="headerlink" title="insert()"></a>insert()</h5><p>insert(x)将x插入set容器中,自动递增排序和去重</p><h5 id="find"><a href="#find" class="headerlink" title="find()"></a>find()</h5><p>find(value)返回set中对应值为value的迭代器</p><h5 id="erase-1"><a href="#erase-1" class="headerlink" title="erase()"></a>erase()</h5><p><code>st.erase(st.find(100));</code></p><p><code>st.erase(it,st.end());</code></p><h5 id="size-1"><a href="#size-1" class="headerlink" title="size()"></a>size()</h5><p>获得set内元素的个数<code>st.size()</code></p><h5 id="clear-1"><a href="#clear-1" class="headerlink" title="clear()"></a>clear()</h5><p>清空所有元素</p><h4 id="set的用途"><a href="#set的用途" class="headerlink" title="set的用途"></a>set的用途</h4><p>如果需要处理数组中元素不唯一的情况,需要使用multiset</p><h2 id="string"><a href="#string" class="headerlink" title="string"></a>string</h2><p><code>#include<string></code></p><p><code>using namespace std;</code></p><p><code>string str;</code></p><h4 id="string中内容的访问"><a href="#string中内容的访问" class="headerlink" title="string中内容的访问"></a>string中内容的访问</h4><h5 id="可以像访问字符数组一样访问"><a href="#可以像访问字符数组一样访问" class="headerlink" title="可以像访问字符数组一样访问"></a>可以像访问字符数组一样访问</h5><p>如果要读入和输出整个字符串,要用cin cout</p><p>想用printf输出,则需要用str.c_str()将str转为字符数组输出</p><h5 id="迭代器"><a href="#迭代器" class="headerlink" title="迭代器"></a>迭代器</h5><p><code>string::iterator it;</code></p><p>string也支持直接对迭代器进行加减某个数字str.begin()+3</p><h4 id="string常用函数"><a href="#string常用函数" class="headerlink" title="string常用函数"></a>string常用函数</h4><h5 id="operator"><a href="#operator" class="headerlink" title="operator+="></a>operator+=</h5><p>将两个string直接拼接起来</p><p><code>str3=str1+str2;</code></p><h5 id="compare-operator"><a href="#compare-operator" class="headerlink" title="compare operator"></a>compare operator</h5><p>可以直接比较,比较规则是字典序</p><h5 id="length-size"><a href="#length-size" class="headerlink" title="length()/size()"></a>length()/size()</h5><p>length()与size()都统计string的长度</p><h5 id="insert-2"><a href="#insert-2" class="headerlink" title="insert()"></a>insert()</h5><p>insert(pos,string)在pos处插入字符串string</p><p>insert(it,it2,it3) it为原字符的欲插入的位置,it2和it3为待插字符串的首位迭代器,用来表示串[it2,it3)将被插在it的位置上</p><h5 id="erase-2"><a href="#erase-2" class="headerlink" title="erase()"></a>erase()</h5><p>str.erase(it)用于删除单个元素,it为需要删除的元素的迭代器</p><p>str.erase(first,last)</p><p>str.erase(pos,length)</p><h5 id="clear-2"><a href="#clear-2" class="headerlink" title="clear()"></a>clear()</h5><p>用于清空string中的数据</p><h5 id="substr()"><a href="#substr()" class="headerlink" title="substr()"></a>substr()</h5><p>substr(pos,len)返回从pos号位置开始,长度为len的子串</p><h5 id="string-npos"><a href="#string-npos" class="headerlink" title="string::npos"></a>string::npos</h5><p>用于作为find函数失配时的返回值,本身是一个常数,为-1或者4294967295</p><h5 id="find-1"><a href="#find-1" class="headerlink" title="find()"></a>find()</h5><p>str.find(str2)当str2时str的子串时,返回其在str中第一次出现的位置,如果不是str的子串,则返回string::npos</p><h2 id="map"><a href="#map" class="headerlink" title="map"></a>map</h2><p>map翻译为映射,一般数组的映射,都是从int型映射到其他,而map可以将任何基本类型映射到任何基本类型里</p><p><code>#include<map></code></p><p><code>using namespace std;</code></p><h4 id="map的定义"><a href="#map的定义" class="headerlink" title="map的定义"></a>map的定义</h4><p><code>map<typename1,typename2> mp;</code>第一个是键的类型,第二个是值的类型</p><h4 id="map容器内元素的访问"><a href="#map容器内元素的访问" class="headerlink" title="map容器内元素的访问"></a>map容器内元素的访问</h4><h5 id="通过访问下表访问"><a href="#通过访问下表访问" class="headerlink" title="通过访问下表访问"></a>通过访问下表访问</h5><p>对于一个定义为map<char,int>mp的map来说,可以直接使用mp[‘c’]的方式来访问它对应的整数,<strong>map中键是唯一的</strong></p><h5 id="通过迭代器访问-1"><a href="#通过迭代器访问-1" class="headerlink" title="通过迭代器访问"></a>通过迭代器访问</h5><p><code>map<typename1,typename2>::iterator it;</code></p><p><strong>map可以使用it->first来访问键it->second来访问值</strong></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c++">map<<span class="hljs-type">char</span>,<span class="hljs-type">int</span>> mp;<br>mp[<span class="hljs-string">'m'</span>]=<span class="hljs-number">20</span>;<br>mp[<span class="hljs-string">'r'</span>]=<span class="hljs-number">30</span>;<br>mp[<span class="hljs-string">'a'</span>]=<span class="hljs-number">40</span>;<br><span class="hljs-keyword">for</span>(map<<span class="hljs-type">char</span>,<span class="hljs-type">int</span>>::iterator it=mp.<span class="hljs-built_in">begin</span>();it!=mp.<span class="hljs-built_in">end</span>();it++){<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%c %d"</span>,it->first,it->second);<br>}<br></code></pre></td></tr></table></figure><p><strong>map会按键从小到大的顺序自动排序</strong></p><h4 id="map常用函数"><a href="#map常用函数" class="headerlink" title="map常用函数"></a>map常用函数</h4><h5 id="find-2"><a href="#find-2" class="headerlink" title="find()"></a>find()</h5><p>find(key)返回值为key的映射的<strong>迭代器</strong></p><h5 id="erase-3"><a href="#erase-3" class="headerlink" title="erase()"></a>erase()</h5><p>mp.erase(it) it为迭代器</p><p>mp.erase(key)</p><p>mp.erase(first,last)都是迭代器,也是左闭右开</p><h5 id="size-2"><a href="#size-2" class="headerlink" title="size()"></a>size()</h5><p>用来获得map中映射的对数</p><h5 id="clear-3"><a href="#clear-3" class="headerlink" title="clear()"></a>clear()</h5><p>用来清空map中的所有元素</p><h4 id="map的常见用途"><a href="#map的常见用途" class="headerlink" title="map的常见用途"></a>map的常见用途</h4><p>需要建立字符串与整数之间映射的题目;判断大整数或其他类型数据是否存在的题目,可以把map当bool数组用;字符串和字符串之间的映射;</p><p>map的键和值是唯一的,如果需要一个键对应多个值,就需要用multimap</p><p>还有unordered_map来处理只映射补排序的要求,速度比map要快得多</p><h2 id="queue"><a href="#queue" class="headerlink" title="queue"></a>queue</h2><h4 id="queue的定义"><a href="#queue的定义" class="headerlink" title="queue的定义"></a>queue的定义</h4><p>队列,先进先出</p><p><code>#include<queue></code></p><p><code>using namespace std;</code></p><p><code>queue<typename> name</code></p><h4 id="元素的访问"><a href="#元素的访问" class="headerlink" title="元素的访问"></a>元素的访问</h4><p>只能通过front()来访问队首元素 back()来访问队尾元素</p><h4 id="常用函数"><a href="#常用函数" class="headerlink" title="常用函数"></a>常用函数</h4><h5 id="push"><a href="#push" class="headerlink" title="push()"></a>push()</h5><p>push(x)将x入队</p><h5 id="pop"><a href="#pop" class="headerlink" title="pop()"></a>pop()</h5><p>令队首元素出队</p><h5 id="front-back"><a href="#front-back" class="headerlink" title="front() back()"></a>front() back()</h5><p>获得队首元素和队尾元素</p><h5 id="empty"><a href="#empty" class="headerlink" title="empty()"></a>empty()</h5><p>检测队列queue是否为空,返回true则空</p><h5 id="size-3"><a href="#size-3" class="headerlink" title="size()"></a>size()</h5><p>返回queue中元素的个数</p><h4 id="queue的常见用途"><a href="#queue的常见用途" class="headerlink" title="queue的常见用途"></a>queue的常见用途</h4><p>实现广度优先搜索时,不用自己手动实现一个队列,而是用queue作为代替,提高程序的准确性</p><p>使用front() back()函数前,需要先用empty()判断是否为空,可能出现因为空而错误</p><h2 id="priority-queue"><a href="#priority-queue" class="headerlink" title="priority_queue"></a>priority_queue</h2><p>优先队列,底层是用堆来进行实现的,<strong>队首元素一定是当前队列中优先级最高的那一个</strong></p><h4 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h4><p><code>priority_queue<typename> name;</code></p><h4 id="元素的访问-1"><a href="#元素的访问-1" class="headerlink" title="元素的访问"></a>元素的访问</h4><p>只能通过top()函数访问队首元素</p><h4 id="priority-queue常用函数"><a href="#priority-queue常用函数" class="headerlink" title="priority_queue常用函数"></a>priority_queue常用函数</h4><p>push() pop() top()empty() size()</p><h4 id="队内优先级的设置"><a href="#队内优先级的设置" class="headerlink" title="队内优先级的设置"></a>队内优先级的设置</h4><h5 id="基本数据类型的优先级设置"><a href="#基本数据类型的优先级设置" class="headerlink" title="基本数据类型的优先级设置"></a>基本数据类型的优先级设置</h5><p>一般都是从大到小,下面两种定义是等价的</p><p><code>priority_queue<int> q;</code></p><p><code>priority_queue<int,vector<int>,less<int>> q;</code></p><p>其中第二个参数填写的是来承载底层数据结构的容器,如果第一个参数是double或char型,则此处只需要填写vector<double>,第三个参数是对第一个参数的比较类</p><p>less<int>表示数字大的优先级大 greater<int>表示数字小的优先级大</p><h5 id="结构体的优先级设置"><a href="#结构体的优先级设置" class="headerlink" title="结构体的优先级设置"></a>结构体的优先级设置</h5><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">fruit</span>{<br> string name;<br> <span class="hljs-type">int</span> price;<br> <span class="hljs-keyword">friend</span> <span class="hljs-type">bool</span> <span class="hljs-keyword">operator</span> < (fruit f1,fruit f2){<br> <span class="hljs-keyword">return</span> f1.price<f2.price;<br> }<br>}<br>priority_queue<fruit> q;<br></code></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">fruit</span>{<br> string name;<br> <span class="hljs-type">int</span> price;<br>}f1,f2,f3;<br><span class="hljs-keyword">struct</span> <span class="hljs-title class_">cmp</span>{<br> <span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">operator</span><span class="hljs-params">()</span><span class="hljs-params">(fruit f1,fruit f2)</span></span>{<br> <span class="hljs-keyword">return</span> f1.price>f2.price;<br> }<br>};<br>priority_queue<fruit,vector<fruit>,cmp> q;<br></code></pre></td></tr></table></figure><p>如果结构体内数据庞大,最好使用引用来提高效率</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">friend</span> <span class="hljs-type">bool</span> <span class="hljs-keyword">operator</span> < (<span class="hljs-type">const</span> fruit &f1,<span class="hljs-type">const</span> fruit &f2){<br> <span class="hljs-keyword">return</span> f1.price>f2.price;<br>}<br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">operator</span><span class="hljs-params">()</span><span class="hljs-params">(<span class="hljs-type">const</span> fruit &f1,<span class="hljs-type">const</span> fruit &f2)</span></span>{<br> <span class="hljs-keyword">return</span> f1.price>f2.price;<br>}<br></code></pre></td></tr></table></figure><h2 id="stack"><a href="#stack" class="headerlink" title="stack"></a>stack</h2><h4 id="stack的定义"><a href="#stack的定义" class="headerlink" title="stack的定义"></a>stack的定义</h4><p><code>stack <typename> name;</code></p><h4 id="元素访问"><a href="#元素访问" class="headerlink" title="元素访问"></a>元素访问</h4><p>栈是先进后出的数据结构,STL中的stack只能通过top()来进行访问栈顶元素</p><h4 id="常用函数-1"><a href="#常用函数-1" class="headerlink" title="常用函数"></a>常用函数</h4><h5 id="push-top-pop-empty-size"><a href="#push-top-pop-empty-size" class="headerlink" title="push() top() pop() empty() size()"></a>push() top() pop() empty() size()</h5><h2 id="pair"><a href="#pair" class="headerlink" title="pair"></a>pair</h2><blockquote><p>想要将两个元素一起作为一个合成元素,又不想定义结构体,就可以用pair</p></blockquote><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">pair</span>{<br>typeName1 first;<br> typeName2 second;<br>};<br></code></pre></td></tr></table></figure><h4 id="定义-1"><a href="#定义-1" class="headerlink" title="定义"></a>定义</h4><p><code>#include<utility></code></p><p><code>pair<typename1,typename2> p;</code></p><p>初始化<code>pair<string,int> p("h",5);</code></p><p> <code>make_pair("h",5);</code></p><p>访问元素是只有first和second 按照正常结构体的方式访问就可以</p><h4 id="pair常用函数"><a href="#pair常用函数" class="headerlink" title="pair常用函数"></a>pair常用函数</h4><p>可以直接用比较符来比较,比较规则是以first的大小作为标准,只有first相同时才判断second的大小</p><h4 id="常见用途"><a href="#常见用途" class="headerlink" title="常见用途"></a>常见用途</h4><p>代替二元结构体和构造函数</p><p>作为map的键值进行插入</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c++">map<string,<span class="hljs-type">int</span>> mp;<br>mp.<span class="hljs-built_in">insert</span>(<span class="hljs-built_in">make_pair</span>(<span class="hljs-string">"h"</span>,<span class="hljs-number">5</span>));<br></code></pre></td></tr></table></figure><h2 id="algorithm头文件下的常用函数"><a href="#algorithm头文件下的常用函数" class="headerlink" title="algorithm头文件下的常用函数"></a>algorithm头文件下的常用函数</h2><h3 id="max-min-abs"><a href="#max-min-abs" class="headerlink" title="max() min() abs()"></a>max() min() abs()</h3><p>返回最大最小值以及绝对值,abs(x)返回x的绝对值,x必须为整数,浮点型的绝对值需要使用math头文件下的fabs</p><h3 id="swap"><a href="#swap" class="headerlink" title="swap()"></a>swap()</h3><p>交换xy的值</p><h3 id="reverse"><a href="#reverse" class="headerlink" title="reverse()"></a>reverse()</h3><p>reverse(it,it2)可以将数组指针在[it,it2)之间的元素或容器的迭代器进行反转</p><h3 id="next-permutation"><a href="#next-permutation" class="headerlink" title="next_permutation()"></a>next_permutation()</h3><p>给出一个序列在全排列中的下一个序列</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-type">int</span> a[<span class="hljs-number">10</span>]={<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>};<br><span class="hljs-keyword">do</span>{<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d%d%d"</span>,a[<span class="hljs-number">0</span>],a[<span class="hljs-number">1</span>],a[<span class="hljs-number">2</span>]);<br>}<span class="hljs-keyword">while</span>(<span class="hljs-built_in">next_permutation</span>(a,a+<span class="hljs-number">3</span>));<br></code></pre></td></tr></table></figure><h3 id="fill"><a href="#fill" class="headerlink" title="fill()"></a>fill()</h3><p>把数组或容器中的某一段区间赋为某个相同的值,与memset不同,memset(str,c,n)这里的赋值可以是数组类型对应范围中的任意值fill(a,a+5,233)</p><h3 id="sort"><a href="#sort" class="headerlink" title="sort()"></a>sort()</h3><p><code>sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填))</code></p><h4 id="如何使用sort排序"><a href="#如何使用sort排序" class="headerlink" title="如何使用sort排序"></a>如何使用sort排序</h4><p>必须加上头文件</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><algorithm></span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><br><span class="hljs-built_in">sort</span>(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));<br></code></pre></td></tr></table></figure><p>如果不写比较函数,则默认递增</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><algorithm></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-type">int</span> a[<span class="hljs-number">6</span>]={<span class="hljs-number">9</span>,<span class="hljs-number">4</span>,<span class="hljs-number">2</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">-1</span>};<br> <span class="hljs-built_in">sort</span>(a, &a[<span class="hljs-number">6</span>]);<span class="hljs-comment">//sort(a,a+6);</span><br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">6</span>;i++)<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d "</span>, a[i]);<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><span class="hljs-comment">//sort函数的第三个参数为compare函数,可以人为定义cmp函数,比如结构体之内的排序,可以通过自定义cmp函数实现</span><br></code></pre></td></tr></table></figure><h4 id="cmp函数的编写"><a href="#cmp函数的编写" class="headerlink" title="cmp函数的编写"></a>cmp函数的编写</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-comment">//例为成绩的排序</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">cmp</span><span class="hljs-params">(Student a,Student b)</span></span>{<br> <span class="hljs-keyword">if</span>(a.score!=b.score)<span class="hljs-keyword">return</span> a.score>b.score;<br> <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> <span class="hljs-built_in">strcmp</span>(a.name,b.name)<<span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h4 id="容器的排序"><a href="#容器的排序" class="headerlink" title="容器的排序"></a>容器的排序</h4><p>只有vector string deque可以使用sort</p><h3 id="lower-bound-upper-bound"><a href="#lower-bound-upper-bound" class="headerlink" title="lower_bound() upper_bound()"></a>lower_bound() upper_bound()</h3><p>lower_bound(first,last,val)来寻找在数组或容器中的[first,last)范围内第一个值<strong>大于等于</strong>val元素的位置,如果是数组,则返回该位置的指针,如果是容器,则返回该位置的迭代器</p><p>upper_bound(first,last,val)用来寻找在数组或容器中的[first,last)范围内第一个值<strong>大于</strong>val元素的位置,如果是数组,则返回该位置的指针,如果是容器,则返回该位置的迭代器</p>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>数学问题</title>
<link href="/2023/03/09/%E6%95%B0%E5%AD%A6%E9%97%AE%E9%A2%98/"/>
<url>/2023/03/09/%E6%95%B0%E5%AD%A6%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<h1 id="数学问题"><a href="#数学问题" class="headerlink" title="数学问题"></a>数学问题</h1><h2 id="最大公约数与最小公倍数"><a href="#最大公约数与最小公倍数" class="headerlink" title="最大公约数与最小公倍数"></a>最大公约数与最小公倍数</h2><h3 id="最大公约数"><a href="#最大公约数" class="headerlink" title="最大公约数"></a>最大公约数</h3><p>a b都为正整数 gcd(a,b)=gcd(b,a%b)</p><p>递归边界:0和任意一个正整数的最大公约数都是那个正整数</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">gcd</span><span class="hljs-params">(<span class="hljs-type">int</span> a,<span class="hljs-type">int</span> b)</span></span>{<br> <span class="hljs-keyword">if</span>(b==<span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> a;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">gcd</span>(b, a % b);<br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-type">int</span> n, m;<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d%d"</span>, &n, &m);<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, <span class="hljs-built_in">gcd</span>(n, m));<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h3 id="最小公倍数"><a href="#最小公倍数" class="headerlink" title="最小公倍数"></a>最小公倍数</h3><p>ab的最大公约数是d,那么ab的最小公倍数是ab/d</p><p><strong>由于ab在计算的过程中可能会溢出,所以更合适的写法为a/d*b</strong></p><h2 id="分数的四则运算"><a href="#分数的四则运算" class="headerlink" title="分数的四则运算"></a>分数的四则运算</h2><h3 id="分数的表示和化简"><a href="#分数的表示和化简" class="headerlink" title="分数的表示和化简"></a>分数的表示和化简</h3><h4 id="分数的表示"><a href="#分数的表示" class="headerlink" title="分数的表示"></a>分数的表示</h4><figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs x86asm">struct Fraction{<br><span class="hljs-keyword">int</span> <span class="hljs-meta">up</span>,<span class="hljs-meta">down</span><span class="hljs-comment">;</span><br>}<br></code></pre></td></tr></table></figure><p>分子和分母需要没有除了1以外的公约数</p><p>down为非负数</p><p>如果分数值为0,那么是分子的值为0</p><h4 id="分数的化简"><a href="#分数的化简" class="headerlink" title="分数的化简"></a>分数的化简</h4><p>如果分母为负数,那么分子分母都变成相反数</p><p>如果分子为0,那么分母为1</p><p>求分子分母最大公约数,同时除以</p><h3 id="分数的四则运算-1"><a href="#分数的四则运算-1" class="headerlink" title="分数的四则运算"></a>分数的四则运算</h3><h4 id="分数的加法"><a href="#分数的加法" class="headerlink" title="分数的加法"></a>分数的加法</h4><p><code>result.up=f1.up*f2.down+f2.up*f1.down</code></p><p><code>result.down=f1.down*f2.down</code></p><h3 id="分数的输出"><a href="#分数的输出" class="headerlink" title="分数的输出"></a>分数的输出</h3><p>由于分数的乘法和除法过程中可能超过int表示范围,因此一般使用long long来储存</p><h2 id="素数"><a href="#素数" class="headerlink" title="素数"></a>素数</h2><h3 id="素数的判断"><a href="#素数的判断" class="headerlink" title="素数的判断"></a>素数的判断</h3><p>只用判断n能否被2,3,…sqrt(n)整除</p><h3 id="素数表的获取"><a href="#素数表的获取" class="headerlink" title="素数表的获取"></a>素数表的获取</h3><p>最常规的判断素数的方法复杂度为nsqrt(n)</p><p><strong>筛法,Eratosthenes筛法</strong>,时间复杂度为Onloglogn</p><p><strong>算法从小到大枚举所有数,对每一个素数,筛去它的所有倍数,剩下的就是素数了</strong></p><p>2是素数是唯一事先确定的。然后将2的倍数都删除掉,</p><p>剩下的第一个3就是素数,继续将3的倍数删除掉,</p><p>4被删除,</p><p>5未被删除,将5的倍数继续删除掉,</p><p>…</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-type">int</span> prime[<span class="hljs-number">105</span>],pNum=<span class="hljs-number">0</span>;<br><span class="hljs-type">int</span> P[<span class="hljs-number">105</span>] = {<span class="hljs-number">0</span>};<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">find_prime</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">2</span>; i < <span class="hljs-number">101</span>;i++){<br> <span class="hljs-keyword">if</span>(P[i]==<span class="hljs-number">0</span>){<br> prime[pNum++] = i;<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> j = i; j < <span class="hljs-number">101</span>;j+=i)<br> P[j] = <span class="hljs-number">1</span>;<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="质因子分解"><a href="#质因子分解" class="headerlink" title="质因子分解"></a>质因子分解</h2><p>可以对正整数n设置一个结构体factor </p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">factor</span>{<br><span class="hljs-type">int</span> x,cnt;<span class="hljs-comment">//x为质因子,cnt为质因子个数</span><br>}fac[<span class="hljs-number">10</span>];<span class="hljs-comment">//数组存放所有的质因子,只需要十位就可以</span><br></code></pre></td></tr></table></figure><p>每个数的质因子都小于sqrtn或者有一个大于sqrtn剩下的都小于</p><p>PAT A1059</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cmath></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><br><span class="hljs-type">const</span> <span class="hljs-type">int</span> MAXN=<span class="hljs-number">100001</span>;<br><span class="hljs-type">int</span> prime[MAXN], pNum = <span class="hljs-number">0</span>;<br><span class="hljs-type">int</span> p[MAXN];<br><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">is_prime</span><span class="hljs-params">(<span class="hljs-type">int</span> n)</span></span>{<br> <span class="hljs-keyword">if</span>(n==<span class="hljs-number">1</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> <span class="hljs-type">int</span> sqr = (<span class="hljs-type">int</span>)<span class="hljs-built_in">sqrt</span>(<span class="hljs-number">1.0</span> * n);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">2</span>; i <= sqr;i++){<br> <span class="hljs-keyword">if</span>(n%i==<span class="hljs-number">0</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">find_Prime</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">1</span>; i < MAXN;i++){<br> <span class="hljs-keyword">if</span>(<span class="hljs-built_in">is_prime</span>(i))<br> prime[pNum++] = i;<br> }<br>}<br><br><span class="hljs-keyword">struct</span> <span class="hljs-title class_">factor</span>{<br> <span class="hljs-type">int</span> x, cnt;<br>} fac[<span class="hljs-number">10</span>];<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-built_in">find_Prime</span>();<br> <span class="hljs-type">int</span> n, num = <span class="hljs-number">0</span>;<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &n);<br> <span class="hljs-keyword">if</span>(n==<span class="hljs-number">1</span>)<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"1=1"</span>);<br> <span class="hljs-keyword">else</span>{<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d="</span>, n);<br> <span class="hljs-type">int</span> sqr = (<span class="hljs-type">int</span>)<span class="hljs-built_in">sqrt</span>(<span class="hljs-number">1.0</span> * n);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < pNum && prime[i] <= sqr;i++){<br> <span class="hljs-keyword">if</span>(n%prime[i]==<span class="hljs-number">0</span>){<br> fac[num].x = prime[i];<br> fac[num].cnt = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">while</span>(n%prime[i]==<span class="hljs-number">0</span>){<br> fac[num].cnt++;<br> n /= prime[i];<br> }<br> num++;<br> }<br> <span class="hljs-keyword">if</span>(n==<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">break</span>;<br> }<br> <span class="hljs-keyword">if</span>(n!=<span class="hljs-number">1</span>){<br> fac[num].x = n;<br> fac[num++].cnt = <span class="hljs-number">1</span>;<br> }<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < num;i++){<br> <span class="hljs-keyword">if</span>(i><span class="hljs-number">0</span>)<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"*"</span>);<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d"</span>, fac[i].x);<br> <span class="hljs-keyword">if</span>(fac[i].cnt><span class="hljs-number">1</span>)<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"^%d"</span>, fac[i].cnt);<br> }<br> }<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="大整数运算"><a href="#大整数运算" class="headerlink" title="大整数运算"></a>大整数运算</h2><p>需要转换成数组,按每一位进行加减法</p><h2 id="扩展欧几里得算法"><a href="#扩展欧几里得算法" class="headerlink" title="扩展欧几里得算法"></a>扩展欧几里得算法</h2><p>给定两个非零整数a和b,求一组整数解,使得ax+by=gcd(a,b)</p><p>ax1+by1=gcd;</p><p>求出递推:</p><p>x1=y2</p><p>y1=x2-(a/b)y2</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> <span class="hljs-title function_">exGcd</span><span class="hljs-params">(<span class="hljs-type">int</span> a,<span class="hljs-type">int</span> b,<span class="hljs-type">int</span> &x,<span class="hljs-type">int</span> &y)</span>{<br> <span class="hljs-keyword">if</span>(b==<span class="hljs-number">0</span>){<br> x=<span class="hljs-number">1</span>;<br> y=<span class="hljs-number">0</span>;<br> <span class="hljs-keyword">return</span> a;<br> }<br> <span class="hljs-type">int</span> g=exGcd(b,a%b,x,y);<br> <span class="hljs-type">int</span> temp=x;<br> x=y;<br> y=temp-(a/b)*y;<br> <span class="hljs-keyword">return</span> g;<br>}<span class="hljs-comment">//x y就是所求解</span><br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>其他高效技巧与算法</title>
<link href="/2023/03/08/%E5%85%B6%E4%BB%96%E9%AB%98%E6%95%88%E6%8A%80%E5%B7%A7%E4%B8%8E%E7%AE%97%E6%B3%95/"/>
<url>/2023/03/08/%E5%85%B6%E4%BB%96%E9%AB%98%E6%95%88%E6%8A%80%E5%B7%A7%E4%B8%8E%E7%AE%97%E6%B3%95/</url>
<content type="html"><![CDATA[<h2 id="其他高效技巧与算法"><a href="#其他高效技巧与算法" class="headerlink" title="其他高效技巧与算法"></a>其他高效技巧与算法</h2><h3 id="打表"><a href="#打表" class="headerlink" title="打表"></a>打表</h3><p>时间换空间,把所有可能的情况都列举出来,需要的时候直接查表</p><p>①在程序中一次性计算出所有需要用到的结果,之后的查询直接取这些结果</p><p>②在程序B中分一次或多次计算出所有需要用到的结果,手工把结果写在程序A的数组中,在程序A中直接使用这些结果</p><p>③对于一些不会做的题目,先暴力计算小范围数据的结果,然后找规律</p><h3 id="递推"><a href="#递推" class="headerlink" title="递推"></a>递推</h3><p>有几个PAT,输入字符串,看能组成几个PAT</p><p><strong>直接暴力会超时</strong>,考虑记录A的数量,将每个A的左侧P和右侧T直接相乘,就可以得到PAT的个数</p><p>P的数量用一个一维数组存储,从左向右遍历,后一个字符记录P的个数等于前一个字符所记录P的个数,若当前字符为P则+1</p><p>接着从右向左遍历,若为T则给T的计数值+1,若为A则将当前T的计数值与当前位置的P的个数相乘(记得要模)加到ans上</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstring></span></span><br><span class="hljs-type">const</span> <span class="hljs-type">int</span> MAXN=<span class="hljs-number">100010</span>;<br><span class="hljs-type">const</span> <span class="hljs-type">int</span> MOD = <span class="hljs-number">1000000007</span>;<br><span class="hljs-type">char</span> str[MAXN];<br><span class="hljs-type">int</span> leftP[MAXN] = {<span class="hljs-number">0</span>};<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-type">int</span> rightT=<span class="hljs-number">0</span>;<br> <span class="hljs-built_in">gets</span>(str);<br> <span class="hljs-type">int</span> len = <span class="hljs-built_in">strlen</span>(str);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < len;i++){<br> <span class="hljs-keyword">if</span>(i><span class="hljs-number">0</span>){<br> leftP[i] = leftP[i - <span class="hljs-number">1</span>];<br> }<br> <span class="hljs-keyword">if</span>(str[i]==<span class="hljs-string">'P'</span>)<br> leftP[i]++;<br> }<br> <span class="hljs-type">int</span> ans = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = len - <span class="hljs-number">1</span>; i >= <span class="hljs-number">0</span>;i--){<br> <span class="hljs-keyword">if</span>(str[i]==<span class="hljs-string">'T'</span>)<br> rightT++;<br> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str[i]==<span class="hljs-string">'A'</span>)<br> ans = (ans + rightT*leftP[i]) % MOD;<br> }<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d"</span>, ans);<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><br></code></pre></td></tr></table></figure><h3 id="随机选择算法"><a href="#随机选择算法" class="headerlink" title="随机选择算法"></a>随机选择算法</h3><p>类似于快速排序算法,题为寻找第K大的数,选择主元进行partition,如果对应的序号就是自己想要找的数,则就是这个元,若对应序号比当前序号大或者小,则需要在此之前或者之后寻找,<strong>随机选择算法将时间复杂度可以降低为O(n)</strong></p><p>给定一个由整数组成的集合,集合中整数各不相同,现在要将它分成两个子集合,使得这两个子集合的并为原集合,交为空,同时在两个子集合的元素个数n1,n2之差的绝对值尽可能小的前提下,要求他们各自的元素之和的差的绝对值尽可能大,求各自的元素之和的差的绝对值</p><p>可以使用随机选择算法,就可以求原集合中第n/2大的元素,自动把这个集合切割为两部分,其中一部分都小于,另一部分大于等于</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdlib></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><ctime></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><algorithm></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cmath></span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-type">const</span> <span class="hljs-type">int</span> MAXN = <span class="hljs-number">10010</span>;<br><br><span class="hljs-type">int</span> A[MAXN], n;<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">randpartition</span><span class="hljs-params">(<span class="hljs-type">int</span> A[],<span class="hljs-type">int</span> left,<span class="hljs-type">int</span> right)</span></span>{<br> <span class="hljs-type">int</span> p = <span class="hljs-built_in">round</span>(<span class="hljs-number">1.0</span> * <span class="hljs-built_in">rand</span>() / RAND_MAX * (right - left) + left);<br> <span class="hljs-built_in">swap</span>(A[p],A[left]);<br> <span class="hljs-type">int</span> temp = A[left];<br> <span class="hljs-keyword">while</span>(left<right){<br> <span class="hljs-keyword">while</span>(left < right && A[right] > temp){<br> right--;<br> }<br> A[left] = A[right];<br> <span class="hljs-keyword">while</span>(left < right && A[left] < temp){<br> left++;<br> }<br> A[right] = A[left];<br> }<br> A[left] = temp;<br> <span class="hljs-keyword">return</span> left;<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">randselect</span><span class="hljs-params">(<span class="hljs-type">int</span> A[],<span class="hljs-type">int</span> left,<span class="hljs-type">int</span> right,<span class="hljs-type">int</span> k)</span></span>{<br> <span class="hljs-keyword">if</span>(left==right)<br> <span class="hljs-keyword">return</span>;<br> <span class="hljs-type">int</span> p = <span class="hljs-built_in">randpartition</span>(A, left, right);<br> <span class="hljs-type">int</span> M = p - left + <span class="hljs-number">1</span>;<br> <span class="hljs-keyword">if</span>(k<M)<br> <span class="hljs-built_in">randselect</span>(A, left, p - <span class="hljs-number">1</span>, k);<br> <span class="hljs-keyword">else</span><br> <span class="hljs-built_in">randselect</span>(A, p + <span class="hljs-number">1</span>, right, k);<br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-built_in">srand</span>((<span class="hljs-type">unsigned</span>)<span class="hljs-built_in">time</span>(<span class="hljs-literal">NULL</span>));<br> <span class="hljs-type">int</span> sum = <span class="hljs-number">0</span>, sum1 = <span class="hljs-number">0</span>;<span class="hljs-comment">//分别记录所有元素和以及切分后前n/2个元素和</span><br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>,&n);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < n;i++){ <br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &A[i]);<br> sum += A[i];<br> }<br> <span class="hljs-built_in">randselect</span>(A, <span class="hljs-number">0</span>, n - <span class="hljs-number">1</span>, n / <span class="hljs-number">2</span>);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < n / <span class="hljs-number">2</span>;i++){<br> sum1 += A[i];<br> }<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, sum - sum1 - sum1);<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>贪心</title>
<link href="/2023/03/07/%E8%B4%AA%E5%BF%83/"/>
<url>/2023/03/07/%E8%B4%AA%E5%BF%83/</url>
<content type="html"><![CDATA[<h2 id="贪心"><a href="#贪心" class="headerlink" title="贪心"></a>贪心</h2><h4 id="简单贪心"><a href="#简单贪心" class="headerlink" title="简单贪心"></a>简单贪心</h4><p>贪心考虑当前状态下局部最优的策略,来使全局的结果达到最优。</p><p>若想要获得最优的结果,则要求中间的每步策略都是最优的,因此使用贪心法要对采用的策略进行证明,一般采用反证法和数学归纳法</p><h4 id="区间贪心"><a href="#区间贪心" class="headerlink" title="区间贪心"></a>区间贪心</h4><p>题目为判断最多不重合的区间数目</p><p>将所有区间的右端点从小到大排序,选择右端点最小的,且内部不与已经选择的重合(左端点和上一个右端点重合不算)区间作为目标。</p><p>也可以将所有区间的左端点从大到小排序,然后选择左端点最大的区间。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><algorithm></span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-comment">//右端点从小到大排序,然后将重合的区间去掉</span><br><span class="hljs-keyword">struct</span> <span class="hljs-title class_">interval</span>{<br> <span class="hljs-type">int</span> x;<br> <span class="hljs-type">int</span> y;<br>} I[<span class="hljs-number">110</span>];<br><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">cmp</span><span class="hljs-params">(interval a,interval b)</span></span>{<br> <span class="hljs-keyword">return</span> a.y < b.y;<br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-type">int</span> n;<br> <span class="hljs-keyword">while</span>(<span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>,&n)!=EOF){<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < n;i++)<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d%d"</span>, &I[i].x, &I[i].y);<br> <span class="hljs-built_in">sort</span>(I, I + n, cmp);<br> <span class="hljs-type">int</span> ans = <span class="hljs-number">1</span>,lastI=I[<span class="hljs-number">0</span>].y;<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">1</span>; i < n;i++){<br> <span class="hljs-keyword">if</span>(I[i].x>=lastI){<br> ans++;<br> lastI = I[i].y;<br> }<br> <span class="hljs-keyword">else</span>{<br> lastI = <span class="hljs-built_in">min</span>(lastI, I[<span class="hljs-number">0</span>].y);<br> }<br> }<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, ans);<br> }<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>递归</title>
<link href="/2023/03/07/%E9%80%92%E5%BD%92/"/>
<url>/2023/03/07/%E9%80%92%E5%BD%92/</url>
<content type="html"><![CDATA[<h2 id=""><a href="#" class="headerlink" title=""></a></h2><h2 id="递归"><a href="#递归" class="headerlink" title="递归"></a>递归</h2><h4 id="分治"><a href="#分治" class="headerlink" title="分治"></a>分治</h4><p>把问题划分为若干个子问题,分别解决之后合并得到原问题的解</p><h4 id="递归-1"><a href="#递归-1" class="headerlink" title="递归"></a>递归</h4><p>反复调用自身函数,每次把问题规模缩小,直到范围缩小到可以直接得到边界数据的结果,然后再在返回路上求解</p><p>①递归边界②递归调用</p><h4 id="全排列问题"><a href="#全排列问题" class="headerlink" title="全排列问题"></a>全排列问题</h4><p>给n个数,输出全排列</p><p>思路:考虑放到把数放到空中的这个思路,第一位选了某个数,那么这个数的hashtable对应位置设置为true,把对应P[index]数组也设置成这个数,index表示数的位置。继续递归调用求下一个位置填入什么数,记得要在之后把该数的hashtable设置为false,以便于到同级别的下一个数继续递归时方便使用</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><br><span class="hljs-type">const</span> <span class="hljs-type">int</span> maxn = <span class="hljs-number">10</span>;<br><span class="hljs-type">int</span> n, P[maxn], hashTable[maxn] = {<span class="hljs-literal">false</span>};<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">generateP</span><span class="hljs-params">(<span class="hljs-type">int</span> index)</span></span>{<br> <span class="hljs-keyword">if</span>(index==n+<span class="hljs-number">1</span>){<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">1</span>; i <= n;i++){<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d"</span>, P[i]);<br> }<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span>;<br> }<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> x = <span class="hljs-number">1</span>; x <= n;x++){<br> <span class="hljs-keyword">if</span>(hashTable[x]==<span class="hljs-literal">false</span>){<br> P[index] = x;<br> hashTable[x] = <span class="hljs-literal">true</span>;<br> <span class="hljs-built_in">generateP</span>(index + <span class="hljs-number">1</span>);<br> hashTable[x] = <span class="hljs-literal">false</span>;<br> }<br> }<br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> n = <span class="hljs-number">3</span>;<br> <span class="hljs-built_in">generateP</span>(<span class="hljs-number">1</span>);<br> <span class="hljs-built_in">system</span>(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h4 id="n皇后问题"><a href="#n皇后问题" class="headerlink" title="n皇后问题"></a>n皇后问题</h4><p>如果采用组合数来枚举,枚举数过多,会无法承受。所以考虑写出n列皇后对应的行数,再考虑放置是否合法即可(与上面全排列相同,总共需要n的阶乘次枚举)可以考虑在全排列的基础上求解</p><p>由于全排列枚举,所以肯定不在同一行或者列,即要考虑是否在同一条对角线上,<strong>遍历每2个皇后(暴力</strong>,判断是否在同一条对角线上,若不是,则累计计数变量count</p><p>优化:如果判断出前面一部分皇后放置后,剩下的皇后怎样都不可能合法,那么就不用继续计算下去了,可以直接返回上一层:<strong>回溯</strong></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">generateP</span><span class="hljs-params">(<span class="hljs-type">int</span> index)</span></span>{<br> <span class="hljs-keyword">if</span>(index==n+<span class="hljs-number">1</span>){<br> count++;<br> <span class="hljs-keyword">return</span>;<br> }<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> x = <span class="hljs-number">1</span>; x <= n;x++){<br> <span class="hljs-keyword">if</span>(hashTable[x]==<span class="hljs-literal">false</span>){<br> <span class="hljs-type">bool</span> flag = <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> pre = <span class="hljs-number">1</span>; pre < index;pre++){<br> <span class="hljs-keyword">if</span>(<span class="hljs-built_in">abs</span>(x-P[pre])==<span class="hljs-built_in">abs</span>(pre-index)){<br> flag = <span class="hljs-literal">false</span>;<br> <span class="hljs-keyword">break</span>;<br> }<br> }<br> <span class="hljs-keyword">if</span>(flag){<br> P[index] = x;<br> hashTable[x] = <span class="hljs-literal">true</span>;<br> <span class="hljs-built_in">generateP</span>(index + <span class="hljs-number">1</span>);<br> hashTable[x] = <span class="hljs-literal">false</span>;<br> }<br> }<br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>散列</title>
<link href="/2023/03/07/%E6%95%A3%E5%88%97/"/>
<url>/2023/03/07/%E6%95%A3%E5%88%97/</url>
<content type="html"><![CDATA[<h2 id="散列"><a href="#散列" class="headerlink" title="散列"></a>散列</h2><p>假设一个长度为n的数列,再给一个长度m的数列,问第二个数列中的数是否在第一个数列中出现过,或统计出现次数,可以用一个数组存储长度为n的数列,对应出现的数作为下标,数组内容统计数的出现次数-><strong>来降低时间复杂度</strong></p><p>现在的问题为,若输入的数列很长,或者一个字符串,那么就不能直接设置为数组下标了,想要解决这个问题,就需要用到<strong>散列</strong></p><p><strong>散列:将元素通过一个函数转换为整数,使得该整数可以尽量唯一地代表这个元素</strong>H(key)=key</p><p>除留余数法:H(key)=key%mod</p><p>这种方法会产生冲突,为了解决冲突,有以下几种方法</p><h5 id="线性探查法"><a href="#线性探查法" class="headerlink" title="线性探查法"></a>线性探查法</h5><p>得到H(key)已经被占用时,则检查H(key)+1是否被使用,如果使用就继续检查下一个,若超过表长,则回到首部继续</p><h5 id="平方探查法"><a href="#平方探查法" class="headerlink" title="平方探查法"></a>平方探查法</h5><p>H(key)+1×1; H(key)-1×1;H(key)+2×2若超过表长,则把目标对表长取模;若目标小于0,则模表长再加表长再模表长</p><h5 id="链地址法"><a href="#链地址法" class="headerlink" title="链地址法"></a>链地址法</h5><p>把所有目标相同的key连接成一条单链表,可以设定一个数组,每个元素中存放一条单链表。可以使用标准库中的map来直接使用hash的功能,unordered_map速度更快</p><h3 id="字符串hash初步"><a href="#字符串hash初步" class="headerlink" title="字符串hash初步"></a>字符串hash初步</h3><p>如果key不是整数,假设key是二维整点,坐标为(x,y)其中0≤x,y≤Range,可以令H(P)=x*range+y来唯一的表示整点</p><p>字符串转化也类似,若为A-Z,则把A-Z看作0-25,这样可以获得如下代码</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">hashFunc</span><span class="hljs-params">(<span class="hljs-type">char</span> S[],<span class="hljs-type">int</span> len)</span></span>{<br> <span class="hljs-type">int</span> id=<span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i=<span class="hljs-number">0</span>;i<len;i++){<br> id=id*<span class="hljs-number">26</span>+(s[i]=<span class="hljs-string">'A'</span>);<br> }<br> <span class="hljs-keyword">return</span> id;<br>}<span class="hljs-comment">//len不能太长</span><br></code></pre></td></tr></table></figure><p>N个字符串三位大写字母组成,M个查询字符串,问每个M在N个字符串中出现的次数</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><cstdio></span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><iostream></span></span><br><br><span class="hljs-type">const</span> <span class="hljs-type">int</span> maxn=<span class="hljs-number">100</span>;<br><span class="hljs-type">char</span> S[maxn][<span class="hljs-number">5</span>],temp[<span class="hljs-number">5</span>];<br><span class="hljs-type">int</span> hashtable[<span class="hljs-number">26</span> * <span class="hljs-number">26</span> * <span class="hljs-number">26</span>+<span class="hljs-number">10</span>];<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">hashFunc</span><span class="hljs-params">(<span class="hljs-type">char</span> S[],<span class="hljs-type">int</span> len)</span></span>{<br> <span class="hljs-type">int</span> id=<span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < len;i++){<br> id = id * <span class="hljs-number">26</span> + (S[i] - <span class="hljs-string">'A'</span>);<br> }<br> <span class="hljs-keyword">return</span> id;<br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-type">int</span> n, m;<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d%d"</span>,&n,&m);<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < n;i++){<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%s"</span>, S[i]);<br> <span class="hljs-type">int</span> id = <span class="hljs-built_in">hashFunc</span>(S[i], <span class="hljs-number">3</span>);<br> hashtable[id]++;<br> }<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < m;i++){<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%s"</span>, temp);<br> <span class="hljs-type">int</span> id = <span class="hljs-built_in">hashFunc</span>(temp, <span class="hljs-number">3</span>);<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, hashtable[id]);<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>算法笔记阅读</title>
<link href="/2023/01/12/%E7%AE%97%E6%B3%95%E7%AC%94%E8%AE%B0%E9%98%85%E8%AF%BB/"/>
<url>/2023/01/12/%E7%AE%97%E6%B3%95%E7%AC%94%E8%AE%B0%E9%98%85%E8%AF%BB/</url>
<content type="html"><![CDATA[<blockquote><p>这篇是对于《算法笔记》这本书的知识摘录,目前记录了c的基础部分</p></blockquote><h3 id="基本数据类型"><a href="#基本数据类型" class="headerlink" title="基本数据类型"></a>基本数据类型</h3><p>布尔型在c语言中必须添加stdbool.h头文件,c++中不需要;非零即true;用%d输出布尔型变量</p><h4 id="符号常量"><a href="#符号常量" class="headerlink" title="符号常量"></a>符号常量</h4><p><code>#define pi 3.14</code></p><p>const 数据类型 变量名 = 常量</p><p><code>const double pi = 3.14</code></p><h4 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h4><p>条件运算符 ( ? :)</p><p>A?B:C 即若A为真则返回B 若A为假则返回C</p><h3 id="顺序结构"><a href="#顺序结构" class="headerlink" title="顺序结构"></a>顺序结构</h3><h4 id="输入输出"><a href="#输入输出" class="headerlink" title="输入输出"></a>输入输出</h4><p>使用scanf输入</p><p><code>scanf("%d",&n);</code>n为变量名</p><p><img src="http://trk607.bvimg.com/19485/9b7febb9b794f54c.png" alt="photo01"></p><p>输出时要是想输出%或\需要在前面再加一个%或\</p><p>输出格式:%md可以使不足m位的int型变量以m位进行右对齐输出,其中高位用空格补齐,如果变量本身超过m位,则保持原样</p><p>%0md和上面那个不同的是补位不用空格而用0</p><p>%。mf可以让浮点数保留m位小数输出</p><h5 id="对于字符串输入输出"><a href="#对于字符串输入输出" class="headerlink" title="对于字符串输入输出"></a>对于字符串输入输出</h5><p>使用getchar()输入单个字符,putchar()输出单个字符</p><h4 id="typedef"><a href="#typedef" class="headerlink" title="typedef"></a>typedef</h4><p>给复杂数据类型起别名</p><p><code>typedef long long LL;</code></p><p>便于提高编码效率</p><h4 id="常用math函数"><a href="#常用math函数" class="headerlink" title="常用math函数"></a>常用math函数</h4><p><code>fabs(double x)</code>对于double类型变量取绝对值</p><p><code>floor(double x)和ceil(double x)</code>用于对double类型变量的向下取整和向上取整,返回类型位double</p><p><code>pow(double r, double p)</code>用于返回<br>$$<br>r^p<br>$$<br><code>sqrt(double x)</code>用于返回double型变量的算术平方根</p><p><code>log(double x)</code>用于返回double型变量的以自然对数为底的对数,c语言中没有对任意底数求对数的函数,需要使用换底公式来转换为以e为底数的对数</p><p><code>sin(double x) cos(double x) tan(double x)</code></p><p><code>round(double x)</code>用于将double型变量x四舍五入,返回类型也是double型,需要取整</p><h3 id="选择结构"><a href="#选择结构" class="headerlink" title="选择结构"></a>选择结构</h3><h4 id="if语句"><a href="#if语句" class="headerlink" title="if语句"></a>if语句</h4><h4 id="switch语句"><a href="#switch语句" class="headerlink" title="switch语句"></a>switch语句</h4><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-keyword">switch</span>(表达式){<br><span class="hljs-keyword">case</span> 表达式<span class="hljs-number">1</span>:<br>...<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">default</span>:<br>...<br>}<br></code></pre></td></tr></table></figure><p>如果没有break那么符合条件及之后的所有语句都会进行输出</p><h3 id="循环结构"><a href="#循环结构" class="headerlink" title="循环结构"></a>循环结构</h3><h4 id="while语句"><a href="#while语句" class="headerlink" title="while语句"></a>while语句</h4><h4 id="do-while语句"><a href="#do-while语句" class="headerlink" title="do while语句"></a>do while语句</h4><h4 id="for语句"><a href="#for语句" class="headerlink" title="for语句"></a>for语句</h4><h3 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h3><h4 id="一维数组"><a href="#一维数组" class="headerlink" title="一维数组"></a>一维数组</h4><p>数组就是从某个地址开始连续若干个位置形成的元素集合</p><h4 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-keyword">include</span><span class="hljs-string"><stdio.h></span></span><br><br><span class="hljs-type">int</span> <span class="hljs-title function_">main</span><span class="hljs-params">()</span>{<br> <span class="hljs-type">int</span> a[<span class="hljs-number">10</span>]={<span class="hljs-number">3</span>,<span class="hljs-number">1</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">2</span>};<br> <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i=<span class="hljs-number">1</span>;i<=<span class="hljs-number">4</span>;i++){<br> <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> j=<span class="hljs-number">0</span>;j<<span class="hljs-number">5</span>-i;j++){<br> <span class="hljs-keyword">if</span>(a[j]>a[j+<span class="hljs-number">1</span>]){<br> <span class="hljs-type">int</span> temp= a[j];<br> a[j]=a[j+<span class="hljs-number">1</span>];<br> a[j+<span class="hljs-number">1</span>]=temp;<br> }<br> }<br> }<br> <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i=-;i<<span class="hljs-number">5</span>;i++){<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d "</span>,a[i]);<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h4 id="二维数组"><a href="#二维数组" class="headerlink" title="二维数组"></a>二维数组</h4><h4 id="memset"><a href="#memset" class="headerlink" title="memset"></a>memset</h4><p>对数组中每一个元素赋以相同的值</p><p><code>memset(数组名,值,sizeof(数组名))</code></p><p>头文件需要string.h头文件,一般只用此对数组赋值0和-1,因为memset是按字节赋值,int型的四个bit会被赋值为同一个,而0的补码全0,-1的补码全为1,如果对数组赋其他数字,应使用fill函数,但memset函数的执行速度更快</p><h4 id="字符数组"><a href="#字符数组" class="headerlink" title="字符数组"></a>字符数组</h4><h5 id="字符数组的初始化"><a href="#字符数组的初始化" class="headerlink" title="字符数组的初始化"></a>字符数组的初始化</h5><p>直接大括号内单引号单个初始化;也可以直接赋值字符串来初始化,双引号内赋值</p><h5 id="字符数组的输入输出"><a href="#字符数组的输入输出" class="headerlink" title="字符数组的输入输出"></a>字符数组的输入输出</h5><p>输入类型有%s和%c c是单个字符的输入,可以识别空格和换行,s是字符串的输入,通过空格和换行识别字符串的结束,且用scanf输入时,后面对应的数组名不用加&取地址符</p><p>getchar和putchar分别用来输入和输出单个字符,<code>str[i][j]=getchar(); putchar(str[i][j])</code></p><p>gets输入,puts输出,gets用来输入一行字符串,gets识别换行符\n作为输入结束,就是每次输入需要重启一行</p><p>字符数组最后都有一个结束字符\0,所以字符数组要比字符的长度多1,int型不用加\0,且空字符与空格并不是一种东西;如果使用输入字符串数组并不是scanf和gets类型,则需要在输入的每个字符串后面加\0,否则输出无法识别</p><h4 id="string-h头文件"><a href="#string-h头文件" class="headerlink" title="string.h头文件"></a>string.h头文件</h4><h5 id="strlen()"><a href="#strlen()" class="headerlink" title="strlen()"></a>strlen()</h5><p>可以得到字符数组第一个\0前的字符个数</p><h5 id="strcmp"><a href="#strcmp" class="headerlink" title="strcmp()"></a>strcmp()</h5><p>返回两个字符串大小的比较结果<code>strcmp(字符数组1,字符数组2)</code>如果1小于2则返回负数,1大于2返回正数,相等为0</p><h5 id="strcpy"><a href="#strcpy" class="headerlink" title="strcpy()"></a>strcpy()</h5><p><code>strcpy(字符数组1,字符数组2)</code>把第二个数组复制给数组1</p><h5 id="strcat"><a href="#strcat" class="headerlink" title="strcat()"></a>strcat()</h5><p><code>strcat(字符数组1,字符数组2)</code>把数组2连接到数组1后面</p><h5 id="sscanf-sprintf"><a href="#sscanf-sprintf" class="headerlink" title="sscanf sprintf"></a>sscanf sprintf</h5><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-built_in">sscanf</span>(str,<span class="hljs-string">"%d"</span>,&n);<br><span class="hljs-built_in">sprintf</span>(str,<span class="hljs-string">"%d"</span>,n);<br></code></pre></td></tr></table></figure><p>sscanf作用是把str中的内容以%d写入到n中,sprintf把n以%d 的格式写入到str字符数组,从右至左</p><h3 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h3><h4 id="函数的定义"><a href="#函数的定义" class="headerlink" title="函数的定义"></a>函数的定义</h4><h3 id="指针"><a href="#指针" class="headerlink" title="指针"></a>指针</h3><h4 id="什么是指针"><a href="#什么是指针" class="headerlink" title="什么是指针"></a>什么是指针</h4><p>指针是一个unsigned类型的整数</p><h4 id="指针变量"><a href="#指针变量" class="headerlink" title="指针变量"></a>指针变量</h4><p>指针变量用来存放指针,指针变量通过在某种数据类型后面加*来表示这是一个指针变量</p><p>如果有好几个同种类型的指针变量都要同时定义,星号只会结合于第一个变量名,若需要每个变量都是指针变量,那么需要在后面的每个变量名之前都加上星号</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> a;<br><span class="hljs-type">int</span>* p=&a;<br></code></pre></td></tr></table></figure><p>int*是变量的类型,p是变量名,用于存储地址,因此地址&a是赋值给p而不是 *p的</p><p>如果定义了 int* p = &a 那么指针变量p就存放了a的地址,可以通过p来获得变量a,*p就代表着获取了变量a的值</p><p>对指针变量来说,把其存储的地址的类型称为基类型,如int* p的指针变量,int就是它的基类型。基类型必须和指针变量存储的地址类型相同,也就是说,上面定义的指针变量p不能够存放double型或char型数据的地址,而必须是int型数据的地址。</p><h4 id="指针与数组"><a href="#指针与数组" class="headerlink" title="指针与数组"></a>指针与数组</h4><h4 id="使用指针变量作为函数参数"><a href="#使用指针变量作为函数参数" class="headerlink" title="使用指针变量作为函数参数"></a>使用指针变量作为函数参数</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">void</span> <span class="hljs-title function_">change</span><span class="hljs-params">(<span class="hljs-type">int</span>* p)</span>{<br> *p=<span class="hljs-number">233</span>;<br>}<br><span class="hljs-type">int</span> <span class="hljs-title function_">main</span><span class="hljs-params">()</span>{<br> <span class="hljs-type">int</span> a=<span class="hljs-number">1</span>;<br> <span class="hljs-type">int</span>* p=&a;<br> change(p);<br>}<br></code></pre></td></tr></table></figure><h4 id="交换"><a href="#交换" class="headerlink" title="交换"></a>交换</h4><p>p68,需要对指针中内容进行交换,而不是地址的副本交换</p><h4 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h4><h4 id="指针的引用"><a href="#指针的引用" class="headerlink" title="指针的引用"></a>指针的引用</h4><p>想要通过传入的地址来达到交换两个变量的效果,此处可以通过引用来实现</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">void</span> <span class="hljs-title function_">swap</span><span class="hljs-params">(<span class="hljs-type">int</span>* &a,<span class="hljs-type">int</span>* &b)</span>{<br> <span class="hljs-type">int</span>* temp=a;<br> a=b;<br> b=temp;<br>}<br></code></pre></td></tr></table></figure><p>这样做就相当于直接交换两个整型变量,因为a和b作为变量别名出现了</p><p>注意的是,常量不可以使用引用,不可以写成swap(&a,&b),必须要用指针变量存放&a,并且将指针变量作为参数传入</p><h3 id="结构体"><a href="#结构体" class="headerlink" title="结构体"></a>结构体</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Name</span>{</span><br> <span class="hljs-comment">//一些基本的数据结构或者自定义的数据类型</span><br>}Alice,Bob,stu[<span class="hljs-number">100</span>];<br></code></pre></td></tr></table></figure><h4 id="访问结构体内的元素"><a href="#访问结构体内的元素" class="headerlink" title="访问结构体内的元素"></a>访问结构体内的元素</h4><p>有两种方法,.和-></p><p>可以写作stu.name ; (*p).id ; p->id</p><h4 id="结构体的初始化"><a href="#结构体的初始化" class="headerlink" title="结构体的初始化"></a>结构体的初始化</h4><p>使用构造函数,构造函数不用写返回类型,而且函数名和结构体名相同</p><p><img src="http://trk607.bvimg.com/19485/05763eac0f4a46fb.png" alt="photo02"></p><p>只要参数个数和类型不能完全相同,就可以定义任意多个构造函数,来适应多个不同的初始化场合</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">studentInfo</span>{<br> <span class="hljs-type">int</span> id;<br> <span class="hljs-type">char</span> gender;<br> <br> <span class="hljs-built_in">studentInfo</span>(){} <span class="hljs-comment">//不初始化就定义结构体变量</span><br> <span class="hljs-built_in">studentInfo</span>(<span class="hljs-type">int</span> _id): <span class="hljs-built_in">id</span>(_id){}<br> <span class="hljs-built_in">studentInfo</span>(<span class="hljs-type">int</span> _id,<span class="hljs-type">char</span> _gender):<span class="hljs-built_in">id</span>(_id),<span class="hljs-built_in">gender</span>(_gender)()<br>};<br></code></pre></td></tr></table></figure><h3 id="补充"><a href="#补充" class="headerlink" title="补充"></a>补充</h3><h4 id="cin与cout"><a href="#cin与cout" class="headerlink" title="cin与cout"></a>cin与cout</h4><p>需要添加头文件iostream和using namespace std才能使用</p><p>如果想读入一整行,需要使用getline函数,cin.getline(str,100);把一整行都读入char型数组str中</p><h4 id="浮点数的比较"><a href="#浮点数的比较" class="headerlink" title="浮点数的比较"></a>浮点数的比较</h4><p>eps取1e-8</p><p><code>#define equ(a,b) ((fabs(a)-(b))<(eps))</code></p><p>如果差的绝对值小于eps,那么就认为两数相同</p>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>可以评论的第一篇博客</title>
<link href="/2023/01/11/hello-world/"/>
<url>/2023/01/11/hello-world/</url>
<content type="html"><![CDATA[<p>欢迎来到我的博客,可以在这篇底下进行评论 : D</p><p>祝你天天开心~</p>]]></content>
</entry>
</search>