-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
534 lines (268 loc) · 464 KB
/
atom.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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Kahvia`s Home</title>
<subtitle>你站在桥上看风景,看风景人在楼上看你。</subtitle>
<link href="https://blog.kahvia.cn/atom.xml" rel="self"/>
<link href="https://blog.kahvia.cn/"/>
<updated>2024-08-28T14:59:15.065Z</updated>
<id>https://blog.kahvia.cn/</id>
<author>
<name>Kahvia</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Linux小知识</title>
<link href="https://blog.kahvia.cn/2024/08/28/LinuxOperations.html"/>
<id>https://blog.kahvia.cn/2024/08/28/LinuxOperations.html</id>
<published>2024-08-28T07:12:03.408Z</published>
<updated>2024-08-28T14:59:15.065Z</updated>
<content type="html"><![CDATA[<h3 id="添加用户"><a class="markdownIt-Anchor" href="#添加用户"></a> 添加用户</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adduser xxx</span><br></pre></td></tr></table></figure><h3 id="为用户赋予去除sudo权限"><a class="markdownIt-Anchor" href="#为用户赋予去除sudo权限"></a> 为用户赋予/去除sudo权限</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo usermod -a -G sudo username</span><br></pre></td></tr></table></figure><p><code>sudo usermod -a -G sudo username</code> 这是一个Linux命令,用于管理用户组权限。它表示将用户(username)添加到sudo用户组。</p><ul><li><code>usermod</code>: 用户管理工具</li><li><code>-a</code>: 表示追加(append),即如果该用户已经存在于其他组,不会将其移除</li><li><code>-G</code>: 指定用户应加入的组名,这里是<code>sudo</code></li><li><code>username</code>: 需要修改权限的用户名</li></ul><p>执行这个命令后,指定的用户会获得sudo权限,允许他们使用sudo命令来执行需要管理员权限的操作。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo usermod -G usergroup username</span><br></pre></td></tr></table></figure><p>将用户转移到 usergroup 用户组中,即移出 sudo 用户群。</p><h3 id="安装zsh"><a class="markdownIt-Anchor" href="#安装zsh"></a> 安装Zsh</h3><p><a href="https://www.zsh.org/">Zsh</a>是 bash 的平替,有着如诸如输入目录名称自动 cd ,以及目录名自动更正等功能。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt update</span><br><span class="line">sudo apt install zsh</span><br></pre></td></tr></table></figure><h3 id="安装homebrew"><a class="markdownIt-Anchor" href="#安装homebrew"></a> 安装HomeBrew</h3><figure class="highlight bash"><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><span class="line"><span class="comment">#官方</span></span><br><span class="line">/bin/bash -c <span class="string">"<span class="subst">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)</span>"</span></span><br><span class="line"><span class="comment">#非官方</span></span><br><span class="line">/bin/zsh -c <span class="string">"<span class="subst">$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)</span>"</span></span><br></pre></td></tr></table></figure><h3 id="安装nodejs"><a class="markdownIt-Anchor" href="#安装nodejs"></a> 安装Nodejs</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install node@20</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h3 id="添加用户"><a class="markdownIt-Anchor" href="#添加用户"></a> 添加用户</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><sp</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="Linux" scheme="https://blog.kahvia.cn/tags/Linux/"/>
</entry>
<entry>
<title>Python常用语法</title>
<link href="https://blog.kahvia.cn/2024/07/16/PythonGrammar.html"/>
<id>https://blog.kahvia.cn/2024/07/16/PythonGrammar.html</id>
<published>2024-07-16T02:05:01.856Z</published>
<updated>2024-07-16T05:16:26.059Z</updated>
<content type="html"><![CDATA[<h3 id="字符串格式化"><a class="markdownIt-Anchor" href="#字符串格式化"></a> 字符串格式化</h3><p>格式化的过程中,如果遇到数字,可以使用 <code>:[格式]</code>来指定数字的格式。</p><ol><li>采用 f 前缀进行格式化。</li></ol><figure class="highlight python"><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><span class="line">name = <span class="string">'Kahvia'</span></span><br><span class="line">money = <span class="number">143.257</span></span><br><span class="line">dialog = <span class="string">f'Hello <span class="subst">{name}</span>, your money is <span class="subst">{money:<span class="number">.2</span>f}</span>.'</span></span><br><span class="line"><span class="built_in">print</span>(dialog)</span><br></pre></td></tr></table></figure><blockquote><p>Hello Kahvia, your money is 143.26.</p></blockquote><ol start="2"><li>采用 format 方法</li></ol><figure class="highlight python"><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><span class="line">name = <span class="string">'Kahvia'</span></span><br><span class="line">name2 = <span class="string">'Adong'</span></span><br><span class="line">dialog = <span class="string">'Hello {0}, and {1}.'</span>.<span class="built_in">format</span>(name, name2)</span><br><span class="line"><span class="built_in">print</span>(dialog)</span><br><span class="line">dialog = <span class="string">'Hello {n1}, and {n2}.'</span>.<span class="built_in">format</span>(n1=name, n2=name2)</span><br><span class="line"><span class="built_in">print</span>(dialog)</span><br></pre></td></tr></table></figure><blockquote><p>Hello Kahvia, and Adong.<br />Hello Kahvia, and Adong.</p></blockquote><h3 id="自定义函数"><a class="markdownIt-Anchor" href="#自定义函数"></a> 自定义函数</h3><p>采用关键词 def 来定义函数,并跟随<code>:</code>表示下面的缩进行是函数体。</p><figure class="highlight python"><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><span class="line"><span class="keyword">def</span> <span class="title function_">make_friends</span>(<span class="params">name1, name2</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{name1}</span> and <span class="subst">{name2}</span> are friends now!"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">name = <span class="string">'Kahvia'</span></span><br><span class="line">name2 = <span class="string">'Adong'</span></span><br><span class="line">make_friends(name, name2)</span><br></pre></td></tr></table></figure><blockquote><p>Kahvia and Adong are friends now!</p></blockquote><h3 id="引入模块"><a class="markdownIt-Anchor" href="#引入模块"></a> 引入模块</h3><p>采用 import 引入一个模块中的方法和变量。</p><ol><li><code>import statistics</code>,使用模块中的方法时,采用<code>statistics.median([1,2,3])</code></li><li><code>from statistics import median, mean</code>,使用方法时,采用<code>median([1,2,3])</code></li><li><code>from statistics import *</code>,使用方法同2。但是容易造成模块之间的方法或者变量冲突。</li></ol><p>常使用第一种和第二种。第三方模块可以在网站<a href="https://pypi.org/">PyPI · The Python Package Index</a>上进行查看。</p><h3 id="类"><a class="markdownIt-Anchor" href="#类"></a> 类</h3><h4 id="定义"><a class="markdownIt-Anchor" href="#定义"></a> 定义</h4><p>采用 class 关键词定义一个类,并在对应的代码块中采用<code>_init_</code>来定义初始化对象的构造函数。定义其它方法时,也必须要将 self 作为第一个形参。</p><figure class="highlight python"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line"> self.name = name</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">say_hello</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'Hello my name is <span class="subst">{self.name}</span>.'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Kahvia = Person(<span class="string">'Kahvia'</span>)</span><br><span class="line">Kahvia.say_hello()</span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><p>Hello my name is Kahvia.</p></blockquote><h4 id="继承"><a class="markdownIt-Anchor" href="#继承"></a> 继承</h4><p>定义类的时候,后接括号包裹父类。</p><figure class="highlight python"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Teacher</span>(<span class="title class_ inherited__">Person</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, level</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(name)</span><br><span class="line"> self.level = level</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">teach</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"I am <span class="subst">{self.name}</span>, a teacher."</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>(<span class="title class_ inherited__">Person</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, class_no</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(name)</span><br><span class="line"> self.class_no = class_no</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">study</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"I am <span class="subst">{self.name}</span>, a student."</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">t1 = Teacher(<span class="string">"Kahvia"</span>, <span class="number">6</span>)</span><br><span class="line">s1 = Student(<span class="string">"Adong"</span>, <span class="number">1</span>)</span><br><span class="line">t1.teach()</span><br><span class="line">s1.study()</span><br></pre></td></tr></table></figure><blockquote><p>I am Kahvia, a teacher.<br />I am Adong, a student.</p></blockquote><h3 id="文件读写"><a class="markdownIt-Anchor" href="#文件读写"></a> 文件读写</h3><p>注意,读模式打开文件时,若是文件不存在,会报错。</p><h4 id="readline"><a class="markdownIt-Anchor" href="#readline"></a> readline</h4><p>一次只读一行,内容包括换行符。</p><figure class="highlight python"><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><span class="line">file = <span class="built_in">open</span>(<span class="string">'book.txt'</span>, <span class="string">'r'</span>, encoding=<span class="string">'utf-8'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 像下面这样写是不对的,python不允许在条件语句中进行赋值操作,这是为了防止出现在比较中将 == 写成 = 的低级错误,这种错误不容易发现,因为可以运行。</span></span><br><span class="line"><span class="comment"># while (line = file.readline()) != "":</span></span><br><span class="line"><span class="comment"># print(line)</span></span><br><span class="line"></span><br><span class="line">line = file.readline()</span><br><span class="line"><span class="keyword">while</span> line != <span class="string">""</span>:</span><br><span class="line"> <span class="comment"># 打印的end设置为空,防止默认的换行与文件中的换行叠加。</span></span><br><span class="line"> <span class="built_in">print</span>(line, end=<span class="string">""</span>)</span><br><span class="line"> line = file.readline()</span><br><span class="line">file.close()</span><br></pre></td></tr></table></figure><blockquote><p>你存在<br />我深深的脑海里<br />我的心里</p></blockquote><h4 id="read"><a class="markdownIt-Anchor" href="#read"></a> read</h4><p>一次全读出来,不适合对大文件使用。</p><figure class="highlight python"><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><span class="line">file = <span class="built_in">open</span>(<span class="string">'book.txt'</span>, <span class="string">'r'</span>, encoding=<span class="string">'utf-8'</span>)</span><br><span class="line"><span class="comment"># 注意打印结尾有print默认的换行</span></span><br><span class="line"><span class="built_in">print</span>(file.read())</span><br><span class="line">file.close()</span><br></pre></td></tr></table></figure><blockquote><p>你存在<br />我深深的脑海里<br />我的心里</p></blockquote><h4 id="readlines"><a class="markdownIt-Anchor" href="#readlines"></a> readlines</h4><p>读出文件中所有行,放在列表中并返回。</p><figure class="highlight python"><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><span class="line">file = <span class="built_in">open</span>(<span class="string">'book.txt'</span>, <span class="string">'r'</span>, encoding=<span class="string">'utf-8'</span>)</span><br><span class="line"><span class="built_in">print</span>(file.readlines())</span><br><span class="line">file.close()</span><br></pre></td></tr></table></figure><blockquote><p>[‘你存在\n’, ‘我深深的脑海里\n’, ‘我的心里’]</p></blockquote><h4 id="with-open-as"><a class="markdownIt-Anchor" href="#with-open-as"></a> with open … as …</h4><p>这种写法可以不用close,执行完毕即close。</p><figure class="highlight python"><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><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'book.txt'</span>, <span class="string">'r'</span>, encoding=<span class="string">'utf-8'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> <span class="comment"># 注意打印结尾有print默认的换行</span></span><br><span class="line"> <span class="built_in">print</span>(file.read())</span><br></pre></td></tr></table></figure><h4 id="write"><a class="markdownIt-Anchor" href="#write"></a> write</h4><p>write不会自动添加换行符,要换行只能自己补充<code>\n</code>。使用 w 模式打开时,若无文件会自动创建,有则清空。若是不希望清空,则需指定为 a 模式,即append,意为追加。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'book.txt'</span>, <span class="string">'w'</span>, encoding=<span class="string">'utf-8'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> file.write(<span class="string">"Hello World"</span>)</span><br></pre></td></tr></table></figure><h4 id="同时读写"><a class="markdownIt-Anchor" href="#同时读写"></a> 同时读写</h4><p>正常情况下,指定打开模式为 r 时,只能读,指定 w 时,只能写。若要既能读又能写,则需要指定为<code>r+</code>,此时write语句会以追加的形式写入到文件后面,同append。</p><h3 id="异常处理"><a class="markdownIt-Anchor" href="#异常处理"></a> 异常处理</h3><p>使用 try…except…else… 来处理异常。</p><h3 id="代码测试"><a class="markdownIt-Anchor" href="#代码测试"></a> 代码测试</h3><p>使用 unittest 。</p><h3 id="高阶函数和匿名函数"><a class="markdownIt-Anchor" href="#高阶函数和匿名函数"></a> 高阶函数和匿名函数</h3><p>高阶函数:将另一个函数作为参数的函数。</p><p>匿名函数(lambda函数):<code>lambda para1, para2, ... : para1 op para2 op ...</code>,比如<code>lambda num: num * 5</code>就是一个表达式,传入一个数字,返回五倍的数字。</p><p>lambda 表达式可用于高阶函数作为实参传递。</p>]]></content>
<summary type="html"><h3 id="字符串格式化"><a class="markdownIt-Anchor" href="#字符串格式化"></a> 字符串格式化</h3>
<p>格式化的过程中,如果遇到数字,可以使用 <code>:[格式]</code>来指定数字的格式。</p>
<ol>
<li</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="python" scheme="https://blog.kahvia.cn/tags/python/"/>
</entry>
<entry>
<title>LaTeX语法</title>
<link href="https://blog.kahvia.cn/2024/06/21/LaTeX.html"/>
<id>https://blog.kahvia.cn/2024/06/21/LaTeX.html</id>
<published>2024-06-21T10:03:10.459Z</published>
<updated>2024-07-17T16:07:06.530Z</updated>
<content type="html"><![CDATA[<h3 id="anzhiyu主题配置数学公式"><a class="markdownIt-Anchor" href="#anzhiyu主题配置数学公式"></a> Anzhiyu主题配置数学公式</h3><p>有两种方法。</p><p>方法一,参考<a href="https://www.yyyzyyyz.cn/posts/654d8712aff4/#4-%E4%BD%BF%E7%94%A8pandoc%E8%8E%B7%E5%BE%97%E6%9B%B4%E5%A5%BD%E7%9A%84mathjax%E6%94%AF%E6%8C%81">为hexo博客更换pandoc渲染</a>,使用<em>mathjax</em>无论是前端渲染还是后端渲染公式块都无法正常换行。</p><p>方法二,参考<a href="https://blog.windsky.tech/2021/01/30/Hexo-Katex/">Hexo博客渲染KaTeX数学公式</a>,可以正常渲染。</p><p>最终采用了第二种渲染方法。步骤如下所示。</p><ol><li><p>关闭主题自带的 mathjax 和 katex 。因为方法二采用的是自己启用 katex 。</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># Math (数学)</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># About the per_page</span></span><br><span class="line"><span class="comment"># if you set it to true, it will load mathjax/katex script in each page (true 表示每一页都加载js)</span></span><br><span class="line"><span class="comment"># if you set it to false, it will load mathjax/katex script according to your setting (add the 'mathjax: true' in page's front-matter)</span></span><br><span class="line"><span class="comment"># (false 需要时加载,须在使用的 Markdown Front-matter 加上 mathjax: true)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># MathJax</span></span><br><span class="line"><span class="attr">mathjax:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">per_page:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># KaTeX</span></span><br><span class="line"><span class="attr">katex:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">per_page:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">hide_scrollbar:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>为什么不用主题自带的 mathjax ,因为无法正确换行。<br />为什么不用主题自带的 katex ,因为渲染经常失灵,本地渲染成功后部署到 github 以后才是正常的,不过经常本地都渲染失败,根据我多方查找资料,这跟 pjax 有关,关掉主题中的 pjax 或许有效,但会影响其它功能。至于 pjax 如何使渲染失效,我不清楚,因为<a href="https://blog.pai233.top/20210930/hexo-katex/">路人甲</a>也不清楚,<a href="https://blog.aqcoder.cn/posts/6e665e82/#%E8%A7%A3%E5%86%B3%E8%BF%87%E7%A8%8B">路人乙</a>也不是很清楚。但终归是找到的方法二这样的解决方法。</p></li><li><p>卸载hexo自带的渲染渲染器,因为它渲染不了数学公式。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm uni hexo-renderer-marked</span><br></pre></td></tr></table></figure><p>安装 hexo-renderer-markdown-it-plus 渲染器。此渲染器默认包含且开启了 <code>@iktakahiro/markdown-it-katex</code> 插件,可渲染 11.1 版本以前的 KaTeXKATEX 公式。但 KaTeXKATEX 自 13.0 开始渲染机制发生了变化,需要更换为 <code>@andatoshiki/markdown-it-katex</code> 插件。</p><figure class="highlight bash"><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><span class="line">npm i hexo-renderer-markdown-it-plus</span><br><span class="line">npm install katex</span><br><span class="line">npm install @andatoshiki/markdown-it-katex</span><br></pre></td></tr></table></figure><p>在<code>_config.yml</code>中配置 markdown_it_plus 渲染器,即关闭其自带的 <code>@iktakahiro/markdown-it-katex</code> 插件,启用新版插件 <code>@andatoshiki/markdown-it-katex</code>。</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><span class="line"><span class="attr">markdown_it_plus:</span></span><br><span class="line"> <span class="comment"># ...</span></span><br><span class="line"> <span class="attr">plugins:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">plugin:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">'@iktakahiro/markdown-it-katex'</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">plugin:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">'@andatoshiki/markdown-it-katex'</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure></li><li><p>在主题配置文件中,引入katex的css文件。</p><figure class="highlight yaml"><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><span class="line"><span class="attr">inject:</span></span><br><span class="line"> <span class="attr">head:</span></span><br><span class="line"> <span class="comment"># 自定义css</span></span><br><span class="line"> <span class="comment"># - <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"></span></span><br><span class="line"> <span class="bullet">-</span> <span class="string"><link</span> <span class="string">rel="stylesheet"</span> <span class="string">href="https://lib.baomitu.com/KaTeX/latest/katex.min.css"></span></span><br></pre></td></tr></table></figure></li><li><p><code>hexo cl</code>、<code>hexo g</code>、<code>hexo s</code>,小三连查看效果,确认生效后<code>hexo cl</code>、<code>hexo g -d</code>,部署到云端。</p></li></ol><h3 id="分数"><a class="markdownIt-Anchor" href="#分数"></a> 分数</h3><p>frac :fraction,分数。</p><figure class="highlight latex"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\frac</span>{son}{mother}</span><br></pre></td></tr></table></figure><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mrow><mi>s</mi><mi>o</mi><mi>n</mi></mrow><mrow><mi>m</mi><mi>o</mi><mi>t</mi><mi>h</mi><mi>e</mi><mi>r</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\frac{son}{mother}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.7935600000000003em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><h3 id="偏导"><a class="markdownIt-Anchor" href="#偏导"></a> 偏导</h3><p>partial :偏爱的。</p><figure class="highlight latex"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\frac</span>{<span class="keyword">\partial</span> f}{<span class="keyword">\partial</span> x}</span><br></pre></td></tr></table></figure><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>f</mi></mrow><mrow><mi mathvariant="normal">∂</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\frac{\partial f}{\partial x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.0574399999999997em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714399999999998em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><h3 id="向量"><a class="markdownIt-Anchor" href="#向量"></a> 向量</h3><p>vec :vector,向量。</p><p>overrightarrow:上方右箭头。</p><p>overleftarrow:上方左箭头。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mspace width="1em"/><mover accent="true"><mi>x</mi><mo stretchy="true">→</mo></mover><mspace width="1em"/><mover accent="true"><mi>y</mi><mo stretchy="true">←</mo></mover></mrow><annotation encoding="application/x-tex">\vec x \quad \overrightarrow x \quad \overleftarrow y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.147em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9525600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span class="svg-align" style="top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="height:0.522em;min-width:0.888em;"><svg width='400em' height='0.522em' viewBox='0 0 400000 522' preserveAspectRatio='xMaxYMin slice'><path d='M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 151.7 139 205zm0 0v40h399900v-40z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9525600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span><span class="svg-align" style="top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="height:0.522em;min-width:0.888em;"><svg width='400em' height='0.522em' viewBox='0 0 400000 522' preserveAspectRatio='xMinYMin slice'><path d='M400000 241H110l3-3c68.7-52.7 113.7-120 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202 l-3-3h399890zM100 241v40h399900v-40z'/></svg></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span></span></p><h3 id="点乘"><a class="markdownIt-Anchor" href="#点乘"></a> 点乘</h3><p>cdot:circle dot,圆点。</p><figure class="highlight latex"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\vec</span> x <span class="keyword">\cdot</span> <span class="keyword">\vec</span> y</span><br></pre></td></tr></table></figure><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mo>⋅</mo><mover accent="true"><mi>y</mi><mo>⃗</mo></mover></mrow><annotation encoding="application/x-tex">\vec x \cdot \vec y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.714em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9084399999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.17994em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span></span></p>]]></content>
<summary type="html"><h3 id="anzhiyu主题配置数学公式"><a class="markdownIt-Anchor" href="#anzhiyu主题配置数学公式"></a> Anzhiyu主题配置数学公式</h3>
<p>有两种方法。</p>
<p>方法一,参考<a href="http</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="latex" scheme="https://blog.kahvia.cn/tags/latex/"/>
</entry>
<entry>
<title>机器学习</title>
<link href="https://blog.kahvia.cn/2024/06/21/MachineLearning.html"/>
<id>https://blog.kahvia.cn/2024/06/21/MachineLearning.html</id>
<published>2024-06-21T07:47:15.746Z</published>
<updated>2024-06-25T17:49:53.153Z</updated>
<content type="html"><![CDATA[<h3 id="机器学习分类"><a class="markdownIt-Anchor" href="#机器学习分类"></a> 机器学习分类</h3><p>机器学习分为监督学习和非监督学习。</p><p>监督学习:输入数据得到“正确的”输出,输入与输出是映射关系。回归算法(Regression),比如用线性回归来预测房价;分类算法(Classification),比如输入肿瘤信息将其分类为良性、恶性等类别。</p><p>非监督学习:输入数据得到的输出没有“正确”的概念,常用于寻找数据中的结构。聚类算法(Clustering),将相似的数据归类在一起;异常检测(Anomaly Detection),找出不寻常的数据;降维(Dimensionality Reduction),将大数据集压缩成小数据集并尽可能减少信息丢失。</p><h3 id="线性回归"><a class="markdownIt-Anchor" href="#线性回归"></a> 线性回归</h3><p>x -> f -> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span> 。</p><ul><li>x 是输入变量(input variable),又称特征(feature)。</li><li>y 是输出变量(output variable),又称目标变量(target variable),是训练集(training set)中的实际真实值。</li><li>m 是训练样本数,数据集的大小。number of training examples。</li><li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span> 是模型(model)预测值</li></ul><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>s</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>l</mi><mi>e</mi><mspace width="1em"/><mi>t</mi><mi>r</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>i</mi><mi>n</mi><mi>g</mi><mspace width="1em"/><mi>e</mi><mi>x</mi><mi>a</mi><mi>m</mi><mi>p</mi><mi>l</mi><mi>e</mi><mspace linebreak="newline"></mspace><mspace linebreak="newline"></mspace><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo>=</mo><msup><mi>i</mi><mrow><mi>t</mi><mi>h</mi></mrow></msup><mspace width="1em"/><mi>t</mi><mi>r</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>i</mi><mi>n</mi><mi>g</mi><mspace width="1em"/><mi>e</mi><mi>x</mi><mi>a</mi><mi>m</mi><mi>p</mi><mi>l</mi><mi>e</mi></mrow><annotation encoding="application/x-tex">(x,y) = single \quad training \quad example \\\\(x^{(i)},y^{(i)}) = i^{th} \quad training \quad example</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span><span class="mspace newline"></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.188em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.938em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.938em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.093548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">i</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">h</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span></span></span></span></p><p>通过训练集训练模型(model),然后给模型输入x,模型输出 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span> 作为预测值。</p><h4 id="单输入线性回归linear-regression-with-one-variable"><a class="markdownIt-Anchor" href="#单输入线性回归linear-regression-with-one-variable"></a> 单输入线性回归(Linear regression with one variable)</h4><p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>o</mi><mi>d</mi><mi>e</mi><mi>l</mi><mo>:</mo><msub><mi>f</mi><mrow><mi>w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>w</mi><mi>x</mi><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">model : f_{w,b}(x) = wx + b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span></p><p>w 代表权重(weight),b 代表基础值(base value)。</p><h5 id="代价函数"><a class="markdownIt-Anchor" href="#代价函数"></a> 代价函数</h5><p>Cost function : Squared error cost function.</p><p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>J</mi><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><mn>2</mn><mi>m</mi></mrow></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">(</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mfrac><mn>1</mn><mrow><mn>2</mn><mi>m</mi></mrow></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">(</mo><msub><mi>f</mi><mrow><mi>w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">J(w,b) = \frac{1}{2m} \sum\limits_{i=1}^{m}(\hat{y}^{(i)} - y^{(i)})^2 = \frac1{2m} \sum\limits_{i=1}^m(f_{w,b}(x^{(i)}) - y^{(i)})^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.09618em;">J</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></p><p>训练集的代价越小,模型越符合预期。代价函数中的 2 是为了梯度下降中求偏导时使公式更加简洁,因为 J 求偏导时外函数的导数会产生乘 2 ,正好抵消。</p><h5 id="梯度下降gradient-descent-algorithm"><a class="markdownIt-Anchor" href="#梯度下降gradient-descent-algorithm"></a> 梯度下降(Gradient descent algorithm)</h5><p>用于最小化代价函数的一种算法。参考<a href="https://www.bilibili.com/video/BV19f421Q7CL/?spm_id_from=333.337.search-card.all.click&vd_source=c1d0ac10ebe4bb4e8cf6648904e6ed40">不至于吧,梯度下降简单得有点离谱了啊</a>。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>w</mi><mo>=</mo><mi>w</mi><mo>−</mo><mi>α</mi><mfrac><mi mathvariant="normal">∂</mi><mrow><mi mathvariant="normal">∂</mi><mi>w</mi></mrow></mfrac><mi>J</mi><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mspace linebreak="newline"></mspace><mspace linebreak="newline"></mspace><mi>b</mi><mo>=</mo><mi>b</mi><mo>−</mo><mi>α</mi><mfrac><mi mathvariant="normal">∂</mi><mrow><mi mathvariant="normal">∂</mi><mi>b</mi></mrow></mfrac><mi>J</mi><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">w = w - \alpha \frac{\partial}{\partial w} J(w,b) \\\\b = b - \alpha \frac{\partial}{\partial b} J(w,b)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.05744em;vertical-align:-0.686em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style="margin-right:0.09618em;">J</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span></span><span class="mspace newline"></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.05744em;vertical-align:-0.686em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal">b</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord" style="margin-right:0.05556em;">∂</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style="margin-right:0.09618em;">J</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span></span></span></span></span></p><p>其中,α 代表学习率,用于控制步长,防止步长过大导致 J 在最小值附近反复横跳而无法收敛。因此学习率的合适取值很重要。</p><p>偏导则作为方向以及基本步长。梯度是偏导数构成的向量。</p><h4 id="多元线性回归multiple-linear-regression"><a class="markdownIt-Anchor" href="#多元线性回归multiple-linear-regression"></a> 多元线性回归(Multiple linear regression)</h4><p>注:不是多元回归(Multivariate regression)。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x</mi><mi>j</mi></msub><mo>=</mo><msup><mi>j</mi><mrow><mi>t</mi><mi>h</mi></mrow></msup><mi>f</mi><mi>e</mi><mi>a</mi><mi>t</mi><mi>u</mi><mi>r</mi><mi>e</mi><mspace linebreak="newline"></mspace><mi>n</mi><mo>=</mo><mi>n</mi><mi>u</mi><mi>m</mi><mi>b</mi><mi>e</mi><mi>r</mi><mspace width="1em"/><mi>o</mi><mi>f</mi><mspace width="1em"/><mi>f</mi><mi>e</mi><mi>a</mi><mi>t</mi><mi>u</mi><mi>r</mi><mi>e</mi><mi>s</mi><mspace linebreak="newline"></mspace><msup><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>f</mi><mi>e</mi><mi>a</mi><mi>t</mi><mi>u</mi><mi>r</mi><mi>e</mi><mi>s</mi><mspace width="1em"/><mi>o</mi><mi>f</mi><mspace width="1em"/><msup><mi>i</mi><mrow><mi>t</mi><mi>h</mi></mrow></msup><mspace width="1em"/><mi>t</mi><mi>r</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>i</mi><mi>n</mi><mi>g</mi><mspace width="1em"/><mi>e</mi><mi>x</mi><mi>a</mi><mi>m</mi><mi>p</mi><mi>l</mi><mi>e</mi><mspace linebreak="newline"></mspace><msubsup><mi>x</mi><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mo>=</mo><mi>v</mi><mi>a</mi><mi>l</mi><mi>u</mi><mi>e</mi><mspace width="1em"/><mi>o</mi><mi>f</mi><mspace width="1em"/><mi>f</mi><mi>e</mi><mi>a</mi><mi>t</mi><mi>u</mi><mi>r</mi><mi>e</mi><mspace width="1em"/><mi>j</mi><mspace width="1em"/><mi>i</mi><mi>n</mi><mspace width="1em"/><msup><mi>i</mi><mrow><mi>t</mi><mi>h</mi></mrow></msup><mspace width="1em"/><mi>t</mi><mi>r</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>i</mi><mi>n</mi><mi>g</mi><mspace width="1em"/><mi>e</mi><mi>x</mi><mi>a</mi><mi>m</mi><mi>p</mi><mi>l</mi><mi>e</mi></mrow><annotation encoding="application/x-tex">x_j = j^{th}feature \\n = number \quad of \quad features \\\vec x^{(i)} = features \quad of \quad i^{th} \quad training \quad example \\x^{(i)}_j = value \quad of \quad feature \quad j \quad in \quad i^{th} \quad training \quad example</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.093548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">h</span></span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">u</span><span class="mord mathnormal">m</span><span class="mord mathnormal">b</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.938em;vertical-align:0em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.938em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.093548em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal">i</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">h</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.4577719999999998em;vertical-align:-0.412972em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.093548em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">u</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal">i</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">h</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span></span></span></span></p><p>现引入多个特征值x,每个x的下标不同。每个特征值都有对应的权重。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>f</mi><mrow><mover accent="true"><mi>w</mi><mo>⃗</mo></mover><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mo stretchy="false">)</mo><mo>=</mo><msub><mi>w</mi><mn>1</mn></msub><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><msub><mi>w</mi><mn>2</mn></msub><msub><mi>x</mi><mn>2</mn></msub><mo>+</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo>+</mo><msub><mi>w</mi><mi>n</mi></msub><msub><mi>x</mi><mi>n</mi></msub><mo>+</mo><mi>b</mi><mo>=</mo><mover accent="true"><mi>w</mi><mo>⃗</mo></mover><mo>⋅</mo><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mo>+</mo><mi>b</mi><mspace linebreak="newline"></mspace><mover accent="true"><mi>w</mi><mo>⃗</mo></mover><mo>=</mo><mo stretchy="false">[</mo><msub><mi>w</mi><mn>1</mn></msub><mspace width="1em"/><msub><mi>w</mi><mn>2</mn></msub><mspace width="1em"/><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mspace width="1em"/><msub><mi>w</mi><mi>n</mi></msub><mo stretchy="false">]</mo><mspace linebreak="newline"></mspace><mover accent="true"><mi>x</mi><mo>⃗</mo></mover><mo>=</mo><mo stretchy="false">[</mo><msub><mi>x</mi><mn>1</mn></msub><mspace width="1em"/><msub><mi>x</mi><mn>2</mn></msub><mspace width="1em"/><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mspace width="1em"/><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">f_{\vec w,b}(\vec x) = w_1x_1 + w_2x_2 + ... + w_nx_n + b = \vec w \cdot \vec x + b \\\vec w = [w_1 \quad w_2 \quad ... \quad w_n] \\\vec x = [x_1 \quad x_2 \quad ... \quad x_n]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.041108em;vertical-align:-0.2911079999999999em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.5450000000000004em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord accent mtight"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-2.714em;"><span class="pstrut" style="height:2.714em;"></span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span></span><span style="top:-2.714em;"><span class="pstrut" style="height:2.714em;"></span><span class="accent-body" style="left:-0.15216em;"><span class="overlay mtight" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.2911079999999999em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.714em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.15216em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.79733em;vertical-align:-0.08333em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.714em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.15216em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.714em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.714em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">x</span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.20772em;"><span class="overlay" style="height:0.714em;width:0.471em;"><svg width='0.471em' height='0.714em' style='width:0.471em' viewBox='0 0 471 714' preserveAspectRatio='xMinYMin'><path d='M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 53.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 1110.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359c-16-25.333-24-45-24-59z'/></svg></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:1em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span></span></p><h5 id="向量化"><a class="markdownIt-Anchor" href="#向量化"></a> 向量化</h5><p>在 python 中,我们常使用 numpy 库来进行科学计算。</p><p>通过<code>np.array()</code>初始化一维数组,通过<code>np.dot()</code>方法调用点乘运算。点乘方法比单纯的循环遍历相乘之和更加快速,特别是数据量大的情况下,因为 numpy 方法可以使用一些硬件来实现加速计算,比如分成多个部分并行计算?这比单纯的循环或许快上许多。</p><figure class="highlight python"><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><span class="line">w = np.array([<span class="number">1.0</span>, <span class="number">2.0</span>, <span class="number">3.0</span>])</span><br><span class="line">x = np.array([<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>])</span><br><span class="line">b = <span class="number">2</span></span><br><span class="line"><span class="comment"># 通过点乘的方式来简化运算</span></span><br><span class="line">f = np.dot(w,x) + b</span><br></pre></td></tr></table></figure><h5 id="特征缩放"><a class="markdownIt-Anchor" href="#特征缩放"></a> 特征缩放</h5><p>在使用梯度下降求解模型参数以最小化代价函数时,有时因为不同参数的取值范围不同,特别是一个范围特别大,一个范围特别小的情况下,会导致不同参数在各自方向上的下降步子相差较大。如果说梯度下降最好的情况是不同方向上的步子一致,经过合成后迈出的一步刚好是去往最低点的方向,那么上面提到的情况就是走得有点斜,相比较之下就是饶了圈子,虽然也能到达最低点,但是由于走的距离变长,需要的步子也就变多,即迭代次数变多。如下图所示,较优的是步子较少的路线,绕远路的则是较差路线。</p><p><img src="https://pics.kahvia.cn/img/%E7%89%B9%E5%BE%81%E7%BC%A9%E6%94%BE%E8%83%8C%E6%99%AF%E7%A4%BA%E4%BE%8B.png" alt="特征缩放背景图例" /></p><p>为了尽可能减少迭代次数,通过“特征缩放”可以协调不同方向上的下降距离,以优化梯度下降。而特征缩放的做法就是:对数据集的各个特征值进行处理,使得不同的特征具有相似的取值范围。下面有两种简单方法。</p><ol><li><strong>均值归一化(Mean normalization)</strong>:<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>=</mo><mfrac><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>μ</mi><mi>i</mi></msub></mrow><mrow><msub><mi>x</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi></mrow></msub><mo>−</mo><msub><mi>x</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">x_i = \frac {x_i - \mu_i} {x_{max} - x_{min}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2995389999999998em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.854439em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mord mathnormal mtight">a</span><span class="mord mathnormal mtight">x</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.446108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">μ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>,其中 μ 代表某个特征中的平均值,这是缩放到 0 的周围。</li><li><strong>最小-最大值归一化(min-max normalization)</strong>:<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>=</mo><mfrac><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></mrow><mrow><msub><mi>x</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi></mrow></msub><mo>−</mo><msub><mi>x</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi></mrow></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">x_i = \frac {x_i - x_{min}} {x_{max} - x_{min}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.263531em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8184309999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mord mathnormal mtight">a</span><span class="mord mathnormal mtight">x</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>,这是缩放到 [0,1] 区间。</li></ol>]]></content>
<summary type="html"><h3 id="机器学习分类"><a class="markdownIt-Anchor" href="#机器学习分类"></a> 机器学习分类</h3>
<p>机器学习分为监督学习和非监督学习。</p>
<p>监督学习:输入数据得到“正确的”输出,输入与输出是映射关系。回归算法(</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="MachineLeaning" scheme="https://blog.kahvia.cn/tags/MachineLeaning/"/>
</entry>
<entry>
<title>Anaconda</title>
<link href="https://blog.kahvia.cn/2024/06/05/Anaconda.html"/>
<id>https://blog.kahvia.cn/2024/06/05/Anaconda.html</id>
<published>2024-06-05T15:18:40.580Z</published>
<updated>2024-06-06T06:59:45.873Z</updated>
<content type="html"><![CDATA[<h3 id="删除conda源"><a class="markdownIt-Anchor" href="#删除conda源"></a> 删除conda源</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">conda config --remove-key channels</span><br></pre></td></tr></table></figure><h3 id="conda配置"><a class="markdownIt-Anchor" href="#conda配置"></a> conda配置</h3><p><a href="https://mirrors4.tuna.tsinghua.edu.cn/help/anaconda/">anaconda | 镜像站使用帮助 | 清华大学开源软件镜像站</a></p><p>修改<code>C:\Users\用户名\.condarc</code>文件内容为下面内容。其中envs_dirs是指定conda环境的安装位置。</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><span class="line">channels:</span><br><span class="line"> - defaults</span><br><span class="line">show_channel_urls: <span class="literal">true</span></span><br><span class="line">default_channels:</span><br><span class="line"> - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main</span><br><span class="line"> - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r</span><br><span class="line"> - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2</span><br><span class="line">custom_channels:</span><br><span class="line"> conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud</span><br><span class="line"> deepmodeling: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/</span><br><span class="line">envs_dirs:</span><br><span class="line"> - D://Anaconda//envs</span><br><span class="line"> </span><br></pre></td></tr></table></figure><p>通过<code>conda info</code>查看conda信息。看到D:\Anaconda\envs在envs directories的第一位,就代表虚拟环境默认安装位置设置好了。通过channel URLs也可以看见清华镜像源也设置好了。</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><span class="line">(adong) PS C:\WINDOWS\system32> conda info</span><br><span class="line"></span><br><span class="line"> active environment : adong</span><br><span class="line"> active <span class="built_in">env</span> location : D:\Anaconda\envs\adong</span><br><span class="line"> shell level : 2</span><br><span class="line"> user config file : C:\Users\91430\.condarc</span><br><span class="line"> populated config files : C:\Users\91430\.condarc</span><br><span class="line"> conda version : 24.1.2</span><br><span class="line"> conda-build version : 24.1.2</span><br><span class="line"> python version : 3.11.7.final.0</span><br><span class="line"> solver : libmamba (default)</span><br><span class="line"> virtual packages : __archspec=1=x86_64</span><br><span class="line"> __conda=24.1.2=0</span><br><span class="line"> __cuda=12.3=0</span><br><span class="line"> __win=0=0</span><br><span class="line"> base environment : D:\Anaconda (writable)</span><br><span class="line"> conda av data <span class="built_in">dir</span> : D:\Anaconda\etc\conda</span><br><span class="line"> conda av metadata url : None</span><br><span class="line"> channel URLs : https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64</span><br><span class="line"> https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch</span><br><span class="line"> https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/win-64</span><br><span class="line"> https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/noarch</span><br><span class="line"> https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/win-64</span><br><span class="line"> https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/noarch</span><br><span class="line"> package cache : D:\Anaconda\pkgs</span><br><span class="line"> C:\Users\91430\.conda\pkgs</span><br><span class="line"> C:\Users\91430\AppData\Local\conda\conda\pkgs</span><br><span class="line"> envs directories : D:\Anaconda\envs</span><br><span class="line"> C:\Users\91430\.conda\envs</span><br><span class="line"> C:\Users\91430\AppData\Local\conda\conda\envs</span><br><span class="line"> platform : win-64</span><br><span class="line"> user-agent : conda/24.1.2 requests/2.31.0 CPython/3.11.7 Windows/10 Windows/10.0.22000 solver/libmamba conda-libmamba-solver/24.1.0 libmambapy/1.5.6 aau/0.4.3 c/2cby9s0faIgGPUHiAZNUZA s/l8VpJfZM5eNDkpX7Ia9NMQ e/678Mj-yGtTUNyUgyuxwmKw</span><br><span class="line"> administrator : True</span><br><span class="line"> netrc file : None</span><br><span class="line"> offline mode : False</span><br></pre></td></tr></table></figure><h3 id="吴恩达机器学习optional-labs环境配置"><a class="markdownIt-Anchor" href="#吴恩达机器学习optional-labs环境配置"></a> 吴恩达机器学习Optional Labs环境配置</h3><p>采用的是JupyterNotebook、JupyterLab,以及lab的一些插件。</p><p>由于安装的anaconda的base环境自带一套Jupyter,在Jupyter以及lab插件的版本上,或许存在兼容问题,比如我在base环境下查看拓展。</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><span class="line">(base) C:\Users\91430>jupyter labextension list</span><br><span class="line">JupyterLab v4.0.13</span><br><span class="line">D:\Anaconda\share\jupyter\labextensions</span><br><span class="line"> jupyter-matplotlib v0.11.4 enabled ok</span><br><span class="line"> jupyterlab-plotly v5.15.0 enabled X</span><br><span class="line"> @jupyter-notebook/lab-extension v7.0.8 enabled ok</span><br><span class="line"> @jupyter-widgets/jupyterlab-manager v5.0.11 enabled ok (python, jupyterlab_widgets)</span><br><span class="line"> @lckr/jupyterlab_variableinspector v3.1.0 enabled ok (python, lckr_jupyterlab_variableinspector)</span><br><span class="line"> @pyviz/jupyterlab_pyviz v3.0.0 enabled ok</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> The following extensions are outdated:</span><br><span class="line"> jupyterlab-plotly</span><br><span class="line"></span><br><span class="line"> Consider checking <span class="keyword">if</span> an update is available <span class="keyword">for</span> these packages.</span><br></pre></td></tr></table></figure><p>可以看到 plotly 的版本是有问题的。刚安装anaconda的时候,Lab的版本和plotly的版本比现在还高,后来,我参考了<a href="https://github.com/jupyterlab/jupyterlab/issues/14590">这个Issue</a>,将 Lab 和 plotly 进行降级,期望能兼容,然而并没有,结果如上所示。</p><p>所以我新建了一个conda环境<code>conda create -n adong python=3.7</code>,其中n代表name,adong则是我取的环境名,后面可以接环境要安装的包,这里安装的python3.7。</p><p>安装完成后,通过<code>conda activate adong</code>切换到新环境,输入<code>conda install "jupyterlab>=3" "ipywidgets>=7.6"</code>安装 jupyterlab 和插件ipywidgets。此后,缺啥装啥就行了,通过<code>conda install xxx</code>进行安装即可。</p><p>有一些必要的,比如<code>numpy matplotlib ipympl</code>。安装完成后,在该环境下通过输入命令<code>jupyter notebook</code>,即可正常使用相关功能,效果如下所示。</p><p><img src="https://pics.kahvia.cn/img/jupyterlab%E5%B1%95%E7%A4%BA.gif" alt="效果展示" /></p>]]></content>
<summary type="html"><h3 id="删除conda源"><a class="markdownIt-Anchor" href="#删除conda源"></a> 删除conda源</h3>
<figure class="highlight bash"><table><tr><td class="gutt</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="Anaconda" scheme="https://blog.kahvia.cn/tags/Anaconda/"/>
</entry>
<entry>
<title>SSH连接问题</title>
<link href="https://blog.kahvia.cn/2024/06/02/SshProblems.html"/>
<id>https://blog.kahvia.cn/2024/06/02/SshProblems.html</id>
<published>2024-06-02T05:52:50.144Z</published>
<updated>2024-06-02T06:26:36.246Z</updated>
<content type="html"><![CDATA[<h3 id="问题描述"><a class="markdownIt-Anchor" href="#问题描述"></a> 问题描述</h3><p>不知从哪一天开始,xshell突然无法连接我的云服务器。在那一天之前,一切正常。</p><h3 id="故障原因"><a class="markdownIt-Anchor" href="#故障原因"></a> 故障原因</h3><p>在参考其他人博客内容进行故障排错无果后,我突发奇想,将校园网换成热点试了一下,结果成功了。所以故障原因大概率是校园网。去网上搜了一下,可能是校园网设置了ssh拦截,所以校园网不管连接哪个服务器的22端口都不行。解决方法参考<a href="https://blog.csdn.net/Gaowumao/article/details/118272547">该博客文章</a>。</p><h3 id="解决方法"><a class="markdownIt-Anchor" href="#解决方法"></a> 解决方法</h3><ol><li><code>vim /etc/ssh/sshd_config</code>打开配置修改页面</li><li>添加自定义端口<code>Port 1022</code></li><li><code>systemctl restart sshd</code>重启sshd服务(centos7写法)</li><li><code>firewall-cmd --zone=public --add-port=1022/tcp --permanent</code>为防火墙打开对应的端口(未开启防火墙则省略这一步)</li><li><code>firewall-cmd --reload</code>防火墙重新加载配置(未开启防火墙则省略这一步)</li><li><code>firewall-cmd --list-all</code>查看已开放端口列表(未开启防火墙则省略这一步),出现1022则成功</li><li>去服务器服务商设置安全策略(或者有的地方叫安全组),入口规则添加1022,即允许外部访问服务器1022端口</li></ol><p>这样一套小连招下来,我的Xshell就能通过1022端口正常连接服务器了。</p><h3 id="参考博客"><a class="markdownIt-Anchor" href="#参考博客"></a> 参考博客</h3><p><a href="https://blog.csdn.net/qq_45782768/article/details/130174381">校园网SSH连接不上阿里云_校园网 用不了ssh-CSDN博客</a></p><p><a href="https://www.cnblogs.com/yizhipanghu/p/11171211.html">Centos7 防火墙开放端口,查看状态,查看开放端口 - 香菜哥哥 - 博客园 (cnblogs.com)</a></p><p><a href="https://blog.csdn.net/Gaowumao/article/details/118272547">XShell 无法连接云服务器的那些坑_为什么连校园网无法用xshell-CSDN博客</a></p><p><a href="https://blog.csdn.net/qq_50956771/article/details/136628785?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-136628785-blog-118272547.235%5Ev43%5Epc_blog_bottom_relevance_base6&spm=1001.2101.3001.4242.1&utm_relevant_index=3">踩坑:xshell连接阿里云失败 “Could not connect to ‘xxxxxxxxx‘: Connection failed.“,校园网_could not connect to ‘116.63.168.95’ (port 2673): -CSDN博客</a></p>]]></content>
<summary type="html"><h3 id="问题描述"><a class="markdownIt-Anchor" href="#问题描述"></a> 问题描述</h3>
<p>不知从哪一天开始,xshell突然无法连接我的云服务器。在那一天之前,一切正常。</p>
<h3 id="故障原因"><a clas</summary>
<category term="小问题" scheme="https://blog.kahvia.cn/categories/%E5%B0%8F%E9%97%AE%E9%A2%98/"/>
<category term="ssh centos7 xshell" scheme="https://blog.kahvia.cn/tags/ssh-centos7-xshell/"/>
</entry>
<entry>
<title>DaisyUI指南</title>
<link href="https://blog.kahvia.cn/2024/04/19/DaisyUI.html"/>
<id>https://blog.kahvia.cn/2024/04/19/DaisyUI.html</id>
<published>2024-04-19T15:29:10.512Z</published>
<updated>2024-04-21T10:01:19.246Z</updated>
<content type="html"><![CDATA[<h3 id="主题切换"><a class="markdownIt-Anchor" href="#主题切换"></a> 主题切换</h3><p>参考<a href="https://daisyui.com/components/theme-controller/">主题控制器</a>。以下甄选了几个好看的主题。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/** <span class="doctag">@type</span> {<span class="type">import('tailwindcss').Config</span>} */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">content</span>: [<span class="string">"./src/**/*.{html,js,vue}"</span>],</span><br><span class="line"> <span class="attr">theme</span>: {</span><br><span class="line"> <span class="attr">extend</span>: {},</span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [<span class="built_in">require</span>(<span class="string">"daisyui"</span>)],</span><br><span class="line"> <span class="attr">daisyui</span>: {</span><br><span class="line"> <span class="attr">themes</span>: [</span><br><span class="line"> <span class="string">"light"</span>,</span><br><span class="line"> <span class="string">"dark"</span>,</span><br><span class="line"> <span class="string">"halloween"</span>,</span><br><span class="line"> <span class="string">"garden"</span>,</span><br><span class="line"> <span class="string">"forest"</span>,</span><br><span class="line"> <span class="string">"lofi"</span>,</span><br><span class="line"> <span class="string">"pastel"</span>,</span><br><span class="line"> <span class="string">"fantasy"</span>,</span><br><span class="line"> <span class="string">"wireframe"</span>,</span><br><span class="line"> <span class="string">"dracula"</span>,</span><br><span class="line"> <span class="string">"cmyk"</span>,</span><br><span class="line"> <span class="string">"autumn"</span>,</span><br><span class="line"> ], <span class="comment">// false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"]</span></span><br><span class="line"> <span class="attr">darkTheme</span>: <span class="string">"dark"</span>, <span class="comment">// name of one of the included themes for dark mode</span></span><br><span class="line"> <span class="attr">base</span>: <span class="literal">true</span>, <span class="comment">// applies background color and foreground color for root element by default</span></span><br><span class="line"> <span class="attr">styled</span>: <span class="literal">true</span>, <span class="comment">// include daisyUI colors and design decisions for all components</span></span><br><span class="line"> <span class="attr">utils</span>: <span class="literal">true</span>, <span class="comment">// adds responsive and modifier utility classes</span></span><br><span class="line"> <span class="attr">prefix</span>: <span class="string">""</span>, <span class="comment">// prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors)</span></span><br><span class="line"> <span class="attr">logs</span>: <span class="literal">true</span>, <span class="comment">// Shows info about daisyUI version and used config in the console when building your CSS</span></span><br><span class="line"> <span class="attr">themeRoot</span>: <span class="string">":root"</span>, <span class="comment">// The element that receives theme color CSS variables</span></span><br><span class="line"> },</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="我的主题切换器"><a class="markdownIt-Anchor" href="#我的主题切换器"></a> 我的主题切换器</h4><p>其中 tabindex=“0” 代表元素能否通过进行聚焦(用点的或者Tab键),此处第一个tabindex="0"不能省略,因为下面的ul的dropdown-content的底层css样式写的就是:上面那个Theme div聚焦了,下面这个列表才显示。至于第二个ul的聚焦,没啥用,可以删掉,因为input能直接聚焦。</p><p>通过 <strong>:checked=“index == themeIndex”</strong>来初始化主题选择器的<strong>radio</strong>的选项默认选中。</p><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"><template></span><br><span class="line"> <div class="dropdown"></span><br><span class="line"> <div tabindex="0" role="button" class="btn m-1"></span><br><span class="line"> Theme</span><br><span class="line"> <svg width="12px" height="12px" class="h-2 w-2 fill-current opacity-60 inline-block"</span><br><span class="line"> xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048"></span><br><span class="line"> <path d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z"></path></span><br><span class="line"> </svg></span><br><span class="line"> </div></span><br><span class="line"> <ul tabindex="0" class="dropdown-content z-[1] p-2 shadow-2xl bg-base-300 rounded-box w-52"></span><br><span class="line"> <li v-for="(theme, index) in themeList" @click="changeTheme(index, theme)"></span><br><span class="line"> <input type="radio" name="theme-dropdown"</span><br><span class="line"> class="theme-controller btn btn-sm btn-block btn-ghost justify-start" :aria-label="theme"</span><br><span class="line"> :value="theme" :checked="index == themeIndex" /></span><br><span class="line"> </li></span><br><span class="line"> </ul></span><br><span class="line"> </div></span><br><span class="line"></template></span><br><span class="line"></span><br><span class="line"><script setup></span><br><span class="line">import { ref, onMounted } from 'vue';</span><br><span class="line">import { useThemeStore } from '@/stores/themeStore';</span><br><span class="line"></span><br><span class="line">const { changeThemeTo, getCurrentThemeIndex } = useThemeStore();</span><br><span class="line"></span><br><span class="line">const themeIndex = ref(0);</span><br><span class="line">const themeList = ref([</span><br><span class="line"> "light",</span><br><span class="line"> "dark",</span><br><span class="line"> "halloween",</span><br><span class="line"> "garden",</span><br><span class="line"> "forest",</span><br><span class="line"> "lofi",</span><br><span class="line"> "pastel",</span><br><span class="line"> "fantasy",</span><br><span class="line"> "wireframe",</span><br><span class="line"> "black",</span><br><span class="line"> "luxury",</span><br><span class="line"> "dracula",</span><br><span class="line"> "cmyk",</span><br><span class="line"> "autumn",</span><br><span class="line">])</span><br><span class="line"></span><br><span class="line">function changeTheme(index, themeName) {</span><br><span class="line"> themeIndex.value = index;</span><br><span class="line"> changeThemeTo(index, themeName);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">onMounted(() => {</span><br><span class="line"> themeIndex.value = getCurrentThemeIndex();</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"></script></span><br><span class="line"></span><br><span class="line"><style scoped></style></span><br></pre></td></tr></table></figure><p>以下是pinia持久化的内容。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//themeStore.js</span></span><br><span class="line"><span class="keyword">import</span> { ref } <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> { defineStore } <span class="keyword">from</span> <span class="string">'pinia'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> useThemeStore = <span class="title function_">defineStore</span>(<span class="string">'theme'</span>, <span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">const</span> theme = <span class="title function_">ref</span>(<span class="string">'light'</span>);</span><br><span class="line"> <span class="keyword">const</span> themeIndex = <span class="title function_">ref</span>(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">initialTheme</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">let</span> html = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">'html'</span>)[<span class="number">0</span>];</span><br><span class="line"> html.<span class="title function_">setAttribute</span>(<span class="string">'data-theme'</span>, theme.<span class="property">value</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">changeThemeTo</span>(<span class="params">index, themeName</span>) {</span><br><span class="line"> themeIndex.<span class="property">value</span> = index;</span><br><span class="line"> theme.<span class="property">value</span> = themeName;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">getCurrentThemeIndex</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> themeIndex.<span class="property">value</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> { theme, themeIndex, initialTheme, changeThemeTo, getCurrentThemeIndex }</span><br><span class="line">}, {</span><br><span class="line"> <span class="attr">persist</span>: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>即便在控制器中初始化了默认<strong>radio</strong>的默认选中,但是在App.vue的onMounted函数中调用初始化主题仍然是必要的。因为主题控制器大多在导航栏中,而有的登陆界面中没有导航栏,意味着主题控制器未生效,此时需要根据本地数据主动初始化主题。</p><h3 id="封装好的popingalert"><a class="markdownIt-Anchor" href="#封装好的popingalert"></a> 封装好的PopingAlert</h3><figure class="highlight html"><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><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">ref</span>=<span class="string">"alert"</span> <span class="attr">role</span>=<span class="string">"alert"</span> <span class="attr">class</span>=<span class="string">"alert w-fit absolute left-1/2 -translate-x-1/2 transition-all duration-1000"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:class</span>=<span class="string">"{ 'opacity-0 invisible -top-3': !visible, 'opacity-100 top-3': visible, [alertTypeClass]: true }"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">v-if</span>=<span class="string">"type == 'default'"</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">class</span>=<span class="string">"stroke-info shrink-0 w-6 h-6"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">v-if</span>=<span class="string">"type == 'info'"</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">class</span>=<span class="string">"stroke-current shrink-0 w-6 h-6"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">v-if</span>=<span class="string">"type == 'success'"</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">class</span>=<span class="string">"stroke-current shrink-0 h-6 w-6"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">v-if</span>=<span class="string">"type == 'warning'"</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">class</span>=<span class="string">"stroke-current shrink-0 h-6 w-6"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">v-if</span>=<span class="string">"type == 'error'"</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">class</span>=<span class="string">"stroke-current shrink-0 h-6 w-6"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">span</span>></span>{{ messgae }}<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { ref, computed } <span class="keyword">from</span> <span class="string">'vue'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> alert = <span class="title function_">ref</span>(<span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> type = <span class="title function_">ref</span>(<span class="string">"default"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> messgae = <span class="title function_">ref</span>(<span class="string">"Hello world."</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> visible = <span class="title function_">ref</span>(<span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">showAlert</span>(<span class="params">msg, typeName = <span class="string">"default"</span></span>) {</span><br><span class="line"> messgae.<span class="property">value</span> = msg;</span><br><span class="line"> type.<span class="property">value</span> = typeName;</span><br><span class="line"> visible.<span class="property">value</span> = <span class="literal">true</span>;</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =></span> visible.<span class="property">value</span> = <span class="literal">false</span>, <span class="number">2000</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">defineExpose</span>({ showAlert });</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> alertTypeClass = <span class="title function_">computed</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">let</span> typeClass = <span class="string">"default"</span>;</span><br><span class="line"> <span class="keyword">switch</span> (type.<span class="property">value</span>) {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'info'</span>:</span><br><span class="line"> typeClass = <span class="string">'alert-info'</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'success'</span>:</span><br><span class="line"> typeClass = <span class="string">'alert-success'</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'warning'</span>:</span><br><span class="line"> typeClass = <span class="string">'alert-warning'</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'error'</span>:</span><br><span class="line"> typeClass = <span class="string">'alert-error'</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line"> <span class="attr">default</span>:</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> typeClass;</span><br><span class="line">})</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h3 id="主题切换"><a class="markdownIt-Anchor" href="#主题切换"></a> 主题切换</h3>
<p>参考<a href="https://daisyui.com/components/theme-controller/">主题控制器</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="DaisyUI Tailwind" scheme="https://blog.kahvia.cn/tags/DaisyUI-Tailwind/"/>
</entry>
<entry>
<title>VueUse</title>
<link href="https://blog.kahvia.cn/2024/03/16/Vue-use.html"/>
<id>https://blog.kahvia.cn/2024/03/16/Vue-use.html</id>
<published>2024-03-16T11:00:29.186Z</published>
<updated>2024-03-16T11:12:39.088Z</updated>
<content type="html"><![CDATA[<p>这是 Vue 的一个第三方库,提供了许多意想不到的功能。比如异步 computed 。</p><h3 id="computedasync"><a class="markdownIt-Anchor" href="#computedasync"></a> <a href="https://vueuse.org/core/computedAsync/#computedasync">computedAsync</a></h3><p>Vue 官方的 computed 是同步的,有时并不能满足开发需求。比如我根据“县名”异步查询行政区下的“乡镇”,在 resolve 之前,我希望有个默认值。当然了,我可以定义一个 ref 变量来存放默认值,异步查询后更改 ref 的值。这意味着,我要在选择县之后的回调函数中,手动调用异步函数,然后等待异步函数 resolve ,再修改 ref 的值。这显然很麻烦。</p><p>但是这个库函数,直接传入异步函数和默认值,组件直接使用 computed 的结果即可,自然是方便很多。</p><p>比如。</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> towns = <span class="title function_">computedAsync</span>(</span><br><span class="line"> <span class="keyword">async</span> () => {</span><br><span class="line"> <span class="keyword">if</span> (country.<span class="property">value</span>) {</span><br><span class="line"> <span class="keyword">let</span> towns = <span class="keyword">await</span> <span class="title function_">getTowns</span>((country.<span class="property">value</span> <span class="keyword">as</span> <span class="built_in">any</span>).<span class="property">name</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">addIdToDistinct</span>(towns <span class="keyword">as</span> <span class="built_in">any</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> [{ <span class="attr">id</span>: <span class="number">0</span>, <span class="attr">name</span>: <span class="string">''</span> }];</span><br><span class="line"> },</span><br><span class="line"> [{ <span class="attr">id</span>: <span class="number">0</span>, <span class="attr">name</span>: <span class="string">''</span> }],</span><br><span class="line"> { <span class="attr">lazy</span>: <span class="literal">true</span> }</span><br><span class="line">)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>这是 Vue 的一个第三方库,提供了许多意想不到的功能。比如异步 computed 。</p>
<h3 id="computedasync"><a class="markdownIt-Anchor" href="#computedasync"></a> <a href="h</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="uniapp" scheme="https://blog.kahvia.cn/tags/uniapp/"/>
</entry>
<entry>
<title>项目过程中积累的css技巧</title>
<link href="https://blog.kahvia.cn/2024/03/11/css-skills.html"/>
<id>https://blog.kahvia.cn/2024/03/11/css-skills.html</id>
<published>2024-03-11T11:12:59.343Z</published>
<updated>2024-05-06T07:35:25.758Z</updated>
<content type="html"><![CDATA[<h3 id="flex布局设置多行首对齐且整体居中"><a class="markdownIt-Anchor" href="#flex布局设置多行首对齐且整体居中"></a> Flex布局设置多行首对齐且整体居中</h3><p>假定项目中的待展示元素宽高固定,每一行要求左对齐,一行最多五个,在此基础上,依据设备的不同,每一行多余的屏幕空间不同。如何将每行排满后多余的屏幕空间分配给该行的每个元素?</p><p>答:采用一个空盒子对展示元素进行包裹。对于空盒子,采用<strong> flex-bias </strong>设置一行内所占空间为 20% ,同时空盒子也进行 flex 布局,对展示元素进行水平和垂直的居中处理。</p><figure class="highlight plaintext"><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><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><template></span><br><span class="line"> <div class="categories"></span><br><span class="line"> <div class="wrapper" v-for="category in categories"></span><br><span class="line"> <navigator class="navigator-item" url="/pages/index/index" open-type="navigate"</span><br><span class="line"> hover-class="navigator-hover"></span><br><span class="line"> <image class="icon" :src="category.icon_data" /></span><br><span class="line"> <text>{{ category.name }}</text></span><br><span class="line"> </navigator></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></template></span><br><span class="line"></span><br><span class="line"><script setup></span><br><span class="line">import { ref, onMounted } from 'vue'</span><br><span class="line">import { getCats } from '@/services/product';</span><br><span class="line">import { useProductStore } from '@/stores/piniaStores';</span><br><span class="line">import { storeToRefs } from 'pinia';</span><br><span class="line"></span><br><span class="line">const { categories } = storeToRefs(useProductStore());</span><br><span class="line"></span><br><span class="line">onMounted(() => {</span><br><span class="line"> getCats();</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"></script></span><br><span class="line"></span><br><span class="line"><style scoped></span><br><span class="line">.categories {</span><br><span class="line"> width: 100%;</span><br><span class="line"> display: flex;</span><br><span class="line"> flex-wrap: wrap;</span><br><span class="line"> justify-content: flex-start;</span><br><span class="line"> margin-top: 10px;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">.wrapper {</span><br><span class="line"> flex-basis: 20%;</span><br><span class="line"> display: flex;</span><br><span class="line"> justify-content: center;</span><br><span class="line"> align-items: center;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">.navigator-item {</span><br><span class="line"> position: relative;</span><br><span class="line"> width: 50px;</span><br><span class="line"> height: 50px;</span><br><span class="line"> margin-bottom: 25px;</span><br><span class="line"> background-color: #6196A6;</span><br><span class="line"> border-radius: 10px;</span><br><span class="line"> display: flex;</span><br><span class="line"> flex-direction: column;</span><br><span class="line"> align-items: center;</span><br><span class="line"> justify-content: center;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">.navigator-item text {</span><br><span class="line"> position: absolute;</span><br><span class="line"> bottom: -20px;</span><br><span class="line"> font-size: x-small;</span><br><span class="line"> font-weight: 500;</span><br><span class="line"> color: black;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">image {</span><br><span class="line"> width: 30px;</span><br><span class="line"> height: 30px;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></style></span><br></pre></td></tr></table></figure><p><img src="https://pics.kahvia.cn/img/20240311193512.png" alt="效果图" /></p><h3 id="淡入淡出动画"><a class="markdownIt-Anchor" href="#淡入淡出动画"></a> 淡入淡出动画</h3><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">ref</span>=<span class="string">"alert"</span> <span class="attr">role</span>=<span class="string">"alert"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">class</span>=<span class="string">"alert w-fit absolute top-0 left-1/2 -translate-x-1/2 transition-all duration-1000"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:class</span>=<span class="string">"{ 'opacity-0 invisible': !visible, 'opacity-100': visible }"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">xmlns</span>=<span class="string">"http://www.w3.org/2000/svg"</span> <span class="attr">fill</span>=<span class="string">"none"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 24 24"</span> <span class="attr">class</span>=<span class="string">"stroke-info shrink-0 w-6 h-6"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">stroke-linecap</span>=<span class="string">"round"</span> <span class="attr">stroke-linejoin</span>=<span class="string">"round"</span> <span class="attr">stroke-width</span>=<span class="string">"2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">d</span>=<span class="string">"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span>></span>{{ messgae }}<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><p>在添加 transition 的情况下,<strong>visibility</strong> 的 visible 到 hidden 是 duration 结束后的突变,并不会有过渡效果,而 hidden 到 visible 是 duration 刚开始就突变的。</p><p>这意味着元素在获得 hidden 的时候是会因为 duration 而延迟,延迟期间仍然可以进行交互(包括看见、点击、拖拽等等),直到 visibility : hidden被添加。</p><p>同样意味着元素在获得 visible 的时候是瞬间生效的,不会因为 duration 有任何的延迟。</p><p>这样一来,当我们点击按钮让它显示的时候,它是瞬间出现的。再次点击按钮让它消失的时候,它会等待 duration 度过,然后瞬间消失。</p><p>我们只需要添加 opacity 不透明度的变化,让元素在 duration 期间淡入淡出,即可实现视觉和交互层面的淡入淡出。</p><p><img src="https://pics.kahvia.cn/img/MS%E6%B8%90%E5%85%A5%E6%B8%90%E5%87%BA.gif" alt="渐入渐出" /></p><h3 id="flex布局未溢出时居中溢出时start"><a class="markdownIt-Anchor" href="#flex布局未溢出时居中溢出时start"></a> Flex布局未溢出时居中,溢出时start</h3><p><a href="https://stackoverflow.com/questions/34184535/change-justify-content-value-when-flex-items-overflow-container">参考问答</a></p><p>问题描述:通过 <code>justify-content:center</code>,可以设置 Flex 布局主轴居中,但是溢出设置滚动时,会导致滚动内容异常(居中导致的)。期望效果:未溢出时主轴居中,溢出时 flex-start 的效果。</p><p>解决方法:为 flex 盒子添加 before 和 after 伪元素,分别设置外边距 <code>margin:auto</code>。在未溢出的时候,自动外边距会占据剩余的空间,将元素居中。在溢出的时候,该属性会被忽略,正常溢出,无不良效果,即普通的靠左的从左到右依次排列,溢出滚动。</p><figure class="highlight css"><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><span class="line"><span class="selector-class">.iconSelector</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-class">.iconSelector</span><span class="selector-pseudo">::after</span> {</span><br><span class="line"> <span class="attribute">content</span>: <span class="string">''</span>;</span><br><span class="line"> <span class="comment">/* Insert pseudo-element */</span></span><br><span class="line"> <span class="attribute">margin</span>: auto;</span><br><span class="line"> <span class="comment">/* Make it push flex items to the center */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h3 id="flex布局设置多行首对齐且整体居中"><a class="markdownIt-Anchor" href="#flex布局设置多行首对齐且整体居中"></a> Flex布局设置多行首对齐且整体居中</h3>
<p>假定项目中的待展示元素宽高固定,每一行要求左对齐</summary>
<category term="经验" scheme="https://blog.kahvia.cn/categories/%E7%BB%8F%E9%AA%8C/"/>
<category term="css" scheme="https://blog.kahvia.cn/tags/css/"/>
</entry>
<entry>
<title>vue3知识点</title>
<link href="https://blog.kahvia.cn/2024/03/09/vue3Knowledge.html"/>
<id>https://blog.kahvia.cn/2024/03/09/vue3Knowledge.html</id>
<published>2024-03-09T10:28:17.575Z</published>
<updated>2024-03-16T11:57:50.279Z</updated>
<content type="html"><![CDATA[<h3 id="样式穿透"><a class="markdownIt-Anchor" href="#样式穿透"></a> 样式穿透</h3><p>使用样式穿透,可以穿透子组件影响到下面的类的样式,做到对第三方组件的样式自定义。</p><h4 id="采用"><a class="markdownIt-Anchor" href="#采用"></a> 采用>>></h4><figure class="highlight css"><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><span class="line">uni-data-picker>>><span class="selector-class">.input-value-border</span> {</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid black;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">50px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="采用-deep"><a class="markdownIt-Anchor" href="#采用-deep"></a> 采用 /deep/</h4><figure class="highlight css"><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><span class="line">uni-data-picker /deep/ <span class="selector-class">.input-value-border</span> {</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid red;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">50px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="采用-v-deep"><a class="markdownIt-Anchor" href="#采用-v-deep"></a> 采用 ::v-deep</h4><figure class="highlight css"><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><span class="line">uni-data-picker::v-deep .input-value-border {</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">3px</span> solid orange;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">50px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="父组件获取子组件属性"><a class="markdownIt-Anchor" href="#父组件获取子组件属性"></a> 父组件获取子组件属性</h3><p>根据<a href="https://cn.vuejs.org/api/sfc-script-setup.html#defineexpose">官方文档</a>,采用组合式 api 编写的组件,内部定义的属性、方法,都是不对外开放的。可以调用 defineExpose() 方法,暴露需要的属性和方法。外部通过 ref 进行模板引用,即可访问暴露出来的属性和方法。</p><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"><template></span><br><span class="line"> <uni-popup ref="popPage" type="bottom" background-color="#f7f7f7"></span><br><span class="line"> <div class="boxBack"></span><br><span class="line"> <div class="box"></span><br><span class="line"> <input type="nickname" placeholder="请输入分类名称" v-model="catName"></span><br><span class="line"> <button ref="nickBtn" @click="">确认</button></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"> </uni-popup></span><br><span class="line"></template></span><br><span class="line"></span><br><span class="line"><script setup lang="ts"></span><br><span class="line">import { ref } from 'vue';</span><br><span class="line"></span><br><span class="line">const popPage = ref(null);</span><br><span class="line">const catName = ref("");</span><br><span class="line"></span><br><span class="line">function popUp() {</span><br><span class="line"> console.log(popPage.value);</span><br><span class="line"> (popPage.value as any).open();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">defineExpose({</span><br><span class="line"> popUp</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></script></span><br><span class="line"></span><br><span class="line"><!-- 弹出层样式 --></span><br><span class="line"><style scoped></span><br><span class="line"></style></span><br></pre></td></tr></table></figure><h3 id="props设置默认值"><a class="markdownIt-Anchor" href="#props设置默认值"></a> props设置默认值</h3><figure class="highlight ts"><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><span class="line"><span class="comment">//Boolean 类型的未传递 prop 将被转换为 false。————官方文档</span></span><br><span class="line"><span class="keyword">let</span> props = <span class="title function_">defineProps</span>({</span><br><span class="line"> <span class="attr">title</span>: <span class="title class_">String</span>,</span><br><span class="line"> <span class="attr">showBack</span>: {</span><br><span class="line"> <span class="attr">type</span>: <span class="title class_">Boolean</span>,</span><br><span class="line"> <span class="attr">default</span>: <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h3 id="watch-props的值"><a class="markdownIt-Anchor" href="#watch-props的值"></a> watch props的值</h3><p>要使用 getter 函数。此处的 props.catName 是一个外部传入常量,如果给 watch 这个东西,那么 watch 调用,生成监视的时候,收到的参数是一个常量,这不对。要给 watch 一个getter 函数,让它自己调用函数去看,这样监视器看到返回值跟之前不一样了,才知道发生了变化。</p><figure class="highlight ts"><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><span class="line"><span class="title function_">watch</span>(<span class="function">() =></span> props.<span class="property">catName</span>, <span class="keyword">async</span> (oldCatName, newCatName) => {</span><br><span class="line"> <span class="keyword">if</span> ((productsMap.<span class="property">value</span> <span class="keyword">as</span> <span class="built_in">any</span>)[props.<span class="property">catName</span>].<span class="property">length</span> == <span class="number">0</span>)</span><br><span class="line"> <span class="title function_">getProsByCatName</span>();</span><br><span class="line">})</span><br></pre></td></tr></table></figure><blockquote><p><a href="https://cn.vuejs.org/guide/essentials/watchers.html#watch-source-types">侦听器 | Vue.js (vuejs.org)</a></p></blockquote>]]></content>
<summary type="html"><h3 id="样式穿透"><a class="markdownIt-Anchor" href="#样式穿透"></a> 样式穿透</h3>
<p>使用样式穿透,可以穿透子组件影响到下面的类的样式,做到对第三方组件的样式自定义。</p>
<h4 id="采用"><a class=</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="vue" scheme="https://blog.kahvia.cn/tags/vue/"/>
</entry>
<entry>
<title>MemFireDb</title>
<link href="https://blog.kahvia.cn/2024/03/06/MemFireDb.html"/>
<id>https://blog.kahvia.cn/2024/03/06/MemFireDb.html</id>
<published>2024-03-06T04:41:35.603Z</published>
<updated>2024-05-04T08:54:02.957Z</updated>
<content type="html"><![CDATA[<h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3><p>以最近的 uniapp 开发微信小程序为例。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm install @supabase/supabase-js</span><br><span class="line">npm install supabase-wechat-stable-v2</span><br></pre></td></tr></table></figure><h3 id="配置数据库连接"><a class="markdownIt-Anchor" href="#配置数据库连接"></a> 配置数据库连接</h3><figure class="highlight ts"><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><span class="line"><span class="comment">//fireDb.ts</span></span><br><span class="line"><span class="keyword">import</span> { createClient } <span class="keyword">from</span> <span class="string">"supabase-wechat-stable-v2"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//这两个常量可以在MemFireDb官网数据库的api中找到</span></span><br><span class="line"><span class="keyword">const</span> supabaseUrl = <span class="string">"https://xxxx.baseapi.memfiredb.com"</span>;</span><br><span class="line"><span class="keyword">const</span> publicAnonKey = <span class="string">"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"</span>;</span><br><span class="line"><span class="comment">// Create a single supabase client for interacting with your database</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> supabase = <span class="title function_">createClient</span>(supabaseUrl, publicAnonKey);</span><br></pre></td></tr></table></figure><h3 id="微信授权手机号一键登陆"><a class="markdownIt-Anchor" href="#微信授权手机号一键登陆"></a> 微信授权手机号一键登陆</h3><p>在 uniapp 中,设置 button 的 open-type 为 getPhoneNumber,并监听事件getPhoneNumber。</p><figure class="highlight plaintext"><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><span class="line"><template></span><br><span class="line"><button class="btn" open-type="getPhoneNumber" @getphonenumber="wxLogin"></span><br><span class="line"> <image</span><br><span class="line"> src="data:image/svg+xml;base64,xxx" /></span><br><span class="line"> <text>微信快捷登录</text></span><br><span class="line"> </button></span><br><span class="line"></template></span><br></pre></td></tr></table></figure><p>监听事件发生时,调用 wxLogin 函数,传入一个事件对象,根据 code 值判断是否获取到电话号码。</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">wxLogin</span> = <span class="keyword">async</span> (<span class="params">e: <span class="built_in">any</span></span>) => {</span><br><span class="line"> wx.<span class="title function_">login</span>({</span><br><span class="line"> <span class="attr">success</span>: <span class="keyword">async</span> res => {</span><br><span class="line"> <span class="comment">//在getPhoneNumber事件中,如果code为undefined,则用户未授权,否则用户已经授权,获取到手机号码</span></span><br><span class="line"> <span class="keyword">if</span> (!e.<span class="property">detail</span>.<span class="property">code</span>) {</span><br><span class="line"> wx.<span class="title function_">showToast</span>({</span><br><span class="line"> <span class="attr">title</span>: <span class="string">"授权失败"</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">"none"</span>,</span><br><span class="line"> <span class="attr">duration</span>: <span class="number">2000</span></span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//微信登录,新用户则自动注册</span></span><br><span class="line"> <span class="keyword">const</span> { data, error } = <span class="keyword">await</span> supabase.<span class="property">auth</span>.<span class="title function_">signInWithWechat</span>({ <span class="attr">code</span>: res.<span class="property">code</span> })</span><br><span class="line"> <span class="keyword">let</span> { <span class="attr">user</span>: { <span class="attr">data</span>: { user } } } = data <span class="keyword">as</span> <span class="built_in">any</span>;</span><br><span class="line"> <span class="title function_">setProfile</span>(user);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (error) {</span><br><span class="line"> wx.<span class="title function_">showToast</span>({</span><br><span class="line"> <span class="attr">title</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(error) || error?.<span class="property">message</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">"none"</span>,</span><br><span class="line"> <span class="attr">duration</span>: <span class="number">2000</span></span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (data) {</span><br><span class="line"> <span class="comment">//获取到用户信息后,绑定电话号码到小程序用户上</span></span><br><span class="line"> <span class="keyword">const</span> { data, error } = <span class="keyword">await</span> supabase.<span class="property">auth</span>.<span class="title function_">wechatBindPhone</span>({</span><br><span class="line"> <span class="attr">code</span>: e.<span class="property">detail</span>.<span class="property">code</span>,</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">if</span> (error) {</span><br><span class="line"> wx.<span class="title function_">showToast</span>({</span><br><span class="line"> <span class="attr">title</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(error) || error?.<span class="property">message</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">"none"</span>,</span><br><span class="line"> <span class="attr">duration</span>: <span class="number">2000</span></span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (data) {</span><br><span class="line"> wx.<span class="title function_">showToast</span>({</span><br><span class="line"> <span class="attr">title</span>: <span class="string">'登录成功!'</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">"none"</span>,</span><br><span class="line"> <span class="attr">duration</span>: <span class="number">1000</span></span><br><span class="line"> })</span><br><span class="line"> wx.<span class="title function_">switchTab</span>({</span><br><span class="line"> <span class="attr">url</span>: <span class="string">'/pages/index/index'</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="获取微信头像"><a class="markdownIt-Anchor" href="#获取微信头像"></a> 获取微信头像</h3><p>操作与获取手机号码类似。</p><figure class="highlight plaintext"><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><span class="line"><button class="avatarCoverBtn" open-type="chooseAvatar" @chooseavatar="chooseAvatar"></span><br><span class="line"><image class="avatar" :src="profile.avatar" mode="scaleToFill" /></span><br><span class="line"></button></span><br></pre></td></tr></table></figure><p>在获取到头像的本地路径后,需要转存到对象存储的存储桶中,获取对应的网络地址,然后更新数据库中的头像信息和小程序本地的头像信息。我采用 Pinia 进行状态管理,因此在 updateAvatar 函数中,对 userStore 里的头像信息进行了更新。</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">chooseAvatar</span> = (<span class="params">e: <span class="built_in">any</span></span>) => {</span><br><span class="line"> <span class="keyword">let</span> { avatarUrl } = e.<span class="property">detail</span></span><br><span class="line"> wx.<span class="title function_">getImageInfo</span>({</span><br><span class="line"> <span class="attr">src</span>: avatarUrl, <span class="comment">// 图片路径,必须是本地路径,可以相对路径或绝对路径</span></span><br><span class="line"> <span class="attr">success</span>: <span class="keyword">async</span> <span class="keyword">function</span> (<span class="params">res</span>) {</span><br><span class="line"> <span class="keyword">const</span> file = { <span class="attr">fileType</span>: <span class="string">"image"</span>, <span class="attr">width</span>: res.<span class="property">width</span>, <span class="attr">height</span>: res.<span class="property">height</span>, <span class="attr">tempFilePath</span>: avatarUrl }</span><br><span class="line"> <span class="keyword">const</span> fileExt = avatarUrl.<span class="title function_">split</span>(<span class="string">'.'</span>).<span class="title function_">pop</span>()</span><br><span class="line"> <span class="keyword">const</span> fileName = <span class="string">`<span class="subst">${<span class="built_in">Math</span>.random()}</span>.<span class="subst">${fileExt}</span>`</span></span><br><span class="line"> <span class="keyword">const</span> filePath = <span class="string">`<span class="subst">${profile.value.id}</span>/<span class="subst">${fileName}</span>`</span></span><br><span class="line"> <span class="keyword">let</span> { <span class="attr">error</span>: uploadError } = <span class="keyword">await</span> supabase.<span class="property">storage</span></span><br><span class="line"> .<span class="title function_">from</span>(<span class="string">'avatars'</span>)</span><br><span class="line"> .<span class="title function_">upload</span>(filePath, file <span class="keyword">as</span> <span class="built_in">any</span>)</span><br><span class="line"> <span class="keyword">if</span> (uploadError) {</span><br><span class="line"> <span class="keyword">throw</span> uploadError</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//获取具有一年期限的头像url</span></span><br><span class="line"> <span class="keyword">const</span> { data } = <span class="keyword">await</span> supabase</span><br><span class="line"> .<span class="property">storage</span></span><br><span class="line"> .<span class="title function_">from</span>(<span class="string">'avatars'</span>)</span><br><span class="line"> .<span class="title function_">createSignedUrl</span>(filePath, <span class="number">31556952</span>);</span><br><span class="line"> <span class="comment">//更新头像</span></span><br><span class="line"> <span class="title function_">updateAvatar</span>(data!.<span class="property">signedUrl</span>);</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>注:存储桶我设置为私有,且设置了行级安全策略,因此在存储头像的时候,需要存入对应 uid 文件夹下,否则没有权限。</p><blockquote><p><a href="https://document.memfiredb.com/docs/guides/storage#%E5%85%B1%E6%9C%89%E6%A1%B6%E5%92%8C%E7%A7%81%E6%9C%89%E6%A1%B6">存储桶的私有和共有</a>,详细描述了二者的区别,以及对应的获取资源 url 的方式。</p></blockquote><h3 id="自己维护users的信息"><a class="markdownIt-Anchor" href="#自己维护users的信息"></a> 自己维护users的信息</h3><p>在 public 中新建 users 表。为其创建两个触发器,分别在 auth.users 插入和更新时触发,用以同步 users 中的变化。</p><figure class="highlight postgresql"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> USERS (</span><br><span class="line"> id <span class="type">uuid</span> <span class="keyword">references</span> auth.users <span class="keyword">not</span> <span class="keyword">null</span> <span class="keyword">primary key</span>,</span><br><span class="line"> <span class="keyword">role</span> <span class="type">text</span>,</span><br><span class="line"> email <span class="type">text</span>,</span><br><span class="line"> last_sign_in_at <span class="type">text</span>,</span><br><span class="line"> raw_app_meta_data <span class="type">jsonb</span>,</span><br><span class="line"> raw_user_meta_data <span class="type">jsonb</span></span><br><span class="line">);</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">or replace</span> <span class="keyword">function</span> <span class="built_in">public</span>.handle_new_user()</span><br><span class="line"><span class="keyword">returns</span> <span class="type">trigger</span> <span class="keyword">as</span> $$<span class="language-pgsql"></span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">begin</span></span></span><br><span class="line"><span class="language-pgsql"> <span class="keyword">insert</span> <span class="keyword">into</span> <span class="built_in">public</span>.users (id, <span class="keyword">role</span>, email,last_sign_in_at,raw_app_meta_data,raw_user_meta_data)</span></span><br><span class="line"><span class="language-pgsql"> <span class="keyword">values</span> (<span class="built_in">new</span>.id,<span class="built_in">new</span>.<span class="keyword">role</span>, <span class="built_in">new</span>.email,<span class="built_in">new</span>.last_sign_in_at,<span class="built_in">new</span>.raw_app_meta_data,<span class="built_in">new</span>.raw_user_meta_data);</span></span><br><span class="line"><span class="language-pgsql"> <span class="keyword">return</span> <span class="built_in">new</span>;</span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">end</span>;</span></span><br><span class="line"><span class="language-pgsql">$$</span> <span class="keyword">language</span> plpgsql <span class="keyword">security</span> <span class="keyword">definer</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">trigger</span> on_new_user</span><br><span class="line"><span class="keyword">after</span> <span class="keyword">insert</span> <span class="keyword">on</span> auth.users <span class="keyword">for</span> <span class="keyword">each</span> <span class="keyword">row</span></span><br><span class="line"><span class="keyword">execute</span> <span class="keyword">procedure</span> <span class="built_in">public</span>.handle_new_user ();</span><br><span class="line"></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">or replace</span> <span class="keyword">function</span> <span class="built_in">public</span>.update_user()</span><br><span class="line"><span class="keyword">returns</span> <span class="type">trigger</span> <span class="keyword">as</span> $$<span class="language-pgsql"></span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">begin</span></span></span><br><span class="line"><span class="language-pgsql"> <span class="keyword">UPDATE</span> <span class="built_in">public</span>.users</span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">SET</span> <span class="keyword">role</span> = <span class="built_in">new</span>.<span class="keyword">role</span>, </span></span><br><span class="line"><span class="language-pgsql"> email = <span class="built_in">new</span>.email,</span></span><br><span class="line"><span class="language-pgsql"> last_sign_in_at = <span class="built_in">new</span>.last_sign_in_at,</span></span><br><span class="line"><span class="language-pgsql"> raw_app_meta_data = <span class="built_in">new</span>.raw_app_meta_data,</span></span><br><span class="line"><span class="language-pgsql"> raw_user_meta_data = <span class="built_in">new</span>.raw_user_meta_data</span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">WHERE</span> id = <span class="built_in">new</span>.id;</span></span><br><span class="line"><span class="language-pgsql"></span></span><br><span class="line"><span class="language-pgsql"> <span class="keyword">return</span> <span class="built_in">new</span>;</span></span><br><span class="line"><span class="language-pgsql"><span class="keyword">end</span>;</span></span><br><span class="line"><span class="language-pgsql">$$</span> <span class="keyword">language</span> plpgsql <span class="keyword">security</span> <span class="keyword">definer</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">trigger</span> on_update_user</span><br><span class="line"><span class="keyword">after</span> <span class="keyword">update</span> <span class="keyword">on</span> auth.users <span class="keyword">for</span> <span class="keyword">each</span> <span class="keyword">row</span></span><br><span class="line"><span class="keyword">execute</span> <span class="keyword">procedure</span> <span class="built_in">public</span>.update_user ();</span><br></pre></td></tr></table></figure><p>为其设定行级安全策略,仅超级管理员可以访问。</p><figure class="highlight postgresql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(get_my_claim(<span class="string">'role'</span>::<span class="type">text</span>) = <span class="string">'"super_admin"'</span>::<span class="type">jsonb</span>)</span><br></pre></td></tr></table></figure><h3 id="查询行数"><a class="markdownIt-Anchor" href="#查询行数"></a> 查询行数</h3><p>其中 head 表示是否只获取每一行的开头,而不获取具体数据。设置为 true 时,返回的 data 为 null 。estimated 是指在行数小的时候返回具体值,行数多的时候返回估计值。注意不能使用 range ,不然 count 的结果就是 range 的范围了。</p><figure class="highlight postgresql"><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></pre></td><td class="code"><pre><span class="line">export const getUsersNum = () => {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">new</span> Promise(async (resolve, reject) => {</span><br><span class="line"> const { data, count, error } = await supabase</span><br><span class="line"> .<span class="keyword">from</span>(<span class="string">'users'</span>)</span><br><span class="line"> .<span class="keyword">select</span>(<span class="string">'*'</span>, { count: <span class="string">'estimated'</span>, head: <span class="keyword">true</span> })</span><br><span class="line"> <span class="keyword">if</span> (count)</span><br><span class="line"> resolve(count);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> reject();</span><br><span class="line"> })</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="input失焦空查询"><a class="markdownIt-Anchor" href="#input失焦空查询"></a> input失焦空查询</h3><p>当为一个input输入框添加失去焦点时的事件函数 blur 时,如果是调用的异步查询函数,比如 supabase 的 select 时,会在查询时添加奇怪的参数,导致查询结果为空数组。</p><p><img src="https://pics.kahvia.cn/img/supabase%E7%9A%84input%E5%A4%B1%E7%84%A6%E7%A9%BA%E6%9F%A5%E8%AF%A21.png" alt="不正常的参数" /></p><p>为了正常查询,在 blur 触发的时候去调用同步函数,通过同步函数去调用异步查询函数即可,就像这样:<code>@blur="()=>getOrders()"</code></p><p><img src="https://pics.kahvia.cn/img/supabase%E7%9A%84input%E5%A4%B1%E7%84%A6%E7%A9%BA%E6%9F%A5%E8%AF%A22.png" alt="正常查询" /></p><p>可以看见奇怪的事件参数消失了,数据正常查询。</p><h3 id="请求未发送"><a class="markdownIt-Anchor" href="#请求未发送"></a> 请求未发送</h3><p>在对数据库进行一个字段更新的异步操作时,发现请求未成功发送。<code>supabase.from('address').update({ 'default': false }).eq('id', *fromAid*);</code></p><p>经过查阅<a href="https://www.reddit.com/r/Supabase/comments/13jsbv1/comment/jkilyj5/?utm_source=reddit&utm_medium=web2x&context=3">资料</a>得知,supabase <strong>自己封装的链式调用</strong>,在不需 await 的情况下,需要用 .then() 来表示请求的构造完成。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">supabase.<span class="title function_">from</span>(<span class="string">'address'</span>).<span class="title function_">update</span>({ <span class="string">'default'</span>: <span class="literal">true</span> }).<span class="title function_">eq</span>(<span class="string">'id'</span>, fromAid).<span class="title function_">then</span>();</span><br></pre></td></tr></table></figure><p>这样就可以在使用其自定义链式调用的情况下,正常发送无需等待的异步请求。</p>]]></content>
<summary type="html"><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3>
<p>以最近的 uniapp 开发微信小程序为例。</p>
<figure class="highlight bash"><table><tr><td</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="PostgreSQL" scheme="https://blog.kahvia.cn/tags/PostgreSQL/"/>
</entry>
<entry>
<title>TypeScript</title>
<link href="https://blog.kahvia.cn/2024/02/29/TypeScript.html"/>
<id>https://blog.kahvia.cn/2024/02/29/TypeScript.html</id>
<published>2024-02-29T05:43:41.729Z</published>
<updated>2024-03-07T09:23:51.225Z</updated>
<content type="html"><![CDATA[<h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -g typescript</span><br></pre></td></tr></table></figure><h3 id="编译ts文件"><a class="markdownIt-Anchor" href="#编译ts文件"></a> 编译ts文件</h3><p>使用该命令可以将 ts 文件转换成可执行的 js 文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tsc xxx.ts</span><br></pre></td></tr></table></figure><p>通过 node 命令执行相应的 js 文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node xxx.js</span><br></pre></td></tr></table></figure><h3 id="直接运行ts文件"><a class="markdownIt-Anchor" href="#直接运行ts文件"></a> 直接运行ts文件</h3><p>先安装所需工具包。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -g ts-node</span><br></pre></td></tr></table></figure><p>使用该工具包直接执行 ts 文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ts-node xxx.ts</span><br></pre></td></tr></table></figure><h3 id="使用时的一些小问题"><a class="markdownIt-Anchor" href="#使用时的一些小问题"></a> 使用时的一些小问题</h3><h4 id="类型本身定义是错误的"><a class="markdownIt-Anchor" href="#类型本身定义是错误的"></a> 类型本身定义是错误的</h4><p>比如,在使用 MemFireDB 的微信SDK开发小程序的时候,我使用了一个方法用于获取用户信息。</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> { <span class="attr">data</span>: { user } } = <span class="keyword">await</span> supabase.<span class="property">auth</span>.<span class="title function_">getUser</span>();</span><br></pre></td></tr></table></figure><p>对于 user 对应的官方 type 是 User,如下所示。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">interface</span> <span class="title class_">User</span> {</span><br><span class="line"> <span class="attr">id</span>: <span class="built_in">string</span></span><br><span class="line"> <span class="attr">app_metadata</span>: <span class="title class_">UserAppMetadata</span></span><br><span class="line"> <span class="attr">user_metadata</span>: <span class="title class_">UserMetadata</span></span><br><span class="line"> <span class="attr">aud</span>: <span class="built_in">string</span></span><br><span class="line"> confirmation_sent_at?: <span class="built_in">string</span></span><br><span class="line"> recovery_sent_at?: <span class="built_in">string</span></span><br><span class="line"> email_change_sent_at?: <span class="built_in">string</span></span><br><span class="line"> new_email?: <span class="built_in">string</span></span><br><span class="line"> new_phone?: <span class="built_in">string</span></span><br><span class="line"> invited_at?: <span class="built_in">string</span></span><br><span class="line"> action_link?: <span class="built_in">string</span></span><br><span class="line"> email?: <span class="built_in">string</span></span><br><span class="line"> phone?: <span class="built_in">string</span></span><br><span class="line"> <span class="attr">created_at</span>: <span class="built_in">string</span></span><br><span class="line"> confirmed_at?: <span class="built_in">string</span></span><br><span class="line"> email_confirmed_at?: <span class="built_in">string</span></span><br><span class="line"> phone_confirmed_at?: <span class="built_in">string</span></span><br><span class="line"> last_sign_in_at?: <span class="built_in">string</span></span><br><span class="line"> role?: <span class="built_in">string</span></span><br><span class="line"> updated_at?: <span class="built_in">string</span></span><br><span class="line"> identities?: <span class="title class_">UserIdentity</span>[]</span><br><span class="line"> factors?: <span class="title class_">Factor</span>[]</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>然而经过实际打印输出我发现,这个 user 的数据结构如下所示。</p><figure class="highlight json"><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><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"data"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"id"</span><span class="punctuation">:</span><span class="string">"xxx"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"app_metadata"</span><span class="punctuation">:</span><span class="punctuation">{</span><span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"xxx"</span><span class="punctuation">:</span><span class="string">"xxxx"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>所以正确的的 User 定义应该是下面这样的。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">interface</span> <span class="title class_">User</span> {</span><br><span class="line"> <span class="attr">data</span>:{</span><br><span class="line"> <span class="attr">id</span>: <span class="built_in">string</span></span><br><span class="line"> <span class="attr">app_metadata</span>: <span class="title class_">UserAppMetadata</span></span><br><span class="line"> <span class="attr">xxx</span>:xxxx</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>虽然我发现了错误,但我业务做一半,也不能不用这个了吧。所以我自己定义了一个 type ,如下所示。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">interface</span> <span class="title class_">MyUser</span> {</span><br><span class="line"> <span class="attr">data</span>: <span class="title class_">User</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>然后使用断言 as 进行强制类型转换,先取消原有的类型声明,再声明为新的类型。</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> myUser = user <span class="keyword">as</span> <span class="built_in">unknown</span> <span class="keyword">as</span> <span class="title class_">MyUser</span>;</span><br></pre></td></tr></table></figure><p>这样一来,我就可以通过 <a href="http://myUser.data.id">myUser.data.id</a> 这种形式,正常使用数据。</p>]]></content>
<summary type="html"><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span cla</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="ts" scheme="https://blog.kahvia.cn/tags/ts/"/>
</entry>
<entry>
<title>uniapp知识点</title>
<link href="https://blog.kahvia.cn/2024/02/29/Uniapp.html"/>
<id>https://blog.kahvia.cn/2024/02/29/Uniapp.html</id>
<published>2024-02-29T01:47:57.745Z</published>
<updated>2024-05-15T07:59:03.276Z</updated>
<content type="html"><![CDATA[<h3 id="在vscode中开发uniapp"><a class="markdownIt-Anchor" href="#在vscode中开发uniapp"></a> 在vscode中开发uniapp</h3><h4 id="使用命令行创建uniapp项目"><a class="markdownIt-Anchor" href="#使用命令行创建uniapp项目"></a> 使用命令行创建uniapp项目</h4><p>此处是vue3+ts。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx degit dcloudio/uni-preset-vue<span class="comment">#vite-ts my-vue3-project</span></span><br></pre></td></tr></table></figure><h4 id="安装插件"><a class="markdownIt-Anchor" href="#安装插件"></a> 安装插件</h4><ul><li>uni-create-view</li><li>uni-helper</li><li>uniapp小程序扩展</li></ul><h4 id="ts相关"><a class="markdownIt-Anchor" href="#ts相关"></a> TS相关</h4><p>在根目录创建 <code>tsconfig.json</code> 文件,并进行个性化配置,个性化配置是可选的,没有<code>tsconfig.json</code>时会自动使用默认配置运行。推荐配置如下:</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// tsconfig.json</span></span><br><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"compilerOptions"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"target"</span><span class="punctuation">:</span> <span class="string">"esnext"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"module"</span><span class="punctuation">:</span> <span class="string">"esnext"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"strict"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"jsx"</span><span class="punctuation">:</span> <span class="string">"preserve"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"moduleResolution"</span><span class="punctuation">:</span> <span class="string">"node"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"esModuleInterop"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"sourceMap"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"skipLibCheck"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"importHelpers"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"allowSyntheticDefaultImports"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"useDefineForClassFields"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"resolveJsonModule"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"lib"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"esnext"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"dom"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"types"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"@dcloudio/types"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"@types/wechat-miniprogram"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"@uni-helper/uni-app-types"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"@uni-helper/uni-ui-types"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"baseUrl"</span><span class="punctuation">:</span> <span class="string">"./"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"paths"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"@/*"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"src/*"</span></span><br><span class="line"> <span class="punctuation">]</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"vueCompilerOptions"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"nativeTags"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"block"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"component"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"template"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"slot"</span></span><br><span class="line"> <span class="punctuation">]</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"exclude"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"node_modules"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"unpackage"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="string">"src/**/*.nvue"</span></span><br><span class="line"> <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><blockquote><p>vueCompilerOptions以及nativeTags的配置是必须的。否则uniapp的标签比如view会出现<strong><a href="https://blog.csdn.net/weixin_41844140/article/details/134901640?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-134901640-blog-134186772.235%5Ev43%5Epc_blog_bottom_relevance_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-134901640-blog-134186772.235%5Ev43%5Epc_blog_bottom_relevance_base3&utm_relevant_index=2">类型错误</a></strong>。</p><p>baseUrl 和 paths 用于映射@/开头的 import 路径。详情参考<a href="https://www.typescriptlang.org/zh/tsconfig#paths">TypeScript: TSConfig</a>。</p></blockquote><p>安装TS类型支持包。前者是微信小程序组件的TS类型,后者是uniapp组件的TS类型。这些类型已在上方配置文件中的types添加。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types</span><br></pre></td></tr></table></figure><h4 id="json文件相关"><a class="markdownIt-Anchor" href="#json文件相关"></a> json文件相关</h4><p>在 uniapp 项目中,我们可能会在 json 文件中有注释,vscode 识别 json 文件时,不允许有注释在其中,会报错,如下图所示。</p><p><img src="https://pics.kahvia.cn/img/20240301171803.png" alt="json文件内注释报错" /></p><p>解决方法:在 vscode 的设置中,搜索 associations ,添加文件关联键值对,即<strong> xxx.json jsonc </strong>。如下图所示,报错已消失。</p><p>注:.json 文件是标准的 json 格式,除了不允许有注释以外,还有其它的一些严格规则。.jsonc 文件则是拓展的 json 格式,能有注释在其中,以及可以省略 key 的引号等等。像 package.json 这种文件,最好还是不要加注释在里面。</p><p><img src="https://pics.kahvia.cn/img/20240301174049.png" alt="vscode文件关联" /></p><h3 id="uni-ui"><a class="markdownIt-Anchor" href="#uni-ui"></a> uni-ui</h3><p><a href="https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html">uni-ui 介绍 | uni-app官网 (dcloud.net.cn)</a></p><h4 id="安装-uni-ui-所需的-sass-预处理器和加载器"><a class="markdownIt-Anchor" href="#安装-uni-ui-所需的-sass-预处理器和加载器"></a> 安装 uni-ui 所需的 sass 预处理器和加载器</h4><p>安装 sass</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i sass -D 或 yarn add sass -D </span><br></pre></td></tr></table></figure><p>安装 sass-loader</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i sass-loader@10.1.1 -D 或 yarn add sass-loader@10.1.1 -D</span><br></pre></td></tr></table></figure><h4 id="安装uni-ui"><a class="markdownIt-Anchor" href="#安装uni-ui"></a> 安装uni-ui</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i @dcloudio/uni-ui 或 yarn add @dcloudio/uni-ui</span><br></pre></td></tr></table></figure><h4 id="配置uni-ui组件自动导入"><a class="markdownIt-Anchor" href="#配置uni-ui组件自动导入"></a> 配置uni-ui组件自动导入</h4><figure class="highlight json"><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><span class="line"><span class="comment">// pages.json</span></span><br><span class="line"><span class="punctuation">{</span></span><br><span class="line"><span class="attr">"easycom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="attr">"autoscan"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"custom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="comment">// uni-ui 规则如下配置</span></span><br><span class="line"><span class="attr">"^uni-(.*)"</span><span class="punctuation">:</span> <span class="string">"@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 其他内容</span></span><br><span class="line">pages<span class="punctuation">:</span><span class="punctuation">[</span></span><br><span class="line"><span class="comment">// ...</span></span><br><span class="line"><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="安装-uni-ui-的-ts-类型包"><a class="markdownIt-Anchor" href="#安装-uni-ui-的-ts-类型包"></a> 安装 uni-ui 的 ts 类型包</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -D @uni-helper/uni-ui-types</span><br></pre></td></tr></table></figure><p>然后在 tsconfig.json 中的 types 里写上对应的类型。现在就可以在 uni-ui 的组件标签上看到对应的类型了。</p><h3 id="pinia"><a class="markdownIt-Anchor" href="#pinia"></a> Pinia</h3><h4 id="pinia本体"><a class="markdownIt-Anchor" href="#pinia本体"></a> pinia本体</h4><p>本人采用 vue 版本 3.4.21, pinia 版本 2.0.36,不会发生依赖冲突以及各种报错。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i pinia@2.0.36</span><br></pre></td></tr></table></figure><p>创建 pinia 实例。</p><figure class="highlight tsx"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { createApp } <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> { createPinia } <span class="keyword">from</span> <span class="string">'pinia'</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">'./App.vue'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> pinia = <span class="title function_">createPinia</span>()</span><br><span class="line"><span class="keyword">const</span> app = <span class="title function_">createApp</span>(<span class="title class_">App</span>)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">use</span>(pinia)</span><br><span class="line">app.<span class="title function_">mount</span>(<span class="string">'#app'</span>)</span><br></pre></td></tr></table></figure><h5 id="常用操作"><a class="markdownIt-Anchor" href="#常用操作"></a> 常用操作</h5><p>使用 <a href="https://pinia.vuejs.org/zh/core-concepts/#using-the-store">storeToRefs()</a> 取出 store 中的响应式数据。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">import</span> { useUserStore } <span class="keyword">from</span> <span class="string">'../../stores/piniaStores'</span></span><br><span class="line"><span class="keyword">import</span> { storeToRefs } <span class="keyword">from</span> <span class="string">'pinia'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> userStore = <span class="title function_">useUserStore</span>();</span><br><span class="line"><span class="keyword">const</span> {nickName} = <span class="title function_">storeToRefs</span>(userStore);</span><br></pre></td></tr></table></figure><h4 id="pinia的持久化插件"><a class="markdownIt-Anchor" href="#pinia的持久化插件"></a> pinia的持久化插件</h4><p><a href="https://prazdevs.github.io/pinia-plugin-persistedstate/">Home | pinia-plugin-persistedstate (prazdevs.github.io)</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i pinia-plugin-persistedstate</span><br></pre></td></tr></table></figure><p>注意:是 pinia-plugin-persistedstate 这个插件,而非 <a href="https://seb-l.github.io/pinia-plugin-persist/">pinia-plugin-persist</a> 这个坑比插件。后者使用自定义 Storage 的时候,比如我是用的 uni 的storage,会报错说没有sessionStorage,这让我研究了一下午自己的官方文档,怀疑是自己的问题,最后得出结论是插件官方的问题。</p><p>在 main.ts 中配置持久化。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">import</span> { createPinia } <span class="keyword">from</span> <span class="string">'pinia'</span></span><br><span class="line"><span class="keyword">import</span> piniaPluginPersistedstate <span class="keyword">from</span> <span class="string">'pinia-plugin-persistedstate'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> pinia = <span class="title function_">createPinia</span>()</span><br><span class="line">pinia.<span class="title function_">use</span>(piniaPluginPersistedstate)</span><br></pre></td></tr></table></figure><p>我配置完成后是如下所示。</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { createSSRApp } <span class="keyword">from</span> <span class="string">"vue"</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">"./App.vue"</span>;</span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> <span class="title class_">Pinia</span> <span class="keyword">from</span> <span class="string">'pinia'</span>;</span><br><span class="line"><span class="keyword">import</span> piniaPluginPersistedstate <span class="keyword">from</span> <span class="string">'pinia-plugin-persistedstate'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">createApp</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> app = <span class="title function_">createSSRApp</span>(<span class="title class_">App</span>);</span><br><span class="line"> <span class="keyword">const</span> pinia = <span class="title class_">Pinia</span>.<span class="title function_">createPinia</span>();</span><br><span class="line"> pinia.<span class="title function_">use</span>(piniaPluginPersistedstate);</span><br><span class="line"> app.<span class="title function_">use</span>(pinia);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> app,</span><br><span class="line"> <span class="title class_">Pinia</span>,</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>因为是为了 uniapp 采用的 pinia ,而 uniapp 没有 sessionStorage ,所以在定义 store 的时候需要自定义 storage。参考代码如下。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">import</span> { defineStore } <span class="keyword">from</span> <span class="string">'pinia'</span></span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">StorageLike</span> } <span class="keyword">from</span> <span class="string">'pinia-plugin-persistedstate'</span>;</span><br><span class="line"><span class="keyword">import</span> { ref } <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="attr">uniStorege</span>: <span class="title class_">StorageLike</span> = {</span><br><span class="line"> <span class="title function_">setItem</span>(<span class="params">key, value</span>) {</span><br><span class="line"> uni.<span class="title function_">setStorageSync</span>(key, value);</span><br><span class="line"> },</span><br><span class="line"> <span class="title function_">getItem</span>(<span class="params">key</span>) {</span><br><span class="line"> <span class="keyword">return</span> uni.<span class="title function_">getStorageSync</span>(key);</span><br><span class="line"> },</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)</span></span><br><span class="line"><span class="comment">// 第一个参数是你的应用中 Store 的唯一 ID。</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> useUserStore = <span class="title function_">defineStore</span>(<span class="string">'user'</span>, <span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">const</span> nickName = <span class="title function_">ref</span>(<span class="string">"Kahvia"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">setName</span>(<span class="params">name: <span class="built_in">string</span></span>) {</span><br><span class="line"> nickName.<span class="property">value</span> = name;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> { nickName, setName };</span><br><span class="line">}, {</span><br><span class="line"> <span class="attr">persist</span>: {</span><br><span class="line"> <span class="attr">storage</span>: uniStorege,</span><br><span class="line"> },</span><br><span class="line">})</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>关于插件的其它可选配置,可以参照官方文档。</p><h3 id="为-uniapp-的请求添加拦截器"><a class="markdownIt-Anchor" href="#为-uniapp-的请求添加拦截器"></a> 为 uniapp 的请求添加拦截器</h3><p>拦截器的作用是,在请求发送前拦截请求,或收到请求结果后拦截结果,对请求或结果作一定的处理后,再放行。常用于简化操作,比如发送请求前统一添加域名前缀,或收到请求结果后提取关键数据、展示错误信息等。减少了代码的冗余。ps:比如我以前做项目的时候,都是在一个 js 文件中定义常量 baseUrl,在有请求的页面引入该 js 文件,采用 baseUrl + ‘/user/upload’ 这种形式的代码,这意味着我有多少个请求,我就写了多少个这样的拼接代码,的确写了很多无用代码。</p><p>以下代码块则展示了如何添加请求发送前的拦截器。</p><figure class="highlight ts"><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><span class="line"><span class="comment">//utils/http.ts</span></span><br><span class="line"><span class="keyword">import</span> { useUserStore } <span class="keyword">from</span> <span class="string">"@/stores/piniaStores"</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="attr">baseUrl</span>: <span class="built_in">string</span> = <span class="string">"https://www.kahvia.cn"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> httpInterceptor = {</span><br><span class="line"> <span class="title function_">invoke</span>(<span class="params">options: UniApp.RequestOptions</span>) {</span><br><span class="line"> <span class="comment">//请求添加前缀</span></span><br><span class="line"> <span class="keyword">if</span> (!options.<span class="property">url</span>.<span class="title function_">startsWith</span>(<span class="string">"http"</span>))</span><br><span class="line"> options.<span class="property">url</span> = baseUrl + options.<span class="property">url</span>;</span><br><span class="line"> <span class="comment">//设置超时时间</span></span><br><span class="line"> options.<span class="property">timeout</span> = <span class="number">10000</span>;</span><br><span class="line"> <span class="comment">//设置请求头</span></span><br><span class="line"> options.<span class="property">header</span> = {</span><br><span class="line"> <span class="comment">//保留原有请求头</span></span><br><span class="line"> ...options.<span class="property">header</span>,</span><br><span class="line"> <span class="comment">//添加请求来源</span></span><br><span class="line"> <span class="string">'source-client'</span>: <span class="string">'miniapp'</span></span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">const</span> userStore = <span class="title function_">useUserStore</span>();</span><br><span class="line"> <span class="keyword">const</span> token = userStore.<span class="property">profile</span>?.<span class="property">token</span>;</span><br><span class="line"> <span class="keyword">if</span> (token)</span><br><span class="line"> options.<span class="property">header</span>.<span class="property">Authorization</span> = token;</span><br><span class="line"></span><br><span class="line"> },</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">uni.<span class="title function_">addInterceptor</span>(<span class="string">"request"</span>, httpInterceptor);</span><br><span class="line">uni.<span class="title function_">addInterceptor</span>(<span class="string">"uploadFile"</span>, httpInterceptor);</span><br></pre></td></tr></table></figure><p>uniapp 中没有关于请求结果的拦截器,得用 Promise 手动封装。</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//utils/http.ts</span></span><br><span class="line"><span class="comment">//接上个拦截器代码块</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//自己封装的数据类型</span></span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">Data</span><T> {</span><br><span class="line"> <span class="attr">code</span>: <span class="built_in">number</span>,</span><br><span class="line"> <span class="attr">msg</span>: <span class="built_in">string</span>,</span><br><span class="line"> <span class="attr">data</span>: T</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//封装uni-request,对数据结果进行统一处理,即拦截请求结果。上面的interceptor是请求发送前拦截。</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> http = <T><span class="function">(<span class="params">options: UniApp.RequestOptions</span>) =></span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span><<span class="title class_">Data</span><T>>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> uni.<span class="title function_">request</span>({</span><br><span class="line"> ...options,</span><br><span class="line"> <span class="comment">//服务器有响应结果,不管状态码是200还是401亦或是500,都会走success函数。</span></span><br><span class="line"> <span class="title function_">success</span>(<span class="params">res</span>) {</span><br><span class="line"> <span class="comment">//状态码正常,则resolve,axios内部也是如此实现的。</span></span><br><span class="line"> <span class="keyword">if</span> (res.<span class="property">statusCode</span> >= <span class="number">200</span> && res.<span class="property">statusCode</span> < <span class="number">300</span>) {</span><br><span class="line"> <span class="comment">//用as对返回类型进行断言</span></span><br><span class="line"> <span class="title function_">resolve</span>(res.<span class="property">data</span> <span class="keyword">as</span> <span class="title class_">Data</span><T>);</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (res.<span class="property">statusCode</span> == <span class="number">401</span>) {</span><br><span class="line"> <span class="comment">//401代表token无效,身份验证失败</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"Authorization error"</span>);</span><br><span class="line"> uni.<span class="title function_">showToast</span>({ <span class="attr">title</span>: <span class="string">"身份验证失效,请重新登录"</span> });</span><br><span class="line"> <span class="title function_">reject</span>(res);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> uni.<span class="title function_">showToast</span>({ <span class="attr">title</span>: <span class="string">"服务器异常"</span> });</span><br><span class="line"> <span class="title function_">reject</span>(res);</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//服务器没有返回结果,代表请求未成功发送,即网络异常。</span></span><br><span class="line"> <span class="title function_">fail</span>(<span class="params">err</span>) {</span><br><span class="line"> uni.<span class="title function_">showToast</span>({ <span class="attr">title</span>: <span class="string">"网络异常,请检查网络"</span> })</span><br><span class="line"> <span class="title function_">reject</span>(err);</span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这样一来,自己封装的网络请求模块就完成了。在需要的地方导入使用即可。</p><p>注:泛型 T 的使用是为了更好地处理数据。每个请求返回的 data 部分都是变化的,有的是字符数组,有的是对象数组,根据选择使用。</p><figure class="highlight ts"><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><span class="line"><span class="keyword">import</span> {http} <span class="keyword">from</span> <span class="string">'@/utils/http'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">clickTest</span>(<span class="params"></span>){</span><br><span class="line"> userStore.<span class="title function_">setName</span>(<span class="string">"Adong"</span>);</span><br><span class="line"> <span class="keyword">const</span> res = <span class="keyword">await</span> http<<span class="built_in">string</span>[]>({</span><br><span class="line"> <span class="attr">method</span>:<span class="string">"GET"</span>,</span><br><span class="line"> <span class="attr">url</span>:<span class="string">"/test"</span></span><br><span class="line"> })</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(res);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>当请求的结果有效,即 resolve 后,该 Promise 对象的状态会变成 fulfilled(已兑现),变量 res 有了有效值,继续执行下面的 log 语句。当请求的结果无效,即 reject 后,该 Promise 对象的状态变为 rejected(已拒绝),此时异步函数直接结束,不会执行下面的 log 语句。</p><p>注:Promise 对象的初始状态为 pending(待定)。</p><h3 id="uniapp知识点"><a class="markdownIt-Anchor" href="#uniapp知识点"></a> uniapp知识点</h3><h4 id="svg"><a class="markdownIt-Anchor" href="#svg"></a> svg</h4><p>uniapp 中不支持 svg 标签,所以涉及到的 svg 图片可以转换成 base64 进行使用。</p><p><a href="https://www.zhangxinxu.com/sp/svgo/">SVG在线工具</a>。通过这个工具我们可以实现上述操作。我就用这个工具将 iconfont 上面的图标转换成了 base64 ,用 img 标签进行了插入。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">img</span> <span class="attr">class</span>=<span class="string">"searchIcon"</span> <span class="attr">src</span>=<span class="string">"data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTEwMjQgOTYzLjdMNzU2LjggNjk2LjVjNjAuMi03My42IDk2LjUtMTY3LjUgOTYuNS0yNjkuOEM4NTMuMyAxOTEuNCA2NjEuOSAwIDQyNi43IDBTMCAxOTEuNCAwIDQyNi43czE5MS40IDQyNi43IDQyNi43IDQyNi43YzEwMi4zIDAgMTk2LjMtMzYuMyAyNjkuOC05Ni41TDk2My43IDEwMjRsNjAuMy02MC4zek00MjYuNyA3NjhDMjM4LjUgNzY4IDg1LjMgNjE0LjkgODUuMyA0MjYuN1MyMzguNSA4NS4zIDQyNi43IDg1LjMgNzY4IDIzOC41IDc2OCA0MjYuNyA2MTQuOSA3NjggNDI2LjcgNzY4eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=="</span>></span></span><br></pre></td></tr></table></figure><h4 id="自定义导航栏"><a class="markdownIt-Anchor" href="#自定义导航栏"></a> 自定义导航栏</h4><p>设置 navigationStyle 为 custom 以取消默认导航栏。然后手写导航栏组件添加到页面中使用即可。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"><span class="attr">"easycom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="attr">"autoscan"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"custom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="comment">// uni-ui 规则如下配置</span></span><br><span class="line"><span class="attr">"^uni-(.*)"</span><span class="punctuation">:</span> <span class="string">"@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"pages"</span><span class="punctuation">:</span> <span class="punctuation">[</span> <span class="comment">//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages</span></span><br><span class="line"><span class="punctuation">{</span></span><br><span class="line"><span class="attr">"path"</span><span class="punctuation">:</span> <span class="string">"pages/index/index"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"style"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="comment">//取消默认导航栏</span></span><br><span class="line"><span class="attr">"navigationStyle"</span><span class="punctuation">:</span> <span class="string">"custom"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"navigationBarTitleText"</span><span class="punctuation">:</span> <span class="string">"首页"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"navigationBarTextStyle"</span><span class="punctuation">:</span> <span class="string">"white"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"globalStyle"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="attr">"navigationBarTextStyle"</span><span class="punctuation">:</span> <span class="string">"white"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"navigationBarTitleText"</span><span class="punctuation">:</span> <span class="string">"uni-app"</span><span class="punctuation">,</span></span><br><span class="line"><span class="comment">// "navigationBarBackgroundColor": "#F8F8F8",</span></span><br><span class="line"><span class="comment">// "backgroundColor": "#F8F8F8"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><h4 id="image标签"><a class="markdownIt-Anchor" href="#image标签"></a> image标签</h4><p>uniapp 中不能使用 img 标签。使用 img 标签后,会被解析成 image 标签,导致为 img 写的 css 样式失效。</p><h4 id="样式隔离"><a class="markdownIt-Anchor" href="#样式隔离"></a> 样式隔离</h4><p>在某些情况下,比如我写了一个组件,里面用到了 uniapp 提供的内置组件,如 uni-file-picker ,当我尝试通过 vue 的样式穿透去修改内置组件的样式时,怎么改都不行,用上 !important 也不行,在调试的时候看穿透的样式根本没修改成功。这时候或许就是 uniapp 自带的样式隔离起了作用。使用以下代码进行样式隔离的取消,可以解决问题。</p><figure class="highlight plaintext"><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><span class="line"><script lang="ts"></span><br><span class="line">export default {</span><br><span class="line"> options: {</span><br><span class="line"> styleIsolation: 'shared'</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></script></span><br></pre></td></tr></table></figure><p>非常傻逼的一个问题。<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#%E7%BB%84%E4%BB%B6%E6%A0%B7%E5%BC%8F%E9%9A%94%E7%A6%BB">样式隔离。</a>这个文档是微信官方文档,因此推断是微信小程序的特有设定。</p><h4 id="禁止手指滑动"><a class="markdownIt-Anchor" href="#禁止手指滑动"></a> 禁止手指滑动</h4><p>在自定义的加载遮罩显示时,需要禁止手指滑动,以防下面的页面被滑动。</p><p>在最外层添加 @touchmove.stop.prevent=“() => { }” 。</p><figure class="highlight plaintext"><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><span class="line"><template></span><br><span class="line"> <div @touchmove.stop.prevent="() => { }" class="loading" :class="{ alignTop: ifAlignTop, alignBottom: !ifAlignTop }"</span><br><span class="line"> v-if="isLoading"></span><br><span class="line"> <uni-load-more icon-type="circle" color="white" status="loading" :icon-size="30"</span><br><span class="line"> :content-text="{ contentrefresh: content, contentdown: '', contentnomore: '' }" /></span><br><span class="line"> </div></span><br><span class="line"></template></span><br></pre></td></tr></table></figure><h4 id="自定义遮罩的位置问题"><a class="markdownIt-Anchor" href="#自定义遮罩的位置问题"></a> 自定义遮罩的位置问题</h4><p>在 uniapp 中,App.vue 文件中并不能写 template ,所以全局遮罩并不方便实现。 所以需要定义一个遮罩组件,在每个页面分别引入使用。</p><p>然而,遮罩放在每个页面的根节点下有时也并不方便。举个例子,遮罩的高度一般是100vh,假设我通过绝对定位对页面进行上左对齐,当页面可以滚动的时候,即页面高度大于100vh的时候,如果我在页面底部触发了遮罩,由于遮罩高度不够,页面底部就是无遮罩状态。如果我对遮罩的高度预设成300vh,可以达到遮住底部的效果,但是遮罩中间的加载用的提示信息又跑到了别处,而不在屏幕中间。想要动态控制遮罩的高度或者其中的文字位置是不现实的,每个页面的高度都不一样,而 uniapp 中又不容易获取滚动高度。</p><p><s>因此,固定遮罩的高度为100vh,尝试调整遮罩的引入位置以及对齐位置才是更合理的做法。比如我在页面底部触发了从底部弹出的弹出层,那么封装一个组件,引入弹出层和遮罩层,将自定义组件标记为相对定位,遮罩层标记为绝对定位,并使遮罩下左对齐。</s></p><h4 id="scroll-view-滚动条问题"><a class="markdownIt-Anchor" href="#scroll-view-滚动条问题"></a> scroll-view 滚动条问题</h4><p>在微信小程序中,仅设置 show-scrollbar = “false” 是没用的,同时还要设置 enhanced = “true”。</p><figure class="highlight plaintext"><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><span class="line"><scroll-view :scroll-y="true" class="cats" :show-scrollbar="false" :enhanced="true"></span><br><span class="line"> <div :key="index" v-for="(cat, index) in categories" class="cat" :class="{ catActive: catIsActive(index) }"</span><br><span class="line"> @click=setActive(index)></span><br><span class="line"> <text>{{ cat.name }}</text></span><br><span class="line"> </div></span><br><span class="line"></scroll-view></span><br></pre></td></tr></table></figure><p>别用uniapp的这个组件写 flex 布局。因为flex布局中的 align-content 会无效,调了一下午没吊用。🐕都不用。自己写的 flex 布局盒子好用的一批。</p><h4 id="第三方组件引入问题"><a class="markdownIt-Anchor" href="#第三方组件引入问题"></a> 第三方组件引入问题</h4><p>以 NutUi 为例,配置 easycom 自动导入的代码如下所示。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="attr">"easycom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="attr">"autoscan"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"custom"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"><span class="comment">// uni-ui 规则如下配置</span></span><br><span class="line"><span class="attr">"^uni-(.*)"</span><span class="punctuation">:</span> <span class="string">"@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"^nut-(.*)?-(.*)"</span><span class="punctuation">:</span> <span class="string">"nutui-uniapp/components/$1$2/$1$2.vue"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"^nut-(.*)"</span><span class="punctuation">:</span> <span class="string">"nutui-uniapp/components/$1/$1.vue"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>可以看到引入规则中的组件名称是短横线命名法。因此在使用组件时,也应使用短横线命名,因为大驼峰命名会导致自动引入出问题,我甚至曾怀疑是 uniapp 的问题,毕竟是真不太好用。</p><figure class="highlight html"><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><span class="line"><span class="comment"><!-- 有效 --></span></span><br><span class="line"><span class="tag"><<span class="name">nut-button</span> <span class="attr">type</span>=<span class="string">"danger"</span>></span>TEST<span class="tag"></<span class="name">nut-button</span>></span></span><br><span class="line"><span class="comment"><!-- 无效 --></span></span><br><span class="line"><span class="comment"><!-- <NutButton type="danger">TEST</NutButton> --></span></span><br></pre></td></tr></table></figure><p>当然有时也会出现大驼峰名称能用的情况,这种情况通常是短横线名称的组件以意想不到的方式被引入了。比如上面代码中两种写法,如果同时存在,你会发现大驼峰形式的也能正常用,因为短横线写法已经引入了这个组件。至于为什么大驼峰不能正常引入组件,我只能猜测 easycom 就是浅显地凭借所写标签名称进行自动引入的。</p>]]></content>
<summary type="html"><h3 id="在vscode中开发uniapp"><a class="markdownIt-Anchor" href="#在vscode中开发uniapp"></a> 在vscode中开发uniapp</h3>
<h4 id="使用命令行创建uniapp项目"><a class</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="uniapp" scheme="https://blog.kahvia.cn/tags/uniapp/"/>
</entry>
<entry>
<title>使用nrm管理npm镜像源</title>
<link href="https://blog.kahvia.cn/2024/02/04/NpmMirrorManage.html"/>
<id>https://blog.kahvia.cn/2024/02/04/NpmMirrorManage.html</id>
<published>2024-02-04T09:58:19.119Z</published>
<updated>2024-06-22T06:00:26.310Z</updated>
<content type="html"><![CDATA[<h3 id="安装nrm"><a class="markdownIt-Anchor" href="#安装nrm"></a> 安装nrm</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g nrm</span><br></pre></td></tr></table></figure><h3 id="查看镜像源"><a class="markdownIt-Anchor" href="#查看镜像源"></a> 查看镜像源</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nrm <span class="built_in">ls</span></span><br></pre></td></tr></table></figure><h3 id="选用镜像源"><a class="markdownIt-Anchor" href="#选用镜像源"></a> 选用镜像源</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nrm use xxx</span><br></pre></td></tr></table></figure><p>比如<strong>nrm use taobao</strong>。当 npm 命令卡进度的时候,请先查看当前源是否是镜像源,因为在2024年6月22日这天突然发现变回了默认源,切换为镜像源后恢复正常。</p>]]></content>
<summary type="html"><h3 id="安装nrm"><a class="markdownIt-Anchor" href="#安装nrm"></a> 安装nrm</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre></summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="node.js" scheme="https://blog.kahvia.cn/tags/node-js/"/>
</entry>
<entry>
<title>基础算法</title>
<link href="https://blog.kahvia.cn/2024/01/15/AlgorithmAcBase1.html"/>
<id>https://blog.kahvia.cn/2024/01/15/AlgorithmAcBase1.html</id>
<published>2024-01-15T10:16:23.498Z</published>
<updated>2024-01-28T14:27:25.713Z</updated>
<content type="html"><![CDATA[<h3 id="快速排序"><a class="markdownIt-Anchor" href="#快速排序"></a> 快速排序</h3><ol><li>选取基准值(分界值)x,可以是数组的第一个元素,也可以是数组的最后一个元素,中间元素亦可。</li><li>使用双指针<strong> i </strong>和 <strong>j</strong> 从数组的两端开始扫描,从左端找到一个<strong>>=x</strong>的值a,从右端找到一个<strong><=x</strong>的值b,交换ab的值,交换后<strong>i以及i之前的元素</strong>都小于等于x,<strong>j以及j之后的元素</strong>都大于等于x。交换后i应递增,j应递减,继续查找可以交换的值,知道ij相遇甚至错开(i > j)。</li><li>当数组成功划分两部分,左部分小于等于x,右部分大于等于x的时候,左右两部分分别递归调用快速排序。</li></ol><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/4.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"><span class="type">int</span> t[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">quick_sort</span><span class="params">(<span class="type">int</span> l, <span class="type">int</span> r)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(l >= r) <span class="keyword">return</span>;</span><br><span class="line"> <span class="type">int</span> i = l - <span class="number">1</span>, j = r + <span class="number">1</span>, x = t[(l + r) / <span class="number">2</span>];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(i < j){</span><br><span class="line"> <span class="comment">//基准值元素也可以交换,在左区间或者右区间都可以,因此while (t[i] < x);没有等号=。</span></span><br><span class="line"> <span class="comment">//如果是不能交换,即while (t[i] <= x);</span></span><br><span class="line"> <span class="comment">//那么比如6 2 3,基准值为2时。从左边找到了一个比2大的值6,但是从右边找不到比2小的,j--会一直执行,死循环了。</span></span><br><span class="line"> <span class="keyword">do</span> i++; <span class="keyword">while</span> (t[i] < x);</span><br><span class="line"> <span class="keyword">do</span> j--; <span class="keyword">while</span> (t[j] > x);</span><br><span class="line"> <span class="keyword">if</span>(i < j) <span class="built_in">swap</span>(t[i],t[j]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/*在划分区间递归调用快排的时候,i==j或者i>j</span></span><br><span class="line"><span class="comment"> ①当i==j时,举例数组为2 1. l==0,r==1。区间为[0,1]。</span></span><br><span class="line"><span class="comment"> x = t[(l + r) / 2];取值为x=2,相当于取数组首元素为基准值,经过循环后i==j==0。</span></span><br><span class="line"><span class="comment"> 正确的分法:划分区间应为[0,0]和[1,1],即[l, j]和[j + 1, r],或者将j换成i。</span></span><br><span class="line"><span class="comment"> 也就是将相遇处的元素划分给右区间。</span></span><br><span class="line"><span class="comment"> 错误的分法:如果划分给左区间,即[l, j - 1]和[j, r]的话,区间为[0,-1]和[0,1]。</span></span><br><span class="line"><span class="comment"> 右区间的快排与当前快排区间相同,导致右区间递归与当前相同,陷入死循环。</span></span><br><span class="line"><span class="comment"> 若想使得该分法正确,应当x = t[(l + r + 1) / 2],即取数组尾元素为基准值。</span></span><br><span class="line"><span class="comment"> ②当i>j时。举例,在上一轮while中交换ij元素后,进入下一轮while循环前,</span></span><br><span class="line"><span class="comment"> i == 1, j == 2,进入循环后,i++变成2,j--变成1,此时发生i > j的情况。且<2的元素<=x, >1的元素>=x。</span></span><br><span class="line"><span class="comment"> 这种情况下划分区间时,根据①的两种分法,为了保证划分的正确性:</span></span><br><span class="line"><span class="comment"> 若取数组首元素为基准值,则应采用j,即[l, j]和[j + 1, r]。</span></span><br><span class="line"><span class="comment"> 如果采用[l, i]和[i + 1, r],右区间为[3, r]很显然缺少了下标2对应的>=x的元素,同理左区间会多一个。</span></span><br><span class="line"><span class="comment"> 若取数组尾元素为基准值,则应采用i,即[l, i - 1]和[i, r]。原理同上。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> 总结:一整个快速排序中包含很多个小快速排序,可能出现i==j和i>j的情况。因此,为了确保两种情况下都正常运行,分类如下。</span></span><br><span class="line"><span class="comment"> ①x = t[(l + r) / 2];或者说取左端点元素为基准值的情况下,递归区间划分[l, j]和[j + 1, r]。</span></span><br><span class="line"><span class="comment"> ②x = t[(l + r + 1) / 2];或者说取右端点元素为基准值的情况下,递归区间划分[l, i - 1]和[i, r]。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="built_in">quick_sort</span>(l,j);</span><br><span class="line"> <span class="built_in">quick_sort</span>(j + <span class="number">1</span>,r);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&t[i]);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">quick_sort</span>(<span class="number">0</span>, n - <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>,t[i]);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="归并排序"><a class="markdownIt-Anchor" href="#归并排序"></a> 归并排序</h3><ol><li>数组一分为二,递归调用归并排序。</li><li>利用双指针,合并一分为二的数组,将结果存到额外数组 tmp 中。</li><li>合并完成后,将结果数组覆盖至原数组中。</li></ol><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/16.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"><span class="type">int</span> t[N], tmp[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">merge_sort</span><span class="params">(<span class="type">int</span> l, <span class="type">int</span> r)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(l >= r) <span class="keyword">return</span>;</span><br><span class="line"> <span class="comment">//右移等同除以二</span></span><br><span class="line"> <span class="type">int</span> mid = l + r >> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//从数组中间一分为二,各自归并排序</span></span><br><span class="line"> <span class="built_in">merge_sort</span>(l, mid), <span class="built_in">merge_sort</span>(mid + <span class="number">1</span>, r);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//k是结果数组的下一个放置元素的位置,ij为数组左右两部分的起始指针</span></span><br><span class="line"> <span class="type">int</span> k = <span class="number">0</span>, i = l, j = mid + <span class="number">1</span>;</span><br><span class="line"> <span class="comment">//比较ij指针值的大小,择其小存于结果中</span></span><br><span class="line"> <span class="keyword">while</span>(i <= mid && j <= r){</span><br><span class="line"> <span class="keyword">if</span>(t[i] <= t[j]) tmp[k++] = t[i++];</span><br><span class="line"> <span class="keyword">else</span> tmp[k++] = t[j++];</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//当某一部分已经全部加入结果后,另一部分的剩余元素直接加入结果</span></span><br><span class="line"> <span class="keyword">while</span>(i <= mid) tmp[k++] = t[i++];</span><br><span class="line"> <span class="keyword">while</span>(j <= r) tmp[k++] = t[j++];</span><br><span class="line"></span><br><span class="line"> <span class="comment">//用有序的结果覆盖原来无序的数组</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = l, j = <span class="number">0</span>; i <= r; i++,j++)</span><br><span class="line"> t[i] = tmp[j];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &t[i]);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">merge_sort</span>(<span class="number">0</span>, n - <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) <span class="built_in">printf</span>(<span class="string">"%d "</span>, t[i]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="归并排序的应用求解逆序对数量"><a class="markdownIt-Anchor" href="#归并排序的应用求解逆序对数量"></a> 归并排序的应用——求解逆序对数量</h4><p>对于任意给定的数字序列,举例如<strong> 4 3 2 1 </strong>,若交换相邻元素,可以减少一个逆序对而不影响这两个元素于其它元素的逆序关系。此处交换<strong> 4 , 3 </strong>会得到<strong> 3 4 2 1 </strong>,可以发现,前半部分元素与后半部分的逆序关系保持不变,前半部分内部消除了一个逆序对。</p><p>因此,我们可以考虑将数组一分为二,左右两部分分别消除内部逆序对,得到两个有序的序列,再消除序列之间的逆序对。若有两个有序序列为<strong> 2 4 6 </strong>和<strong> 1 3 5 </strong>,使用双指针分别指向两个序列开头,将序列2的小元素移到大序列的前面,比如1移到2的前面,越过了2 4 6三个元素,那么就减少了三个逆序对。多次操作,直到大序列整体有序。</p><p>很显然,上述的操作就是归并排序的一种表现。将数组不断地一分为二,当一组只有两个元素的时候,对这一组一分为二成两个序列,每个序列一个元素,使用双指针归并后,表现为逆序的两个元素交换位置。同样长度为2的毗邻序列各自有序,同样可以使用双指针进行逆序对的消除。</p><p>因此,求解逆序对的数量,我们只需要在归并排序中,保存序列2元素越过的序列1元素个数即可。</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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/17.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//逆序对的数量</span></span><br><span class="line"><span class="comment">//https://www.acwing.com/problem/content/790/</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="type">long</span> t[N], tmp[N];</span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="type">long</span> counts = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">calculate_reverse_pair</span><span class="params">(<span class="type">int</span> l, <span class="type">int</span> r)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(l >= r) <span class="keyword">return</span>;</span><br><span class="line"> <span class="type">int</span> mid = l + r >> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="built_in">calculate_reverse_pair</span>(l, mid), <span class="built_in">calculate_reverse_pair</span>(mid + <span class="number">1</span>, r);</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> k = <span class="number">0</span>, i = l, j = mid + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(i <= mid && j <= r){</span><br><span class="line"> <span class="keyword">if</span>(t[i] <= t[j]) {</span><br><span class="line"> tmp[k++] = t[i++];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> tmp[k++] = t[j++];</span><br><span class="line"> <span class="comment">//将后半部分的小元素移到前半部分时,越过的前半部分元素个数即为逆序对个数</span></span><br><span class="line"> counts += (mid - i + <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span>(i <= mid) tmp[k++] = t[i++];</span><br><span class="line"> <span class="keyword">while</span>(j <= r) tmp[k++] = t[j++];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = l, j = <span class="number">0</span>; i <= r; i++, j++)</span><br><span class="line"> t[i] = tmp[j];</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) <span class="built_in">scanf</span>(<span class="string">"%lld"</span>, &t[i]);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">calculate_reverse_pair</span>(<span class="number">0</span>, n - <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld"</span>, counts);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="二分"><a class="markdownIt-Anchor" href="#二分"></a> 二分</h3><p>二分就是寻找一个边界,将整个数组一分为二,一边满足性质,另一边不满足。</p><h4 id="整数二分"><a class="markdownIt-Anchor" href="#整数二分"></a> 整数二分</h4><p><a href="https://www.acwing.com/problem/content/791/">AcWing—数的范围</a></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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/16.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"><span class="type">int</span> t[N];</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n, q;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &q);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &t[i]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(q--){</span><br><span class="line"> <span class="type">int</span> x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &x);</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> l = <span class="number">0</span>, r = n - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(l < r){</span><br><span class="line"> <span class="type">int</span> mid = l + r >> <span class="number">1</span>;</span><br><span class="line"> <span class="comment">//查找x1位置时,x1以及其后元素都满足>=x这个性质</span></span><br><span class="line"> <span class="comment">//当mid对应元素满足性质时,x1应在mid或者mid前,更新右区间为mid</span></span><br><span class="line"> <span class="keyword">if</span>(t[mid] >= x) r = mid;</span><br><span class="line"> <span class="comment">//当mid对应元素不满足性质时,x1应在mid后,更新左区间为mid + 1.</span></span><br><span class="line"> <span class="keyword">else</span> l = mid + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(t[l] != x) <span class="built_in">printf</span>(<span class="string">"-1 -1\n"</span>);</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, l);</span><br><span class="line"> <span class="type">int</span> l = <span class="number">0</span>, r = n - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(l < r){</span><br><span class="line"> <span class="comment">//在l == mid == r - 1时,若是t[mid]满足性质,左区间会更新为mid</span></span><br><span class="line"> <span class="comment">//为防止死循环,mid应上取整</span></span><br><span class="line"> <span class="type">int</span> mid = l + r + <span class="number">1</span> >> <span class="number">1</span>;</span><br><span class="line"> <span class="comment">//查找x_last元素位置时,x_last及其前面元素满足<=x的性质</span></span><br><span class="line"> <span class="comment">//当mid对应元素满足该性质时,x_last应在mid或者mid后,更新左区间为mid</span></span><br><span class="line"> <span class="comment">//当mid对应元素不满足时,x_last应在mid前,更新右区间为mid - 1</span></span><br><span class="line"> <span class="keyword">if</span>(t[mid] <= x) l = mid;</span><br><span class="line"> <span class="keyword">else</span> r = mid - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, l);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="浮点数二分"><a class="markdownIt-Anchor" href="#浮点数二分"></a> 浮点数二分</h4><p><a href="https://www.acwing.com/problem/content/792/">AcWing—三次方根</a></p><p>在求解次方根的问题中,需要注意,当x处于(0,1)的区间内时,其n次方根的结果会大于x。比如0.01的平方根是0.1。因此在使用二分求解n次方根的时候,我们需要将右边界加1。</p><p>二分结束的条件设置为一定的精度,比如当结果保留6位小数的时候,我们可以设置精度为1e-8,保留7位则1e-9,以此类推。确保结果的准确性。</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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/16.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">double</span> x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lf"</span>, &x);</span><br><span class="line"></span><br><span class="line"> <span class="type">bool</span> aboveZero = <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">if</span>(x < <span class="number">0</span>) aboveZero = <span class="literal">false</span>, x = <span class="number">0</span> - x;</span><br><span class="line"></span><br><span class="line"> <span class="type">double</span> l = <span class="number">0</span>, r = x + <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(r - l > <span class="number">1e-8</span>){</span><br><span class="line"> <span class="type">double</span> mid = (l + r) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">if</span>(mid*mid*mid >= x) r = mid;</span><br><span class="line"> <span class="keyword">else</span> l = mid;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lf"</span>, !aboveZero?-l:l);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="高精度"><a class="markdownIt-Anchor" href="#高精度"></a> 高精度</h3><h4 id="加法"><a class="markdownIt-Anchor" href="#加法"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/18.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function">vector<<span class="type">int</span>> <span class="title">add</span><span class="params">(vector<<span class="type">int</span>> &A, vector<<span class="type">int</span>> &B)</span></span>{</span><br><span class="line"> vector<<span class="type">int</span>> C;</span><br><span class="line"> <span class="type">int</span> t = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; t != <span class="number">0</span> || i < A.<span class="built_in">size</span>() || i < B.<span class="built_in">size</span>(); i++){</span><br><span class="line"> <span class="keyword">if</span>(i < A.<span class="built_in">size</span>()) t += A[i];</span><br><span class="line"> <span class="keyword">if</span>(i < B.<span class="built_in">size</span>()) t += B[i];</span><br><span class="line"> C.<span class="built_in">push_back</span>(t % <span class="number">10</span>);</span><br><span class="line"> t = t >= <span class="number">10</span> ? <span class="number">1</span> : <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> C;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> string a, b;</span><br><span class="line"> vector<<span class="type">int</span>> A, B;</span><br><span class="line"></span><br><span class="line"> cin >> a >> b;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = a.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) A.<span class="built_in">push_back</span>(a[i] - <span class="string">'0'</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = b.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) B.<span class="built_in">push_back</span>(b[i] - <span class="string">'0'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">auto</span> C = <span class="built_in">add</span>(A, B);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(C.<span class="built_in">size</span>() != <span class="number">0</span>){</span><br><span class="line"> cout << C.<span class="built_in">back</span>();</span><br><span class="line"> C.<span class="built_in">pop_back</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="减法正减正"><a class="markdownIt-Anchor" href="#减法正减正"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/18.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">//比较两个数的大小</span></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(vector<<span class="type">int</span>> &A, vector<<span class="type">int</span>> &B)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(A.<span class="built_in">size</span>() != B.<span class="built_in">size</span>()) <span class="keyword">return</span> A.<span class="built_in">size</span>() >= B.<span class="built_in">size</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = A.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--){</span><br><span class="line"> <span class="keyword">if</span>(A[i] > B[i]) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">if</span>(A[i] < B[i]) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">vector<<span class="type">int</span>> <span class="title">sub</span><span class="params">(vector<<span class="type">int</span>> &A, vector<<span class="type">int</span>> &B)</span></span>{</span><br><span class="line"> vector<<span class="type">int</span>> C;</span><br><span class="line"> <span class="type">int</span> t = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; t != <span class="number">0</span> || i < A.<span class="built_in">size</span>() || i < B.<span class="built_in">size</span>(); i++){</span><br><span class="line"> <span class="comment">//A位减去被借的位</span></span><br><span class="line"> <span class="keyword">if</span>(i < A.<span class="built_in">size</span>()) t = A[i] - t;</span><br><span class="line"> <span class="comment">//再减B位</span></span><br><span class="line"> <span class="keyword">if</span>(i < B.<span class="built_in">size</span>()) t -= B[i];</span><br><span class="line"> <span class="comment">//若位运算结果为负数,代表需要借位。+10取余为借位后的结果。若不需借位也无妨,+10取余为0。</span></span><br><span class="line"> C.<span class="built_in">push_back</span>((t + <span class="number">10</span>) % <span class="number">10</span>);</span><br><span class="line"> <span class="comment">//保存借位</span></span><br><span class="line"> t = t < <span class="number">0</span> ? <span class="number">1</span> : <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//去除最高位前面的0.比如运算结果为003,则去掉00,保留结果为3.</span></span><br><span class="line"> <span class="keyword">while</span>(C.<span class="built_in">size</span>() > <span class="number">1</span> && C.<span class="built_in">back</span>() == <span class="number">0</span>)</span><br><span class="line"> C.<span class="built_in">pop_back</span>();</span><br><span class="line"> <span class="keyword">return</span> C;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> string a, b;</span><br><span class="line"> vector<<span class="type">int</span>> A, B;</span><br><span class="line"></span><br><span class="line"> cin >> a >> b;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = a.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) A.<span class="built_in">push_back</span>(a[i] - <span class="string">'0'</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = b.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) B.<span class="built_in">push_back</span>(b[i] - <span class="string">'0'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将小数-大数转换成-(大数-小数)</span></span><br><span class="line"> <span class="type">bool</span> a_greater = <span class="built_in">cmp</span>(A, B);</span><br><span class="line"> <span class="keyword">auto</span> C = a_greater ? <span class="built_in">sub</span>(A, B) : <span class="built_in">sub</span>(B, A);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果是小数-大数,则在结果前面添加负号</span></span><br><span class="line"> <span class="keyword">if</span>(!a_greater) <span class="built_in">printf</span>(<span class="string">"-"</span>);</span><br><span class="line"> <span class="keyword">while</span>(C.<span class="built_in">size</span>() != <span class="number">0</span>){</span><br><span class="line"> cout << C.<span class="built_in">back</span>();</span><br><span class="line"> C.<span class="built_in">pop_back</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="乘法"><a class="markdownIt-Anchor" href="#乘法"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/22.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">//乘法的实质就是123 * 4 = 100 * 4 + 20 * 4 + 3 * 4.结果的个位诞生于最低位乘以4,十位诞生于十位乘以4加上个位进的位</span></span><br><span class="line"><span class="comment">//以此类推。</span></span><br><span class="line"><span class="function">vector<<span class="type">int</span>> <span class="title">mul</span><span class="params">(vector<<span class="type">int</span>> &A, <span class="type">int</span> b)</span></span>{</span><br><span class="line"> vector<<span class="type">int</span>> C;</span><br><span class="line"> <span class="type">int</span> t = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">//大数每一位乘以小数,并加上低位进的位,得到的结果最后一位,为当前位的数,结果的其余位都是进位。</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < A.<span class="built_in">size</span>(); i++){</span><br><span class="line"> t += A[i] * b;</span><br><span class="line"> C.<span class="built_in">push_back</span>(t % <span class="number">10</span>);</span><br><span class="line"> t /= <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(t) C.<span class="built_in">push_back</span>(t);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(C.<span class="built_in">size</span>() > <span class="number">1</span> && C.<span class="built_in">back</span>() == <span class="number">0</span>) C.<span class="built_in">pop_back</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> C;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> string a;</span><br><span class="line"> <span class="type">int</span> b;</span><br><span class="line"> cin >> a >> b;</span><br><span class="line"></span><br><span class="line"> vector<<span class="type">int</span>> A;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = a.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) A.<span class="built_in">push_back</span>(a[i] - <span class="string">'0'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">auto</span> C = <span class="built_in">mul</span>(A, b);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = C.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) <span class="built_in">printf</span>(<span class="string">"%d"</span>, C[i]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="除法"><a class="markdownIt-Anchor" href="#除法"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/22.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><algorithm></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function">vector<<span class="type">int</span>> <span class="title">div</span><span class="params">(vector<<span class="type">int</span>> A, <span class="type">int</span> b)</span></span>{</span><br><span class="line"> vector<<span class="type">int</span>> C;</span><br><span class="line"> <span class="type">int</span> t = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//从大数高位开始除</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = A.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--){</span><br><span class="line"> t = t * <span class="number">10</span> + A[i];</span><br><span class="line"> <span class="comment">//能除就除</span></span><br><span class="line"> <span class="keyword">if</span>(t >= b) C.<span class="built_in">push_back</span>(t / b), t = t % b;</span><br><span class="line"> <span class="comment">//不能除,商就置零</span></span><br><span class="line"> <span class="keyword">else</span> C.<span class="built_in">push_back</span>(<span class="number">0</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//翻转数组,并去除高位0。</span></span><br><span class="line"> <span class="built_in">reverse</span>(C.<span class="built_in">begin</span>(), C.<span class="built_in">end</span>());</span><br><span class="line"> <span class="keyword">while</span>(C.<span class="built_in">size</span>() > <span class="number">1</span> && C.<span class="built_in">back</span>() == <span class="number">0</span>) C.<span class="built_in">pop_back</span>();</span><br><span class="line"> <span class="comment">//翻转回来,把最终的余数补在数组最后面</span></span><br><span class="line"> <span class="built_in">reverse</span>(C.<span class="built_in">begin</span>(), C.<span class="built_in">end</span>());</span><br><span class="line"> C.<span class="built_in">push_back</span>(t);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> C;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> string a;</span><br><span class="line"> <span class="type">int</span> b;</span><br><span class="line"> vector<<span class="type">int</span>> A;</span><br><span class="line"></span><br><span class="line"> cin >> a >> b;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = a.<span class="built_in">size</span>() - <span class="number">1</span>; i >= <span class="number">0</span>; i--) A.<span class="built_in">push_back</span>(a[i] - <span class="string">'0'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">auto</span> C = <span class="built_in">div</span>(A, b);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < C.<span class="built_in">size</span>() - <span class="number">1</span>; i++) <span class="built_in">printf</span>(<span class="string">"%d"</span>, C[i]);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n%d"</span>, C.<span class="built_in">back</span>());</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="前缀与差分"><a class="markdownIt-Anchor" href="#前缀与差分"></a> 前缀与差分</h3><h4 id="前缀和一维"><a class="markdownIt-Anchor" href="#前缀和一维"></a> 前缀和(一维)</h4><p>对于一个普通的一维数组(从 a1 = a[1] 开始,a[0] = 0),前n项和称为前缀和。通过Sn - S(k-1)可以得到S[k,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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/23.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"><span class="type">int</span> a[N], s[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n, m;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &m);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &a[i]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) s[i] = s[i - <span class="number">1</span>] + a[i];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(m--){</span><br><span class="line"> <span class="type">int</span> l, r;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &l, &r);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, s[r] - s[l - <span class="number">1</span>]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="子矩阵的和"><a class="markdownIt-Anchor" href="#子矩阵的和"></a> 子矩阵的和</h4><p><a href="https://www.acwing.com/problem/content/798/">796. 子矩阵的和 - AcWing题库</a></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/23.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1010</span>;</span><br><span class="line"><span class="type">int</span> a[N][N], s[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">//n行m列,q个询问</span></span><br><span class="line"> <span class="type">int</span> n, m, q;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &n, &m, &q);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <=m; j++)</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &a[i][j]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++)</span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> * a11 a12 | a13</span></span><br><span class="line"><span class="comment"> * a21 a22 | a23</span></span><br><span class="line"><span class="comment"> * --------|----</span></span><br><span class="line"><span class="comment"> * a31 a32 | a33</span></span><br><span class="line"><span class="comment"> * 比如s[3][3] = s[3][2] + s[2][3] - s[2][2](这是去除重复加的部分)+ a[3][3]</span></span><br><span class="line"><span class="comment"> * */</span></span><br><span class="line"> s[i][j] = s[i][j - <span class="number">1</span>] + s[i - <span class="number">1</span>][j] - s[i - <span class="number">1</span>][j - <span class="number">1</span>] + a[i][j];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(q--){</span><br><span class="line"> <span class="type">int</span> x1, y1, x2, y2;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d%d"</span>, &x1, &y1, &x2, &y2);</span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> * a11 a12 a13 | a14 a15</span></span><br><span class="line"><span class="comment"> * a21 a22 a23 | a24 a25</span></span><br><span class="line"><span class="comment"> * ------------|--------</span></span><br><span class="line"><span class="comment"> * a31 a32 a33 | a34 a35</span></span><br><span class="line"><span class="comment"> * a41 a42 a43 | a44 a45</span></span><br><span class="line"><span class="comment"> * s[[3][4], [4][5]] = s[4][5] - s[4][3] - s[2][5] + s[2][3](补回多减的重叠部分)</span></span><br><span class="line"><span class="comment"> * 实际上,这里的s[[3][4], [4][5]]整体类似于上一个注释位置中的a[3][3],都是被夹的一部分,只是包含数据个数不同的区别。</span></span><br><span class="line"><span class="comment"> * */</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, s[x2][y2] - s[x2][y1 - <span class="number">1</span>] - s[x1 - <span class="number">1</span>][y2] + s[x1 - <span class="number">1</span>][y1 - <span class="number">1</span>]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="差分"><a class="markdownIt-Anchor" href="#差分"></a> 差分</h3><h4 id="一维差分"><a class="markdownIt-Anchor" href="#一维差分"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/25.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"><span class="comment">//a数组为前缀和数组,b为差分数组</span></span><br><span class="line"><span class="type">int</span> a[N], b[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">insert</span><span class="params">(<span class="type">int</span> l, <span class="type">int</span> r, <span class="type">int</span> c)</span></span>{</span><br><span class="line"> <span class="comment">//对于前缀和数组a而言,要使[l, r]的前缀和+c</span></span><br><span class="line"> <span class="comment">//只需使差分数组b的第l位元素+c,这会让l及其以后的前缀和+c</span></span><br><span class="line"> <span class="comment">//然后第r+1位元素-c,这会让r+1及其以后的前缀和-c,即[r + 1, ?]的前缀和保持不变。</span></span><br><span class="line"> b[l] += c;</span><br><span class="line"> b[r + <span class="number">1</span>] -= c;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n, m;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &m);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//初始时,将a和b都看作全为零的的数组,前缀和和差分都为0。</span></span><br><span class="line"> <span class="comment">//然后输入数组a。</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &a[i]);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将输入的数组a看作待添加的元素c,即区间[i,i]上的元素都加上常数c(a[i])。</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) <span class="built_in">insert</span>(i, i, a[i]);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//同样的执行m次insert即可。</span></span><br><span class="line"> <span class="keyword">while</span>(m--){</span><br><span class="line"> <span class="type">int</span> l, r, c;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &l, &r, &c);</span><br><span class="line"> <span class="built_in">insert</span>(l, r, c);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//计算前缀和。</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) b[i] += b[i - <span class="number">1</span>];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) <span class="built_in">printf</span>(<span class="string">"%d "</span>, b[i]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="二维差分"><a class="markdownIt-Anchor" href="#二维差分"></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2024/1/27.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1010</span>;</span><br><span class="line"><span class="type">int</span> a[N][N], b[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">insert</span><span class="params">(<span class="type">int</span> x1, <span class="type">int</span> y1, <span class="type">int</span> x2, <span class="type">int</span> y2, <span class="type">int</span> c)</span></span>{</span><br><span class="line"> b[x1][y1] += c;</span><br><span class="line"> b[x2 + <span class="number">1</span>][y1] -= c;</span><br><span class="line"> b[x1][y2 + <span class="number">1</span>] -= c;</span><br><span class="line"> b[x2 + <span class="number">1</span>][y2 + <span class="number">1</span>] += c;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">int</span> n, m, q;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &n, &m, &q);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++)</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &a[i][j]);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//初始化差分数组</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++)</span><br><span class="line"> <span class="built_in">insert</span>(i, j, i, j, a[i][j]);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//更新差分数组</span></span><br><span class="line"> <span class="keyword">while</span>(q--){</span><br><span class="line"> <span class="type">int</span> x1, y1, x2, y2, c;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d%d%d"</span>, &x1, &y1, &x2, &y2, &c);</span><br><span class="line"> <span class="built_in">insert</span>(x1, y1, x2, y2, c);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//更新前缀和数组</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++)</span><br><span class="line"> a[i][j] = a[i][j - <span class="number">1</span>] + a[i - <span class="number">1</span>][j] - a[i - <span class="number">1</span>][j - <span class="number">1</span>] + b[i][j];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++){</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, a[i][j]);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h3 id="快速排序"><a class="markdownIt-Anchor" href="#快速排序"></a> 快速排序</h3>
<ol>
<li>选取基准值(分界值)x,可以是数组的第一个元素,也可以是数组的最后一个元素,中间元素亦可。</li>
<li>使用双指针</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="Algorithm" scheme="https://blog.kahvia.cn/tags/Algorithm/"/>
</entry>
<entry>
<title>数据结构——基础问题</title>
<link href="https://blog.kahvia.cn/2023/11/02/AlgorithmForGraduateTest.html"/>
<id>https://blog.kahvia.cn/2023/11/02/AlgorithmForGraduateTest.html</id>
<published>2023-11-02T14:44:06.902Z</published>
<updated>2023-11-05T14:30:49.237Z</updated>
<content type="html"><![CDATA[<h2 id="六-哈夫曼树"><a class="markdownIt-Anchor" href="#六-哈夫曼树"></a> 六、哈夫曼树</h2><h3 id="1合并果子"><a class="markdownIt-Anchor" href="#1合并果子"></a> 1.合并果子</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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2023/10/31.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//https://www.acwing.com/problem/content/150/</span></span><br><span class="line"><span class="comment">//使用哈夫曼树的知识合并果子堆,计算最小花费体力</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">//定义一个优先队列,第一个参数是队列元素的类型,第二个是使用的容器类型,第三个是排序方式。</span></span><br><span class="line"> <span class="comment">//此处使用升序排序,即小的元素优先出队。</span></span><br><span class="line"> priority_queue<<span class="type">int</span>, vector<<span class="type">int</span>>, greater<<span class="type">int</span>>> stones_heap;</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> n;</span><br><span class="line"> cin>>n;</span><br><span class="line"> <span class="keyword">while</span> (n--){</span><br><span class="line"> <span class="type">int</span> stones;</span><br><span class="line"> cin>>stones;</span><br><span class="line"> stones_heap.<span class="built_in">push</span>(stones);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> strength_used = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (stones_heap.<span class="built_in">size</span>() > <span class="number">1</span>){</span><br><span class="line"> <span class="comment">//取出最小的两个结点(果子堆)</span></span><br><span class="line"> <span class="type">int</span> min1 = stones_heap.<span class="built_in">top</span>();</span><br><span class="line"> stones_heap.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="type">int</span> min2 = stones_heap.<span class="built_in">top</span>();</span><br><span class="line"> stones_heap.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="comment">//将这两个果子堆合并</span></span><br><span class="line"> stones_heap.<span class="built_in">push</span>(min1 + min2);</span><br><span class="line"> <span class="comment">//累计合并果子堆花费的体力</span></span><br><span class="line"> strength_used += (min1 + min2);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> cout<<strength_used;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="2荷马史诗"><a class="markdownIt-Anchor" href="#2荷马史诗"></a> 2.荷马史诗</h3><p>K叉哈夫曼树的问题类似于二叉哈夫曼树。需要注意的点是,在K叉哈夫曼树中,我们每次合并结点都会取出最小的K个结点,在我们进行最后一次合并的时候,可能存在的结点个数不足K个。</p><p>如1,2,3,4,5,6 ——> 6(1,2,3),4,5,6 ——> 6(1,2,3),15(4,5,6).</p><p>这时候我们需要补充零结点进去充数。 6(1,2,3),15(4,5,6),0 ——> 21(6,15).然后我们会发现,将二层的0和底部的6交换,会让K叉树的结果变好。所以,我们应在开始合并前就补充零结点,使得刚好其元素个数刚好能构建K叉哈夫曼树。</p><p>这时候我们可以分析什么时候该补充零结点。我们每次合并结点都会将K个结点合并成一个结点,减少了K-1个结点。刚开始N个元素,全部合并后仅剩1个元素,减少了N-1个结点。每次合并减少K-1个,共需减少N-1个,合并次数为(N-1)/ (K-1)。即不能整除的时候,说明需要补充零结点。</p><p>由于荷马史诗的编码要求编码树的高度最小,所以在合并结点的时候,除了选择最小的K个结点,还要在节点值相同的时候,优先选择结点展开的子树高度(深度)最小的结点。</p><p>比如,1,3,4,3 ——> 4(1,3),4,3 。根据值最小原则,可以选第一个4,也可以选第二个4,与3合并。很显然,前者合并到最后的高度为3,后者为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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2023/11/1.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//https://www.acwing.com/problem/content/151/</span></span><br><span class="line"><span class="comment">//荷马史诗</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"iostream"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"algorithm"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"queue"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"vector"</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">//define a pair of data. long long for word_code and int for Huffman coding node depth.</span></span><br><span class="line"><span class="keyword">typedef</span> pair<<span class="type">long</span> <span class="type">long</span>, <span class="type">int</span>> PLI;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> priority_queue<PLI, vector<PLI>, greater<>> words;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//k is the system of numeration</span></span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> words_num, k;</span><br><span class="line"> cin>>words_num>>k;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (words_num--){</span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> word;</span><br><span class="line"> cin>>word;</span><br><span class="line"> words.<span class="built_in">push</span>({word, <span class="number">0</span>});</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//every loop for merge will delete k nodes and add a combined node,</span></span><br><span class="line"> <span class="comment">//so k-1 nodes decrease in each merge.</span></span><br><span class="line"> <span class="comment">//the loop will continues until there is only one node.</span></span><br><span class="line"> <span class="comment">//loop time = (words_num - 1) / (k-1).</span></span><br><span class="line"> <span class="comment">//if the time is not a integer, just add zero node until it can be a integer.</span></span><br><span class="line"> <span class="keyword">while</span> ((words.<span class="built_in">size</span>() - <span class="number">1</span>) % (k - <span class="number">1</span>) != <span class="number">0</span>)</span><br><span class="line"> words.<span class="built_in">push</span>({<span class="number">0</span>,<span class="number">0</span>});</span><br><span class="line"></span><br><span class="line"> <span class="comment">//the with power length is the new coded book length</span></span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> wpl = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (words.<span class="built_in">size</span>() > <span class="number">1</span>){</span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> combined_node_val = <span class="number">0</span>;</span><br><span class="line"> <span class="type">int</span> max_depth = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < k; ++i) {</span><br><span class="line"> <span class="comment">//get the min node</span></span><br><span class="line"> <span class="keyword">auto</span> min_node = words.<span class="built_in">top</span>();</span><br><span class="line"> <span class="comment">//merge</span></span><br><span class="line"> combined_node_val += min_node.first;</span><br><span class="line"> <span class="comment">//save the highest son-tree's depth</span></span><br><span class="line"> max_depth = <span class="built_in">max</span>(max_depth, min_node.second);</span><br><span class="line"> <span class="comment">//delete the node</span></span><br><span class="line"> words.<span class="built_in">pop</span>();</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//add the combined node.</span></span><br><span class="line"> words.<span class="built_in">push</span>({combined_node_val,max_depth + <span class="number">1</span>});</span><br><span class="line"> <span class="comment">//the new combined node value is a part of the WPL.</span></span><br><span class="line"> wpl += combined_node_val;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> cout<<wpl<<endl<<words.<span class="built_in">top</span>().second;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="七-拓扑排序有向图问题"><a class="markdownIt-Anchor" href="#七-拓扑排序有向图问题"></a> 七、拓扑排序(有向图问题)</h2><h3 id="1基于广搜广度优先遍历的拓扑排序实现方法"><a class="markdownIt-Anchor" href="#1基于广搜广度优先遍历的拓扑排序实现方法"></a> 1.基于广搜(广度优先遍历)的拓扑排序实现方法</h3><p>广度优先遍历(BFS),实际上就是一层一层地遍历。</p><ol><li>将第一个顶点入队</li><li>队列出队,将出队的顶点连接的顶点进行入队,我简称为出队展开。</li><li>重复步骤2直到队列为空</li></ol><ul><li>注意,需要开一个数组保存顶点是否被遍历过。顶点入队的时候,就该标记为被遍历过了,防止重复入队(比如出现回环的时候,A<—>B,A出队会B会入队,B出队A会入队,会出现死循环)。</li></ul><p>拓扑排序实现方式</p><pre><code>1. 入队的标准改为:入度为0的顶点才能入队。2. 当顶点入队的时候,将该顶点可以通往顶点的入度减1(即在图中隐藏该入队的顶点,代表该工程任务结束)3. 简单来说,就是在BFS出队展开时,只让入度为0的顶点入队(即只有前置任务全部完成,才能将新的任务加入执行清单)。</code></pre><ul><li>需要开一个数组维护每个顶点的入度。</li><li>因为只有入度为0的才能入队,重边,或者回环,都会导致度不为0无法入队,所以不需要BFS那个判断是否被遍历过的数组。</li></ul><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><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Created by Kahiva on 2023/11/5.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//https://www.acwing.com/problem/content/850/</span></span><br><span class="line"><span class="comment">//拓扑排序(采用广度遍历实现)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"iostream"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"algorithm"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"queue"</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">//n个顶点m条边</span></span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line"><span class="comment">//定义一个常量N,即最大可能用到的顶点数。定义入度数组和模拟队列的数组时可以用到。</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100010</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span> {</span><br><span class="line"> <span class="type">int</span> nodeId;</span><br><span class="line"> Node* next;</span><br><span class="line"> <span class="built_in">Node</span>(<span class="type">int</span> id):<span class="built_in">nodeId</span>(id), <span class="built_in">next</span>(<span class="literal">NULL</span>){};</span><br><span class="line">}*link[N];</span><br><span class="line"></span><br><span class="line"><span class="comment">//保存各顶点的入度</span></span><br><span class="line"><span class="type">int</span> inDegree[N];</span><br><span class="line"><span class="comment">//采用数组模拟队列,出队移动头索引,入队移动尾索引。这样可以在模拟队列的同时,保留原队列中的元素。</span></span><br><span class="line"><span class="type">int</span> checkQueue[N];</span><br><span class="line"></span><br><span class="line"><span class="comment">//将某个点和另一个点的边加入邻接表表示的图中。</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">addLink</span><span class="params">(<span class="type">int</span> fromNodeId, <span class="type">int</span> toNodeId)</span></span>{</span><br><span class="line"> Node* node = <span class="keyword">new</span> <span class="built_in">Node</span>(toNodeId);</span><br><span class="line"> node->next = link[fromNodeId];</span><br><span class="line"> link[fromNodeId] = node;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">topSort</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">//head指向队头,rear指向队列最后一个元素</span></span><br><span class="line"> <span class="type">int</span> head = <span class="number">0</span>, rear = <span class="number">-1</span>;</span><br><span class="line"> <span class="comment">//因为顶点编号从1开始,所以入度数组从索引1开始遍历</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; ++i) {</span><br><span class="line"> <span class="comment">//遍历顶点,如果顶点入度为0,就入队</span></span><br><span class="line"> <span class="keyword">if</span> (!inDegree[i]){</span><br><span class="line"> checkQueue[++rear] = i;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (head <= rear){</span><br><span class="line"> <span class="comment">//取出队头元素</span></span><br><span class="line"> <span class="keyword">auto</span> top = checkQueue[head++];</span><br><span class="line"> <span class="comment">//遍历它的邻边,将邻边那头对应点的入度减一</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> p = link[top]; p ; p = p->next){</span><br><span class="line"> inDegree[p->nodeId]--;</span><br><span class="line"> <span class="comment">//如果没有了前置结点,代表可以入队(即被遍历,或者说该工程任务可以执行了)</span></span><br><span class="line"> <span class="keyword">if</span> (inDegree[p->nodeId] == <span class="number">0</span>){</span><br><span class="line"> checkQueue[++rear] = p->nodeId;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果队列中的元素个数刚好等于顶点个数,就代表拓扑排序成立,即不存在闭环。</span></span><br><span class="line"> <span class="comment">//因为如果有闭环,闭环上结点的入度始终不为0,无法入队。</span></span><br><span class="line"> <span class="keyword">return</span> n == rear + <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> cin>>n>>m;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (m--){</span><br><span class="line"> <span class="type">int</span> from, to;</span><br><span class="line"> cin>>from>>to;</span><br><span class="line"> <span class="built_in">addLink</span>(from, to);</span><br><span class="line"> inDegree[to]++;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果拓扑排序无效,则输出-1</span></span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">topSort</span>())</span><br><span class="line"> cout<<<span class="string">"-1"</span>;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; ++i)</span><br><span class="line"> cout<<checkQueue[i]<<<span class="string">' '</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h2 id="六-哈夫曼树"><a class="markdownIt-Anchor" href="#六-哈夫曼树"></a> 六、哈夫曼树</h2>
<h3 id="1合并果子"><a class="markdownIt-Anchor" href="#1合并果子"></a> </summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="Algorithm" scheme="https://blog.kahvia.cn/tags/Algorithm/"/>
</entry>
<entry>
<title>Clion中Cmake的设置问题</title>
<link href="https://blog.kahvia.cn/2023/10/15/Clion-cmake.html"/>
<id>https://blog.kahvia.cn/2023/10/15/Clion-cmake.html</id>
<published>2023-10-15T08:58:30.017Z</published>
<updated>2023-10-15T09:14:10.042Z</updated>
<content type="html"><![CDATA[<h3 id="1设置可执行程序输出目录"><a class="markdownIt-Anchor" href="#1设置可执行程序输出目录"></a> 1.设置可执行程序输出目录</h3><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">set</span>(CMAKE_RUNTIME_OUTPUT_DIRECTORY <span class="string">"${CMAKE_CURRENT_SOURCE_DIR}/bin"</span>)</span><br></pre></td></tr></table></figure><h3 id="2将cpp文件添加为生成可执行文件的源文件"><a class="markdownIt-Anchor" href="#2将cpp文件添加为生成可执行文件的源文件"></a> 2.将cpp文件添加为“生成可执行文件”的源文件</h3><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">add_executable</span>(AcWing3375 Acwing/graduate/AcWing3375.cpp)</span><br></pre></td></tr></table></figure><h3 id="完整的cmake设置"><a class="markdownIt-Anchor" href="#完整的cmake设置"></a> 完整的cmake设置</h3><figure class="highlight cmake"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.24</span>)</span><br><span class="line"><span class="comment">#指定cmake工程名</span></span><br><span class="line"><span class="keyword">project</span>(algorithm)</span><br><span class="line"></span><br><span class="line"><span class="comment">#c++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">14</span>)</span><br><span class="line"><span class="comment"># 指定可执行程序输出目录</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_RUNTIME_OUTPUT_DIRECTORY <span class="string">"${CMAKE_CURRENT_SOURCE_DIR}/bin"</span>)</span><br><span class="line"><span class="keyword">add_executable</span>(AcWing3375 Acwing/graduate/AcWing3375.cpp)</span><br></pre></td></tr></table></figure><h3 id="附普通的gitignore文件"><a class="markdownIt-Anchor" href="#附普通的gitignore文件"></a> 附:普通的gitignore文件</h3><figure class="highlight plaintext"><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><span class="line">/.idea/</span><br><span class="line">/cmake-build-debug/</span><br><span class="line">/bin/</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h3 id="1设置可执行程序输出目录"><a class="markdownIt-Anchor" href="#1设置可执行程序输出目录"></a> 1.设置可执行程序输出目录</h3>
<figure class="highlight cmake"><table><tr><</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="clion cmake" scheme="https://blog.kahvia.cn/tags/clion-cmake/"/>
</entry>
<entry>
<title>Vue3使用Echarts</title>
<link href="https://blog.kahvia.cn/2023/07/19/vue3-echarts.html"/>
<id>https://blog.kahvia.cn/2023/07/19/vue3-echarts.html</id>
<published>2023-07-19T01:30:49.148Z</published>
<updated>2023-07-19T11:13:09.375Z</updated>
<content type="html"><![CDATA[<h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3><p>响应式布局,是为五个不同的屏幕尺寸制定不同的显示比例。这是网页收缩导致网页布局变乱的究极解决方案。</p>]]></content>
<summary type="html"><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3>
<p>响应式布局,是为五个不同的屏幕尺寸制定不同的显示比例。这是网页收缩导致网页布局变乱的究极解决方案。</p>
</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="echarts vue3" scheme="https://blog.kahvia.cn/tags/echarts-vue3/"/>
</entry>
<entry>
<title>响应式布局</title>
<link href="https://blog.kahvia.cn/2023/07/04/ResponsiveDesign.html"/>
<id>https://blog.kahvia.cn/2023/07/04/ResponsiveDesign.html</id>
<published>2023-07-04T11:58:41.653Z</published>
<updated>2023-07-04T13:58:56.460Z</updated>
<content type="html"><![CDATA[<h3 id="响应式布局"><a class="markdownIt-Anchor" href="#响应式布局"></a> 响应式布局</h3><p>响应式布局,是为五个不同的屏幕尺寸制定不同的显示比例。这是网页收缩导致网页布局变乱的究极解决方案。</p>]]></content>
<summary type="html"><h3 id="响应式布局"><a class="markdownIt-Anchor" href="#响应式布局"></a> 响应式布局</h3>
<p>响应式布局,是为五个不同的屏幕尺寸制定不同的显示比例。这是网页收缩导致网页布局变乱的究极解决方案。</p>
</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="html element" scheme="https://blog.kahvia.cn/tags/html-element/"/>
</entry>
<entry>
<title>Nodejs-包</title>
<link href="https://blog.kahvia.cn/2023/06/28/NodeJsPackage.html"/>
<id>https://blog.kahvia.cn/2023/06/28/NodeJsPackage.html</id>
<published>2023-06-28T06:31:43.686Z</published>
<updated>2023-06-29T07:59:06.907Z</updated>
<content type="html"><![CDATA[<h3 id="包的类型"><a class="markdownIt-Anchor" href="#包的类型"></a> 包的类型</h3><ul><li>项目包:用于编写项目和和业务逻辑</li><li>软件包:封装工具和方法进行使用<ul><li>本地软件包:当前项目内使用,封装<strong>属性和方法</strong>,存在于 node_modules中。</li><li>全局软件包:本机所有项目使用,封装<strong>命令和工具</strong>,存在于系统设置的位置。</li></ul></li></ul><h3 id="软件包的结构"><a class="markdownIt-Anchor" href="#软件包的结构"></a> 软件包的结构</h3><p>如下图所示。整个util包由三部分组成,libs、index.js、package.json。</p><ul><li>libs中,存放工具包的源代码 js 文件。</li><li>index.js文件作为入口文件,通过这个文件统一暴露对外工具方法等。</li><li>package.json文件,描述包的一些信息。</li></ul><p><img src="https://pics.kahvia.cn/img/image-20230628145428487.png" alt="包的结构图" /></p><h3 id="libs示例"><a class="markdownIt-Anchor" href="#libs示例"></a> libs示例</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//printHello.js</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">printHello</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"Hello,Adong. It's your first tools package."</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> words = <span class="string">"How old are you?"</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = {</span><br><span class="line"> printHello,</span><br><span class="line"> words</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="indexjs示例"><a class="markdownIt-Anchor" href="#indexjs示例"></a> index.js示例</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//下面这用法叫做解析重构</span></span><br><span class="line"><span class="keyword">let</span> { printHello, words } = <span class="built_in">require</span>(<span class="string">"./libs/printHello"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> resHeaderUtil = <span class="built_in">require</span>(<span class="string">"./libs/resHeaderUtil-commonjs"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//对libs中的工具,统一作模块暴露</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = {</span><br><span class="line"> printHello,</span><br><span class="line"> words,</span><br><span class="line"> resHeaderUtil</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="packagejson示例"><a class="markdownIt-Anchor" href="#packagejson示例"></a> package.json示例</h3><figure class="highlight json"><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><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"name"</span><span class="punctuation">:</span> <span class="string">"kahvia_tools"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"author"</span><span class="punctuation">:</span> <span class="string">"Kahvia"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"description"</span><span class="punctuation">:</span> <span class="string">"包含了设置http请求的响应头的工具和输出你好的工具函数"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"main"</span><span class="punctuation">:</span> <span class="string">"index.js"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"version"</span><span class="punctuation">:</span> <span class="string">"1.0.0"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"license"</span><span class="punctuation">:</span> <span class="string">"MIT"</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>其中,main表示工具包的入口文件,version代表版本,license表示许可证。</p><h3 id="软件包的使用"><a class="markdownIt-Anchor" href="#软件包的使用"></a> 软件包的使用</h3><p>在使用软件包时,路径只需要到软件包的根目录即可。无需指定更详细的路径。它会自动寻找index.js,若无则查找package.json中的main入口。</p><figure class="highlight javascript"><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><span class="line"><span class="keyword">let</span> kahvia_utils = <span class="built_in">require</span>(<span class="string">"./util"</span>)</span><br><span class="line"></span><br><span class="line">kahvia_utils.<span class="title function_">printHello</span>()</span><br></pre></td></tr></table></figure><p>结果如下所示。</p><p><img src="https://pics.kahvia.cn/img/image-20230628150604791.png" alt="工具包使用结果" /></p><h3 id="npm"><a class="markdownIt-Anchor" href="#npm"></a> NPM</h3><p>npm是nodejs的包管理器。</p><p>若项目中没有package.json,可以通过以下命令执行初始化。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm init -y</span><br></pre></td></tr></table></figure><p>若我们需要安装某个软件包,则通过以下命令执行安装,软件包会存放在node_modules目录下,软件包的版本则会保存在package-lock.json文件中,用作固化版本。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i package-name</span><br></pre></td></tr></table></figure><p>我们使用下载的软件包时,可以<strong>直接通过包名引入</strong>,而不用通过路径。</p><p>当我们协同开发时,git不会同步我们的node_modules文件夹。可能别人使用了某个包,但是我们自己没有使用,所以本地没有这个包。我们可以通过以下命令,根据package.json文件,安装本地缺少的包。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i</span><br></pre></td></tr></table></figure><h3 id="常用的软件包"><a class="markdownIt-Anchor" href="#常用的软件包"></a> 常用的软件包</h3><h4 id="nodemon"><a class="markdownIt-Anchor" href="#nodemon"></a> nodemon</h4><p>一个全局软件包,需要全局安装。通过这个nodemon启动 js 文件,可以检测代码更改,自动重启程序。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i nodemon -g</span><br></pre></td></tr></table></figure><h4 id="webpack"><a class="markdownIt-Anchor" href="#webpack"></a> webpack</h4><p>一个常用的打包工具,安装在项目的dev环境中。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i webpack webpack-cli --save-dev</span><br></pre></td></tr></table></figure><p>在项目的package.json中添加自定义脚本命令。其中,build是自定义的名称,什么都可以,其后面的值即webpack才是真正执行的命令。</p><figure class="highlight json"><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><span class="line"><span class="attr">"scripts"</span><span class="punctuation">:</span><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"build"</span><span class="punctuation">:</span><span class="string">"webpack"</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>将要打包的文件放在根目录的src目录中,通过npm run build,实现项目打包。不过这里的打包只能实现<strong>部分</strong> js 文件的打包,至于为什么是<strong>部分</strong>,因为打包那种nodejs写的后端项目,会报很多错误,而我暂时还不太懂问题出在哪里。目前打包给前端页面引用的js文件是没有问题的。</p><p>通过配置项目根目录的webpack.config.js文件,可以配置打包的参数,比如入口、出口、插件等。其中,entry是入口,output是出口,path是输出路径,filename是打包后的文件名。</p><figure class="highlight javascript"><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><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="htmlwebpackplugin根据自动生成目标页面并连接打包压缩的js文件"><a class="markdownIt-Anchor" href="#htmlwebpackplugin根据自动生成目标页面并连接打包压缩的js文件"></a> HtmlWebpackPlugin(根据自动生成目标页面并连接打包压缩的JS文件)</h5><p>webpack通过上述方式打包的话,只能打包普通的静态js文件。也就是说,打包完成后,我们需要手动为页面引入打包后的js文件,这无疑的麻烦的。通过HtmlWebpackPlugin,我们可以将页面一起打包,自动为页面引入打包好的js文件,一起输出到目标目录。</p><blockquote><p>详细的使用可以参考<a href="https://www.webpackjs.com/plugins/html-webpack-plugin/#basic-usage">官方文档</a></p></blockquote><p>通过如下命令安装插件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev html-webpack-plugin</span><br></pre></td></tr></table></figure><p>在webpack配置文件中,配置如下。其中,template作为模板,即以此模板在目标目录生成一份以filename为文件名的html文件,同时为其引入打包好的js文件。output中的clean属性可以清除上一次打包的东西。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./public/index.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'test.html'</span></span><br><span class="line"> })</span><br><span class="line"> ]</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="css-loaderstyle-loader加载器把css打包到js文件中"><a class="markdownIt-Anchor" href="#css-loaderstyle-loader加载器把css打包到js文件中"></a> css-loader,style-loader(加载器,把css打包到js文件中)</h5><blockquote><p><a href="https://www.webpackjs.com/loaders/css-loader/">这两个加载器的官方文档</a></p></blockquote><ul><li>css-loader:解析css代码。</li><li>style-loader:把解析后的css代码插入到DOM。最后css代码在打包后的js文件中,通过函数的方式保存。</li></ul><p>按照下方命令安装加载器。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev css-loader style-loader</span><br></pre></td></tr></table></figure><p>在webpack配置文件中配置加载器。下方的module部分。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./Login/login.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'login.html'</span></span><br><span class="line"> })</span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">module</span>: {</span><br><span class="line"> <span class="attr">rules</span>: [</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/i</span>,</span><br><span class="line"> <span class="attr">use</span>: [<span class="string">"style-loader"</span>, <span class="string">"css-loader"</span>],</span><br><span class="line"> },</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>use数组中的元素顺序是有影响的。loader是从右到左应用的。在这种情况下,首先应用css-loader,然后应用style-loader。即先解析css引用,再绑定DOM元素。</p><p>配置好加载器以后,就可以把使用到的css文件引用到入口js文件中了。比如我这里的打包入口是hello.js文件,那我在文件内容开头import即可。</p><figure class="highlight js"><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><span class="line"><span class="comment">//hello.js</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'../Login/login.css'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//测试打包</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"hello, kahvia !"</span>)</span><br><span class="line"><span class="comment">//二次输出</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"what's up ?"</span>)</span><br></pre></td></tr></table></figure><p>以上都完成后,即可打包。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run build</span><br></pre></td></tr></table></figure><h5 id="mini-css-extract-plugin提取css文件"><a class="markdownIt-Anchor" href="#mini-css-extract-plugin提取css文件"></a> mini-css-extract-plugin(提取css文件)</h5><blockquote><p><a href="https://www.webpackjs.com/plugins/mini-css-extract-plugin/">MiniCssExtractPlugin | webpack 中文文档</a></p></blockquote><p>我们在上面通过style-loader,是将css打包进js文件,这会导致js文件比平常更大。所以官方更推荐的一个做法是将css提取出来,而不是打包进js文件。通过<strong>mini-css-extract-plugin</strong>这个插件,配合css-loader我们可以做到提取css文件。</p><p>值得注意的是,mini-css-extract-plugin<strong>不能</strong>和style-loader一起使用,因为既要单独提取,又要打包进js文件,这不是相互矛盾了吗?</p><p>顺带一提,单独提取的css文件,是不会被压缩的。</p><p>通过以下命令安装插件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev mini-css-extract-plugin</span><br></pre></td></tr></table></figure><p>再在webpack配置文件中引入该插件,为其配置plugin选项,并在rules-use中添加插件内置的loader。</p><figure class="highlight js"><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><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"><span class="comment">//引入css提取插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">MiniCssExtractPlugin</span> <span class="keyword">from</span> <span class="string">'mini-css-extract-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./Login/login.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'login.html'</span></span><br><span class="line"> }),</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">MiniCssExtractPlugin</span>()</span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">module</span>: {</span><br><span class="line"> <span class="attr">rules</span>: [</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/i</span>,</span><br><span class="line"> <span class="attr">use</span>: [<span class="title class_">MiniCssExtractPlugin</span>.<span class="property">loader</span>, <span class="string">"css-loader"</span>],</span><br><span class="line"> },</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="cssminimizerwebpackplugin压缩提取的css文件"><a class="markdownIt-Anchor" href="#cssminimizerwebpackplugin压缩提取的css文件"></a> CssMinimizerWebpackPlugin(压缩提取的css文件)</h5><p>通过上述的mini-css-extract-plugin插件,只能做到提取,但是会发现提取出来的css文件并没有做到压缩。而CssMinimizerWebpackPlugin就是为了压缩而使用的。</p><p>通过命令安装插件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install css-minimizer-webpack-plugin --save-dev</span><br></pre></td></tr></table></figure><p>在webpack配置文件中引入并配置。其中optimization-minimizer是配置项。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"><span class="comment">//引入css提取插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">MiniCssExtractPlugin</span> <span class="keyword">from</span> <span class="string">'mini-css-extract-plugin'</span></span><br><span class="line"><span class="comment">//引入css压缩插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">CssMinimizerPlugin</span> <span class="keyword">from</span> <span class="string">'css-minimizer-webpack-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./Login/login.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'login.html'</span></span><br><span class="line"> }),</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">MiniCssExtractPlugin</span>(),</span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">module</span>: {</span><br><span class="line"> <span class="attr">rules</span>: [</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/i</span>,</span><br><span class="line"> <span class="attr">use</span>: [<span class="title class_">MiniCssExtractPlugin</span>.<span class="property">loader</span>, <span class="string">"css-loader"</span>],</span><br><span class="line"> },</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//优化</span></span><br><span class="line"> <span class="attr">optimization</span>: {</span><br><span class="line"> <span class="comment">//minimize 减小</span></span><br><span class="line"> <span class="attr">minimizer</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">CssMinimizerPlugin</span>()</span><br><span class="line"> ]</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="打包图片"><a class="markdownIt-Anchor" href="#打包图片"></a> 打包图片</h5><p>在上述操作中,我们可以打包html,css,js了,但是图片该如何处理呢?如果项目中的图片,采用网络地址url访问,那么我们打包后自然可以正常使用。但如果采用的是本地的图片呢?我们就需要把图片也一起打包了。</p><blockquote><p><a href="https://www.webpackjs.com/guides/asset-modules/">资源模块 | webpack 中文文档</a></p></blockquote><p>在webpack5中,我们无需使用外置loader,配置如下所示,在rule中配置图片打包。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"><span class="comment">//引入css提取插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">MiniCssExtractPlugin</span> <span class="keyword">from</span> <span class="string">'mini-css-extract-plugin'</span></span><br><span class="line"><span class="comment">//引入css压缩插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">CssMinimizerPlugin</span> <span class="keyword">from</span> <span class="string">'css-minimizer-webpack-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./Login/login.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'login.html'</span></span><br><span class="line"> }),</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">MiniCssExtractPlugin</span>(),</span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">module</span>: {</span><br><span class="line"> <span class="attr">rules</span>: [</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/i</span>,</span><br><span class="line"> <span class="attr">use</span>: [<span class="title class_">MiniCssExtractPlugin</span>.<span class="property">loader</span>, <span class="string">"css-loader"</span>],</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//配置图片打包</span></span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(png|jpg|gif)$/i</span>,</span><br><span class="line"> <span class="attr">type</span>: <span class="string">'asset'</span></span><br><span class="line"> },</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//优化</span></span><br><span class="line"> <span class="attr">optimization</span>: {</span><br><span class="line"> <span class="comment">//minimize 减小</span></span><br><span class="line"> <span class="attr">minimizer</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">CssMinimizerPlugin</span>()</span><br><span class="line"> ]</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在asset类型下,大于8kb的图片会直接作拷贝处理,小于8kb的会转为base64,通过uri的方式替换项目中的src引用。</p><p>类似于css打包,我们将要打包的图片也引入入口JS文件即可。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//hello.js</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'../Login/login.css'</span></span><br><span class="line"><span class="comment">//导入需要打包的本地图片</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'../Login/ganda.jpg'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//测试打包</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"hello, kahvia !"</span>)</span><br><span class="line"><span class="comment">//二次输出</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"what's up ?"</span>)</span><br></pre></td></tr></table></figure><p>正常打包即可。</p><h5 id="搭建热更新开发环境"><a class="markdownIt-Anchor" href="#搭建热更新开发环境"></a> 搭建热更新开发环境</h5><p>下载webpack-dev-server。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i webpack-dev-server --save-dev</span><br></pre></td></tr></table></figure><p>在webpack配置文件中,设置模式(mode)为开发模式(development),并在package.json中配置自定义命令,即scripts中的选项,“dev”: “webpack serve --open”。</p><p>设置开发模式。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span></span><br><span class="line"><span class="keyword">import</span> { getRecentDir } <span class="keyword">from</span> <span class="string">'./utils/recentPath.js'</span></span><br><span class="line"><span class="comment">//引入插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HtmlWebpackPlugin</span> <span class="keyword">from</span> <span class="string">'html-webpack-plugin'</span></span><br><span class="line"><span class="comment">//引入css提取插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">MiniCssExtractPlugin</span> <span class="keyword">from</span> <span class="string">'mini-css-extract-plugin'</span></span><br><span class="line"><span class="comment">//引入css压缩插件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">CssMinimizerPlugin</span> <span class="keyword">from</span> <span class="string">'css-minimizer-webpack-plugin'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> <span class="comment">//设置热更新开发模式</span></span><br><span class="line"> <span class="attr">mode</span>: <span class="string">"development"</span>,</span><br><span class="line"> <span class="comment">//设置入口</span></span><br><span class="line"> <span class="attr">entry</span>: <span class="string">'./src/hello.js'</span>,</span><br><span class="line"> <span class="comment">//出口</span></span><br><span class="line"> <span class="attr">output</span>: {</span><br><span class="line"> <span class="attr">path</span>: path.<span class="title function_">resolve</span>(<span class="title function_">getRecentDir</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>), <span class="string">'dist'</span>),</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'testPack.js'</span>,</span><br><span class="line"> <span class="attr">clean</span>: <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//插件</span></span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">MiniCssExtractPlugin</span>({</span><br><span class="line"> <span class="comment">// filename: "login.css"</span></span><br><span class="line"> }),</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>({</span><br><span class="line"> <span class="attr">template</span>: <span class="string">'./Login/login.html'</span>,</span><br><span class="line"> <span class="attr">filename</span>: <span class="string">'login.html'</span></span><br><span class="line"> }),</span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">module</span>: {</span><br><span class="line"> <span class="attr">rules</span>: [</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/i</span>,</span><br><span class="line"> <span class="attr">use</span>: [<span class="title class_">MiniCssExtractPlugin</span>.<span class="property">loader</span>, <span class="string">"css-loader"</span>],</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//配置图片打包</span></span><br><span class="line"> {</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(png|jpg|gif)$/i</span>,</span><br><span class="line"> <span class="attr">type</span>: <span class="string">'asset'</span></span><br><span class="line"> },</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//优化</span></span><br><span class="line"> <span class="attr">optimization</span>: {</span><br><span class="line"> <span class="comment">//minimize 减小</span></span><br><span class="line"> <span class="attr">minimizer</span>: [</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">CssMinimizerPlugin</span>()</span><br><span class="line"> ]</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在package.json中,如下所示。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"module"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"devDependencies"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"css-loader"</span><span class="punctuation">:</span> <span class="string">"^6.8.1"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"css-minimizer-webpack-plugin"</span><span class="punctuation">:</span> <span class="string">"^5.0.1"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"html-webpack-plugin"</span><span class="punctuation">:</span> <span class="string">"^5.5.3"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"mini-css-extract-plugin"</span><span class="punctuation">:</span> <span class="string">"^2.7.6"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"style-loader"</span><span class="punctuation">:</span> <span class="string">"^3.3.3"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack"</span><span class="punctuation">:</span> <span class="string">"^5.88.0"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack-cli"</span><span class="punctuation">:</span> <span class="string">"^5.1.4"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack-dev-server"</span><span class="punctuation">:</span> <span class="string">"^4.15.1"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"scripts"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"build"</span><span class="punctuation">:</span> <span class="string">"webpack"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"dev"</span><span class="punctuation">:</span> <span class="string">"webpack serve --open"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>通过自定义命令启动。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run dev</span><br></pre></td></tr></table></figure><p>这种情况下,会自动创建一个8080端口的服务,服务器的根目录为项目的public目录和webpack配置文件中的出口目录。默认打开的是public目录下的index网页,而我们要查看的网页在出口目录,那么我们可以为public目录的index网页添加重定向,自动跳转到我们要查看的网页。</p><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="comment"><!-- public目录下的index.html --></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"en"</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"X-UA-Compatible"</span> <span class="attr">content</span>=<span class="string">"IE=edge"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"viewport"</span> <span class="attr">content</span>=<span class="string">"width=device-width, initial-scale=1.0"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">title</span>></span>Document<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> location.<span class="property">href</span> = <span class="string">"/login.html"</span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><h5 id="生产模式"><a class="markdownIt-Anchor" href="#生产模式"></a> 生产模式</h5><p>上面使用到了开发模式,配合webpack-dev-server可以热更新。与之相对的,还有生产模式(production),即打包模式。</p><p>我们开发模式用的更多,所以mode设置为development,那打包的时候怎么办呢?再去修改mode吗?这很显然不方便。所以我们可以通过自定义命令指定模式。命令的优先级>配置文件。</p><p>在package.json文件中,我们这样设置,在build和dev后面加上–mode=[mode]即可。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"module"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"devDependencies"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"css-loader"</span><span class="punctuation">:</span> <span class="string">"^6.8.1"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"css-minimizer-webpack-plugin"</span><span class="punctuation">:</span> <span class="string">"^5.0.1"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"html-webpack-plugin"</span><span class="punctuation">:</span> <span class="string">"^5.5.3"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"mini-css-extract-plugin"</span><span class="punctuation">:</span> <span class="string">"^2.7.6"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"style-loader"</span><span class="punctuation">:</span> <span class="string">"^3.3.3"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack"</span><span class="punctuation">:</span> <span class="string">"^5.88.0"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack-cli"</span><span class="punctuation">:</span> <span class="string">"^5.1.4"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"webpack-dev-server"</span><span class="punctuation">:</span> <span class="string">"^4.15.1"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"scripts"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"build"</span><span class="punctuation">:</span> <span class="string">"webpack --mode=production"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"dev"</span><span class="punctuation">:</span> <span class="string">"webpack serve --open --mode=development"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>这样一来,开发的时候就使用热更新开发模式,打包的时候就使用生产模式,两不误。</p>]]></content>
<summary type="html"><h3 id="包的类型"><a class="markdownIt-Anchor" href="#包的类型"></a> 包的类型</h3>
<ul>
<li>项目包:用于编写项目和和业务逻辑</li>
<li>软件包:封装工具和方法进行使用
<ul>
<li>本地软件包:当前项</summary>
<category term="知识" scheme="https://blog.kahvia.cn/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="node.js" scheme="https://blog.kahvia.cn/tags/node-js/"/>
</entry>
</feed>