-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
669 lines (323 loc) · 301 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>CSP01:密码</title>
<link href="/2024/12/08/CSP01/"/>
<url>/2024/12/08/CSP01/</url>
<content type="html"><![CDATA[<h1 id="题目背景"><a href="#题目背景" class="headerlink" title="题目背景"></a>题目背景</h1><p>西西艾弗网对用户密码有一套安全级别评定标准。</p><h2 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a>题目描述</h2><p>在西西艾弗网上,用户的密码是一个由大写字母(<code>A-Z</code>)、小写字母(<code>a-z</code>)、数字(<code>0-9</code>)和特殊字符(<code>*</code> 和 <code>#</code>)共 6464 种字符组成的字符串。</p><p>根据复杂程度不同,密码安全度被分为高、中、低三档。</p><ul><li>高:由上述 6464 种字符组成,长度大于等于 66 个字符,包含字母、数字和特殊字符,同一个字符出现不超过 22 次;</li><li>中:由上述 6464 种字符组成,长度大于等于 66 个字符,包含字母、数字和特殊字符,且未达到高安全度要求;</li><li>低:由上述 6464 种字符组成,长度大于等于 66 个字符,且未达到中安全度要求;</li></ul><p>小 P 为自己准备了 n<em>n</em> 个候选密码,试编写程序帮小 P 自动判别每个密码的安全级别。保证这 n<em>n</em> 个密码都至少满足低安全度要求,当安全度为高、中、低时分别输出 <code>2</code>、<code>1</code>、<code>0</code> 即可。</p><h2 id="输入格式"><a href="#输入格式" class="headerlink" title="输入格式"></a>输入格式</h2><p>从标准输入读入数据。</p><p>输入共 n+1<em>n</em>+1 行。</p><p>第一行包含一个正整数 n<em>n</em>,表示待判别的密码个数;</p><p>接下来 n<em>n</em> 行,每行一个字符串,表示一个安全度至少为低的候选密码。</p><h2 id="输出格式"><a href="#输出格式" class="headerlink" title="输出格式"></a>输出格式</h2><p>输出到标准输出。</p><p>输出共 n<em>n</em> 行,每行输出一个整数 <code>2</code>、<code>1</code> 或 <code>0</code>,表示对应密码的安全度。</p><h2 id="样例输入"><a href="#样例输入" class="headerlink" title="样例输入"></a>样例输入</h2><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></pre></td><td class="code"><pre><code class="hljs plain">4<br>csp#ccsp<br>csp#ccsp2024<br>Csp#ccsp2024<br>CSP#2024<br></code></pre></td></tr></table></figure><h2 id="样例输出"><a href="#样例输出" class="headerlink" title="样例输出"></a>样例输出</h2><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></pre></td><td class="code"><pre><code class="hljs plain">0<br>1<br>2<br>2<br></code></pre></td></tr></table></figure><h2 id="样例解释"><a href="#样例解释" class="headerlink" title="样例解释"></a>样例解释</h2><p>第一个密码不含数字,安全度为低;</p><p>第二个密码中小写字母 <code>c</code> 出现 33 次,安全度为中;</p><p>和第二个密码相比,第三个密码把一个小写字母 <code>c</code> 变为了大写,满足了高安全度要求;</p><p>第四个密码同样满足高安全度要求。</p><h2 id="子任务"><a href="#子任务" class="headerlink" title="子任务"></a>子任务</h2><p>全部的测试数据满足 n≤100<em>n</em>≤100,且输入的每个字符串均不超过 2020 个字符。</p><h1 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h1><p>这道题很简单,主要是对于字符的判断(数字、大小写字母、特殊字符)。</p><p>使用<strong>正则表达式</strong>:</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">judge_security</span>(<span class="hljs-params">u_pwd</span>):<br> <span class="hljs-keyword">if</span> re.search(<span class="hljs-string">r'[a-z]'</span>, u_pwd) <span class="hljs-keyword">or</span> re.search(<span class="hljs-string">r'[A-Z]'</span>, u_pwd):<br> <span class="hljs-keyword">if</span> re.search(<span class="hljs-string">r'[0-9]'</span>, u_pwd):<br> <span class="hljs-keyword">if</span> re.search(<span class="hljs-string">r'[^a-zA-Z0-9]'</span>, u_pwd):<br> char_dict = Counter(u_pwd)<br> char_show_nums = <span class="hljs-built_in">list</span>(char_dict.values())<br> <span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> char_show_nums:<br> <span class="hljs-keyword">if</span> num > <span class="hljs-number">2</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> <span class="hljs-number">2</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br><br></code></pre></td></tr></table></figure><p>更简洁:</p><p>使用<code>bool</code>和<code>not</code>和<code>any</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><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">judge_security</span>(<span class="hljs-params">u_pwd</span>): <br> <span class="hljs-comment"># 判断密码中是否包含字母、数字和特殊字符</span><br> has_letter = <span class="hljs-built_in">bool</span>(re.search(<span class="hljs-string">r'[a-zA-Z]'</span>, u_pwd))<br> has_digit = <span class="hljs-built_in">bool</span>(re.search(<span class="hljs-string">r'[0-9]'</span>, u_pwd))<br> has_special = <span class="hljs-built_in">bool</span>(re.search(<span class="hljs-string">r'[^a-zA-Z0-9]'</span>, u_pwd)) <br> <br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span>(has_letter <span class="hljs-keyword">and</span> has_digit <span class="hljs-keyword">and</span> has_special):<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> <br> char_count = Counter(u_pwd)<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">any</span>(count > <span class="hljs-number">2</span> <span class="hljs-keyword">for</span> count <span class="hljs-keyword">in</span> char_count.values()):<br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">2</span><br></code></pre></td></tr></table></figure><h1 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h1><p><strong>字符判断</strong></p><blockquote><p>1、使用内置函数:</p><ul><li><code>isnumeric()</code>:检查字符串是否只包含数字字符。</li><li><code>isalpha()</code>:检查字符串是否只包含字母。</li><li><code>isspace()</code>:检查字符串是否只包含空白字符(如空格、制表符、换行符等)。</li><li><code>ispunct()</code>:检查字符串是否只包含标点符号。</li><li><code>isalnum()</code>:检查字符串是否只包含字母和数字。</li><li><code>isupper()</code> 方法判断是否为大写字母。</li><li><code>islower()</code> 方法判断是否为小写字母。</li></ul></blockquote><blockquote><p>2、使用正则表达式:</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">re.search(<span class="hljs-string">r'[a-zA-Z]'</span>, u_pwd) <span class="hljs-comment"># 字母</span><br></code></pre></td></tr></table></figure><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">re.search(<span class="hljs-string">r'[0-9]'</span>, u_pwd) <span class="hljs-comment"># 数字</span><br></code></pre></td></tr></table></figure><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">re.search(<span class="hljs-string">r'^[a-zA-Z0-9]'</span>, u_pwd) <span class="hljs-comment"># 特殊字符</span><br></code></pre></td></tr></table></figure></blockquote><blockquote><p>3、使用ASCII值:</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-keyword">if</span> <span class="hljs-string">'0'</span> <= <span class="hljs-type">char</span> <= <span class="hljs-string">'9'</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"数字"</span><br> elif <span class="hljs-string">'A'</span> <= <span class="hljs-type">char</span> <= <span class="hljs-string">'Z'</span> <span class="hljs-keyword">or</span> <span class="hljs-string">'a'</span> <= <span class="hljs-type">char</span> <= <span class="hljs-string">'z'</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"字母"</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"特殊字符"</span><br></code></pre></td></tr></table></figure></blockquote><p><strong>re.search和re.match的区别</strong></p><blockquote><p>re.match 只能在<strong>起始</strong>位置匹配,而re.search可以扫描<strong>整个</strong>字符串并返回<strong>第一个</strong>成功的匹配</p><p>re.findall 方法可以找到<strong>所有</strong>满足匹配条件的结果,并以列表的形式返回</p></blockquote><p><strong>字符统计出现次数</strong></p><figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs angelscript"><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> Counter<br></code></pre></td></tr></table></figure><blockquote><p>主要功能:可以支持方便、快速的计数,将元素数量统计,然后计数并返回一个字典,键为元素,值为元素个数。</p></blockquote>]]></content>
<categories>
<category>CSP</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>字符判断</tag>
<tag>字符统计</tag>
<tag>正则表达式</tag>
</tags>
</entry>
<entry>
<title>LeetCode09:找到字符串中所有字母异位词</title>
<link href="/2024/12/07/LeetCode09/"/>
<url>/2024/12/07/LeetCode09/</url>
<content type="html"><![CDATA[<h1 id="LeetCode09:找到字符串中所有字母异位词"><a href="#LeetCode09:找到字符串中所有字母异位词" class="headerlink" title="LeetCode09:找到字符串中所有字母异位词"></a>LeetCode09:找到字符串中所有字母异位词</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定两个字符串 <code>s</code> 和 <code>p</code>,找到 <code>s</code> 中所有 <code>p</code> 的 <strong>异位词</strong> 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。</p><p><strong>示例 1:</strong></p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs stylus">输入: s = <span class="hljs-string">"cbaebabacd"</span>, <span class="hljs-selector-tag">p</span> = <span class="hljs-string">"abc"</span><br>输出: <span class="hljs-selector-attr">[0,6]</span><br>解释:<br>起始索引等于 <span class="hljs-number">0</span> 的子串是 <span class="hljs-string">"cba"</span>, 它是 <span class="hljs-string">"abc"</span> 的异位词。<br>起始索引等于 <span class="hljs-number">6</span> 的子串是 <span class="hljs-string">"bac"</span>, 它是 <span class="hljs-string">"abc"</span> 的异位词。<br></code></pre></td></tr></table></figure><p> <strong>示例 2:</strong></p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs stylus">输入: s = <span class="hljs-string">"abab"</span>, <span class="hljs-selector-tag">p</span> = <span class="hljs-string">"ab"</span><br>输出: <span class="hljs-selector-attr">[0,1,2]</span><br>解释:<br>起始索引等于 <span class="hljs-number">0</span> 的子串是 <span class="hljs-string">"ab"</span>, 它是 <span class="hljs-string">"ab"</span> 的异位词。<br>起始索引等于 <span class="hljs-number">1</span> 的子串是 <span class="hljs-string">"ba"</span>, 它是 <span class="hljs-string">"ab"</span> 的异位词。<br>起始索引等于 <span class="hljs-number">2</span> 的子串是 <span class="hljs-string">"ab"</span>, 它是 <span class="hljs-string">"ab"</span> 的异位词。<br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="我的解法"><a href="#我的解法" class="headerlink" title="我的解法"></a>我的解法</h3><p>使用的是双层for循环,通过将p字符串的字母添加到列表,再依次遍历s字符串中数量为len(p)的字符,如果遍历到的字符属于列表,就将列表中的字符remove移除。如果遍历完后,列表为空,则证明此次遍历符合要求。否则进行下一次遍历。每次遍历都需要重新初始化列表。</p><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">findAnagrams</span>(<span class="hljs-params">self, s: <span class="hljs-built_in">str</span>, p: <span class="hljs-built_in">str</span></span>) -> <span class="hljs-type">List</span>[<span class="hljs-built_in">int</span>]:<br> res = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(s)):<br> char_in_b = [c <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> p]<br> num = <span class="hljs-built_in">len</span>(char_in_b)<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(i,i+num):<br> <span class="hljs-keyword">if</span> j > <span class="hljs-built_in">len</span>(s)-<span class="hljs-number">1</span>:<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">if</span> s[j] <span class="hljs-keyword">in</span> char_in_b:<br> char_in_b.remove(s[j])<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">if</span> char_in_b == []:<br> res.append(i)<br> <span class="hljs-keyword">return</span> res<br></code></pre></td></tr></table></figure><h3 id="官方题解"><a href="#官方题解" class="headerlink" title="官方题解"></a>官方题解</h3><p><strong>初始化滑动窗口</strong></p><p>依次在s和p中初始化滑动窗口,并且初始化26个字母的数组用来统计两个窗口中出现的字母次数。</p><p><strong>特殊情况</strong></p><p>首先考虑特殊情况,当p字符串比s字符串长,肯定不存在,返回空列表结果。</p><p><strong>比较初始窗口</strong></p><p>再比较两个初始化滑动窗口中的字母统计,是否相等,相等就添加一个初始化索引0。</p><p><strong>开始滑动</strong></p><p>开始滑动,滑动次数为<code>len_s - len_p</code>,<code>s[i]</code>对应的是左边待剔除的字母,需要-1;<code>s[i+len(p)]</code>对应的是右边待进入的字母,需要+1。每次滑动,需要比较字母统计是否相等,如果相等,结果需要添加<code>i+1</code>,因为滑动后的起始索引加1。</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><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">findAnagrams</span>(<span class="hljs-params">self, s: <span class="hljs-built_in">str</span>, p: <span class="hljs-built_in">str</span></span>) -> <span class="hljs-type">List</span>[<span class="hljs-built_in">int</span>]:<br> res = []<br> <span class="hljs-comment"># 特殊情况</span><br> len_s = <span class="hljs-built_in">len</span>(s)<br> len_p = <span class="hljs-built_in">len</span>(p)<br> <span class="hljs-keyword">if</span> len_p > len_s:<br> <span class="hljs-keyword">return</span> []<br> <span class="hljs-comment"># 初始化窗口</span><br> s_count = [<span class="hljs-number">0</span>] * <span class="hljs-number">26</span><br> p_count = [<span class="hljs-number">0</span>] * <span class="hljs-number">26</span><br> <span class="hljs-comment"># 比较初始化窗口中的内容</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(len_p):<br> s_count[<span class="hljs-built_in">ord</span>(s[i]) - <span class="hljs-number">97</span>] += <span class="hljs-number">1</span><br> p_count[<span class="hljs-built_in">ord</span>(p[i]) - <span class="hljs-number">97</span>] += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> s_count == p_count:<br> res.append(<span class="hljs-number">0</span>)<br> <span class="hljs-comment"># 逐个滑动窗口</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(len_s - len_p):<br> s_count[<span class="hljs-built_in">ord</span>(s[i]) - <span class="hljs-number">97</span>] -= <span class="hljs-number">1</span><br> s_count[<span class="hljs-built_in">ord</span>(s[i+len_p]) - <span class="hljs-number">97</span>] += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> s_count == p_count:<br> res.append(i+<span class="hljs-number">1</span>) <br> <span class="hljs-keyword">return</span> res <br></code></pre></td></tr></table></figure><h3 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h3><p><strong>根据字母获取对应字母表的索引</strong></p><blockquote><p><code>'a'</code> 的 Unicode 码点值是 97 (<code>ord('a') == 97</code>)</p></blockquote><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">ord</span><span class="hljs-params">(char)</span></span> - <span class="hljs-number">97</span><br></code></pre></td></tr></table></figure><p><strong>滑动</strong></p><blockquote><p>滑动次数是两个字符串的长度差,当前for循环其实是滑动前的状态,因为 i 从0开始的。</p></blockquote><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">for</span> i in range(len_s - len_p):<br> <span class="hljs-attribute">s_count</span>[ord(s[i]) - <span class="hljs-number">97</span>] -= <span class="hljs-number">1</span><br> <span class="hljs-attribute">s_count</span>[ord(s[i+len_p]) - <span class="hljs-number">97</span>] += <span class="hljs-number">1</span><br> <span class="hljs-attribute">if</span> s_count == p_count:<br> <span class="hljs-attribute">res</span>.append(i+<span class="hljs-number">1</span>) <br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>滑动窗口</tag>
<tag>数组初始化</tag>
<tag>字母统计</tag>
</tags>
</entry>
<entry>
<title>PAT08:锤子剪刀布</title>
<link href="/2024/12/06/PAT08/"/>
<url>/2024/12/06/PAT08/</url>
<content type="html"><![CDATA[<h1 id="8-锤子剪刀布"><a href="#8-锤子剪刀布" class="headerlink" title="8.锤子剪刀布"></a>8.锤子剪刀布</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs">大家应该都会玩“锤子剪刀布”的游戏:<br>现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。<br></code></pre></td></tr></table></figure><h3 id="输入描述"><a href="#输入描述" class="headerlink" title="输入描述:"></a><strong>输入描述:</strong></h3><figure class="highlight mathematica"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mathematica">输入第<span class="hljs-number">1</span>行给出正整数<span class="hljs-built_in">N</span>(<span class="hljs-operator"><=</span><span class="hljs-number">105</span>),即双方交锋的次数。随后<span class="hljs-built_in">N</span>行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。<span class="hljs-built_in">C</span>代表“锤子”、<span class="hljs-variable">J</span>代表“剪刀”、<span class="hljs-variable">B</span>代<br>表“布”,第<span class="hljs-number">1</span>个字母代表甲方,第<span class="hljs-number">2</span>个代表乙方,中间有<span class="hljs-number">1</span>个空格。<br></code></pre></td></tr></table></figure><h3 id="输出描述"><a href="#输出描述" class="headerlink" title="输出描述:"></a><strong>输出描述:</strong></h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。<br></code></pre></td></tr></table></figure><h3 id="输入例子"><a href="#输入例子" class="headerlink" title="输入例子:"></a><strong>输入例子:</strong></h3><figure class="highlight mipsasm"><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><code class="hljs mipsasm"><span class="hljs-number">10</span><br>C <span class="hljs-keyword">J</span><br><span class="hljs-keyword"></span><span class="hljs-keyword">J </span><span class="hljs-keyword">B</span><br><span class="hljs-keyword"></span>C <span class="hljs-keyword">B</span><br><span class="hljs-keyword"></span><span class="hljs-keyword">B </span><span class="hljs-keyword">B</span><br><span class="hljs-keyword"></span><span class="hljs-keyword">B </span>C<br>C C<br>C <span class="hljs-keyword">B</span><br><span class="hljs-keyword"></span><span class="hljs-keyword">J </span><span class="hljs-keyword">B</span><br><span class="hljs-keyword"></span><span class="hljs-keyword">B </span>C<br><span class="hljs-keyword">J </span><span class="hljs-keyword">J</span><br></code></pre></td></tr></table></figure><h3 id="输出例子"><a href="#输出例子" class="headerlink" title="输出例子:"></a><strong>输出例子:</strong></h3><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">5</span> <span class="hljs-number">3</span> <span class="hljs-number">2</span><br><span class="hljs-attribute">2</span> <span class="hljs-number">3</span> <span class="hljs-number">5</span><br><span class="hljs-attribute">B</span> B<br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><figure class="highlight stylus"><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></pre></td><td class="code"><pre><code class="hljs stylus">import sys<br><br>lst = sys<span class="hljs-selector-class">.stdin</span><span class="hljs-selector-class">.readlines</span>()<br>playNum = lst<span class="hljs-selector-attr">[0]</span><br><br>win_a = <span class="hljs-number">0</span><br>draw_a = <span class="hljs-number">0</span><br>lose_a = <span class="hljs-number">0</span><br>win_b = <span class="hljs-number">0</span><br>draw_b = <span class="hljs-number">0</span><br>lose_b = <span class="hljs-number">0</span><br>a_c = <span class="hljs-number">0</span><br>a_j = <span class="hljs-number">0</span><br>a_b = <span class="hljs-number">0</span><br>b_c = <span class="hljs-number">0</span><br>b_j = <span class="hljs-number">0</span><br>b_b = <span class="hljs-number">0</span><br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> lst<span class="hljs-selector-attr">[1:]</span>:<br> line = line<span class="hljs-selector-class">.split</span>(<span class="hljs-string">' '</span>)<br> <span class="hljs-selector-tag">a</span> = line<span class="hljs-selector-attr">[0]</span><br> <span class="hljs-selector-tag">b</span> = line<span class="hljs-selector-attr">[1]</span><span class="hljs-selector-class">.strip</span>()<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">a</span> == <span class="hljs-selector-tag">b</span>:<br> draw_a += <span class="hljs-number">1</span><br> draw_b += <span class="hljs-number">1</span><br> elif <span class="hljs-selector-tag">a</span> == <span class="hljs-string">'C'</span>:<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'B'</span>:<br> lose_a += <span class="hljs-number">1</span><br> win_b += <span class="hljs-number">1</span><br> b_b += <span class="hljs-number">1</span><br> elif <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'J'</span>:<br> win_a += <span class="hljs-number">1</span><br> lose_b += <span class="hljs-number">1</span><br> a_c += <span class="hljs-number">1</span><br> elif <span class="hljs-selector-tag">a</span> == <span class="hljs-string">'J'</span>:<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'B'</span>:<br> win_a += <span class="hljs-number">1</span><br> lose_b += <span class="hljs-number">1</span><br> a_j += <span class="hljs-number">1</span><br> <br> elif <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'C'</span>:<br> lose_a += <span class="hljs-number">1</span><br> win_b += <span class="hljs-number">1</span><br> b_c += <span class="hljs-number">1</span><br> elif <span class="hljs-selector-tag">a</span> == <span class="hljs-string">'B'</span>:<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'J'</span>:<br> lose_a += <span class="hljs-number">1</span><br> win_b += <span class="hljs-number">1</span><br> b_b += <span class="hljs-number">1</span><br> elif <span class="hljs-selector-tag">b</span> == <span class="hljs-string">'C'</span>:<br> win_a += <span class="hljs-number">1</span><br> lose_b += <span class="hljs-number">1</span><br> a_b += <span class="hljs-number">1</span><br><br>a_all = <span class="hljs-selector-attr">[a_b, a_j, a_c]</span><br>a_paly = <span class="hljs-selector-attr">[<span class="hljs-string">'B'</span>, <span class="hljs-string">'J'</span>, <span class="hljs-string">'C'</span>]</span><br>b_all = <span class="hljs-selector-attr">[b_b, b_j, b_c]</span><br>b_paly = <span class="hljs-selector-attr">[<span class="hljs-string">'B'</span>, <span class="hljs-string">'J'</span>, <span class="hljs-string">'C'</span>]</span><br><br>maxNum_a = <span class="hljs-built_in">max</span>(a_all)<br>maxNum_b = <span class="hljs-built_in">max</span>(b_all)<br>most_a = None<br>most_b = None<br><br><span class="hljs-keyword">for</span> index, <span class="hljs-selector-tag">i</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(a_all):<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">i</span> == maxNum_a:<br> <span class="hljs-keyword">if</span> most_a is None:<br> most_a = a_paly<span class="hljs-selector-attr">[index]</span><br> elif <span class="hljs-built_in">ord</span>(a_paly<span class="hljs-selector-attr">[index]</span>) <= <span class="hljs-built_in">ord</span>(most_a):<br> most_a = a_paly<span class="hljs-selector-attr">[index]</span><br><span class="hljs-keyword">for</span> index, <span class="hljs-selector-tag">i</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(b_all):<br> <span class="hljs-keyword">if</span> <span class="hljs-selector-tag">i</span> == maxNum_b:<br> <span class="hljs-keyword">if</span> most_b is None:<br> most_b = b_paly<span class="hljs-selector-attr">[index]</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">ord</span>(b_paly<span class="hljs-selector-attr">[index]</span>) <= <span class="hljs-built_in">ord</span>(most_b):<br> most_b = b_paly<span class="hljs-selector-attr">[index]</span><br><span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(win_a, draw_a, lose_a)</span></span><br><span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(win_b, draw_b, lose_b)</span></span><br><span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(most_a, most_b)</span></span><br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>若最大值相同,按字母顺序选择</strong></p><blockquote><p>直接先按照字母顺序排列,依次判断是否为最大值</p></blockquote><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">most_win</span>(<span class="hljs-params">b, c, j</span>):<br> <span class="hljs-keyword">if</span> b == <span class="hljs-built_in">max</span>(b, c, j):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'B'</span><br> <span class="hljs-keyword">elif</span> c == <span class="hljs-built_in">max</span>(b, c, j):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'C'</span><br> <span class="hljs-keyword">elif</span> j == <span class="hljs-built_in">max</span>(b, c, j):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'J'</span><br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode08:无重复字符的最长子串</title>
<link href="/2024/07/17/LeetCode08/"/>
<url>/2024/07/17/LeetCode08/</url>
<content type="html"><![CDATA[<h1 id="8-无重复字符的最长子串"><a href="#8-无重复字符的最长子串" class="headerlink" title="8.无重复字符的最长子串"></a>8.无重复字符的最长子串</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一个字符串 <code>s</code> ,请你找出其中不含有重复字符的 <strong>最长 子串</strong> 的长度。</p><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="我的解法"><a href="#我的解法" class="headerlink" title="我的解法"></a>我的解法</h3><p>首先考虑特殊情况,如果字符串为空,结果为0</p><p>初始化一个字典lettersIndex ,用于存储字符和相应的索引;</p><p>初始化最长不重复子串的长度max_length ,0</p><p>初始化子串的起始索引start ,0</p><p><strong>遍历字符串,获取每一个字符和其索引。</strong></p><ul><li><p>检查当前字符,如果在字典中,并且字典中该字符的索引不小于start ,代表已经重复,更新start (该字符在字典中的索引加1,也就是起始索引加1),更新字典中该字符的索引为当前索引。</p></li><li><p>遍历每一个字符,需要计算当前子串的长度,<code>i - start + 1</code></p></li><li><p>更新全局最大长度。<code>max_length = max(max_length, current_length)</code></p></li></ul><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">lengthOfLongestSubstring</span>(<span class="hljs-params">self, s: <span class="hljs-built_in">str</span></span>) -> <span class="hljs-built_in">int</span>:<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> s:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br><br> lettersIndex = {}<br> max_length = <span class="hljs-number">0</span><br> start = <span class="hljs-number">0</span><br><br> <span class="hljs-keyword">for</span> i, char <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(s):<br> <span class="hljs-keyword">if</span> char <span class="hljs-keyword">in</span> lettersIndex <span class="hljs-keyword">and</span> lettersIndex[char] >= start:<br> start = lettersIndex[char] + <span class="hljs-number">1</span><br><br> lettersIndex[char] = i<br> current_length = i - start + <span class="hljs-number">1</span><br> max_length = <span class="hljs-built_in">max</span>(max_length, current_length)<br><br> <span class="hljs-keyword">return</span> max_length<br></code></pre></td></tr></table></figure><h3 id="官方题解"><a href="#官方题解" class="headerlink" title="官方题解"></a>官方题解</h3><p>这种方法的<strong>核心思想</strong>是使用两个指针(左指针和右指针)来维护一个动态的窗口,窗口内的字符都是不重复的。通过不断移动这两个指针,可以找到最长的不重复子串。</p><ol><li><strong>初始化变量</strong>:<ul><li><code>occ = set()</code> 初始化一个集合,用于记录当前子串中出现的字符。</li><li><code>n = len(s)</code> 获取字符串 <code>s</code> 的长度。</li><li><code>rk, ans = -1, 0</code> 初始化右指针 <code>rk</code> 为 -1(表示在字符串左侧),初始化最长子串长度 <code>ans</code> 为 0。</li></ul></li><li><strong>遍历字符串</strong>:<ul><li><code>for i in range(n):</code> 遍历字符串 <code>s</code> 的每一个字符。</li></ul></li><li><strong>左指针移动</strong>:<ul><li><code>if i != 0:</code> 当不是第一个字符时,将左指针左侧的字符从集合中移除,从而缩小子串的范围。</li></ul></li><li><strong>右指针移动</strong>:<ul><li><code>while rk + 1 < n and s[rk + 1] not in occ:</code> 只要右指针右侧的字符不在当前集合中,就不断移动右指针,并将字符加入集合。</li></ul></li><li><strong>更新最长子串长度</strong>:<ul><li><code>ans = max(ans, rk - i + 1)</code> 更新最长不重复子串的长度。这里 <code>rk - i + 1</code> 表示从左指针 <code>i</code> 到右指针 <code>rk</code> 的子串长度。</li></ul></li><li><strong>返回结果</strong>:<ul><li><code>return ans</code> 返回最长不重复子串的长度。</li></ul></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><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">lengthOfLongestSubstring</span>(<span class="hljs-params">self, s: <span class="hljs-built_in">str</span></span>) -> <span class="hljs-built_in">int</span>:<br> <span class="hljs-comment"># 哈希集合,记录每个字符是否出现过</span><br> occ = <span class="hljs-built_in">set</span>()<br> n = <span class="hljs-built_in">len</span>(s)<br> <span class="hljs-comment"># 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动</span><br> rk, ans = -<span class="hljs-number">1</span>, <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> <span class="hljs-keyword">if</span> i != <span class="hljs-number">0</span>:<br> <span class="hljs-comment"># 左指针向右移动一格,移除一个字符</span><br> occ.remove(s[i - <span class="hljs-number">1</span>])<br> <span class="hljs-keyword">while</span> rk + <span class="hljs-number">1</span> < n <span class="hljs-keyword">and</span> s[rk + <span class="hljs-number">1</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> occ:<br> <span class="hljs-comment"># 不断地移动右指针</span><br> occ.add(s[rk + <span class="hljs-number">1</span>])<br> rk += <span class="hljs-number">1</span><br> <span class="hljs-comment"># 第 i 到 rk 个字符是一个极长的无重复字符子串</span><br> ans = <span class="hljs-built_in">max</span>(ans, rk - i + <span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> ans<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>哈希表</tag>
<tag>双指针</tag>
<tag>滑动窗口</tag>
</tags>
</entry>
<entry>
<title>PAT07:A除以B</title>
<link href="/2024/07/17/PAT07/"/>
<url>/2024/07/17/PAT07/</url>
<content type="html"><![CDATA[<h1 id="7-A除以B"><a href="#7-A除以B" class="headerlink" title="7.A除以B"></a>7.A除以B</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dns">本题要求计算<span class="hljs-keyword">A</span>/B,其中<span class="hljs-keyword">A</span>是不超过<span class="hljs-number">1000</span>位的正整数,B是<span class="hljs-number">1</span>位正整数。你需要输出商数Q和余数R,使得<span class="hljs-keyword">A</span> = B * Q + R成立。<br></code></pre></td></tr></table></figure><h3 id="输入描述"><a href="#输入描述" class="headerlink" title="输入描述:"></a><strong>输入描述:</strong></h3><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">输入在<span class="hljs-number">1</span>行中依次给出<span class="hljs-selector-tag">A</span>和<span class="hljs-selector-tag">B</span>,中间以<span class="hljs-number">1</span>空格分隔。<br></code></pre></td></tr></table></figure><h3 id="输出描述"><a href="#输出描述" class="headerlink" title="输出描述:"></a><strong>输出描述:</strong></h3><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">在<span class="hljs-number">1</span>行中依次输出<span class="hljs-selector-tag">Q</span>和R,中间以<span class="hljs-number">1</span>空格分隔。<br></code></pre></td></tr></table></figure><h3 id="输入例子"><a href="#输入例子" class="headerlink" title="输入例子:"></a><strong>输入例子:</strong></h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">123456789050987654321 </span><span class="hljs-number">7</span><br></code></pre></td></tr></table></figure><h3 id="输出例子"><a href="#输出例子" class="headerlink" title="输出例子:"></a><strong>输出例子:</strong></h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">17636684150141093474 </span><span class="hljs-number">3</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><p>太简单了。。</p><p>求商—-> <code>//</code></p><p>求余—-><code>%</code></p><p>输出以空格分割—-> <code>print(a,b)</code></p><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">import sys<br><br><span class="hljs-keyword">for</span> <span class="hljs-built_in">line</span> <span class="hljs-keyword">in</span> sys.<span class="hljs-keyword">stdin</span>:<br> <span class="hljs-keyword">a</span>,b = <span class="hljs-built_in">line</span>.strip().<span class="hljs-built_in">split</span>(<span class="hljs-string">' '</span>)<br> <span class="hljs-keyword">a</span>,b = int(<span class="hljs-keyword">a</span>),int(b)<br> q = <span class="hljs-comment">a//b</span><br> r = <span class="hljs-keyword">a</span> % b <br> print(q,r)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode07:接雨水</title>
<link href="/2024/06/15/LeetCode07/"/>
<url>/2024/06/15/LeetCode07/</url>
<content type="html"><![CDATA[<h1 id="7-接雨水"><a href="#7-接雨水" class="headerlink" title="7.接雨水"></a>7.接雨水</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定 <code>n</code> 个非负整数表示每个宽度为 <code>1</code> 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202406171729580.png" alt="image-20240615192506854"></p><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)动态规划法"><a href="#(1)动态规划法" class="headerlink" title="(1)动态规划法"></a>(1)动态规划法</h3><p>动态规划(Dynamic Programming, DP)是一种算法设计技巧,它将一个复杂的问题分解为更小的子问题,并存储这些子问题的解,以避免重复计算。这种方法特别适用于具有以下两个特性的问题:</p><ol><li><strong>重叠子问题</strong>:问题可以分解为多个子问题,这些子问题会重复出现多次。</li><li><strong>最优子结构</strong>:问题的最优解包含其子问题的最优解。</li></ol><p><strong>思路</strong></p><ol><li>对于下标<code>i</code>,雨水能达到的最大高度是<code>i</code>两边的最大高度的最小值。</li><li>对于下标<code>i</code>,雨水量是能达到的最大高度减去<code>i</code>处的柱子高度<code>height[i]</code></li></ol><ul><li>如何计算两边的最大高度呢?</li></ul><p>朴素的做法是:对于每一个位置,分别向左和向右扫描,记录左右两边的最大高度。</p><p>时间复杂度:O($n^2$)</p><p><strong>动态规划法:</strong>如果已知每个位置两边的最大高度,就可以在O(n)的时间得出结果。</p><p>时间复杂度:O(n)</p><ul><li>如何计算每个位置两边的最大高度呢</li></ul><p>创建2个长度为n的数组<code>leftMax</code>和<code>rightMax</code>。<code>leftMax[i]</code>表示下标<code>i</code>及其左边位置的最大高度,<code>rightMax[i]</code>表示下标<code>i</code>及其右边位置的最大高度。</p><p>显然,两端的元素已经确定。<code>leftMax[0] = height[0]</code>,<code>rightMax[n-1]=height[n-1]</code></p><p>其他元素的计算方式:正向遍历数组height得到<code>leftMax</code>,反向遍历数组height得到<code>rightMax</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><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trap</span>(<span class="hljs-params">self, height</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> height:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> <br> n = <span class="hljs-built_in">len</span>(height)<br> <br> leftMax = [height[<span class="hljs-number">0</span>]] + [<span class="hljs-number">0</span>] * (n-<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,n):<br> leftMax[i] = <span class="hljs-built_in">max</span>(leftMax[i-<span class="hljs-number">1</span>],height[i])<br> <br> rightMax = [<span class="hljs-number">0</span>] * (n-<span class="hljs-number">1</span>) + [height[n-<span class="hljs-number">1</span>]]<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n-<span class="hljs-number">2</span>,-<span class="hljs-number">1</span>,-<span class="hljs-number">1</span>):<br> rightMax[i] = <span class="hljs-built_in">max</span>(rightMax[i+<span class="hljs-number">1</span>],height[i])<br> <br> ans = <span class="hljs-built_in">sum</span>(<span class="hljs-built_in">min</span>(leftMax[i],rightMax[i])-height[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n))<br> <span class="hljs-keyword">return</span> ans<br><br></code></pre></td></tr></table></figure><h2 id="(2)单调栈"><a href="#(2)单调栈" class="headerlink" title="(2)单调栈"></a>(2)单调栈</h2><p>维护一个单调栈,单调栈存储的是下标,满足从栈底到栈顶的下标对应的数组 <code>height</code>中的元素递减。</p><p>从左到右遍历<code>height</code>数组,遍历到下标<code>i</code>的时候,如果栈内至少有2个元素,栈顶为<code>top</code>,<code>top</code>下面是<code>left</code>,则一定有<code>height[top]<=height[left]</code>。如果<code>height[i] > height[top]</code>,则可以接到雨水。</p><p>雨水的宽度:<code>i - left -1</code></p><p>雨水的高度:<code>min(height[left],height[i]) - height[top]</code></p><p><strong>循环条件</strong></p><p>为了得到<code>left</code>,需要将<code>top</code>出栈,对<code>top</code>计算能接到的雨水量后,<code>left</code>就变成了新的<code>top</code>,如此重复操作,直到栈为空或者栈顶对应的元素大于或等于<code>height[i]</code>。完成对<code>top</code>和<code>i</code>的计算后,将<code>i</code>入栈,继续遍历。</p><p>时间复杂度:O(n)</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trap</span>(<span class="hljs-params">self, height</span>):<br> ans = <span class="hljs-number">0</span><br> stack = <span class="hljs-built_in">list</span>()<br> n = <span class="hljs-built_in">len</span>(height)<br> <br> <span class="hljs-keyword">for</span> i, h <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(height):<br> <span class="hljs-keyword">while</span> stack <span class="hljs-keyword">and</span> h > height[stack[-<span class="hljs-number">1</span>]]:<br> top = stack.pop()<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> stack:<br> <span class="hljs-keyword">break</span><br> left = stack[-<span class="hljs-number">1</span>]<br> currWidth = i - left - <span class="hljs-number">1</span><br> currHeight = <span class="hljs-built_in">min</span>(height[left], height[i]) - height[top]<br> ans += currWidth * currHeight<br> stack.append(i)<br> <br> <span class="hljs-keyword">return</span> ans<br></code></pre></td></tr></table></figure><h3 id="(3)-双指针"><a href="#(3)-双指针" class="headerlink" title="(3) 双指针"></a>(3) 双指针</h3><p>在动态规划中,需要维护两个数组<code>leftMax</code>和<code>rightMax</code>,因此空间复杂度是O(n)。使用双指针和双变量可以代替两个数组,使得空间复杂度是O(1)。</p><p><strong>初始值:</strong>指针<code>left=0</code>,指针<code>right=len(height)-1</code>,两个变量<code>leftMax=0,rightMax=0</code></p><p>下标<code>i</code>能接的雨水量由<code>leftMax[i]</code>和<code>rightMax[i]</code>的最小值决定。</p><p>指针<code>left</code>只能右移,指针<code>right</code>只能左移,移动指针过程中需要维护两个变量<code>leftMax</code>和<code>rightMax</code>的值。</p><p><strong>当两个指针没有相遇时:</strong><code>(while left < right)</code></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202406171729670.png" alt="image-20240617172305647"></p><p><strong>时间复杂度:</strong>O(n),其中 n是数组的长度,两个指针的移动总次数不超过 n。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trap</span>(<span class="hljs-params">self, height</span>):<br> ans = <span class="hljs-number">0</span><br> left, right = <span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(height) - <span class="hljs-number">1</span><br> leftMax = rightMax = <span class="hljs-number">0</span><br><br> <span class="hljs-keyword">while</span> left < right:<br> leftMax = <span class="hljs-built_in">max</span>(leftMax, height[left])<br> rightMax = <span class="hljs-built_in">max</span>(rightMax, height[right])<br> <span class="hljs-keyword">if</span> height[left] < height[right]:<br> ans += leftMax - height[left]<br> left += <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>:<br> ans += rightMax - height[right]<br> right -= <span class="hljs-number">1</span><br> <br> <span class="hljs-keyword">return</span> ans<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>双指针</tag>
<tag>单调栈</tag>
<tag>动态规划</tag>
</tags>
</entry>
<entry>
<title>PAT06:部分A+B</title>
<link href="/2024/05/29/PAT06/"/>
<url>/2024/05/29/PAT06/</url>
<content type="html"><![CDATA[<h1 id="6-部分A-B"><a href="#6-部分A-B" class="headerlink" title="6.部分A+B"></a>6.部分A+B</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><h3 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a><strong>题目描述</strong></h3><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs dns">正整数<span class="hljs-keyword">A</span>的“DA(为<span class="hljs-number">1</span>位整数)部分”定义为由<span class="hljs-keyword">A</span>中所有DA组成的新整数PA。例如:给定<span class="hljs-keyword">A</span> = <span class="hljs-number">3862767</span>,DA = <span class="hljs-number">6</span>,则<span class="hljs-keyword">A</span>的“<span class="hljs-number">6</span>部分”PA是<span class="hljs-number">66</span>,因为<span class="hljs-keyword">A</span>中有<span class="hljs-number">2</span>个<span class="hljs-number">6</span>。<br> <br> 现给定<span class="hljs-keyword">A</span>、DA、B、DB,请编写程序计算PA + PB。<br></code></pre></td></tr></table></figure><h3 id="输入描述"><a href="#输入描述" class="headerlink" title="输入描述:"></a><strong>输入描述:</strong></h3><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">输入在一行中依次给出<span class="hljs-selector-tag">A</span>、DA、<span class="hljs-selector-tag">B</span>、DB,中间以空格分隔,其中<span class="hljs-number">0</span> < <span class="hljs-selector-tag">A</span>, <span class="hljs-selector-tag">B</span> < <span class="hljs-number">1010</span>。<br></code></pre></td></tr></table></figure><h3 id="输出描述"><a href="#输出描述" class="headerlink" title="输出描述:"></a><strong>输出描述:</strong></h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">在一行中输出PA + PB的值。<br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><p>这道题比较简单。需要掌握的是如何在一个整数中统计某个数字的计数。</p><p>方法:转换为字符串,使用字符串的count方法。</p><p>另外,n个相同的数字转换为整数使用range方法作为10的次方求和。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> a,da,b,db = line.strip().split(<span class="hljs-string">' '</span>)<br> num1 = <span class="hljs-built_in">str</span>(a).count(da)<br> num2 = <span class="hljs-built_in">str</span>(b).count(db)<br> p1 = <span class="hljs-built_in">sum</span>([<span class="hljs-built_in">int</span>(da) * <span class="hljs-number">10</span> ** i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num1)])<br> p2 = <span class="hljs-built_in">sum</span>([<span class="hljs-built_in">int</span>(db) * <span class="hljs-number">10</span> ** i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num2)])<br> res = p1+p2<br> <span class="hljs-built_in">print</span>(res)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode06:三数之和</title>
<link href="/2024/05/16/LeetCode06/"/>
<url>/2024/05/16/LeetCode06/</url>
<content type="html"><![CDATA[<h1 id="6-三数之和"><a href="#6-三数之和" class="headerlink" title="6.三数之和"></a>6.三数之和</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给你一个整数数组 <code>nums</code> ,判断是否存在三元组 <code>[nums[i], nums[j], nums[k]]</code> 满足 <code>i != j</code>、<code>i != k</code> 且 <code>j != k</code> ,同时还满足 <code>nums[i] + nums[j] + nums[k] == 0</code> 。请</p><p>你返回所有和为 <code>0</code> 且不重复的三元组。</p><p><strong>注意:</strong>答案中不可以包含重复的三元组。</p><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(一)暴力解法(三重循环)"><a href="#(一)暴力解法(三重循环)" class="headerlink" title="(一)暴力解法(三重循环)"></a>(一)暴力解法(三重循环)</h3><p>使用三层嵌套循环来枚举所有可能的三个数的组合。</p><p><strong>时间复杂度:</strong>对于每个元素a,它都与后面所有可能的b和c元素进行了比较。为O($n^3$),n是数组的长度。</p><p><strong>空间复杂度:</strong>由于 <code>arr</code> 可能包含大量的三元组,所以这部分的空间复杂度是最高的,为 O($n^3$)。</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><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">compareArr</span>(<span class="hljs-params">self,arr</span>):<br> unique_str = []<br> res = []<br> <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> arr:<br> new_str = <span class="hljs-string">''</span>.join(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">str</span>,<span class="hljs-built_in">sorted</span>(x)))<br> <span class="hljs-keyword">if</span> new_str <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> unique_str:<br> unique_str.append(new_str)<br> res.append(x)<br> <span class="hljs-keyword">return</span> res<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">threeSum</span>(<span class="hljs-params">self, nums</span>):<br> arr = []<br> count = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i,a <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(nums[:-<span class="hljs-number">2</span>]):<br> <span class="hljs-keyword">for</span> b <span class="hljs-keyword">in</span> nums[i+<span class="hljs-number">1</span>:-<span class="hljs-number">1</span>]:<br> <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> nums[i+<span class="hljs-number">2</span>+count:]:<br> <span class="hljs-keyword">if</span> a+b+c == <span class="hljs-number">0</span>:<br> arr.append([a,b,c])<br> count = count + <span class="hljs-number">1</span><br> count = <span class="hljs-number">0</span><br><br><br> res = self.compareArr(arr)<br> <span class="hljs-keyword">return</span> res<br></code></pre></td></tr></table></figure><h3 id="(二)双指针法"><a href="#(二)双指针法" class="headerlink" title="(二)双指针法"></a>(二)双指针法</h3><p>1、排序。先将 <code>nums</code> 排序,时间复杂度为 O(NlogN)。</p><p>2、特判。非数组返回空;数组首元素大于0返回空(因为后面的肯定比它大,和不可能为0);数组长度小于3返回空;</p><p>3、设置指针。固定最左(最小)元素的指针a ,再使用左右指针指向a后面元素的两端,分别为l,r。</p><p>4、循环条件。</p><ul><li><p>左指针索引j要小于右指针索引k;</p></li><li><p>如果a大于0,则条件一定不能满足,结束循环;</p></li><li><p>如果a和前一个数字相等,说明数字重复,会导致结果重复,跳过;</p></li></ul><p>5、求和。</p><ul><li>如果和等于0,添加到结果列表。左指针右移,右指针左移。在此之前,都需要判断是否下一个元素重复,如果重复就跳过,因为会导致结果重复;</li><li>如果和大于0,右指针左移;</li><li>如果和小于0,左指针右移。(左右移动不需要考虑下一个元素重复,因为我们是在调整指针尝试可能的三元组,不需要担心重复。</li></ul><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><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">threeSum</span>(<span class="hljs-params">self,nums</span>):<br> nums = <span class="hljs-built_in">sorted</span>(nums)<br> length = <span class="hljs-built_in">len</span>(nums)<br> res = []<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> nums <span class="hljs-keyword">or</span> nums[<span class="hljs-number">0</span>]><span class="hljs-number">0</span> <span class="hljs-keyword">or</span> length<<span class="hljs-number">3</span>:<br> <span class="hljs-keyword">return</span> []<br> <span class="hljs-keyword">for</span> i,a <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(nums[:-<span class="hljs-number">2</span>]):<br> <span class="hljs-keyword">if</span> a><span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> res<br> <span class="hljs-keyword">if</span> i><span class="hljs-number">0</span> <span class="hljs-keyword">and</span> nums[i-<span class="hljs-number">1</span>] == a:<br> <span class="hljs-keyword">continue</span><br> j = i + <span class="hljs-number">1</span><br> k = length - <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span>(j<k):<br> l = nums[j]<br> r = nums[k]<br> total = a+l+r<br> <span class="hljs-keyword">if</span> total == <span class="hljs-number">0</span>:<br> res.append([a,l,r])<br> <span class="hljs-keyword">while</span> j < k <span class="hljs-keyword">and</span> nums[k-<span class="hljs-number">1</span>] == nums[k]:<br> k -= <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span> j<k <span class="hljs-keyword">and</span> nums[j+<span class="hljs-number">1</span>]==nums[j]:<br> j += <span class="hljs-number">1</span><br> k-=<span class="hljs-number">1</span><br> j+=<span class="hljs-number">1</span><br> <span class="hljs-keyword">elif</span> total >=<span class="hljs-number">0</span>:<br> k -= <span class="hljs-number">1</span><br> <span class="hljs-keyword">elif</span> total <= <span class="hljs-number">0</span>:<br> j += <span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> res<br></code></pre></td></tr></table></figure><h4 id="图解"><a href="#图解" class="headerlink" title="图解"></a>图解</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909060.png" alt="image-20240516190804739"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909037.png" alt="image-20240516190813879"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909064.png" alt="image-20240516190823405"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909034.png" alt="image-20240516190830238"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909077.png" alt="image-20240516190837075"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909040.png" alt="image-20240516190843531"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909441.png" alt="image-20240516190849453"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909490.png" alt="image-20240516190857189"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909541.png" alt="image-20240516190903303"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909514.png" alt="image-20240516190908873"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909538.png" alt="image-20240516190915484"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202405161909545.png" alt="image-20240516190922452"></p>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>双指针</tag>
<tag>三重循环</tag>
</tags>
</entry>
<entry>
<title>PAT05:德才论</title>
<link href="/2024/04/17/PAT05/"/>
<url>/2024/04/17/PAT05/</url>
<content type="html"><![CDATA[<h1 id="5-德才论"><a href="#5-德才论" class="headerlink" title="5.德才论"></a>5.德才论</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><h3 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a><strong>题目描述</strong></h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs">宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之<br> 小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”<br> <br> 现给出一批考生的德才分数,请根据司马光的理论给出录取排名。<br></code></pre></td></tr></table></figure><h3 id="输入描述"><a href="#输入描述" class="headerlink" title="输入描述:"></a><strong>输入描述:</strong></h3><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs excel">输入第<span class="hljs-number">1</span>行给出<span class="hljs-number">3</span>个正整数,分别为:<span class="hljs-built_in">N</span>(<=<span class="hljs-number">105</span>),即考生总数;L(>=<span class="hljs-number">60</span>),为录取最低分数线,即德分和才分均不低于L的考生才有资格<br>被考虑录取;H(<<span class="hljs-number">100</span>),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到<br>但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于H,但是德分不低于才分的考生属于“才德兼<br>亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线L的考生也按总分排序,但排在第三类考生之后。<br><br>随后<span class="hljs-built_in">N</span>行,每行给出一位考生的信息,包括:准考证号、德分、才分,其中准考证号为<span class="hljs-number">8</span>位整数,德才分为区间[<span class="hljs-number">0</span>, <span class="hljs-number">100</span>]内的整数。数字间以空格分隔。<br></code></pre></td></tr></table></figure><h3 id="输出描述"><a href="#输出描述" class="headerlink" title="输出描述:"></a><strong>输出描述:</strong></h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs">输出第1行首先给出达到最低分数线的考生人数M,随后M行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人<br>总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。<br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><p><strong>分类</strong></p><p>首先,参加排序的考生需要高于最低分数线,在此基础上分为四类:</p><p>1、德、才均高于优先录取线</p><p>2、德高于优先录取线</p><p>3、德、才均低于优先录取线,但德 > 才</p><p>4、德、才均低于优先录取线,但德 < 才</p><p><strong>排序</strong></p><p>将所有满足条件的考生分类完成,逐类排序。排序规则是:按总分排序,总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。</p><p><strong>输出</strong></p><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-comment"># 保存输入数据</span><br>inputs = []<br><span class="hljs-comment"># 保存输出数据</span><br>out1 = []<br>out2 = []<br>out3 = []<br>out4 = []<br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> inputs.append([<span class="hljs-built_in">int</span>(item) <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> line.split()])<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(inputs) == inputs[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>] + <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">break</span><br><br><span class="hljs-comment"># 最低分数线</span><br>low_score = inputs[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>]<br><span class="hljs-comment"># 优先录取线</span><br>high_score = inputs[<span class="hljs-number">0</span>][<span class="hljs-number">2</span>]<br><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(inputs)):<br> total = inputs[i][<span class="hljs-number">1</span>] + inputs[i][<span class="hljs-number">2</span>]<br> <span class="hljs-keyword">if</span> inputs[i][<span class="hljs-number">1</span>] >= high_score <span class="hljs-keyword">and</span> inputs[i][<span class="hljs-number">2</span>] >= high_score:<br> out1.append(inputs[i])<br> <span class="hljs-keyword">elif</span> inputs[i][<span class="hljs-number">1</span>] >= high_score <span class="hljs-keyword">and</span> low_score <= inputs[i][<span class="hljs-number">2</span>] < high_score:<br> out2.append(inputs[i])<br> <span class="hljs-keyword">elif</span> inputs[i][<span class="hljs-number">1</span>] >= low_score <span class="hljs-keyword">and</span> inputs[i][<span class="hljs-number">2</span>] >= low_score <span class="hljs-keyword">and</span> inputs[i][<span class="hljs-number">1</span>] >= inputs[i][<span class="hljs-number">2</span>]:<br> out3.append(inputs[i])<br> <span class="hljs-keyword">elif</span> inputs[i][<span class="hljs-number">1</span>] >= low_score <span class="hljs-keyword">and</span> inputs[i][<span class="hljs-number">2</span>] >= low_score:<br> out4.append(inputs[i])<br><br>out = [out1,out2,out3,out4]<br>res = []<br><span class="hljs-keyword">for</span> i,lst <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(out):<br> lst = <span class="hljs-built_in">sorted</span>(lst,key=<span class="hljs-keyword">lambda</span> x:(x[<span class="hljs-number">1</span>]+x[<span class="hljs-number">2</span>],x[<span class="hljs-number">1</span>],-x[<span class="hljs-number">0</span>]),reverse=<span class="hljs-literal">True</span>)<br> res += lst<br><br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">len</span>(res))<br><span class="hljs-keyword">for</span> lst <span class="hljs-keyword">in</span> res:<br> <span class="hljs-built_in">print</span>(*lst,sep=<span class="hljs-string">' '</span>)<br><br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>多条排序规则</strong></p><blockquote><p><code>sorted()</code> 函数在排序时,会针对列表 <code>lst</code> 中的每个元素 <code>x</code> 调用 <code>key</code> 参数指定的函数(此处为 <code>lambda x: (x[1] + x[2], x[1], -x[0])</code>),得到相应的排序键。<code>key</code> 参数的作用是定义一个映射规则,将待排序的元素转化为一个用于排序的值(排序键)。<code>sorted()</code> 函数根据这些排序键进行排序,从而实现对原始元素列表的定制化排序。</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">lst = <span class="hljs-built_in">sorted</span>(lst,key=<span class="hljs-keyword">lambda</span> x:(x[<span class="hljs-number">1</span>]+x[<span class="hljs-number">2</span>],x[<span class="hljs-number">1</span>],-x[<span class="hljs-number">0</span>]),reverse=<span class="hljs-literal">True</span>)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>排序</tag>
</tags>
</entry>
<entry>
<title>LeetCode05:盛最多水的容器</title>
<link href="/2024/03/29/LeetCode05/"/>
<url>/2024/03/29/LeetCode05/</url>
<content type="html"><![CDATA[<h1 id="5-盛最多水的容器"><a href="#5-盛最多水的容器" class="headerlink" title="5. 盛最多水的容器"></a>5. 盛最多水的容器</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一个长度为 <code>n</code> 的整数数组 <code>height</code> 。有 <code>n</code> 条垂线,第 <code>i</code> 条线的两个端点是 <code>(i, 0)</code> 和 <code>(i, height[i])</code> 。</p><p>找出其中的两条线,使得它们与 <code>x</code> 轴共同构成的容器可以容纳最多的水。</p><p>返回容器可以储存的最大水量。</p><p><strong>说明:</strong>你不能倾斜容器。</p><p><strong>示例 1:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403292020343.jpeg" alt="img"></p><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs dns">输入:[<span class="hljs-number">1,8,6,2</span>,<span class="hljs-number">5,4,8,3</span>,<span class="hljs-number">7</span>]<br>输出:<span class="hljs-number">49</span> <br>解释:图中垂直线代表输入数组 [<span class="hljs-number">1,8,6,2</span>,<span class="hljs-number">5,4,8,3</span>,<span class="hljs-number">7</span>]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 <span class="hljs-number">49</span>。<br></code></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs arduino">输入:height = [<span class="hljs-number">1</span>,<span class="hljs-number">1</span>]<br>输出:<span class="hljs-number">1</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(一)双指针"><a href="#(一)双指针" class="headerlink" title="(一)双指针"></a>(一)双指针</h3><p>这道题的关键是需要理解装的水容量取决于:1、木板之间的距离、2、短木板的高度。</p><p>如图,Left指针和Right指针分别指向起点和终端:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403292020323.png" alt="image-20240329190613762"></p><p>为什么是移动短板:</p><p>因为随着底部距离的减小,如果移动长板,新板高度大于/小于/等于短板,而容量取决于底部距离 * 短板高度,最终容量只会相等或更小。</p><p>移动短板,直至两个指针相遇,每次计算水的容量,最后取最大容量。</p><p><strong>时间复杂度:</strong>O(n),双指针总计最多遍历整个数组一次。</p><p><strong>空间复杂度:</strong>O(1)</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">maxArea</span>(<span class="hljs-params">self, height</span>):<br> length = <span class="hljs-built_in">len</span>(height)<br> area = <span class="hljs-number">0</span><br> i = <span class="hljs-number">0</span><br> j = length - <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span> i < j:<br> x = j - i<br> y = <span class="hljs-built_in">min</span>(height[i],height[j])<br> area = <span class="hljs-built_in">max</span>(area,x * y)<br> <span class="hljs-keyword">if</span> height[i] <= height[j]:<br> i += <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>:<br> j -= <span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> area<br></code></pre></td></tr></table></figure><h3 id="(二)暴力破解"><a href="#(二)暴力破解" class="headerlink" title="(二)暴力破解"></a>(二)暴力破解</h3><p>双层for循环遍历。</p><p>缺点:非常耗时</p><p><strong>时间复杂度:</strong>O($n^2$) <code>n</code>是数组的长度</p><p><strong>空间复杂度:</strong>O(1)</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><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">maxArea</span>(<span class="hljs-params">self, height</span>):<br> length = <span class="hljs-built_in">len</span>(height)<br> max_area = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(length):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(i+<span class="hljs-number">1</span>,length):<br> x = j - i<br> y = <span class="hljs-built_in">min</span>(height[i],height[j])<br> area = x * y<br> max_area = <span class="hljs-built_in">max</span>(max_area,area)<br> <span class="hljs-keyword">return</span> max_area<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>双指针</tag>
</tags>
</entry>
<entry>
<title>PAT04:福尔摩斯的约会</title>
<link href="/2024/03/27/PAT04/"/>
<url>/2024/03/27/PAT04/</url>
<content type="html"><![CDATA[<h1 id="4-福尔摩斯的约会"><a href="#4-福尔摩斯的约会" class="headerlink" title="4.福尔摩斯的约会"></a>4.福尔摩斯的约会</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p><strong>题目描述</strong></p><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs dts">大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! <span class="hljs-number">3485</span>djDkxh4hhGE <span class="hljs-number">2984</span>akDfkkkkggEdsb s<span class="hljs-variable">&hgsfdk</span> d<span class="hljs-variable">&</span>Hyscvnm”。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间“星期四 <span class="hljs-number">14</span>:<span class="hljs-number">04</span>”,因为前面两字符串中第<span class="hljs-number">1</span>对相同的大写英文字母(大小写有区分)是第<span class="hljs-number">4</span>个字母<span class="hljs-string">'D'</span>,代表星期四;第<span class="hljs-number">2</span>对相同的字符是<span class="hljs-string">'E'</span>,那是第<span class="hljs-number">5</span>个英文字母,代表一天里的第<span class="hljs-number">14</span>个钟头(于是一天的<span class="hljs-number">0</span>点到<span class="hljs-number">23</span>点由数字<span class="hljs-number">0</span>到<span class="hljs-number">9</span>、以及大写字母A到N表示);后面两字符串第<span class="hljs-number">1</span>对相同的英文字母<span class="hljs-string">'s'</span>出现在第<span class="hljs-number">4</span>个位置(从<span class="hljs-number">0</span>开始计数)上,代表第<span class="hljs-number">4</span>分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。 <br>(注:两字符串的比较过程必须按照两字符串中对应的下标相同的字符进行比较!)<br> <br></code></pre></td></tr></table></figure><p><strong>输入描述:</strong></p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">输入在4行中分别给出4个非空、不包含空格、且长度不超过60的字符串。<br></code></pre></td></tr></table></figure><p><strong>输出描述:</strong></p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs arcade">在一行中输出约会的时间,格式为“<span class="hljs-built_in">DAY</span> HH:MM”,其中“<span class="hljs-built_in">DAY</span>”是某星期的<span class="hljs-number">3</span>字符缩写,即MON表示星期一,TUE表示星期二,WED表示星期三,THU表示星期<br>四,FRI表示星期五,SAT表示星期六,SUN表示星期日。题目输入保证每个测试存在唯一解。<br></code></pre></td></tr></table></figure><p><strong>输入例子:</strong></p><figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs 1c"><span class="hljs-number">3485</span>djDkxh4hhGE<br><span class="hljs-number">2984</span>akDfkkkkggEdsb<br>s<span class="hljs-meta">&hgsfdk</span><br>d<span class="hljs-meta">&Hyscvnm</span><br></code></pre></td></tr></table></figure><p><strong>输出例子:</strong></p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">THU</span> <span class="hljs-number">14</span>:<span class="hljs-number">04</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)我的解法"><a href="#(1)我的解法" class="headerlink" title="(1)我的解法"></a>(1)我的解法</h3><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><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><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">dayHour</span>(<span class="hljs-params">str1,str2,min_length</span>):<br> day_flag = <span class="hljs-literal">True</span><br> hour_flag = <span class="hljs-literal">True</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(min_length):<br> m = str1[i]<br> n = str2[i]<br> <span class="hljs-keyword">if</span> m == n:<br> <span class="hljs-keyword">if</span> <span class="hljs-string">'A'</span> <= m <=<span class="hljs-string">'G'</span>:<br> <span class="hljs-keyword">if</span> day_flag:<br> day = m<br> day_flag = <span class="hljs-literal">False</span><br> <span class="hljs-keyword">continue</span><br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> day_flag <span class="hljs-keyword">and</span> hour_flag:<br> <span class="hljs-keyword">if</span> m.isdigit() <span class="hljs-keyword">or</span> <span class="hljs-string">'A'</span><= m <=<span class="hljs-string">'N'</span>:<br> hour = m<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">return</span>(day,hour) <br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">minu</span>(<span class="hljs-params">str1,str2,min_length</span>):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(min_length):<br> m = str1[i]<br> n = str2[i]<br> <span class="hljs-keyword">if</span> m == n <span class="hljs-keyword">and</span> m.isalpha() <span class="hljs-keyword">and</span> n.isalpha():<br> <span class="hljs-keyword">return</span> i<br> <br><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_weekday</span>(<span class="hljs-params">letter</span>):<br> weekdays = {<br> <span class="hljs-string">'A'</span>:<span class="hljs-string">'MON'</span>,<br> <span class="hljs-string">'B'</span>:<span class="hljs-string">'TUE'</span>,<br> <span class="hljs-string">'C'</span>:<span class="hljs-string">'WED'</span>,<br> <span class="hljs-string">'D'</span>:<span class="hljs-string">'THU'</span>,<br> <span class="hljs-string">'E'</span>:<span class="hljs-string">'FRI'</span>,<br> <span class="hljs-string">'F'</span>:<span class="hljs-string">'SAT'</span>,<br> <span class="hljs-string">'G'</span>:<span class="hljs-string">'SUN'</span><br> } <br> <span class="hljs-keyword">return</span> weekdays.get(letter) <br> <br><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_hour</span>(<span class="hljs-params">char</span>):<br> <span class="hljs-keyword">if</span> char.isdigit():<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">int</span>(char)<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">ord</span>(char) - <span class="hljs-built_in">ord</span>(<span class="hljs-string">'A'</span>) + <span class="hljs-number">10</span> <br><br><span class="hljs-built_in">all</span> = []<br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> <span class="hljs-built_in">all</span>.append(line.strip())<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(<span class="hljs-built_in">all</span>) == <span class="hljs-number">4</span>:<br> <span class="hljs-keyword">break</span><br><br>a,b,c,d = <span class="hljs-built_in">map</span>(<span class="hljs-built_in">str</span>,<span class="hljs-built_in">all</span>)<br>one = <span class="hljs-built_in">min</span>(<span class="hljs-built_in">len</span>(a),<span class="hljs-built_in">len</span>(b))<br>two = <span class="hljs-built_in">min</span>(<span class="hljs-built_in">len</span>(c),<span class="hljs-built_in">len</span>(d))<br>re1 = dayHour(a,b,one)<br>re2 = minu(c,d,two)<br>day = get_weekday(re1[<span class="hljs-number">0</span>])<br>hour = get_hour(re1[<span class="hljs-number">1</span>])<br><span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{day}</span> <span class="hljs-subst">{hour:02}</span>:<span class="hljs-subst">{re2:02}</span>"</span>)<br></code></pre></td></tr></table></figure><h3 id="2-其他解法"><a href="#2-其他解法" class="headerlink" title="(2)其他解法"></a>(2)其他解法</h3><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><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># coding: utf-8</span><br>a, b, c, d = <span class="hljs-built_in">input</span>(), <span class="hljs-built_in">input</span>(), <span class="hljs-built_in">input</span>(), <span class="hljs-built_in">input</span>()<br><br>DAY = {<span class="hljs-string">'A'</span>: <span class="hljs-string">'MON'</span>, <span class="hljs-string">'B'</span>: <span class="hljs-string">'TUE'</span>, <span class="hljs-string">'C'</span>: <span class="hljs-string">'WED'</span>, <span class="hljs-string">'D'</span>: <span class="hljs-string">'THU'</span>, <span class="hljs-string">'E'</span>: <span class="hljs-string">'FRI'</span>, <span class="hljs-string">'F'</span>: <span class="hljs-string">'SAT'</span>, <span class="hljs-string">'G'</span>: <span class="hljs-string">'SUN'</span>}<br><br>HH = {<span class="hljs-string">"0"</span>: <span class="hljs-string">"00"</span>, <span class="hljs-string">"1"</span>: <span class="hljs-string">"01"</span>, <span class="hljs-string">"2"</span>: <span class="hljs-string">"02"</span>, <span class="hljs-string">"3"</span>: <span class="hljs-string">"03"</span>, <span class="hljs-string">"4"</span>: <span class="hljs-string">"04"</span>, <span class="hljs-string">"5"</span>: <span class="hljs-string">"05"</span>, <span class="hljs-string">"6"</span>: <span class="hljs-string">"06"</span>, <span class="hljs-string">"7"</span>: <span class="hljs-string">"07"</span>, <span class="hljs-string">"8"</span>: <span class="hljs-string">"08"</span>, <span class="hljs-string">"9"</span>: <span class="hljs-string">"09"</span>,<br> <span class="hljs-string">"A"</span>: <span class="hljs-string">"10"</span>, <span class="hljs-string">"B"</span>: <span class="hljs-string">"11"</span>, <span class="hljs-string">"C"</span>: <span class="hljs-string">"12"</span>, <span class="hljs-string">"D"</span>: <span class="hljs-string">"13"</span>, <span class="hljs-string">"E"</span>: <span class="hljs-string">"14"</span>, <span class="hljs-string">"F"</span>: <span class="hljs-string">"15"</span>, <span class="hljs-string">"G"</span>: <span class="hljs-string">"16"</span>, <span class="hljs-string">"H"</span>: <span class="hljs-string">"17"</span>, <span class="hljs-string">"I"</span>: <span class="hljs-string">"18"</span>, <span class="hljs-string">"J"</span>: <span class="hljs-string">"19"</span>,<br> <span class="hljs-string">"K"</span>: <span class="hljs-string">"20"</span>, <span class="hljs-string">"L"</span>: <span class="hljs-string">"21"</span>, <span class="hljs-string">"M"</span>: <span class="hljs-string">"22"</span>, <span class="hljs-string">"N"</span>: <span class="hljs-string">"23"</span>}<br><br>count = <span class="hljs-number">0</span><br>day = <span class="hljs-string">""</span><br><span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> <span class="hljs-keyword">if</span> a[count] == b[count]:<br> <span class="hljs-keyword">if</span> day != <span class="hljs-string">""</span> <span class="hljs-keyword">and</span> a[count] <span class="hljs-keyword">in</span> HH.keys():<br> hh = a[count]<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">elif</span> (a[count] <span class="hljs-keyword">in</span> DAY.keys()) <span class="hljs-keyword">and</span> (b[count] <span class="hljs-keyword">in</span> DAY.keys()):<br> day = a[count]<br> count += <span class="hljs-number">1</span><br><br>count = <span class="hljs-number">0</span><br>lst_x = <span class="hljs-built_in">range</span>(<span class="hljs-number">97</span>, <span class="hljs-number">123</span>)<br>lst_d = <span class="hljs-built_in">range</span>(<span class="hljs-number">65</span>, <span class="hljs-number">91</span>)<br><br><span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">ord</span>(c[count]) <span class="hljs-keyword">in</span> lst_x <span class="hljs-keyword">or</span> <span class="hljs-built_in">ord</span>(c[count]) <span class="hljs-keyword">in</span> lst_d:<br> <span class="hljs-keyword">if</span> c[count] == d[count]:<br> <span class="hljs-keyword">break</span><br> count += <span class="hljs-number">1</span><br><br><span class="hljs-built_in">print</span>(DAY[day], HH[hh] + <span class="hljs-string">':'</span> + <span class="hljs-string">'%02d'</span> % (count))<br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>判断数字或字母</strong></p><blockquote><p>1、使用ASCII码</p><ul><li>数字的ASCII码范围是 48 到 57</li><li>大写字母的ASCII码范围是 65 到 90</li><li>小写字母的ASCII码范围是 97 到 122</li></ul></blockquote><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-built_in">ord</span>(char) - <span class="hljs-built_in">ord</span>(<span class="hljs-string">'A'</span>) + <span class="hljs-number">10</span> <br><span class="hljs-comment"># 意味着赋A值为10开始</span><br><br><span class="hljs-string">'A'</span> <= m <=<span class="hljs-string">'Z'</span><br><span class="hljs-comment"># 直接判断字母是否在具体的范围</span><br><br>lst_x = <span class="hljs-built_in">range</span>(<span class="hljs-number">97</span>, <span class="hljs-number">123</span>)<br><span class="hljs-keyword">if</span> <span class="hljs-built_in">ord</span>(c[count]) <span class="hljs-keyword">in</span> lst_x <br><span class="hljs-comment"># 这个也是根据ASCII判断</span><br></code></pre></td></tr></table></figure><blockquote><p>2、使用内置函数</p><p>可以使用 <code>isdigit()</code> 方法判断是否为数字,使用 <code>isalpha()</code> 方法判断是否为字母。</p><p><code>isupper()</code> 方法判断是否为大写字母 ,<code>islower()</code> 方法判断是否为小写字母。</p><p>3、使用正则表达式</p></blockquote><p><strong>设置选项返回对应值</strong></p><blockquote><p>先根据对应键值对设置字典,再调用字典的<code>get()</code>方法返回值</p></blockquote><figure class="highlight csharp"><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><code class="hljs csharp"><span class="hljs-function">def <span class="hljs-title">get_weekday</span>(<span class="hljs-params">letter</span>):</span><br><span class="hljs-function"> weekdays</span> = {<br> <span class="hljs-string">'A'</span>:<span class="hljs-string">'MON'</span>,<br> <span class="hljs-string">'B'</span>:<span class="hljs-string">'TUE'</span>,<br> <span class="hljs-string">'C'</span>:<span class="hljs-string">'WED'</span>,<br> <span class="hljs-string">'D'</span>:<span class="hljs-string">'THU'</span>,<br> <span class="hljs-string">'E'</span>:<span class="hljs-string">'FRI'</span>,<br> <span class="hljs-string">'F'</span>:<span class="hljs-string">'SAT'</span>,<br> <span class="hljs-string">'G'</span>:<span class="hljs-string">'SUN'</span><br> } <br> <span class="hljs-keyword">return</span> weekdays.<span class="hljs-keyword">get</span>(letter) <br></code></pre></td></tr></table></figure><blockquote><p>要判断选项是否在选项里:</p></blockquote><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver"><span class="hljs-keyword">if</span> x <span class="hljs-keyword">in</span> one_dict.<span class="hljs-built_in">keys</span>()<br></code></pre></td></tr></table></figure><p><strong>字符串格式化</strong></p><figure class="highlight gcode"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gcode"><span class="hljs-string">'%02d'</span> <span class="hljs-meta">%</span> <span class="hljs-comment">(count)</span><br></code></pre></td></tr></table></figure><blockquote><ul><li><code>'%02d'</code>:这是一个格式化字符串,其中:<ul><li><code>%d</code> 表示将后面的变量作为整数进行格式化输出。</li><li><code>0</code> 表示在数字前面补0,如果数字不够两位数的话。</li><li><code>2</code> 表示最少输出的字符数为2位。如果不足两位,则在前面补0。</li></ul></li></ul></blockquote><blockquote><ul><li><code>% (count)</code>: 这里的 <code>count</code> 是一个变量,将会填充到前面定义的格式化字符串中。在这个例子中,<code>count</code> 是一个整数类型的变量。</li></ul></blockquote><p><code>{hour:02}</code> 的作用也是将 <code>hour</code> 变量格式化为两位数的整数,不足两位时在前面补0;</p>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>字典</tag>
</tags>
</entry>
<entry>
<title>【机器学习算法】10种常见机器学习算法</title>
<link href="/2024/03/26/%E3%80%90%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95%E3%80%9110%E7%A7%8D%E5%B8%B8%E8%A7%81%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95/"/>
<url>/2024/03/26/%E3%80%90%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95%E3%80%9110%E7%A7%8D%E5%B8%B8%E8%A7%81%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95/</url>
<content type="html"><![CDATA[<h1 id="【机器学习算法】10种常见机器学习算法"><a href="#【机器学习算法】10种常见机器学习算法" class="headerlink" title="【机器学习算法】10种常见机器学习算法"></a>【机器学习算法】10种常见机器学习算法</h1><p>一般来说,机器学习主要有三种算法:</p><ul><li><p><strong>1. 监督式学习 — 训练要指定输出标签</strong></p><p>监督式学习算法包括一个目标变量(因变量)和用来预测目标变量的预测变量(自变量)。通过这些变量我们可以搭建一个模型,从而对于一个已知的<strong>预测变量值</strong>,我们可以得到对应的<strong>目标变量值</strong>。重复训练这个模型,直到它能在训练数据集上达到预定的准确度。</p><p>监督式学习是一种机器学习的方法,其中模型从标记的训练数据中学习输入和输出之间的映射关系。在监督式学习中,训练数据包括输入数据和对应的输出标签,模型通过学习这些数据来预测新的、之前未见过的数据。</p><p>属于监督式学习的算法有:<strong>支持向量机(SVM),回归模型,决策树,随机森林,K邻近算法,逻辑回归</strong>等。这种方法通常用于分类和回归问题。</p></li><li><p><strong>2. 无监督式学习 — 数据不标记</strong></p><p>与监督式学习不同的是,无监督学习中我们没有需要预测或估计的目标变量。无监督式学习是用来对总体对象进行分类的。它在根据某一指标将客户分类上有广泛应用。</p><p>无监督式学习是一种机器学习的方法,其中<strong>模型从未标记的数据中学习模式和结构,而无需指定输出标签</strong>。在无监督式学习中,算法试图发现数据中的隐藏结构或模式,以便对数据进行分类、聚类或降维等操作。</p><p>属于无监督式学习的算法有:<strong>关联规则,K-means聚类算法,主成分分析(PCA)</strong>等。这种方法通常用于发现数据中的潜在模式和关系,而无需预先标记的输出。</p></li><li><p><strong>3. 强化学习 — 智能体与环境互动</strong></p><p>这个算法可以训练程序做出某一决定。程序在某一情况下尝试所有的可能行动,记录不同行动的结果并试着找出最好的一次尝试来做决定。</p><p>强化学习是一种机器学习方法,其目标是让智能体在与环境互动的过程中学习如何做出决策,以使得长期收益最大化。<strong>在强化学习中,智能体通过尝试不同的行为,并观察环境对其行为的反馈来学习。</strong>这种学习方式类似于试错的过程,通过与环境的交互,智能体逐渐学会采取哪些行动以获得最大的奖励。</p><p>强化学习通常涉及定义一个奖励信号,以便智能体可以根据其行为的好坏进行学习。常见的强化学习算法包括<strong>马尔可夫决策过程、Q学习、深度强化学习(DRL)</strong>等。强化学习在许多领域都有应用,如机器人控制、游戏策略、金融交易等。</p></li></ul><h2 id="常见的机器学习算法"><a href="#常见的机器学习算法" class="headerlink" title="常见的机器学习算法"></a>常见的机器学习算法</h2><p>以下是最常用的机器学习算法,大部分数据问题都可以通过它们解决:</p><h3 id="1-线性回归-Linear-Regression"><a href="#1-线性回归-Linear-Regression" class="headerlink" title="1.线性回归 (Linear Regression)"></a>1.线性回归 (Linear Regression)</h3><h4 id="定义:y-ax-b"><a href="#定义:y-ax-b" class="headerlink" title="定义:y=ax+b"></a>定义:y=ax+b</h4><p>线性回归是利用连续性变量来估计实际数值(例如房价,呼叫次数和总销售额等)。我们通过线性回归算法找出自变量和因变量间的最佳线性关系,图形上可以确定一条最佳直线。这条最佳直线就是回归线。这个回归关系可以用Y=aX+b 表示。</p><p>我们可以假想一个场景来理解线性回归。比如你让一个五年级的孩子在不问同学具体体重多少的情况下,把班上的同学按照体重从轻到重排队。这个孩子会怎么做呢?他有可能会通过观察大家的身高和体格来排队。这就是线性回归!这个孩子其实是认为身高和体格与人的体重有某种相关。而这个关系就像是前一段的Y和X的关系。</p><p>在Y=aX+b这个公式里:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs text">Y- 因变量<br>a- 斜率<br>X- 自变量<br>b- 截距<br></code></pre></td></tr></table></figure><h4 id="求a和b:最小二乘法"><a href="#求a和b:最小二乘法" class="headerlink" title="求a和b:最小二乘法"></a>求a和b:最小二乘法</h4><p>a和b可以通过最小化因变量误差的平方和得到(<strong>最小二乘法</strong>)。</p><p>我们可以使用最小二乘法来估计参数 a 和 b。具体步骤如下:</p><blockquote><ol><li>计算<strong>每个样本点到直线的垂直距离,即残差</strong>,表示为 e<del>i</del> = y<del>i</del> - (ax<del>i</del> + b),其中 (x<del>i</del>, y<del>i</del>) 为第 i 个样本点的坐标。</li><li>我们的目标是<strong>最小化所有残差的平方和,</strong>即最小化 S = Σ(e<del>i</del>^2^),其中 i 从 1 到 n,n 为样本点数。</li><li>为了找到最小化 S 的参数 a 和 b,我们对 S 分别关于 a 和 b 求导,然后令导数等于 0,从而得到关于 a 和 b 的方程组。</li><li>解这个方程组,即可得到最优的参数估计值 a 和 b,使得线性回归模型 y = ax + b 最优地拟合了观测数据。<br>这样得到的参数估计值 a 和 b,就是使得模型与观测数据拟合最好的直线的斜率和截距。</li></ol></blockquote><h4 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h4><p>下图中我们得到的线性回归方程是 y=0.2811X+13.9。通过这个方程,我们可以根据一个人的身高得到他的体重信息。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707932.png" alt="image-20240325210438846"></p><h4 id="根据自变量个数分为:一元-多元"><a href="#根据自变量个数分为:一元-多元" class="headerlink" title="根据自变量个数分为:一元 / 多元"></a>根据自变量个数分为:一元 / 多元</h4><p>线性回归主要有两种:一元线性回归和多元线性回归。</p><p>一元线性回归只有一个自变量,而多元线性回归有多个自变量。</p><p>拟合多元线性回归的时候,可以利用<strong>多项式回归(Polynomial Regression)</strong>或**曲线回归 (Curvilinear Regression)**。</p><blockquote><ol><li><strong>多项式回归</strong>:多项式回归是一种线性回归的扩展,通过引入自变量的高次项来拟合非线性关系。例如,对于一个简单的二次多项式回归模型 y = a0 + a1<em>x + a2</em>x^2^,这样的模型可以拟合出曲线关系。通过选择合适的多项式次数,可以更好地拟合数据,并捕捉到数据中的非线性关系。</li><li><strong>曲线回归</strong>:曲线回归是一种更加灵活的回归方法,可以拟合各种形状的曲线,而不局限于多项式的形式。曲线回归可以采用不同的函数形式,比如指数函数、对数函数、幂函数等,来拟合数据中的非线性关系。通过选择适当的函数形式,曲线回归可以更好地拟合具有复杂形态的数据。</li></ol></blockquote><h4 id="python代码"><a href="#python代码" class="headerlink" title="python代码"></a>python代码</h4><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><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#导入库</span><br><span class="hljs-comment">#导入其他必要的库,如pandas、numpy等</span><br><span class="hljs-keyword">from</span> sklearn <span class="hljs-keyword">import</span> linear_model<br><br><span class="hljs-comment">#加载训练和测试数据集</span><br><span class="hljs-comment">#确定特征和响应变量,并确保它们是数字类型和numpy数组</span><br>x_train = 训练数据集中的自变量数值<br>y_train = 训练数据集中的目标变量数值<br>x_test = 测试数据集中的自变量数值<br><br><span class="hljs-comment">#创建线性回归对象</span><br>linear = linear_model.LinearRegression()<br><br><span class="hljs-comment">#使用训练集训练模型并检查得分</span><br>linear.fit(x_train, y_train) <span class="hljs-comment"># 利用训练数据来拟合/训练线性回归模型</span><br>linear.score(x_train, y_train) <span class="hljs-comment"># 返回拟合性的度量,即确定系数。确定系数是衡量因变量的变化有多少百分比可以由自变量的变化来解释。范围在 0 到 1 之间,越接近 1 表示模型拟合得越好。</span><br><br><span class="hljs-comment">#方程系数(斜率)和截距</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'系数: \n'</span>, linear.coef_)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">'截距: \n'</span>, linear.intercept_)<br><br><span class="hljs-comment">#预测输出</span><br>predicted = linear.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="2-逻辑回归-Logistic-Regression"><a href="#2-逻辑回归-Logistic-Regression" class="headerlink" title="2.逻辑回归 (Logistic Regression)"></a>2.逻辑回归 (Logistic Regression)</h3><h4 id="定义:是分类算法!预测概率值!"><a href="#定义:是分类算法!预测概率值!" class="headerlink" title="定义:是分类算法!预测概率值!"></a>定义:是分类算法!预测概率值!</h4><p>别被它的名字迷惑了,逻辑回归其实是一个分类算法而不是回归算法。通常是利用已知的自变量来预测一个离散型因变量的值(像二进制值0/1,是/否,真/假)。简单来说,它就是通过拟合一个逻辑函数(logit fuction)来<strong>预测一个事件发生的概率</strong>。所以它预测的是一个概率值,自然,它的输出值应该在0到1之间,表示样本属于某一类的概率。通常情况下,我们可以将输出值大于等于0.5的样本预测为正类(1),将输出值小于0.5的样本预测为负类(0)。</p><h4 id="示例-1"><a href="#示例-1" class="headerlink" title="示例"></a>示例</h4><p>同样,我们可以用一个例子来理解这个算法。</p><p>假设你的一个朋友让你回答一道题。可能的结果只有两种:你答对了或没有答对。为了研究你最擅长的题目领域,你做了各种领域的题目。那么这个研究的结果可能是这样的:如果是一道十年级的三角函数题,你有70%的可能性能解出它。但如果是一道五年级的历史题,你会的概率可能只有30%。逻辑回归就是给你这样的概率结果。</p><p>回到数学上,事件结果的胜算对数(log odds)可以用预测变量的线性组合来描述:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs text">odds几率= p/ (1-p) = 事件发生的概率 / 事件不发生的概率<br>ln(odds) = ln(p/(1-p))<br>logit(p) = ln(p/(1-p)) = b0+b1X1+b2X2+b3X3....+bkXk<br></code></pre></td></tr></table></figure><p>在这里,p 是我们感兴趣的事件出现的概率。它通过筛选出特定参数值使得观察到的样本值出现的概率最大化,来估计参数,而不是像普通回归那样最小化误差的平方和。logistic回归主要关注的是事件发生的概率,通过最大化观测样本的概率来确定参数,以便更好地预测事件的发生与否,而不是直接预测具体数值。这种方法对于处理二元分类问题非常有效。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707893.png" alt="image-20240325215838298"></p><h4 id="python代码-1"><a href="#python代码-1" class="headerlink" title="python代码"></a>python代码</h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn.linear_model <span class="hljs-keyword">import</span> LogisticRegression<br><br><span class="hljs-comment"># 假设你有训练数据集的 X(预测变量)和 Y(目标变量),以及测试数据集的 x_test(预测变量)</span><br><br><span class="hljs-comment"># 创建 logistic 回归对象</span><br>model = LogisticRegression()<br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br>model.fit(X, y)<br>model.score(X, y)<br><br><span class="hljs-comment"># 方程系数和截距</span><br><span class="hljs-comment"># 系数表示特征对目标变量的影响程度,而截距则代表了在没有任何特征影响时的基准值或偏移量。</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'系数: \n'</span>, model.coef_)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">'截距: \n'</span>, model.intercept_)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h4 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h4><p><strong>延伸</strong>:</p><p>以下是一些可以尝试的优化模型的方法:</p><ul><li><p>加入交互项(interaction)</p><blockquote><p>通过添加特征之间的交互项,可以捕获特征之间的复杂关系,从而提高模型的表现。例如,如果有两个特征 x1 和 x2,可以添加一个新的特征 x1*x2 作为交互项。</p></blockquote></li><li><p>减少特征变量</p><blockquote><p>通过特征选择技术,可以剔除对模型预测贡献较小的特征,从而简化模型并提高泛化能力。常用的特征选择方法包括方差选择、单变量特征选择、递归特征消除等。</p></blockquote></li><li><p>正则化(<a href="https://link.zhihu.com/?target=http://www.analyticsvidhya.com/blog/2015/02/avoid-over-fitting-regularization/">regularization</a>)</p><blockquote><p>正则化通过在损失函数中加入惩罚项,可以有效控制模型的复杂度,防止过拟合。常见的正则化方法包括 L1 正则化(Lasso)和 L2 正则化(Ridge)。</p></blockquote></li><li><p>使用非线性模型</p><blockquote><p>对于非线性关系较为复杂的数据,可以尝试使用非线性模型,如支持向量机(SVM)、决策树、随机森林、神经网络等,以更好地拟合数据的非线性结构。</p></blockquote></li></ul><h3 id="3-决策树-Decision-Tree"><a href="#3-决策树-Decision-Tree" class="headerlink" title="3.决策树 (Decision Tree)"></a>3.决策树 (Decision Tree)</h3><h4 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h4><p>这是经常使用到的算法。它属于监督式学习,常用来解决分类问题。令人惊讶的是,它既可以运用于类别变量(categorical variables)也可以作用于连续变量。在决策树中,每个内部节点表示一个特征或属性上的测试,每个分支代表一个测试输出,每个叶节点代表一个类别标签(或者在回归任务中代表一个数值)。通过沿着从根节点到叶节点的路径进行测试,最终可以得出针对给定输入实例的预测结果。</p><p>常见的决策树算法包括:ID3、C4.5、CART(Classification And Regression Trees)等。在构建决策树时,算法会根据各种特征的信息增益(或其他指标)来选择合适的特征,并递归地划分数据集,直到达到停止条件为止(如节点包含的样本属于同一类别)。</p><h4 id="示例-2"><a href="#示例-2" class="headerlink" title="示例"></a>示例</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707887.png" alt="image-20240325221749440"></p><p>从上图中我们可以看出,总体人群最终在玩与否的事件上被分成了四个群组。而分组是依据一些特征变量实现的。用来分组的具体指标有很多,比如基尼系数(Gini)、信息增益(Information Gain)、卡方检验(Chi-square)、熵(Entropy)等。</p><p>基尼系数衡量了数据集的不纯度,信息增益衡量了使用某个特征进行分类后带来的纯度提升,卡方检验用于检测特征与类别之间的关联程度,熵衡量了信息的混乱程度。通过这些指标,决策树算法可以选择最优的特征来进行分裂,从而构建出有效的决策树模型。</p><p>理解决策树原理的最好的办法就是玩Jezzball游戏。这是微软的一款经典游戏(见下图)。这个游戏的最终任务是在一个有移动墙壁的房间里,通过建造墙壁来尽可能地将房间分成尽量大的,没有小球的空间。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707899.png" alt="image-20240325222118822"></p><p>每一次你用建墙来分割房间,其实就是在将一个总体分成两部分。决策树也是用类似方法将总体分成尽量多的不同组别。</p><h4 id="python代码-2"><a href="#python代码-2" class="headerlink" title="python代码"></a>python代码</h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-comment"># 导入其他必要的库,如pandas、numpy等...</span><br><br><span class="hljs-keyword">from</span> sklearn <span class="hljs-keyword">import</span> tree<br><span class="hljs-comment"># 假设你已经有了训练数据集的预测变量 X 和目标变量 Y,以及测试数据集的预测变量 x_test</span><br><br><span class="hljs-comment"># 创建决策树对象</span><br>model = tree.DecisionTreeClassifier(criterion=<span class="hljs-string">'gini'</span>) <span class="hljs-comment"># 用于分类,这里你可以根据需求选择算法为基尼系数(gini)或熵(信息增益),默认为基尼系数</span><br><br><span class="hljs-comment"># model = tree.DecisionTreeRegressor() # 用于回归 与分类器不同,回归树的目标是预测连续型变量而不是离散的类别标签。</span><br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br>model.fit(X, y)<br>model.score(X, y)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="4-支持向量机(SVM)"><a href="#4-支持向量机(SVM)" class="headerlink" title="4.支持向量机(SVM)"></a>4.支持向量机(SVM)</h3><h4 id="定义-1"><a href="#定义-1" class="headerlink" title="定义"></a>定义</h4><p>这是一个分类算法。在这个算法中我们将每一个数据作为一个点在一个n维空间上作图(n是特征数),每一个特征值就代表对应坐标值的大小。比如说我们有两个特征:一个人的身高和发长。我们可以将这两个变量在一个二维空间上作图,图上的每个点都有两个坐标值(这些坐标轴也叫做支持向量)。</p><p>支持向量机(Support Vector Machine,SVM)是一种用于分类和回归分析的监督学习模型。其主要思想是找到一个最优的超平面来对数据进行分类或回归,使得两个类别之间的间隔最大化。</p><h4 id="示例-3"><a href="#示例-3" class="headerlink" title="示例"></a>示例</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707841.png" alt="image-20240326162316858"></p><p>现在我们要在图中找到一条直线能最大程度将不同组的点分开。两组数据中距离这条线最近的点到这条线的距离都应该是最远的。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707902.png" alt="image-20240326162414749"></p><p>在上图中,黑色的线就是最佳分割线。因为这条线到两组中距它最近的点,点A和B的距离都是最远的。任何其他线必然会使得到其中一个点的距离比这个距离近。这样根据数据点分布在这条线的哪一边,我们就可以将数据归类。</p><p>我们可以把这个算法想成n维空间里的JezzBall游戏,不过有一些变动:</p><ol><li><p>你可以以任何角度画分割线/分割面(经典游戏中只有垂直和水平方向)。</p></li><li><p>现在这个游戏的目的是把不同颜色的小球分到不同空间里。</p></li><li><p>小球是不动的。</p></li></ol><h4 id="python代码-3"><a href="#python代码-3" class="headerlink" title="python代码"></a>python代码</h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn <span class="hljs-keyword">import</span> svm<br><br><span class="hljs-comment"># 假设你已经有了训练数据集的预测变量 X 和目标变量 Y,以及测试数据集的预测变量 x_test</span><br><br><span class="hljs-comment"># 创建 SVM 分类对象</span><br>model = svm.SVC() <span class="hljs-comment"># 这里有各种选项可供选择,这只是一个简单的分类示例。你可以参考链接获取更多详细信息。</span><br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br>model.fit(X, y)<br>model.score(X, y)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="5-朴素贝叶斯-Naive-Bayes"><a href="#5-朴素贝叶斯-Naive-Bayes" class="headerlink" title="5.朴素贝叶斯 (Naive Bayes)"></a>5.朴素贝叶斯 (Naive Bayes)</h3><h4 id="定义-2"><a href="#定义-2" class="headerlink" title="定义"></a>定义</h4><p>这个算法是建立在贝叶斯理论上的分类方法。<strong>它的假设条件是自变量之间相互独立。</strong>简言之,朴素贝叶斯假定某一特征的出现与其它特征无关。比如说,如果一个水果它是红色的,圆状的,直径大概7cm左右,我们可能猜测它为苹果。即使这些特征之间存在一定关系,在朴素贝叶斯算法中我们都认为红色,圆状和直径在判断一个水果是苹果的可能性上是相互独立的。</p><p>朴素贝叶斯的模型易于建造,并且在分析大量数据问题时效率很高。虽然模型简单,但很多情况下工作得比非常复杂的分类方法还要好。</p><h4 id="数学理论"><a href="#数学理论" class="headerlink" title="数学理论"></a>数学理论</h4><p>贝叶斯理论告诉我们如何从先验概率P(c),P(x)和条件概率P(x|c)中计算后验概率P(c|x)。</p><blockquote><p>在贝叶斯理论中,P(c) 代表的是先验概率,表示在考虑任何新证据之前对事件 c 发生的信念。换句话说,它是基于以往经验和先前已知信息得出的事件 c 的概率。</p><p>P(x) 则代表边缘似然度(marginal likelihood),也称为证据(evidence),表示在所有可能的类别下观察到数据 x 的概率。这通常是一个归一化因子,用于确保后验概率的总和为1。</p><p>P(x|c) 是条件概率,表示在给定类别 c 下观察到数据 x 的概率。它衡量了特征 x 对于类别 c 的贡献程度。</p><p>有了这些概率,我们可以使用贝叶斯公式计算后验概率 P(c|x),即在观察到数据 x 后,关于类别 c 的新信念。具体来说,后验概率告诉了我们在观察到数据 x 之后,事件 c 发生的概率。</p><hr><p>P(c|x)是已知特征x而分类为c的后验概率。</p><p>P(c)是种类c的先验概率。</p><p>P(x|c)是种类c具有特征x的可能性。</p><p>P(x)是特征x的先验概率。</p></blockquote><p>算法如下:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707457.png" alt="image-20240326163149235"></p><h4 id="示例-4"><a href="#示例-4" class="headerlink" title="示例"></a>示例</h4><p>例子: 以下这组训练集包括了天气变量和目标变量“是否出去玩”。我们现在需要根据天气情况将人们分为两组:玩或不玩。整个过程按照如下步骤进行:</p><p>步骤1:根据已知数据做频率表</p><p>步骤2:计算各个情况的概率制作概率表。</p><p>比如阴天(Overcast)的概率为0.29,此时玩的概率为0.64.</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707623.png" alt="image-20240326163518892"></p><p>步骤3:用朴素贝叶斯计算每种天气情况下玩和不玩的后验概率。概率大的结果为预测值。</p><p>提问: 天气晴朗的情况下(sunny),人们会玩。这句陈述是否正确?</p><p>我们可以用上述方法回答这个问题。P(Yes | Sunny)=P(Sunny | Yes) * P(Yes) / P(Sunny)。</p><p>这里,P(Sunny |Yes) = 3/9 = 0.33, P(Sunny) = 5/14 = 0.36, P(Yes)= 9/14 = 0.64。</p><p>那么,P (Yes | Sunny) = 0.33 * 0.64 / 0.36 = 0.60>0.5,说明这个概率值更大。</p><p>当有多种类别和多种特征时,预测的方法相似。朴素贝叶斯通常用于文本分类和多类别分类问题。</p><h4 id="python代码-4"><a href="#python代码-4" class="headerlink" title="python代码"></a>python代码</h4><figure class="highlight stan"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs stan"><span class="hljs-comment"># 导入库</span><br>from sklearn.naive_bayes import GaussianNB<br><span class="hljs-comment"># 假设你有训练数据集的 X(特征)和 Y(目标),以及测试数据集的 x_test(特征)</span><br><br><span class="hljs-comment"># 创建高斯朴素贝叶斯分类器对象</span><br><span class="hljs-title">model</span> = GaussianNB() <span class="hljs-comment"># 还有其他分布用于多项分类,比如伯努利朴素贝叶斯,请参考链接</span><br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br><span class="hljs-title">model</span>.fit(X, y)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = <span class="hljs-title">model</span>.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="6-K邻近算法(KNN)"><a href="#6-K邻近算法(KNN)" class="headerlink" title="6.K邻近算法(KNN)"></a>6.K邻近算法(KNN)</h3><h4 id="定义-3"><a href="#定义-3" class="headerlink" title="定义"></a>定义</h4><p>这个算法既可以解决分类问题,也可以用于回归问题,但工业上用于分类的情况更多。 KNN先记录所有已知数据,再利用一个距离函数,找出已知数据中距离未知事件最近的K组数据,最后按照这K组数据里最常见的类别预测该事件。</p><p>距离函数可以是欧式距离,曼哈顿距离,闵氏距离 (Minkowski Distance), 和汉明距离(Hamming Distance)。前三种用于连续变量,汉明距离用于分类变量。如果K=1,那问题就简化为根据最近的数据分类。K值的选取时常是KNN建模里的关键。</p><h4 id="示例-5"><a href="#示例-5" class="headerlink" title="示例"></a>示例</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707561.png" alt="image-20240326164050505"></p><p>KNN在生活中的运用很多。比如,如果你想了解一个不认识的人,你可能就会从这个人的好朋友和圈子中了解他的信息。</p><p>在用KNN前你需要考虑到:</p><p>(1) KNN的计算成本很高</p><p>(2) 所有特征应该标准化数量级,否则数量级大的特征在计算距离上会有偏移。</p><p>(3) 在进行KNN前预处理数据,例如去除异常值,噪音等。</p><h4 id="python代码-5"><a href="#python代码-5" class="headerlink" title="python代码"></a>python代码</h4><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><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn.neighbors <span class="hljs-keyword">import</span> KNeighborsClassifier<br><br><span class="hljs-comment"># 假设你有训练数据集的 X(特征)和 Y(目标),以及测试数据集的 x_test(特征)</span><br><span class="hljs-comment"># 创建 K 近邻分类器对象</span><br>model = KNeighborsClassifier(n_neighbors=<span class="hljs-number">6</span>) <span class="hljs-comment"># n_neighbors 默认值为 5</span><br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br>model.fit(X, y)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="7-K-均值算法(K-means)"><a href="#7-K-均值算法(K-means)" class="headerlink" title="7.K-均值算法(K-means)"></a>7.K-均值算法(K-means)</h3><h4 id="定义-4"><a href="#定义-4" class="headerlink" title="定义"></a>定义</h4><p>这是一种解决聚类问题的非监督式学习算法。这个方法简单地利用了一定数量的集群(假设K个集群)对给定数据进行分类。同一集群内的数据点是同类的,不同集群的数据点不同类。</p><p>具体来说,K均值算法的工作流程如下:</p><ol><li>随机选择 K 个数据点作为初始的聚类中心。</li><li>将数据集中的每个数据点分配到距离其最近的聚类中心所在的组。</li><li>计算每个组的新中心,即取该组内所有数据点的平均值作为新的聚类中心。</li><li>重复步骤2和3,直到聚类中心不再发生变化或者达到预定的迭代次数。</li></ol><p>K均值算法适用于特征空间中的实例点,且需要事先确定要分成的簇数 K。这个算法简单易懂,计算效率高,因此被广泛应用于图像分割、文档分类、市场分析等领域。但是,K均值算法也有一些局限性,比如对初始聚类中心的选择敏感,对异常值敏感等。</p><h4 id="示例-6"><a href="#示例-6" class="headerlink" title="示例"></a>示例</h4><p>还记得你是怎样从墨水渍中辨认形状的么?K均值算法的过程类似,你也要通过观察集群形状和分布来判断集群数量!</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707468.png" alt="image-20240326164450301"></p><blockquote><p><strong>K均值算法如何划分集群:</strong></p><ol><li><p>从每个集群中选取K个数据点作为质心(centroids)。</p></li><li><p>将每一个数据点与距离自己最近的质心划分在同一集群,即生成K个新集群。</p></li><li><p>找出新集群的质心,这样就有了新的质心。</p></li><li><p>重复2和3,直到结果收敛,即不再有新的质心出现。</p></li></ol></blockquote><h4 id="确定K值"><a href="#确定K值" class="headerlink" title="确定K值"></a>确定K值</h4><p>如果我们在每个集群中计算集群中所有点到质心的距离平方和,再将不同集群的距离平方和相加,我们就得到了这个集群方案的总平方和。</p><p>我们知道,随着集群数量的增加,总平方和会减少。但是如果用总平方和对K作图,你会发现在某个K值之前总平方和急速减少,但在这个K值之后减少的幅度大大降低,这个值就是最佳的集群数。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403261707567.png" alt="image-20240326164651996"></p><h4 id="python代码-6"><a href="#python代码-6" class="headerlink" title="python代码"></a>python代码</h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn.cluster <span class="hljs-keyword">import</span> KMeans<br><br><span class="hljs-comment"># 假设你有训练数据集的属性 X 和测试数据集的属性 x_test</span><br><span class="hljs-comment"># 创建 KMeans 分类器对象 model</span><br>model = KMeans(n_clusters=<span class="hljs-number">3</span>, random_state=<span class="hljs-number">0</span>)<br><span class="hljs-comment"># 通过固定随机种子,我们可以确保每次运行算法时使用相同的随机数序列,从而保证初始点的选择是确定的,使得实验结果具有可重复性。</span><br><br><span class="hljs-comment"># 使用训练集训练模型并检查得分</span><br>model.fit(X)<br><br><span class="hljs-comment"># 预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="8-随机森林-Random-Forest"><a href="#8-随机森林-Random-Forest" class="headerlink" title="8.随机森林 (Random Forest)"></a>8.随机森林 (Random Forest)</h3><h4 id="定义-5"><a href="#定义-5" class="headerlink" title="定义"></a>定义</h4><p>随机森林是对决策树集合的特有名称。随机森林里我们有多个决策树(所以叫“森林”)。为了给一个新的观察值分类,根据它的特征,每一个决策树都会给出一个分类。随机森林算法选出投票最多的分类作为分类结果。</p><p>“随机”体现在两个地方:</p><ol><li>数据的随机性:每棵树只看一部分数据来学习,而不是全部数据。</li><li>特征的随机性:每棵树只看数据中的一部分特征来学习,而不是全部特征。</li></ol><h4 id="怎么生成随机数"><a href="#怎么生成随机数" class="headerlink" title="怎么生成随机数?"></a>怎么生成随机数?</h4><ol><li><p>如果训练集中有N种类别,则有重复地随机选取N个样本。这些样本将组成培养决策树的训练集。</p></li><li><p>如果有M个特征变量,那么选取数m << M,从而在每个节点上随机选取m个特征变量来分割该节点。m在整个森林养成中保持不变。</p></li><li><p>每个决策树都最大程度上进行分割,没有剪枝。</p></li></ol><h4 id="python代码-7"><a href="#python代码-7" class="headerlink" title="python代码"></a>python代码</h4><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><code class="hljs python"><span class="hljs-comment">#导入库</span><br><span class="hljs-keyword">from</span> sklearn.ensemble <span class="hljs-keyword">import</span> RandomForestClassifier<br><span class="hljs-comment">#假设你有训练数据集的特征X和目标值Y,以及测试数据集的特征x_test</span><br><br><span class="hljs-comment">#创建随机森林对象</span><br>model = RandomForestClassifier()<br><br><span class="hljs-comment">#使用训练集训练模型并检查得分</span><br>model.fit(X, y)<br><br><span class="hljs-comment">#预测输出</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure><h3 id="9-降低维度算法(Dimensionality-Reduction-Algorithms)"><a href="#9-降低维度算法(Dimensionality-Reduction-Algorithms)" class="headerlink" title="9.降低维度算法(Dimensionality Reduction Algorithms)"></a>9.降低维度算法(Dimensionality Reduction Algorithms)</h3><h4 id="定义-6"><a href="#定义-6" class="headerlink" title="定义"></a>定义</h4><p>降低维度是指通过保留数据集中最重要的信息来减少特征或变量的数量,从而简化模型并提高计算效率。</p><p>在过去的4-5年里,可获取的数据几乎以指数形式增长。公司/政府机构/研究组织不仅有了更多的数据来源,也获得了更多维度的数据信息。</p><p>例如:电子商务公司有了顾客更多的细节信息,像个人信息,网络浏览历史,个人喜恶,购买记录,反馈信息等,他们关注你的私人特征,比你天天去的超市里的店员更了解你。</p><p>作为一名数据科学家,我们手上的数据有非常多的特征。虽然这听起来有利于建立更强大精准的模型,但它们有时候反倒也是建模中的一大难题。怎样才能从1000或2000个变量里找到最重要的变量呢?这种情况下降维算法及其他算法,如决策树,随机森林,PCA,因子分析,相关矩阵,和缺省值比例等,就能帮我们解决难题。</p><h4 id="python代码-8"><a href="#python代码-8" class="headerlink" title="python代码"></a>python代码</h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn <span class="hljs-keyword">import</span> decomposition<br><br><span class="hljs-comment"># 假设你有训练数据集和测试数据集,命名为train和test</span><br><span class="hljs-comment"># 创建PCA对象</span><br>pca = decomposition.PCA(n_components=k) <span class="hljs-comment"># 默认值 k = min(n_sample, n_features)</span><br><span class="hljs-comment"># 这行代码的含义是创建一个PCA(Principal Component Analysis,主成分分析)对象,并指定降维后的维度数量为 k。在这里,k 是一个参数,表示要将数据降维到的目标维度数量。通常情况下,k 的取值是小于或等于原始数据集中的样本数和特征数中较小的那个值。如果不指定 n_components 参数,则默认会保留所有的主成分(特征)。</span><br><br><span class="hljs-comment"># 对训练数据集进行降维处理</span><br>train_reduced = pca.fit_transform(train)<br><br><span class="hljs-comment"># 对测试数据集进行降维处理</span><br>test_reduced = pca.transform(test)<br></code></pre></td></tr></table></figure><h3 id="10-Gradient-Boost和Adaboost算法"><a href="#10-Gradient-Boost和Adaboost算法" class="headerlink" title="10.Gradient Boost和Adaboost算法"></a>10.Gradient Boost和Adaboost算法</h3><h4 id="定义-7"><a href="#定义-7" class="headerlink" title="定义"></a>定义</h4><p>GBM和AdaBoost都是在有大量数据时提高预测准确度的boosting算法。Boosting是一种集成学习方法。它通过有序结合多个较弱的分类器/估测器的估计结果来提高预测准确度。这些boosting算法在Kaggle,AV Hackthon, CrowdAnalytix等数据科学竞赛中有出色发挥。</p><ol><li><strong>AdaBoost(Adaptive Boosting)</strong>:<ul><li>AdaBoost 通过反复训练弱分类器(通常是决策树桩)来提升整体模型性能。</li><li>在每一轮训练中,它会调整样本的权重,使得之前被错误分类的样本在后续训练中获得更高的权重,以便下一轮能够更关注错分的样本。</li><li>最终的分类器是将所有弱分类器加权组合而成的强分类器。</li></ul></li><li><strong>Gradient Boosting</strong>:<ul><li>Gradient Boosting 通过迭代地训练决策树(或其他基本模型),每次训练的目标是减小上一轮的残差(预测值与实际值的差)。</li><li>在每一轮迭代中,通过梯度下降的方式优化损失函数,使得模型在训练集上拟合得更好。</li><li>最终的模型是将所有基本模型的预测结果加和而得到的。</li></ul></li></ol><h4 id="主要区别"><a href="#主要区别" class="headerlink" title="主要区别"></a>主要区别</h4><p>主要区别:</p><ul><li><p>AdaBoost 的核心思想是调整样本的权重来重点关注错分的样本,而 Gradient Boosting 通过迭代优化残差来不断改进模型。</p></li><li><p>AdaBoost 每一轮训练都会调整样本的权重,可能会造成过拟合;而 Gradient Boosting 则通过加入正则化项来控制模型的复杂度,更容易防止过拟合。</p></li></ul><h4 id="python代码-9"><a href="#python代码-9" class="headerlink" title="python代码"></a>python代码</h4> <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></pre></td><td class="code"><pre><code class="hljs python"> <span class="hljs-comment"># 导入库</span><br><span class="hljs-keyword">from</span> sklearn.ensemble <span class="hljs-keyword">import</span> GradientBoostingClassifier<br><br><span class="hljs-comment"># 假设你已经有了训练数据集的预测变量 X 和目标变量 Y,以及测试数据集的预测变量 x_test</span><br><span class="hljs-comment"># 创建 Gradient Boosting 分类器对象</span><br>model = GradientBoostingClassifier(n_estimators=<span class="hljs-number">100</span>, learning_rate=<span class="hljs-number">1.0</span>, max_depth=<span class="hljs-number">1</span>, random_state=<span class="hljs-number">0</span>)<br><br><span class="hljs-comment"># 创建了一个 GradientBoostingClassifier(梯度提升分类器)的模型对象,并指定了一些参数来配置该模型的训练过程:</span><br><span class="hljs-comment"># n_estimators=100:指定了基础学习器的数量,也就是组成整个集成模型的决策树数量为 100。增加基础学习器的数量可以提高模型性能,但也会增加计算成本。</span><br><span class="hljs-comment"># learning_rate=1.0:学习率控制每棵树对最终结果的贡献程度。较低的学习率意味着每棵树的影响会减弱,通常需要与 n_estimators 结合调参以获得最佳效果。</span><br><span class="hljs-comment"># max_depth=1:每棵决策树的最大深度限制为 1。限制树的深度有助于防止过拟合,提高模型的泛化能力。</span><br><span class="hljs-comment"># random_state=0:随机种子,用于控制随机数生成过程,确保模型的训练过程可复现。设置相同的随机种子可以使实验结果保持一致。</span><br><br><span class="hljs-comment"># 使用训练集训练模型并查看评分</span><br>model.fit(X, y)<br><br><span class="hljs-comment"># 进行预测</span><br>predicted = model.predict(x_test)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>AI学习</category>
</categories>
<tags>
<tag>线性回归</tag>
<tag>逻辑回归</tag>
<tag>决策树</tag>
<tag>支持向量机SVM</tag>
<tag>朴素贝叶斯</tag>
<tag>K近邻KNN</tag>
<tag>K均值</tag>
<tag>随机森林</tag>
<tag>降低维度算法</tag>
<tag>Gradient Boost</tag>
<tag>Adaboost</tag>
</tags>
</entry>
<entry>
<title>北京交通大学-图像处理</title>
<link href="/2024/03/25/%E5%8C%97%E4%BA%AC%E4%BA%A4%E9%80%9A%E5%A4%A7%E5%AD%A6-%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86/"/>
<url>/2024/03/25/%E5%8C%97%E4%BA%AC%E4%BA%A4%E9%80%9A%E5%A4%A7%E5%AD%A6-%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86/</url>
<content type="html"><![CDATA[<h1 id="北京交通大学-图像处理"><a href="#北京交通大学-图像处理" class="headerlink" title="北京交通大学-图像处理"></a>北京交通大学-图像处理</h1><h2 id="I-基本概念"><a href="#I-基本概念" class="headerlink" title="I 基本概念"></a>I 基本概念</h2><h3 id="一、模拟图像"><a href="#一、模拟图像" class="headerlink" title="一、模拟图像"></a>一、模拟图像</h3><p>通过某种连续的物理量,光或电等的强弱变化,记录图像的亮度信息。</p><h3 id="二、数字图像"><a href="#二、数字图像" class="headerlink" title="二、数字图像"></a>二、数字图像</h3><p>采用数字表示方式,记录图像亮度信息,计算机进行存储和处理。</p><h3 id="三、采样和量化"><a href="#三、采样和量化" class="headerlink" title="三、采样和量化"></a>三、采样和量化</h3><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854865.png" alt="image-20240314155530861"></p><blockquote><p>数字图像就是对模拟图像进行了空间采样和亮度量化</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854881.png" alt="image-20240314155619393"></p><p>**1、数字图像的数学模型$f(x,y)$ **</p><p>$(x,y)$表示像素位置,$f(x,y)$表示像素灰度值。</p><p><strong>2、数字图像可以表示为以像素为元素的矩阵</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854911.png" alt="image-20240314160001472"></p><h3 id="四、空间分辨率"><a href="#四、空间分辨率" class="headerlink" title="四、空间分辨率"></a>四、空间分辨率</h3><p><strong>采样间隔</strong></p><p>图像采样间隔是指在数字图像处理中,采样过程中相邻采样点之间的距离。</p><p>采样间隔决定了图像的分辨率和细节表现能力,间隔越小,图像的细节表现能力越高。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854807.png" alt="image-20240314160222022"></p><blockquote><p>采样间隔4x4通常指的是在图像处理中进行采样时,每隔4个像素点取一个样本。</p></blockquote><h3 id="五、亮度分辨率"><a href="#五、亮度分辨率" class="headerlink" title="五、亮度分辨率"></a>五、亮度分辨率</h3><p>衡量图像亮度的量化精度。</p><p>灰度级是指在数字图像中用来表示每个像素亮度或颜色深浅程度的级别。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854819.png" alt="image-20240314160732528"></p><h3 id="六、图像存储与格式"><a href="#六、图像存储与格式" class="headerlink" title="六、图像存储与格式"></a>六、图像存储与格式</h3><p><strong>1、数字存储比特数</strong></p><blockquote><p>8位图像使用8个比特(bit)来表示每个像素的颜色或亮度,因此可以有2^8 = 256个不同的颜色或亮度级别。同样,10位图像使用10个比特来表示每个像素的颜色或亮度,因此可以有2^10=1024个不同的颜色或亮度级别。</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854772.png" alt="image-20240314161631769"></p><p><strong>2、数字图像格式</strong></p><p>数字图像文件存放在记忆卡上的格式、压缩方式(BMP / JPEG / GIF / PNG)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854981.png" alt="image-20240314162359510"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854529.png" alt="image-20240314162659873"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854548.png" alt="image-20240314162713886"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854740.png" alt="image-20240314162747850"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854514.png" alt="image-20240314165009141"></p><h3 id="七、直方图"><a href="#七、直方图" class="headerlink" title="七、直方图"></a>七、直方图</h3><p>数字图像:以空间位置$(x,y)$为自变量的二维函数$f(x,y)$</p><p>不同灰度级分布构成不同图像,统计灰度级出现的次数(概率)— 灰度直方图</p><h4 id="直方图定义"><a href="#直方图定义" class="headerlink" title="直方图定义"></a>直方图定义</h4><p><strong>1、灰度直方图</strong></p><blockquote><p>灰度级的函数、具有该灰度级的像素个数</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854519.png" alt="image-20240314230732842"></p><p>示例:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854060.png" alt="image-20240314230829586"></p><p>灰度直方图反映了图像灰度的分布(统计)特征:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854239.png" alt="image-20240314230943679"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854124.png" alt="image-20240314232014758"></p><p><strong>2、灰度直方图归一化</strong></p><blockquote><p>灰度级出现的概率</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854404.png" alt="image-20240314232100647"></p><h4 id="直方图性质"><a href="#直方图性质" class="headerlink" title="直方图性质"></a>直方图性质</h4><p>直方图表征了图像中灰度级分布特性,一幅图像具有特定的唯一的直方图。</p><p>一个直方图可以对应多副图像。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854345.png" alt="image-20240314232610675"></p><h4 id="直方图应用"><a href="#直方图应用" class="headerlink" title="直方图应用"></a>直方图应用</h4><p><strong>1、图像增强(直方图均衡)</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854678.png" alt="image-20240314232718385"></p><p><strong>2、图像分割(根据直方图获取分割阈值)</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854626.png" alt="image-20240315110528363"></p><p><strong>3、图像分类(直方图对比)</strong></p><p>观测是否有人经过:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854764.png" alt="image-20240315110633267"></p><h2 id="Ⅱ-图像增强"><a href="#Ⅱ-图像增强" class="headerlink" title="Ⅱ 图像增强"></a>Ⅱ 图像增强</h2><p><strong>哪些情况需要增强?</strong></p><p>视觉效果不佳、噪声污染、难以分析理解</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854057.png" alt="image-20240315121435028"></p><blockquote><p>按照特定的需要突出或去除图像中的某些信息</p><p>没有增加图像中的信息量,有可能损失</p><p>没有统一的客观评价标准,特定用途特定方法</p></blockquote><p><strong>如何进行图像增强</strong></p><blockquote><p>通过灰度变换,使得人眼视觉敏感区有灰度级分布</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854067.png" alt="image-20240315121808223"></p><p>主要方法有:灰度变换、平均代数运算、空间域滤波、频域滤波</p><p>灰度变换、代数运算、空间域滤波直接对像素的灰度级进行操作 — <strong>空间域增强</strong></p><p>频域滤波,图像经过傅里叶变换等,对变换后的系数进行操作 — <strong>频域增强</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854080.png" alt="image-20240315122144072"></p><h3 id="一、空间域增强"><a href="#一、空间域增强" class="headerlink" title="一、空间域增强"></a>一、空间域增强</h3><p>直接对构成图像像素的灰度级操作</p><p>T:对输入图像灰度级的变换(操作)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854184.png" alt="image-20240315135605655"></p><h4 id="灰度变换"><a href="#灰度变换" class="headerlink" title="灰度变换"></a>灰度变换</h4><p>简单、常用的空间域图像增强方法,输入图像像素的灰度级进行变换</p><p>T:灰度变换函数(线性/非线性)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854287.png" alt="image-20240315135750032"></p><h5 id="1、线性变换"><a href="#1、线性变换" class="headerlink" title="1、线性变换"></a>1、线性变换</h5><p>这里是反转的效果:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854389.png" alt="image-20240315140012783"></p><p>因为 $d>b$ ,相当于把窄的灰度级拉伸了,这里起到了拉伸的效果:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854807.png" alt="image-20240315185109310"></p><p>对很暗和很亮的地方进行灰度压缩,敏感区拉伸,</p><p>突出感兴趣的区间,相对抑制不感兴趣的灰度区域:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854904.png" alt="image-20240315185748512"></p><h5 id="2、非线性变换"><a href="#2、非线性变换" class="headerlink" title="2、非线性变换"></a>2、非线性变换</h5><blockquote><p>包括对数变换、幂次变换、直方图均衡</p></blockquote><ul><li><p>对数变换</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854785.png" alt="image-20240315190049918"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854752.png" alt="image-20240315190115811"></p></li><li><p>幂次变换</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854091.png" alt="image-20240315190143138"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854066.png" alt="image-20240315190213255"></p><p>实际上对窄带也会进行拉伸:</p><p>低灰度输入图像 — 》 宽带 输出图像</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854356.png" alt="image-20240315190237938"></p><p>不同参数效果不同:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854492.png" alt="image-20240315190404061"></p></li><li><p>直方图均衡</p></li></ul><blockquote><p>直方图统计每个灰度级上的像素个数</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854443.png" alt="image-20240315191556996"></p><p>灰度变换后的图像直方图,是变换前直方图与变换函数导数之比</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854680.png" alt="image-20240315192627621"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854866.png" alt="image-20240315192705656"></p><p>如何实现直方图均衡?</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854711.png" alt="image-20240315192749186"></p><p>计算常数:总像素数除以灰度级别数量</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854036.png" alt="image-20240315193434524"></p><p>目的是找到$f$(D<sub>A</sub>)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854025.png" alt="image-20240315195623929"></p><p>示例:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854111.png" alt="image-20240315195940437"></p><p>应用:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854365.png" alt="image-20240315200034466"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854461.png" alt="image-20240315200125815"></p><h4 id="代数运算"><a href="#代数运算" class="headerlink" title="代数运算"></a>代数运算</h4><h5 id="1、加法运算"><a href="#1、加法运算" class="headerlink" title="1、加法运算"></a>1、加法运算</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854468.png" alt="image-20240315200308426"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854618.png" alt="image-20240315200352448"></p><p>如何恢复原始图像$f(x,y)$? — 求多幅图像均值可以去除叠加性噪声</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854007.png" alt="image-20240315200631436"></p><p>一般求平均的图像越多,去噪效果越好:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854791.png" alt="image-20240315200814661"></p><h5 id="2、减法运算"><a href="#2、减法运算" class="headerlink" title="2、减法运算"></a>2、减法运算</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854103.png" alt="image-20240315201005019"></p><p>分割特定区域:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854025.png" alt="image-20240315205320059"></p><p>检测场景变化:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854269.png" alt="image-20240315205353116"></p><h5 id="3、乘法运算"><a href="#3、乘法运算" class="headerlink" title="3、乘法运算"></a>3、乘法运算</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854180.png" alt="image-20240315205422361"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854005.png" alt="image-20240315205434731"></p><h4 id="空间域滤波"><a href="#空间域滤波" class="headerlink" title="空间域滤波"></a>空间域滤波</h4><blockquote><p>空间域增强是直接对构成图像像素的灰度级操作</p><p>关键是寻求从输入图像到输出图像的变换函数 T </p><p>(上面提到了灰度变换函数,其实也可以通过信号系统分析寻找变换关系)</p></blockquote><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854533.png" alt="image-20240315205601120"></p><h5 id="信号与系统分析"><a href="#信号与系统分析" class="headerlink" title="信号与系统分析"></a>信号与系统分析</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854598.png" alt="image-20240315205741195"></p><p><strong>(1)一维连续线性时不变系统</strong></p><p>一维连续线性时不变系统是指在一维输入和输出场景下,系统具有线性性质并且其参数不随时间变化。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854728.png" alt="image-20240315222829812"></p><p><strong>(2)一维离散线性时不变系统</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854051.png" alt="image-20240315230046412"></p><p>图像 — 》 二维离散系统</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854849.png" alt="image-20240315230123154"></p><p><strong>空间域滤波</strong></p><p>增强效果取决于$h(m,n)$</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854167.png" alt="image-20240315230216862"></p><h5 id="均值滤波器"><a href="#均值滤波器" class="headerlink" title="均值滤波器"></a>均值滤波器</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854209.png" alt="image-20240315231331824"></p><p>经过均值滤波,噪声点削弱:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854288.png" alt="image-20240315231506352"></p><h5 id="高斯滤波器"><a href="#高斯滤波器" class="headerlink" title="高斯滤波器"></a>高斯滤波器</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854482.png" alt="image-20240315231542767"></p><p>图像滤波器应用 — 》 去除噪声</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854773.png" alt="image-20240315231854870"></p><p>图像滤波器应用 — 》 提取感兴趣物体</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854730.png" alt="image-20240315232209812"></p><p>低通滤波 — 》 图像平滑</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854813.png" alt="image-20240315232239456"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854916.png" alt="image-20240321141526883"></p><h5 id="中值滤波器"><a href="#中值滤波器" class="headerlink" title="中值滤波器"></a>中值滤波器</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854903.png" alt="image-20240321141642363"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854042.png" alt="image-20240321141714753"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854452.png" alt="image-20240321141737866"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854506.png" alt="image-20240321141746237"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854487.png" alt="image-20240321141751579"></p><h5 id="高通滤波器"><a href="#高通滤波器" class="headerlink" title="高通滤波器"></a>高通滤波器</h5><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854597.png" alt="image-20240321142130392"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854518.png" alt="image-20240321142140425"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854642.png" alt="image-20240321142233980"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854137.png" alt="image-20240321142545373"></p><p><strong>图像边缘</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403211428113.png" alt="image-20240321142810067"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854239.png" alt="image-20240321142834228"></p><p><strong>基于一阶差分的图像增强</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403211429598.png" alt="image-20240321142924540"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854349.png" alt="image-20240321143007106"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854502.png" alt="image-20240321143037299"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854871.png" alt="image-20240321143054217"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854084.png" alt="image-20240321143101084"></p><p><strong>基于二阶差分的图像增强</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854224.png" alt="image-20240321143138941"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854303.png" alt="image-20240321143203584"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854586.png" alt="image-20240321143211071"></p><p><strong>一阶差分与二阶差分的区别</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854823.png" alt="image-20240321143312664"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854327.png" alt="image-20240321143334420"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854107.png" alt="image-20240321143352892"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854385.png" alt="image-20240321143417116"></p><h3 id="二、频域增强"><a href="#二、频域增强" class="headerlink" title="二、频域增强"></a>二、频域增强</h3><h4 id="一维离散傅里叶变换定义"><a href="#一维离散傅里叶变换定义" class="headerlink" title="一维离散傅里叶变换定义"></a>一维离散傅里叶变换定义</h4><p>傅里叶级数</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854538.png" alt="image-20240321164147630"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854979.png" alt="image-20240321164231072"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854076.png" alt="image-20240321164242383"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854118.png" alt="image-20240321164323604"></p><h4 id="二维离散傅里叶变换定义"><a href="#二维离散傅里叶变换定义" class="headerlink" title="二维离散傅里叶变换定义"></a>二维离散傅里叶变换定义</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854243.png" alt="image-20240321164343891"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854669.png" alt="image-20240321164403481"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854734.png" alt="image-20240321164418029"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854798.png" alt="image-20240321164437280"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854983.png" alt="image-20240321164448740"></p><h4 id="二维离散傅里叶变换性质"><a href="#二维离散傅里叶变换性质" class="headerlink" title="二维离散傅里叶变换性质"></a>二维离散傅里叶变换性质</h4><p>平移特性</p><p>旋转特性</p><p>尺度特性</p><p>卷积特性</p><p>相关特性</p><p>分离特性</p><h4 id="图像滤波器"><a href="#图像滤波器" class="headerlink" title="图像滤波器"></a>图像滤波器</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854251.png" alt="image-20240321173425623"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854337.png" alt="image-20240321173440500"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854379.png" alt="image-20240321173453913"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854649.png" alt="image-20240321173521448"></p><p>(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854881.png" alt="image-20240321173611828"></p><p>(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854910.png" alt="image-20240321173810870"></p><p>(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854149.png" alt="image-20240321173832195"></p><p>(略)</p><h2 id="Ⅲ-形态学处理"><a href="#Ⅲ-形态学处理" class="headerlink" title="Ⅲ 形态学处理"></a>Ⅲ 形态学处理</h2><h3 id="一、基本概念"><a href="#一、基本概念" class="headerlink" title="一、基本概念"></a>一、基本概念</h3><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854739.png" alt="image-20240325174221566"></p><p><strong>图像数学形态学处理</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854510.png" alt="image-20240325174305792"></p><h3 id="二、集合论基础"><a href="#二、集合论基础" class="headerlink" title="二、集合论基础"></a>二、集合论基础</h3><p>集合论</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854562.png" alt="image-20240325174343623"></p><p>集合论运算:交集、并集、补集、差集</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854805.png" alt="image-20240325174454038"></p><p>集合平移:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854182.png" alt="image-20240325174604773"></p><p>集合反射:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854267.png" alt="image-20240325174636894"></p><h3 id="三、数学形态学处理"><a href="#三、数学形态学处理" class="headerlink" title="三、数学形态学处理"></a>三、数学形态学处理</h3><h4 id="膨胀"><a href="#膨胀" class="headerlink" title="膨胀"></a>膨胀</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854316.png" alt="image-20240325174901048"></p><p>最后的结果是点集</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854364.png" alt="image-20240325175926717"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854684.png" alt="image-20240325180303531"></p><p>对字符进行低通滤波或者膨胀</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854925.png" alt="image-20240325180452997"></p><h4 id="腐蚀"><a href="#腐蚀" class="headerlink" title="腐蚀"></a>腐蚀</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854872.png" alt="image-20240325181258767"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854899.png" alt="image-20240325181322439"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854131.png" alt="image-20240325181446238"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854784.png" alt="image-20240325181500973"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854490.png" alt="image-20240325181531517"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854155.png" alt="image-20240325181544426"></p><p>应用:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854541.png" alt="image-20240325181612562"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854091.png" alt="image-20240325181630310"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854118.png" alt="image-20240325181709937"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854472.png" alt="image-20240325181718368"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854644.png" alt="image-20240325181735572"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854702.png" alt="image-20240325181849399"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854677.png" alt="image-20240325181854134"></p><h4 id="开运算"><a href="#开运算" class="headerlink" title="开运算"></a>开运算</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854111.png" alt="image-20240325181918125"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854185.png" alt="image-20240325181953511"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854200.png" alt="image-20240325182016240"></p><h4 id="闭运算"><a href="#闭运算" class="headerlink" title="闭运算"></a>闭运算</h4><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854268.png" alt="image-20240325182032148"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854691.png" alt="image-20240325182040587"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854735.png" alt="image-20240325182054950"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854840.png" alt="image-20240325182129744"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854792.png" alt="image-20240325182154074"><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854243.png" alt="image-20240325182250762"></p><h2 id="Ⅳ-图像分割"><a href="#Ⅳ-图像分割" class="headerlink" title="Ⅳ 图像分割"></a>Ⅳ 图像分割</h2><p>感兴趣区域识别</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854231.png" alt="image-20240325183100012"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854217.png" alt="image-20240325183136453"></p><p>(后面的图有点密恐!!!!!小心!!!!)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854222.png" alt="image-20240325183206679"></p><h3 id="基于阈值"><a href="#基于阈值" class="headerlink" title="基于阈值"></a>基于阈值</h3><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854475.png" alt="image-20240325183252292"></p><p>确定阈值T,大于T保留,小于T视为0</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854554.png" alt="image-20240325183829994">、</p><p>阈值的选取:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854849.png" alt="image-20240325183841551"></p><p>直方图技术:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854937.png" alt="image-20240325183904512"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854927.png" alt="image-20240325183928904"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854803.png"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854086.png" alt="image-20240325184017714"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854060.png" alt="image-20240325184031251"></p><p>最小误差阈值法(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854391.png" alt="image-20240325184058657"></p><p>最大方差阈值法(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854545.png" alt="image-20240325184145549"></p><h3 id="基于边缘"><a href="#基于边缘" class="headerlink" title="基于边缘"></a>基于边缘</h3><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854538.png" alt="image-20240325183318662"></p><p>点检测:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854750.png" alt="image-20240325184233339"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854686.png" alt="image-20240325184243150"></p><p>线检测:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854003.png" alt="image-20240325184252957"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854092.png" alt="image-20240325184303083"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854128.png" alt="image-20240325184314742"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854392.png" alt="image-20240325184332650"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854313.png" alt="image-20240325184338680"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854463.png" alt="image-20240325184352638"></p><p>霍夫变换:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854748.png" alt="image-20240325184420751"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854669.png" alt="image-20240325184428657"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854243.png" alt="image-20240325184442342"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854012.png" alt="image-20240325184451158"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854020.png" alt="image-20240325184500442"></p><h3 id="基于区域"><a href="#基于区域" class="headerlink" title="基于区域"></a>基于区域</h3><p>(略)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854158.png" alt="image-20240325183338037"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854295.png" alt="image-20240325184518642"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854446.png" alt="image-20240325184526153"></p><h3 id="基于学习"><a href="#基于学习" class="headerlink" title="基于学习"></a>基于学习</h3><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403251854609.png" alt="image-20240325183405862"></p>]]></content>
<categories>
<category>图像处理</category>
</categories>
<tags>
<tag>图像增强</tag>
<tag>图像形态学处理</tag>
<tag>图像分割</tag>
</tags>
</entry>
<entry>
<title>迪AI-神经网络基础学习</title>
<link href="/2024/03/23/%E8%BF%AAAI-%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0/"/>
<url>/2024/03/23/%E8%BF%AAAI-%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0/</url>
<content type="html"><![CDATA[<h1 id="迪AI-神经网络基础学习"><a href="#迪AI-神经网络基础学习" class="headerlink" title="迪AI-神经网络基础学习"></a>迪AI-神经网络基础学习</h1><h2 id="一、神经网络"><a href="#一、神经网络" class="headerlink" title="一、神经网络"></a>一、神经网络</h2><p><strong>机器学习流程:</strong></p><blockquote><p>数据获取 — 特征工程(核心)— 建立模型 — 评估与应用</p></blockquote><p><strong>特征工程的作用:</strong></p><ul><li><p>数据特征决定了模型的上限</p></li><li><p>预处理和特征提取是最核心的</p></li><li><p>算法和参数选择决定了如何逼近这个上限</p></li></ul><p><strong>特征如何提取?</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947883.png" alt="image-20240321195233298"></p><p><strong>传统特征提取方法:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947563.png" alt="image-20240321195318340"></p><p><strong>深度学习</strong></p><p>比较麻烦,这就是为什么需要深度学习:</p><p>相当于黑盒子,通过学习提取一系列最合适的特征:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947518.png" alt="image-20240321195433086"></p><p>深度学习的应用:无人驾驶(目标检测和识别)、人脸识别、医学应用、视频换脸、图像修复</p><p><strong>数据集IMAGENET:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947941.png" alt="image-20240321202043785"></p><p>数据规模越大,深度学习算法效果越好:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947619.png" alt="image-20240321202214294"></p><p><strong>计算机视觉-图像分类任务</strong></p><p>3颜色通道RGB</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947592.png" alt="image-20240321202335768"></p><p><strong>面临的挑战:</strong></p><p>照射角度、形状改变、部分遮蔽、背景混入</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947165.png" alt="image-20240321202448792"></p><p><strong>机器学习常规套路</strong></p><ul><li>收集数据、给定标签</li><li>训练一个分类器</li><li>测试、评估</li></ul><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947271.png" alt="image-20240321202638832"></p><p><strong>K近邻</strong></p><p>问圆圈属于什么类别?看周围的类别谁多分类成谁</p><p>K等于几就是画几个在圈里:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947253.png" alt="image-20240321203518694"></p><p>计算流程:</p><ul><li>计算已知类别数据集中的点与当前点距离</li><li>按照距离依次排序</li><li>选取与当前点距离最小的K个点</li><li>确定前K个点所在类别的出现频率</li><li>返回前K个点出现频率最高的类别作为当前点预测分类</li></ul><p>K近邻分析:</p><ul><li><p>KNN算法简单有效,是一种lazy-learning算法</p></li><li><p>分类器不需要使用训练集进行训练,训练时间复杂度为0</p></li><li><p>KNN分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中的文档总数为n,那么KNN的分类时间复杂度为O(n)</p></li><li><p>K值的选择,距离度量和分类决策规则是该算法的三个基本要素</p></li></ul><p><strong>CIFAR-10 数据库简介:</strong></p><p>数据小,32x32x3</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947518.png" alt="image-20240321205957826"></p><p><strong>距离计算:</strong></p><p>和训练集中的5w张图像,分别逐像素相减,取绝对值,然后求和</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947881.png" alt="image-20240321210509541"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947138.png" alt="image-20240321210703137"></p><p>问题:没有区分主体和背景</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947053.png" alt="image-20240321211446688"></p><p><strong>交叉验证:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947044.png" alt="image-20240321210809493"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947909.png" alt="image-20240321210904342"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947574.png" alt="image-20240321211248857"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947664.png" alt="image-20240321210924072"></p><p><strong>神经网络基础</strong></p><p>线性函数,从输入到输出的映射</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947195.png" alt="image-20240321212441827"></p><p><strong>数学表示:</strong></p><p>计算属于每个类别对应的得分,每种动物有自己的权重W,因此W要有10个</p><p>3072由32x32x3得到,每个类别在每个像素点的权重参数</p><p>b是微调,是偏置参数,对于10个类别得到的分数都要进行微调</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947825.png" alt="image-20240321213137771"></p><p><strong>计算方法:</strong></p><p>权重参数越大,表明相应的像素越重要</p><p> <img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947272.png" alt="image-20240321213340108"></p><p><strong>W如何得到的?</strong></p><p>X数据是不会变的,因此神经网络是寻找合适的W</p><p>W初始是随机的,根据某些优化方法,不断改进W</p><p><strong>决策边界</strong></p><p>W是控制着决策边界的,b只是做微调</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947201.png" alt="image-20240321213812143"></p><p><strong>损失函数</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947308.png" alt="image-20240321213939143"></p><p>损失函数为0的时候 等于没有损失</p><p>用错误类别的分数减去正确类别的分数</p><p>+1的作用 相当于容忍程度 错误类别的分数和正确类别的差距至少要大于1分</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403212140249.png" alt="image-20240321214028180"></p><p>不是 模型A和模型B关注的不一样 </p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947599.png" alt="image-20240322000626595"></p><p><strong>正则化:</strong></p><p>惩罚项,由权重参数带来的损失</p><p>λ为惩罚系数,λ越大表示不希望过拟合,正则化惩罚更大,如果小点就是意思意思一下</p><p>因为神经网络的缺点就是过于强大,过拟合的风险很大</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947768.png" alt="image-20240322000825710"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947775.png" alt="image-20240322004702274"></p><p><strong>Softmax分类器</strong></p><p>随意输入一个数x都可以压缩到0-1之间,恰好把分数转化成了概率值</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947957.png" alt="image-20240322004755210"></p><p>将分数x做exp操作,放大差异,转化为概率值就是做归一化:</p><p>就是把自己的分数除以所有分数的和</p><p>归一化之后,用对数函数求损失,希望正确类别的概率离1越近越好 而损失值就越小</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947911.png" alt="image-20240322005341917"></p><p>回归任务 – 得分值</p><p>分类任务 – 概率值</p><p><strong>前向传播</strong></p><p>由x和w怎么得到一个损失</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947178.png" alt="image-20240322005555783"></p><p><strong>反向传播</strong></p><p>根据loss调整w</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947500.png" alt="image-20240322005627191"></p><p>在前向传播中,得分函数往往是多次变换组合,多个W一起去做 ,每一步关注的不一样</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947494.png" alt="image-20240322151332773"></p><p><strong>梯度下降:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947437.png"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947589.png"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947866.png" alt="image-20240322152145853"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947172.png" alt="image-20240322152213537"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947491.png" alt="image-20240322152302055"></p><p>希望损失函数的值越低越好 分别求偏导(相当于对结果做了多少贡献)</p><p>先是f对z求偏导 就知道z对结果的影响</p><p>而x经过了2步,先让f对q做偏导 再乘以q对x求的偏导 — 链式求导</p><p>y同理 逐层计算</p><p>反向传播中就是逐层计算</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947540.png" alt="image-20240322152647722"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947883.png" alt="image-20240322152714770"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947449.png" alt="image-20240322152758276"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947836.png" alt="image-20240322152806729"></p><p>可以</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947997.png" alt="image-20240322155459089"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947129.png" alt="image-20240322155603832"></p><p><strong>整体架构:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947135.png" alt="image-20240322162532669"></p><ul><li><p>层次结构:一层一层办事,在前者的基础上做事</p></li><li><p>神经元: 输入数据的特征数 有多少圈代表有多少输入特征</p></li><li><p>全连接:每个圆圈都连在一起</p></li><li><p>中间层:人类不好理解 计算机可以 </p></li><li><p>权重:线条就是权重 把3个特征转换到4个特征 权重参数 [3,4]</p></li></ul><p>W1 W2W3</p><ul><li>非线性:在每一步矩阵计算后的激活函数</li></ul><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947662.png" alt="image-20240322162850601"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947633.png" alt="image-20240322163512866"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947789.png" alt="image-20240322163522369"></p><p>神经元个数对结果的影响:理论上越多越好,但是出现过拟合</p><p>增加一个神经元、实际上是增加了一组参数</p><p><strong>正则化的作用:</strong></p><p>惩罚力度越小,越符合训练的结果。加大惩罚力度,要平滑的多</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947776.png" alt="image-20240322213718026"></p><p><strong>参数个数对结果的影响:</strong></p><p>神经元个数就是希望转化的特征数量,常见的是64 128 256…</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947434.png" alt="image-20240322213939919"></p><p><strong>激活函数:</strong></p><p>就是非线性变换</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947664.png" alt="image-20240322214049262"></p><p>sigmoid极端处会出现梯度消失 如果梯度为0 会导致后续的梯度也为0 因为是乘法操作</p><p>Relu更实用 没有梯度消失现象</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947022.png" alt="image-20240322220832806"></p><p><strong>数据预处理:</strong></p><p>数据要做预处理 例如中心化(减去均值)、归一化(除以标准差)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947442.png" alt="image-20240323105624533"></p><p><strong>参数初始化:</strong></p><p>权重参数矩阵给随机的值 随机策略 生成随机参数</p><p>0.01 初始化结果就都比较小</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947493.png" alt="image-20240323105606217"></p><p>防止过拟合,还可以使用<strong>DROP-OUT:</strong></p><p>完整的神经网络 全连接 B图就是在训练中 每一层随机杀死神经元 每次训练都是随机选择一部分</p><p>每次训练 架构都简单些 </p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947134.png" alt="image-20240323111955383"></p><p><strong>神经网络:</strong></p><p>就是找权重参数 什么权重参数最适合网络</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947149.png" alt="image-20240323112247340"></p><p> </p><h2 id="二、卷积神经网络CNN"><a href="#二、卷积神经网络CNN" class="headerlink" title="二、卷积神经网络CNN"></a>二、卷积神经网络CNN</h2><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947169.png" alt="image-20240323113605752"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947509.png" alt="image-20240323113709657"></p><p><strong>检索:</strong>判断图片是什么 再寻找相似度高的图片出来</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947827.png" alt="image-20240323113717080"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947057.png" alt="image-20240323113814780"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947516.png" alt="image-20240323113827821"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947008.png" alt="image-20240323113840520"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947334.png" alt="image-20240323113922498"></p><p><strong>卷积与传统神经网络nn的区别</strong>:</p><p>输入数据不是一列向量 是三维的 长方体</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947538.png" alt="image-20240323113955554"></p><p><strong>卷积:</strong>提取特征 </p><p><strong>池化:</strong>压缩特征</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947724.png" alt="image-20240323114107526"></p><p><strong>卷积做了什么?</strong></p><ul><li><p>把一张图像分成很多份,比如猫的眼睛 鼻子 嘴 不同的地方进行处理</p></li><li><p>每一块不止一个像素点 例如3x3的区域 对当前区域使用权重参数得到特征值</p></li><li><p>不同区域得到的特征不一样 选择一种计算方法 计算每个区域的特征值</p></li><li><p>找最好的权重参数 最适合的权重参数</p></li></ul><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947738.png" alt="image-20240323120136530"></p><p><strong>图像颜色通道:</strong></p><p>做计算的时候,每个颜色通道都要分别计算 – RGB</p><p>最后要进行加法操作 把3个通道的结果加起来</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947062.png" alt="image-20240323120351228"></p><p><strong>Filter的通道数</strong>必须和输入数据的通道数相同 </p><p><strong>核:</strong>就是选择多大的区域对应于一个特征值</p><p>做的是内积计算 各元素相乘 每个通道做内积最后加起来得到一个特征值 记得加上b偏置</p><p>最终是得到一个特征图</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947371.png" alt="image-20240323120847575"></p><p>核可以是多个 f1-f6 得到丰富的特征 <strong>结果的通道数就是特征图的个数</strong></p><p>同一个卷积层 核的大小必须是相同的</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947385.png" alt="image-20240323123639001"></p><p>卷积得到的特征图再做卷积</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947481.png" alt="image-20240323124033635"></p><p>6个卷积核 卷积核的通道数一定和输入数据的通道数相同</p><p>10个卷积核 </p><p>…</p><p>经过多次卷积提取有用的特征</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947480.png" alt="image-20240323131330271"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947915.png" alt="image-20240323131749989"></p><p><strong>不同步长</strong>得到的特征图大小不一样</p><p>步长比较小的时候 细粒度越高 特征图更丰富</p><p>图像任务的时候步长一般为1 效率比较低</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947933.png" alt="image-20240323131800029"></p><p><strong>卷积核尺寸</strong>是选择区域的大小 卷积核越小 细粒度越高 </p><p>因为卷积的时候 边界点没有中间点利用的次数多 因此通过填充 让边界信息利用充分</p><p>用0填充 不会对结果产生负面影响</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947052.png" alt="image-20240323132346943"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947004.png" alt="image-20240323132522253"></p><p><strong>卷积核个数</strong> 对应的是得到的特征图的个数</p><p><strong>计算:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947670.png" alt="image-20240323132728711"></p><p>H1 原始输入 FH 是核的高度 P是padding 填充0的圈数</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947643.png" alt="image-20240323132708946"></p><p><strong>例子:</strong></p><p>特征图大小可能不变</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947983.png" alt="image-20240323143545183"></p><p><strong>卷积参数共享:</strong></p><p>每个卷积区域 用相同的核</p><p>每一个卷积核有一个对应的偏置参数</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947013.png" alt="image-20240323144202538"></p><p><strong>池化:</strong></p><p>压缩作用 进行筛选 通道数不变 宽高可以改变</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947226.png" alt="image-20240323144555454"></p><p><strong>最大池化:(常用)</strong></p><p>每个区域选择最大值</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947322.png" alt="image-20240323144656961"></p><p><strong>平均池化:</strong></p><p>每个区域求平均值</p><p><strong>卷积神经网络:</strong></p><p>卷积层+激活函数是一个必须的组合</p><p>两次卷积、一个池化…</p><p><strong>如何将特征图长方体进行分类任务?</strong>还得是全连接层。</p><p>拉成特征向量,输入到全连接层,得到分类结果</p><p><strong>通常是带参数计算的 叫做一层(卷积层、全连接层)</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947695.png" alt="image-20240323144807170"></p><p><strong>特征图变化:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947687.png" alt="image-20240323145055610"></p><p><strong>经典网络:</strong></p><ul><li><strong>ALEXNET</strong></li></ul><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947899.png" alt="image-20240323145543624"></p><p>pool之后 会损失信息 用特征图个数弥补损失 翻倍了</p><ul><li><strong>VGG</strong></li></ul><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947914.png" alt="image-20240323145620441"></p><p>用更深的网络层数去做 效果不一定更好</p><ul><li><strong>RESNET</strong></li></ul><p>利用同等映射 如果表现不好 如果B不好 把B的权重参数全部置为0 A和C直接连接</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947893.png" alt="image-20240323145823746"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947401.png" alt="image-20240323150116911"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947446.png" alt="image-20240323150137949"></p><p><strong>任务是分类还是回归 取决于损失函数和最后的连接</strong></p><p>把resnet当做特征提取 是一种通用的网络结构</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947597.png" alt="image-20240323150220415"></p><p><strong>感受野:</strong></p><p>无论中间多少层 最后感受到的是原始输入的野</p><p>最后的值是前面多少个值得到的</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947022.png" alt="image-20240323150342629"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947604.png" alt="image-20240323162233484"></p><p>为什么:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947589.png" alt="image-20240323162548862"></p><h2 id="三、递归神经网络RNN"><a href="#三、递归神经网络RNN" class="headerlink" title="三、递归神经网络RNN"></a>三、递归神经网络RNN</h2><p>预测结果的时候 可以把中间和前面的结果考虑进来</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947095.png" alt="image-20240323164311174">CNN 主要用于计算机视觉</p><p>RNN 主要用于自然语言处理</p><p>不同时刻,人为区分的,h0 h1 h2..代表中间结果</p><p>ht表示综合之前所有特征 一般只选最后结果</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947122.png" alt="image-20240323165912756"></p><h2 id="四、LSTM网络"><a href="#四、LSTM网络" class="headerlink" title="四、LSTM网络"></a>四、LSTM网络</h2><p>RNN网络记忆好 把之前所有结果记忆下来</p><p>LSTM可以健忘一些 </p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947305.png" alt="image-20240323170019110"></p><p>C决定保留和遗忘</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947270.png" alt="image-20240323170034459"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947326.png" alt="image-20240323170042587"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947857.png" alt="image-20240323170059371"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947862.png" alt="image-20240323170108477"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947616.png" alt="image-20240323170153092"></p><p>LSTM是在RNN基础上改进的,加上了C控制参数,控制当前模型复杂度</p><p>可以进行信息的过滤</p><p><strong>架构:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947963.png" alt="image-20240323170310004"></p><h2 id="五、自然语言处理-词向量模型-Word2Vec"><a href="#五、自然语言处理-词向量模型-Word2Vec" class="headerlink" title="五、自然语言处理-词向量模型-Word2Vec"></a>五、自然语言处理-词向量模型-Word2Vec</h2><p>文本向量化后计算机才认识</p><p>基本的出发点:构建词向量</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947113.png" alt="image-20240323174458965"></p><p>通常,数据的维度越高,能提供的信息也就越多,从而计算结果的可靠性就更值得信赖(50-300维)</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947153.png" alt="image-20240323174546034"></p><p>50维 很难解释 只有计算机认识</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947433.png" alt="image-20240323174807095"></p><p><strong>热度图:</strong></p><p>相近的词位置是相似的</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947503.png" alt="image-20240323174842511"></p><p>如何训练词向量?— 词要如何写成一个向量</p><p>预测下一个词</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947689.png" alt="image-20240323175120105"></p><p>和神经网络的多分类挺像的 预测下一个词哪个词的概率更高</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947672.png" alt="image-20240323175448074"></p><p>先把词在词库中匹配向量 随机初始向量组 然后迭代更新输入变量使损失更小 能够更精准预测下一个词</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947042.png" alt="image-20240323175750416"></p><p><strong>训练数据:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947079.png" alt="image-20240323180029606"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947106.png" alt="image-20240323180151241"></p><p>平移 指定滑动窗口 扫描 得到输入输出</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947168.png" alt="image-20240323180210049"></p><p><strong>不同模型对比:</strong></p><ul><li><strong>CBOW</strong></li></ul><p>输入是上下文,输出中间的词</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947182.png" alt="image-20240323180806133"></p><p>t是输出:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947585.png" alt="image-20240323180826507"></p><ul><li><strong>Skipgram</strong></li></ul><p>输入是中间的词 输出是上下文的预测</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947708.png" alt="image-20240323180856994"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947660.png" alt="image-20240323180939569"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947736.png" alt="image-20240323181000582"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947748.png" alt="image-20240323181025369"></p><p>不仅要更新权重 还要更新数据</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947046.png" alt="image-20240323183800079"></p><p>庞大的语言库 最终希望得到的正确分类概率越高越好 </p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947096.png" alt="image-20240323181132200"></p><p>把原来的输出也放到输入</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947169.png" alt="image-20240323183908065"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947285.png" alt="image-20240323184013420"></p><p>自己添加标签 target为0的 负样本 人为创造的 推荐5个</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947380.png"></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947593.png"></p><p><strong>词向量训练过程:</strong></p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947604.png" alt="image-20240323184307862"></p><p>找对应的矩阵:</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947735.png" alt="image-20240323184444998"></p><p>in out都要进行更新的</p><p>最终得到词向量模型</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202403231947819.png" alt="image-20240323184506669"></p>]]></content>
<categories>
<category>AI学习</category>
</categories>
<tags>
<tag>神经网络</tag>
<tag>CNN</tag>
<tag>RNN</tag>
<tag>LSTM</tag>
<tag>Word2Vec</tag>
</tags>
</entry>
<entry>
<title>LeetCode04:移动零</title>
<link href="/2024/03/13/LeetCode04/"/>
<url>/2024/03/13/LeetCode04/</url>
<content type="html"><![CDATA[<h1 id="4-移动零"><a href="#4-移动零" class="headerlink" title="4.移动零"></a>4.移动零</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一个数组 <code>nums</code>,编写一个函数将所有 <code>0</code> 移动到数组的末尾,同时保持非零元素的相对顺序。</p><p><strong>请注意</strong> ,必须在不复制数组的情况下原地对数组进行操作。</p><p><strong>示例 1:</strong></p><figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs accesslog">输入: nums = <span class="hljs-string">[0,1,0,3,12]</span><br>输出: <span class="hljs-string">[1,3,12,0,0]</span><br></code></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs inform7">输入: nums = <span class="hljs-comment">[0]</span><br>输出: <span class="hljs-comment">[0]</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)我的解法"><a href="#(1)我的解法" class="headerlink" title="(1)我的解法"></a>(1)我的解法</h3><p>通过循环数组的<code>remove</code>操作依次将0移除,移除次数为填0次数,最后在数组末尾填充相应次数的0。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>(<span class="hljs-title class_ inherited__">object</span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">moveZeroes</span>(<span class="hljs-params">self, nums</span>):<br> count = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> <span class="hljs-number">0</span> <span class="hljs-keyword">in</span> nums:<br> nums.remove(<span class="hljs-number">0</span>)<br> count += <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(count):<br> nums.append(<span class="hljs-number">0</span>) <br> <span class="hljs-keyword">return</span> nums<br></code></pre></td></tr></table></figure><h3 id="(2)官方题解"><a href="#(2)官方题解" class="headerlink" title="(2)官方题解"></a>(2)官方题解</h3><h4 id="双指针"><a href="#双指针" class="headerlink" title="双指针"></a>双指针</h4><p>左右指针都在索引起始处,先判断右指针位置的元素是否为0,如果为0,右指针继续走一步;如果不为0,将左右指针的元素对换,左指针继续往前一步。右指针继续走一步,继续处理,直到右指针走到最末。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">moveZeroes</span>(<span class="hljs-params">self, nums</span>):<br> n = <span class="hljs-built_in">len</span>(nums)<br> left = right = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> right < n:<br> <span class="hljs-keyword">if</span> nums[right] != <span class="hljs-number">0</span>:<br> nums[left], nums[right] = nums[right], nums[left]<br> left += <span class="hljs-number">1</span><br> right += <span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> nums<br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>双指针法的时间与空间复杂度</strong></p><blockquote><p>时间复杂度:O(n),其中 n 为序列长度。每个位置至多被遍历两次。</p><p>空间复杂度:O(1)。只需要常数的空间存放若干变量。</p></blockquote><p><strong>双指针元素兑换</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">nums[left], nums[right] = nums[right], nums[left]<br></code></pre></td></tr></table></figure><p><strong>数组操作</strong></p><blockquote><ol><li>创建数组:使用方括号 <code>[]</code> 来创建数组,例如 <code>my_list = [1, 2, 3, 4, 5]</code>。</li><li>访问元素:通过索引来访问数组中的元素,索引从 0 开始,例如 <code>my_list[0]</code> 返回数组的第一个元素。</li><li>切片操作:可以使用切片来获取数组中的子数组,例如 <code>my_list[1:3]</code> 返回索引 1 到 2 的子数组。</li><li>添加元素:使用 <code>append()</code> 方法向数组末尾添加新元素,例如 <code>my_list.append(6)</code>。</li><li>插入元素:使用 <code>insert()</code> 方法在指定位置插入元素,例如 <code>my_list.insert(2, 7)</code> 在索引 2 处插入元素 7。</li><li>删除元素:使用 <code>remove()</code> 方法删除指定元素,例如 <code>my_list.remove(3)</code> 删除元素 3。</li><li>弹出元素:使用 <code>pop()</code> 方法弹出指定索引的元素,例如 <code>my_list.pop(1)</code> 弹出索引 1 处的元素。</li><li>查找元素:使用 <code>index()</code> 方法查找指定元素的索引,例如 <code>my_list.index(4)</code> 返回元素 4 的索引。</li><li>数组长度:使用 <code>len()</code> 函数获取数组的长度,例如 <code>len(my_list)</code> 返回数组的长度。</li><li>排序数组:使用 <code>sort()</code> 方法对数组进行排序,例如 <code>my_list.sort()</code> 对数组进行升序排序。</li></ol></blockquote>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>双指针</tag>
</tags>
</entry>
<entry>
<title>PAT03:数素数</title>
<link href="/2024/03/13/PAT03/"/>
<url>/2024/03/13/PAT03/</url>
<content type="html"><![CDATA[<h1 id="3-数素数"><a href="#3-数素数" class="headerlink" title="3.数素数"></a>3.数素数</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p><strong>题目描述</strong></p><figure class="highlight abnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs abnf">令Pi表示第i(i从<span class="hljs-number">1</span>开始计数)个素数。现任给两个正整数M <<span class="hljs-operator">=</span> N <<span class="hljs-operator">=</span> <span class="hljs-number">10000</span>,请输出PM到PN的所有素数。<br></code></pre></td></tr></table></figure><p><strong>输入描述:</strong></p><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs excel">输入在一行中给出M和<span class="hljs-built_in">N</span>,其间以空格分隔。<br></code></pre></td></tr></table></figure><p><strong>输出描述:</strong></p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。<br></code></pre></td></tr></table></figure><p><strong>输入例子:</strong></p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">5 </span><span class="hljs-number">27</span><br></code></pre></td></tr></table></figure><p><strong>输出例子:</strong></p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">11 </span><span class="hljs-number">13</span> <span class="hljs-number">17</span> <span class="hljs-number">19</span> <span class="hljs-number">23</span> <span class="hljs-number">29</span> <span class="hljs-number">31</span> <span class="hljs-number">37</span> <span class="hljs-number">41</span> <span class="hljs-number">43</span><br><span class="hljs-symbol">47 </span><span class="hljs-number">53</span> <span class="hljs-number">59</span> <span class="hljs-number">61</span> <span class="hljs-number">67</span> <span class="hljs-number">71</span> <span class="hljs-number">73</span> <span class="hljs-number">79</span> <span class="hljs-number">83</span> <span class="hljs-number">89</span><br><span class="hljs-symbol">97 </span><span class="hljs-number">101</span> <span class="hljs-number">103</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="1-我的解法"><a href="#1-我的解法" class="headerlink" title="(1)我的解法"></a>(1)我的解法</h3><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">suShu</span>(<span class="hljs-params">num</span>):<br> <span class="hljs-keyword">if</span> num <= <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> n = <span class="hljs-built_in">int</span>(num**<span class="hljs-number">0.5</span>) + <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>,n+<span class="hljs-number">1</span>):<br> <span class="hljs-keyword">if</span> num % i == <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> num != i:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span> <br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">outNum</span>(<span class="hljs-params">nums</span>):<br> <span class="hljs-keyword">for</span> i,num <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(nums,start=<span class="hljs-number">1</span>):<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">10</span> == <span class="hljs-number">0</span>:<br> <span class="hljs-built_in">print</span>(num)<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">if</span> i == <span class="hljs-built_in">len</span>(nums):<br> <span class="hljs-built_in">print</span>(num,end=<span class="hljs-string">''</span>)<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(num,end=<span class="hljs-string">' '</span>)<br> <br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> res = []<br> m,n = <span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>,line.split())<br> num = <span class="hljs-number">1</span><br> count = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> num += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> suShu(num):<br> count += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> m<=count<=n:<br> res.append(num)<br> <span class="hljs-keyword">elif</span> count > n:<br> <span class="hljs-keyword">break</span><br> outNum(res)<br><br></code></pre></td></tr></table></figure><h3 id="(2)其他解法"><a href="#(2)其他解法" class="headerlink" title="(2)其他解法"></a>(2)其他解法</h3><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><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> sqrt<br><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">isPrime</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">int</span>(sqrt(x))+<span class="hljs-number">1</span>):<br> <span class="hljs-keyword">if</span> x % i == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> no = line.split(<span class="hljs-string">' '</span>)<br> m, n = <span class="hljs-built_in">int</span>(no[<span class="hljs-number">0</span>]), <span class="hljs-built_in">int</span>(no[<span class="hljs-number">1</span>])<br> i,count = <span class="hljs-number">2</span>,<span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> count < n :<br> <span class="hljs-keyword">if</span> isPrime(i):<br> count += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> count >= m:<br> <span class="hljs-keyword">if</span> (count-m+<span class="hljs-number">1</span>)%<span class="hljs-number">10</span> != <span class="hljs-number">0</span>:<br> <span class="hljs-built_in">print</span>(i,end=<span class="hljs-string">' '</span>),<br> <span class="hljs-keyword">else</span> :<br> <span class="hljs-built_in">print</span>(i)<br> i += <span class="hljs-number">1</span><br><br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>素数(质数)</strong></p><blockquote><p>指在大于1的<a href="https://baike.baidu.com/item/%E8%87%AA%E7%84%B6%E6%95%B0/385394?fromModule=lemma_inlink">自然数</a>中,除了1和它本身以外不再有其他<a href="https://baike.baidu.com/item/%E5%9B%A0%E6%95%B0/9539111?fromModule=lemma_inlink">因数</a>的自然数。</p></blockquote><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><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">isPrime</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">int</span>(sqrt(x))+<span class="hljs-number">1</span>):<br> <span class="hljs-keyword">if</span> x % i == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br></code></pre></td></tr></table></figure><p><strong>打印分隔符</strong></p><blockquote><p>打印结束时使用的行尾符号,默认是换行符 <code>\n</code>。</p></blockquote><p><code>sep</code>是间隔中有符号,末尾不会有符号</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-built_in">print</span>(item1, item2, item3, sep=<span class="hljs-string">' 分隔符 '</span>)<br></code></pre></td></tr></table></figure><p><code>end</code>是每个元素后面都有符号,末尾也会有</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-built_in">print</span>(item1, item2, end=<span class="hljs-string">' 结尾符 '</span>)<br></code></pre></td></tr></table></figure><p><strong>每10个处理一次</strong></p><blockquote><p>1、结果列表中的元素索引 % 10 == 0</p><p>2、(输出序数-输出开始数+1)%10 == 0</p></blockquote><p><strong>开根</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">num**<span class="hljs-number">0.5</span><br></code></pre></td></tr></table></figure><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><code class="hljs python"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> sqrt<br>sqrt(num)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode03:最长连续序列</title>
<link href="/2024/03/08/LeetCode03/"/>
<url>/2024/03/08/LeetCode03/</url>
<content type="html"><![CDATA[<h1 id="3-最长连续序列"><a href="#3-最长连续序列" class="headerlink" title="3.最长连续序列"></a>3.最长连续序列</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一个未排序的整数数组 <code>nums</code> ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。</p><p>请你设计并实现时间复杂度为 <code>O(n)</code> 的算法解决此问题。</p><p><strong>示例 1:</strong></p><figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs accesslog">输入:nums = <span class="hljs-string">[100,4,200,1,3,2]</span><br>输出:<span class="hljs-number">4</span><br>解释:最长数字连续序列是 <span class="hljs-string">[1, 2, 3, 4]</span>。它的长度为 <span class="hljs-number">4</span>。<br></code></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs dns">输入:nums = [<span class="hljs-number">0,3,7,2</span>,<span class="hljs-number">5,8,4,6</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>]<br>输出:<span class="hljs-number">9</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)官方题解"><a href="#(1)官方题解" class="headerlink" title="(1)官方题解"></a>(1)官方题解</h3><h4 id="哈希表"><a href="#哈希表" class="headerlink" title="哈希表"></a>哈希表</h4><p>考虑枚举数组中的每个数<code>x</code>,考虑以其为起点,不断尝试寻找<code>x+1</code>,<code>x+2</code>…是否存在。假设匹配到了<code>x+y</code>,那么以<code>x</code>为起点的最长连续序列为<code>x</code>,<code>x+1</code>,<code>x+2</code>…<code>x+y</code>,其长度为<code>y+1</code>,不断枚举并更新答案即可。</p><p>对于匹配的过程,<strong>暴力匹配</strong>是O(n)遍历数组去看是否存在这个数,<strong>更高效的匹配</strong>是用一个哈希表存储数组中的数,查看一个数是否存在,优化到O(1)的时间复杂度。</p><p>仅仅是这样,算法时间复杂度最坏情况下还是会达到O($n^2$)(即外层需要枚举O(n)个数,内层需要暴力匹配O(n)次),无法满足题目的要求。但仔细分析这个过程,我们会发现其中执行了很多不必要的枚举,已知有一个<code>x</code>,<code>x+1</code>,<code>x+2</code>…<code>x+y</code>的连续序列,而重新从<code>x+1</code>,<code>x+2</code>…<code>x+y</code>处开始匹配,得到的结果一定不会优于枚举<code>x</code>为起点的答案,因此,需要跳过。</p><p>判断是否跳过:要枚举的数<code>x</code>一定是在数组中不存在前驱数 <code>x-1</code>的。</p><p><strong>时间复杂度:</strong>外层循环需要O(n)的时间复杂度,只有当一个数是连续序列的第一个数的情况下才会进入内层循环,然后在内层循环中匹配连续序列中的数,因此数组中的每个数只会进入内层循环一次。根据上述分析可知,总时间复杂度为 O(n)。</p><p><strong>空间复杂度:</strong>O(n)。哈希表存储数组中所有的数需要 O(n)的空间。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>(<span class="hljs-title class_ inherited__">object</span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">longestConsecutive</span>(<span class="hljs-params">self,nums</span>):<br> longest_streak = <span class="hljs-number">0</span><br> num_set = <span class="hljs-built_in">set</span>(nums)<br> <br> <span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> num_set:<br> <span class="hljs-keyword">if</span> num - <span class="hljs-number">1</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> num_set:<br> current_num = num<br> current_streak = <span class="hljs-number">1</span><br> <br> <span class="hljs-keyword">while</span> current_num + <span class="hljs-number">1</span> <span class="hljs-keyword">in</span> num_set:<br> current_num += <span class="hljs-number">1</span><br> current_streak += <span class="hljs-number">1</span><br> <br> longest_streak = <span class="hljs-built_in">max</span>(longest_streak,current_streak)<br> <span class="hljs-keyword">return</span> longest_streak<br></code></pre></td></tr></table></figure><h3 id="(2)我的解法"><a href="#(2)我的解法" class="headerlink" title="(2)我的解法"></a>(2)我的解法</h3><p><strong>时间复杂度:</strong><br>排序:首先,算法中使用了排序,其时间复杂度为 O(n log n),其中 n 是数组 nums 的长度。这是因为大多数比较排序算法(如快速排序、归并排序等)的时间复杂度都是 O(n log n)。</p><p>遍历:排序之后,算法遍历了排序后的数组一次以计算最长连续序列的长度。这个遍历的时间复杂度是 O(n),因为每个元素都被访问一次。</p><p>因此,算法的总体时间复杂度主要由排序这一步骤决定,即 O(n log n)。虽然遍历也涉及到数组中的所有元素,但其时间复杂度 O(n) 在排序的时间复杂度 O(n log n) 面前可以忽略不计。</p><p><strong>空间复杂度:</strong></p><p>算法的空间复杂度主要取决于排序算法的空间复杂度。在 Python 中,排序通常使用 Timsort 算法,其最坏情况下的空间复杂度为 O(n)。除此之外,还使用了一个列表 res 来存储每个连续序列的长度,以及几个用于记录状态的变量(如 max_len)。因此,总体空间复杂度也是 O(n)。</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>(<span class="hljs-title class_ inherited__">object</span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">longestConsecutive</span>(<span class="hljs-params">self, nums</span>):<br> <span class="hljs-keyword">if</span> nums == []:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(nums) == <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span><br> nums = <span class="hljs-built_in">sorted</span>(nums)<br> res = []<br> max_len = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> i,num <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(nums):<br> <span class="hljs-keyword">if</span> i<<span class="hljs-built_in">len</span>(nums)-<span class="hljs-number">1</span>: <br> <span class="hljs-keyword">if</span> nums[i+<span class="hljs-number">1</span>] - num == <span class="hljs-number">1</span>:<br> max_len +=<span class="hljs-number">1</span><br> <span class="hljs-keyword">elif</span> nums[i+<span class="hljs-number">1</span>] == num:<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">else</span>:<br> res.append(max_len)<br> max_len = <span class="hljs-number">1</span><br> res.append(max_len)<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">max</span>(res) <br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>使用哈希表的优势</strong></p><blockquote><p>如果输入数组非常大,排序可能会成为性能瓶颈。与之相比,使用哈希表的方法虽然在理论上最坏情况下的时间复杂度也是 O(n),但在实际应用中往往能够更高效地解决问题,尤其是当数据量大且数组中包含大量连续序列时。</p></blockquote><p><strong>集合set()方法</strong></p><blockquote><p><code>set()</code>方法在Python中用于创建一个无序且不重复的元素集合。这是一种基本的数据结构,适用于去除重复元素以及执行各种集合操作(如并集、交集、差集等)。<code>set()</code>可以接收一个可迭代对象作为输入,比如列表、元组、字典等,然后将其转换成一个集合。如果不提供任何参数,<code>set()</code>会创建一个空集合。</p><ul><li>集合中的元素必须是不可变类型(如整数、浮点数、字符串、元组),不能是可变类型(如列表、字典)。</li><li>使用<code>{}</code>可以创建集合,但如果没有提供任何元素,Python会将其解释为一个空字典而不是空集合。因此,创建空集合必须使用<code>set()</code>。</li><li><code>set()</code>创建的集合是无序的,所以无法保证每次遍历集合时元素的顺序相同。</li></ul></blockquote>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>哈希表</tag>
</tags>
</entry>
<entry>
<title>PAT02:数字分类</title>
<link href="/2024/03/07/PAT02/"/>
<url>/2024/03/07/PAT02/</url>
<content type="html"><![CDATA[<h1 id="2-数字分类"><a href="#2-数字分类" class="headerlink" title="2.数字分类"></a>2.数字分类</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字:<br> A1 = 能被5整除的数字中所有偶数的和;</p><p> A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3-n4…;</p><p> A3 = 被5除后余2的数字的个数;</p><p> A4 = 被5除后余3的数字的平均数,精确到小数点后1位;</p><p> A5 = 被5除后余4的数字中最大数字。</p><p><strong>输入:</strong>每个输入包含1个测试用例。<br>每个测试用例先输入一个不超过1000的正整数N。<br>然后给出N个不超过1000的待分类的正整数。数字间以空格分隔。</p><p><strong>输出:</strong>对给定的N个正整数,按题目要求计算A1~A5并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。若其中某一类数字不存在,则在相应位置输出“N”。</p><p><strong>输入例子:</strong></p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">13</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">10</span> <span class="hljs-number">20</span> <span class="hljs-number">16</span> <span class="hljs-number">18</span><br></code></pre></td></tr></table></figure><p><strong>输出例子:</strong></p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">30 </span><span class="hljs-number">11</span> <span class="hljs-number">2</span> <span class="hljs-number">9.7</span> <span class="hljs-number">9</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)我的解法"><a href="#(1)我的解法" class="headerlink" title="(1)我的解法"></a>(1)我的解法</h3><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><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><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> a1 = []<br> a2 = []<br> a3 = []<br> a4 = []<br> a5 = []<br> nums = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>,line.split(<span class="hljs-string">' '</span>))) <br> n = nums[<span class="hljs-number">0</span>]<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> nums[<span class="hljs-number">1</span>:]:<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> i % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>:<br> a1.append(i)<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">1</span>:<br> a2.append(i)<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">2</span>:<br> a3.append(i)<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">3</span>:<br> a4.append(i)<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">4</span>:<br> a5.append(i)<br> <span class="hljs-keyword">if</span> a1:<br> A1 = <span class="hljs-built_in">sum</span>(a1)<br> <span class="hljs-keyword">else</span>:<br> A1 = <span class="hljs-string">'N'</span> <br> <br> A2 = <span class="hljs-number">0</span><br> <span class="hljs-keyword">if</span> a2:<br> <span class="hljs-keyword">for</span> i,num <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(a2):<br> A2 += -((-<span class="hljs-number">1</span>)**(i+<span class="hljs-number">1</span>)*num)<br> <span class="hljs-keyword">else</span>:<br> A2 = <span class="hljs-string">'N'</span><br><br> <span class="hljs-keyword">if</span> a3:<br> A3 = <span class="hljs-built_in">len</span>(a3) <br> <span class="hljs-keyword">else</span>:<br> A3 = <span class="hljs-string">'N'</span> <br><br> <span class="hljs-keyword">if</span> a4:<br> A4 = <span class="hljs-built_in">round</span>(<span class="hljs-built_in">sum</span>(a4) / <span class="hljs-built_in">len</span>(a4),<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">else</span>:<br> A4 = <span class="hljs-string">'N'</span><br> <br> <span class="hljs-keyword">if</span> a5:<br> A5 = <span class="hljs-built_in">max</span>(a5)<br> <span class="hljs-keyword">else</span>:<br> A5 = <span class="hljs-string">'N'</span> <br> <br> <span class="hljs-built_in">print</span>(A1,A2,A3,A4,A5,sep=<span class="hljs-string">' '</span>) <br> <br></code></pre></td></tr></table></figure><h3 id="(2)其他解法"><a href="#(2)其他解法" class="headerlink" title="(2)其他解法"></a>(2)其他解法</h3><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><code class="hljs python">ary = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split()))<br>n, ary = ary[<span class="hljs-number">0</span>], ary[<span class="hljs-number">1</span>:]<br>A1, A2, A4 = [], [], []<br>A3, A5 = <span class="hljs-number">0</span>, -<span class="hljs-number">1</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> ary:<br> <span class="hljs-keyword">if</span> i % <span class="hljs-number">10</span> == <span class="hljs-number">0</span>:<br> A1.append(i)<br> <span class="hljs-keyword">elif</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">1</span>:<br> A2.append(i)<br> <span class="hljs-keyword">elif</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">2</span>:<br> A3 += <span class="hljs-number">1</span><br> <span class="hljs-keyword">elif</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">3</span>:<br> A4.append(i)<br> <span class="hljs-keyword">elif</span> i % <span class="hljs-number">5</span> == <span class="hljs-number">4</span>:<br> <span class="hljs-keyword">if</span> i > A5:<br> A5 = i<br>A1 = <span class="hljs-built_in">str</span>(<span class="hljs-built_in">sum</span>(A1)) <span class="hljs-keyword">if</span> A1 <span class="hljs-keyword">else</span> <span class="hljs-string">'N'</span><br>A2 = <span class="hljs-built_in">str</span>(<span class="hljs-built_in">sum</span>(A2[::<span class="hljs-number">2</span>]) - <span class="hljs-built_in">sum</span>(A2[<span class="hljs-number">1</span>::<span class="hljs-number">2</span>])) <span class="hljs-keyword">if</span> A2 <span class="hljs-keyword">else</span> <span class="hljs-string">'N'</span><br>A3 = <span class="hljs-built_in">str</span>(A3) <span class="hljs-keyword">if</span> A3 <span class="hljs-keyword">else</span> <span class="hljs-string">'N'</span><br>A4 = <span class="hljs-string">'{:.1f}'</span>.<span class="hljs-built_in">format</span>(<span class="hljs-built_in">sum</span>(A4) / <span class="hljs-built_in">len</span>(A4)) <span class="hljs-keyword">if</span> A4 <span class="hljs-keyword">else</span> <span class="hljs-string">'N'</span><br>A5 = <span class="hljs-built_in">str</span>(A5) <span class="hljs-keyword">if</span> A5 != -<span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'N'</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">' '</span>.join((A1, A2, A3, A4, A5)))<br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><p><strong>切片操作</strong></p><blockquote><p>在Python中,对列表进行切片操作时,可以使用<code>[start:stop:step]</code>的形式来指定切片的开始、结束和步长。这里的<code>start</code>表示起始索引,<code>stop</code>表示结束索引(不包含该索引处的元素),<code>step</code>表示步长。计算交错求和的时候,可以计算奇数索引位置上的数字之和减去偶数索引位置上的数字之和。<code>sum(A2[::2])</code>表示求取<code>A2</code>列表中所有偶数索引位置上的数字之和,<code>sum(A2[1::2])</code>表示求取<code>A2</code>列表中所有奇数索引位置上的数字之和。</p></blockquote><p><strong>格式化字符串</strong></p><blockquote><p><code>'{:.1f}'</code> 是一个格式化字符串,它表示将要格式化的值为浮点数,并保留一位小数。这样的格式化字符串会将浮点数格式化为带有一位小数的字符串。</p><ul><li><code>{}</code> 表示一个占位符,用于接受要格式化的值。</li><li><code>:</code> 表示格式说明符的开始。</li><li><code>.1</code> 表示精度为1,即保留一位小数。</li><li><code>f</code> 表示格式化为浮点数。</li></ul><p><code>.format()</code> 方法用于对字符串进行格式化,它可以将指定的值插入到格式化字符串中的大括号处。</p></blockquote><p><strong><code>' '.join()</code>和 <code>sep=' '</code></strong></p><blockquote><p><code>' '.join()</code> 方法的作用是将序列中的元素以指定的字符连接起来形成一个字符串。根据需要在 <code>' '</code> 中间放置任何你想要的分隔符。<code>sep=' '</code> 是 <code>print()</code> 函数的一个参数,用于指定多个要打印内容之间的分隔符</p></blockquote>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode02:字母异位词分组</title>
<link href="/2024/03/06/LeetCode02/"/>
<url>/2024/03/06/LeetCode02/</url>
<content type="html"><![CDATA[<h1 id="2-字母异位词分组"><a href="#2-字母异位词分组" class="headerlink" title="2.字母异位词分组"></a>2.字母异位词分组</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给你一个字符串数组,请你将 <strong>字母异位词</strong> 组合在一起。可以按任意顺序返回结果列表。</p><p><strong>字母异位词</strong> 是由重新排列源单词的所有字母得到的一个新单词。</p><p><strong>示例 1:</strong></p><figure class="highlight prolog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs prolog">输入: strs = [<span class="hljs-string">"eat"</span>, <span class="hljs-string">"tea"</span>, <span class="hljs-string">"tan"</span>, <span class="hljs-string">"ate"</span>, <span class="hljs-string">"nat"</span>, <span class="hljs-string">"bat"</span>]<br>输出: [[<span class="hljs-string">"bat"</span>],[<span class="hljs-string">"nat"</span>,<span class="hljs-string">"tan"</span>],[<span class="hljs-string">"ate"</span>,<span class="hljs-string">"eat"</span>,<span class="hljs-string">"tea"</span>]]<br></code></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs lua">输入: strs = [<span class="hljs-string">""</span>]<br>输出: <span class="hljs-string">[[""]]</span><br></code></pre></td></tr></table></figure><p><strong>示例 3:</strong></p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs lua">输入: strs = [<span class="hljs-string">"a"</span>]<br>输出: <span class="hljs-string">[["a"]]</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)字母排序"><a href="#(1)字母排序" class="headerlink" title="(1)字母排序"></a>(1)字母排序</h3><p>1、首先需要理解什么是字母异位词(相同的字母不同的排列顺序组成的单词)</p><p>2、根据特征进行归类,考虑使用哈希表</p><p>3、构造单词的字符排序,作为键;分组结果,作为值</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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> collections<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">groupAnagrams</span>(<span class="hljs-params">self, strs</span>):<br> mp = collections.defaultdict(<span class="hljs-built_in">list</span>)<br><br> <span class="hljs-keyword">for</span> st <span class="hljs-keyword">in</span> strs:<br> key = <span class="hljs-string">""</span>.join(<span class="hljs-built_in">sorted</span>(st))<br> mp[key].append(st)<br> <br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">list</span>(mp.values())<br></code></pre></td></tr></table></figure><h3 id="(2)字符计数"><a href="#(2)字符计数" class="headerlink" title="(2)字符计数"></a>(2)字符计数</h3><p>1、观察发现,每个字符出现的次数完全相同</p><p>2、根据特征进行归类,考虑使用哈希表</p><p>3、“#1#3…#0”构造各字母出现次数的特征字符串,作为键;具有相同特征字符串的单词放在一组,作为值</p><h4 id="官方题解"><a href="#官方题解" class="headerlink" title="官方题解"></a><strong>官方题解</strong></h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> collections<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">groupAnagrams</span>(<span class="hljs-params">self,strs</span>):<br> mp = collections.defaultdict(<span class="hljs-built_in">list</span>)<br> <br> <span class="hljs-keyword">for</span> st <span class="hljs-keyword">in</span> strs:<br> counts = [<span class="hljs-number">0</span>] *<span class="hljs-number">26</span><br> <span class="hljs-keyword">for</span> ch <span class="hljs-keyword">in</span> st:<br> counts[<span class="hljs-built_in">ord</span>(ch)-<span class="hljs-built_in">ord</span>(<span class="hljs-string">"a"</span>)] += <span class="hljs-number">1</span><br> <span class="hljs-comment"># 需要将list转换为tuple才可以进行哈希</span><br> mp[<span class="hljs-built_in">tuple</span>(counts)].append(st)<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">list</span>(mp.values())<br></code></pre></td></tr></table></figure><h4 id="我的解法"><a href="#我的解法" class="headerlink" title="我的解法"></a><strong>我的解法</strong></h4><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>(<span class="hljs-title class_ inherited__">object</span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">groupAnagrams</span>(<span class="hljs-params">self, strs</span>):<br> total_dict = {}<br> same_map = {}<br> res = []<br> <span class="hljs-keyword">for</span> index,word <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(strs):<br> word_dict = {}<br> <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> word:<br> word_dict[s] = word_dict.get(s,<span class="hljs-number">0</span>) + <span class="hljs-number">1</span><br> total_dict[index] = <span class="hljs-built_in">sorted</span>(word_dict.items())<br> <span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">in</span> total_dict.items():<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">tuple</span>(val) <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> same_map:<br> same_map[<span class="hljs-built_in">tuple</span>(val)] = [key]<br> <span class="hljs-keyword">else</span>:<br> same_map[<span class="hljs-built_in">tuple</span>(val)].append(key)<br> <span class="hljs-keyword">for</span> tar <span class="hljs-keyword">in</span> same_map.values():<br> target = [strs[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> tar]<br> res.append(target)<br> <span class="hljs-keyword">return</span> res<br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><ul><li><strong>时间与空间复杂度</strong></li></ul><blockquote><p>1、字母排序:N是单词的个数,K是单词的最大长度。遍历每个单词的时间复杂度是O(N),对于每个单词的排序时间复杂度为O(Klog(K))。综合以上两点,时间复杂度为O(NKlog(K))。空间上需要O(NK)存储所有单词。</p><p>2、字符计数:因为需要遍历每个单词的每个字符,时间复杂度为O(NK),空间复杂度为O(NK)。</p></blockquote><ul><li><strong><code>defaultdict</code></strong></li></ul><blockquote><p><code>collections.defaultdict(list)</code> 是 Python 中 <code>collections</code> 模块提供的一个类,它是字典的一个子类,用于创建默认值为指定类型(这里是列表)的字典。在使用 <code>defaultdict</code> 时,如果访问一个不存在的键,它会自动创建该键,并将其对应的值初始化为指定类型的默认值。</p></blockquote><ul><li><strong><code>ord()</code> 函数</strong></li></ul><blockquote><p><code>ord()</code> 函数用于返回表示单个字符的 Unicode 字符编码。对于小写字母,<code>ord("a")</code> 返回的是 97,<code>ord("b")</code> 返回的是 98,依此类推。<code>ord(ch) - ord("a")</code>:假设当前字符是小写字母,通过将当前字符的 Unicode 编码减去小写字母 “a” 的 Unicode 编码(即 97),可以得到一个从 0 到 25 的索引值,用来表示该字符在英文字母中的位置,例如 a 对应 0,b 对应 1,依此类推。</p></blockquote><ul><li><strong>字典(dictionary)</strong></li></ul><blockquote><p>在Python中,字典(dictionary)是一种无序的数据类型,用于存储键值对。字典是一种非常灵活和强大的数据结构,常用于存储和操作各种类型的数据。</p></blockquote><p>以下是关于字典的一些常见用法:</p><ol><li><p>创建字典:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">my_dict = {<span class="hljs-string">'A'</span>: <span class="hljs-number">100</span>, <span class="hljs-string">'B'</span>: <span class="hljs-number">200</span>, <span class="hljs-string">'C'</span>: <span class="hljs-number">300</span>}<br></code></pre></td></tr></table></figure></li><li><p>添加或更新键值对:</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><code class="hljs python">my_dict[<span class="hljs-string">'D'</span>] = <span class="hljs-number">400</span> <span class="hljs-comment"># 添加新的键值对</span><br>my_dict[<span class="hljs-string">'A'</span>] = <span class="hljs-number">500</span> <span class="hljs-comment"># 更新已有键的值</span><br></code></pre></td></tr></table></figure></li><li><p>访问字典中的元素:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">value = my_dict[<span class="hljs-string">'A'</span>] <span class="hljs-comment"># 获取键为'A'的值</span><br></code></pre></td></tr></table></figure></li><li><p>删除键值对:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">del</span> my_dict[<span class="hljs-string">'B'</span>] <span class="hljs-comment"># 删除键为'B'的键值对</span><br></code></pre></td></tr></table></figure></li><li><p>遍历字典:</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><code class="hljs python"><span class="hljs-keyword">for</span> key, value <span class="hljs-keyword">in</span> my_dict.items():<br> <span class="hljs-built_in">print</span>(key, value)<br></code></pre></td></tr></table></figure></li><li><p>检查键是否存在:</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><code class="hljs python"><span class="hljs-keyword">if</span> <span class="hljs-string">'A'</span> <span class="hljs-keyword">in</span> my_dict:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'A exists in the dictionary'</span>)<br></code></pre></td></tr></table></figure></li><li><p>获取所有键或所有值:</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><code class="hljs python">keys = my_dict.keys() <span class="hljs-comment"># 获取所有键</span><br>values = my_dict.values() <span class="hljs-comment"># 获取所有值</span><br></code></pre></td></tr></table></figure></li><li><p>获取默认值:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">value = my_dict.get(<span class="hljs-string">'A'</span>, <span class="hljs-number">0</span>) <span class="hljs-comment"># 获取键'A'的值,如果不存在则返回默认值0</span><br></code></pre></td></tr></table></figure></li><li><p>使用字典推导式创建字典:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">squares = {x: x*x <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>)} <span class="hljs-comment"># 创建包含1到5的平方的字典</span><br></code></pre></td></tr></table></figure></li></ol>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>哈希表</tag>
</tags>
</entry>
<entry>
<title>PAT01:A+B和C</title>
<link href="/2024/03/02/PAT01/"/>
<url>/2024/03/02/PAT01/</url>
<content type="html"><![CDATA[<h1 id="1-A-B和C"><a href="#1-A-B和C" class="headerlink" title="1.A+B和C"></a>1.A+B和C</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定区间[-231, 231]内的3个整数A、B和C,请判断A+B是否大于C。</p><p><strong>输入:</strong>输入第1行给出正整数T(<=10),是测试用例的个数。随后给出T组测试用例,每组占一行,顺序给出A、B和C。整数间以空格分隔。</p><p><strong>输出:</strong>对每组测试用例,在一行中输出“Case #X: true”如果A+B>C,否则输出“Case #X: false”,其中X是测试用例的编号(从1开始)。</p><p><strong>输入例子:</strong></p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-number">4</span><br><span class="hljs-symbol">1 </span><span class="hljs-number">2</span> <span class="hljs-number">3</span><br><span class="hljs-symbol">2 </span><span class="hljs-number">3</span> <span class="hljs-number">4</span><br><span class="hljs-symbol">2147483647 </span><span class="hljs-number">0</span> <span class="hljs-number">2147483646</span><br><span class="hljs-symbol">0 </span>-<span class="hljs-number">2147483648</span> -<span class="hljs-number">2147483647</span><br></code></pre></td></tr></table></figure><p><strong>输出例子:</strong></p><figure class="highlight cal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cal"><span class="hljs-keyword">Case</span> <span class="hljs-string">#1</span>: <span class="hljs-literal">false</span><br><span class="hljs-keyword">Case</span> <span class="hljs-string">#2</span>: <span class="hljs-literal">true</span><br><span class="hljs-keyword">Case</span> <span class="hljs-string">#3</span>: <span class="hljs-literal">true</span><br><span class="hljs-keyword">Case</span> <span class="hljs-string">#4</span>: <span class="hljs-literal">false</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)我的解法"><a href="#(1)我的解法" class="headerlink" title="(1)我的解法"></a>(1)我的解法</h3><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><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><br>index = <span class="hljs-number">0</span><br><span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> sys.stdin:<br> index +=<span class="hljs-number">1</span><br> a = line.split()<br> a = [<span class="hljs-built_in">int</span>(i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> a]<br> <span class="hljs-keyword">if</span> index == <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f'Case #<span class="hljs-subst">{index-<span class="hljs-number">1</span>}</span>: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(a[<span class="hljs-number">0</span>]+a[<span class="hljs-number">1</span>]>a[<span class="hljs-number">2</span>]).lower()}</span>'</span>)<br></code></pre></td></tr></table></figure><h3 id="(2)其他解法"><a href="#(2)其他解法" class="headerlink" title="(2)其他解法"></a>(2)其他解法</h3><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><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> a,b,c = <span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>,<span class="hljs-built_in">input</span>().split())<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'Case #'</span>+<span class="hljs-built_in">str</span>((i+<span class="hljs-number">1</span>))+<span class="hljs-string">': true'</span> <span class="hljs-keyword">if</span> a+b>c <span class="hljs-keyword">else</span> <span class="hljs-string">'Case #'</span>+<span class="hljs-built_in">str</span>((i+<span class="hljs-number">1</span>))+<span class="hljs-string">': false'</span>)<br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><ul><li><code>sys.stdin</code></li></ul><blockquote><p><code>sys.stdin</code>是Python中<code>sys</code>模块的一个属性,代表了标准输入流。在计算机程序中,标准输入流是一个用于接收输入数据的通道,通常情况下它是与键盘输入关联的,但也可以通过重定向或管道从文件或其他程序接收输入。</p><p>在Python程序中,使用<code>sys.stdin</code>可以读取来自命令行(或任何被重定向为标准输入源的数据)的输入。<code>sys.stdin</code>本质上是一个文件对象,因此可以对它使用文件操作的方法,如<code>read()</code>, <code>readline()</code>和<code>readlines()</code>等,来读取输入的数据。</p><p>1、<code>sys.stdin.read()</code>: 读取并返回所有剩余的输入数据,直到遇到EOF(文件结束符)。</p><p>2、<code>sys.stdin.readline()</code>: 每次调用读取一行输入,包括行尾的换行符,如果已经到达EOF,则返回一个空字符串。</p><p>3、<code>sys.stdin.readlines()</code>: 读取所有剩余的输入行,并将它们作为字符串列表返回。</p><p><code>for line in sys.stdin:</code>循环会逐行读取标准输入直到EOF。这种方式特别适合处理不确定数量的输入行。</p><p>在命令行环境中,通常可以通过<code>Ctrl+D</code>(在Unix/Linux/macOS系统中)或<code>Ctrl+Z</code>然后回车(在Windows系统中)来发送EOF信号。此外,<code>sys.stdin</code>也常被用于从文件中读取输入,通过命令行重定向操作,例如<code>python script.py < inputfile.txt</code>,这时<code>inputfile.txt</code>的内容会被作为标准输入传递给脚本。</p></blockquote><ul><li><strong>三元运算符</strong></li></ul><blockquote><p><code>print("Case #"+str(i+1)+": true" if b+c>d else "Case #"+str(i+1)+": false")</code>: </p><p>使用条件表达式(三元操作符)简化逻辑判断,而且字符串不能直接拼接整数,需要先对整数进行<code>str()</code></p></blockquote>]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
</tags>
</entry>
<entry>
<title>LeetCode01:两数之和</title>
<link href="/2024/03/02/LeetCode01/"/>
<url>/2024/03/02/LeetCode01/</url>
<content type="html"><![CDATA[<h1 id="1-两数之和"><a href="#1-两数之和" class="headerlink" title="1. 两数之和"></a>1. 两数之和</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>给定一个整数数组 <code>nums</code> 和一个整数目标值 <code>target</code>,请你在该数组中找出 <strong>和为目标值</strong> <em><code>target</code></em> 的那 <strong>两个</strong> 整数,并返回它们的数组下标。</p><p>你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。</p><p>你可以按任意顺序返回答案。</p><p><strong>示例 1:</strong></p><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs inform7">输入:nums = <span class="hljs-comment">[2,7,11,15]</span>, target = 9<br>输出:<span class="hljs-comment">[0,1]</span><br>解释:因为 nums<span class="hljs-comment">[0]</span> + nums<span class="hljs-comment">[1]</span> == 9 ,返回 <span class="hljs-comment">[0, 1]</span> 。<br></code></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs inform7">输入:nums = <span class="hljs-comment">[3,2,4]</span>, target = 6<br>输出:<span class="hljs-comment">[1,2]</span><br></code></pre></td></tr></table></figure><p><strong>示例 3:</strong></p><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs inform7">输入:nums = <span class="hljs-comment">[3,3]</span>, target = 6<br>输出:<span class="hljs-comment">[0,1]</span><br></code></pre></td></tr></table></figure><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="(1)暴力枚举"><a href="#(1)暴力枚举" class="headerlink" title="(1)暴力枚举"></a>(1)暴力枚举</h3><p>枚举数组中的每一个数<code>x</code>,寻找数组中是否存在<code>target-x</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><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">twoSum</span>(<span class="hljs-params">self,nums,target</span>):<br> n = <span class="hljs-built_in">len</span>(nums)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(i+<span class="hljs-number">1</span>,n):<br> <span class="hljs-keyword">if</span> nums[i] + nums[j] == target:<br> <span class="hljs-keyword">return</span> [i,j]<br> <span class="hljs-keyword">return</span> []<br></code></pre></td></tr></table></figure><h3 id="(2)哈希表"><a href="#(2)哈希表" class="headerlink" title="(2)哈希表"></a>(2)哈希表</h3><p>对于数组中的每一个数<code>x</code>,首先查询哈希表中是否存在<code>target-x</code>,如果存在则返回结果,不存在就将<code>x</code>插入到哈希表中,保证不会让<code>x</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><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><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">twoSum</span>(<span class="hljs-params">self,nums,target</span>):<br> hashtable = <span class="hljs-built_in">dict</span>()<br> <span class="hljs-keyword">for</span> i,num <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(nums):<br> num2 = target - num <br> <span class="hljs-built_in">print</span>(num,num2)<br> <span class="hljs-keyword">if</span> num2 <span class="hljs-keyword">in</span> hashtable:<br> <span class="hljs-keyword">return</span> [i,hashtable[num2]]<br> hashtable[num] = i<br> <span class="hljs-built_in">print</span>(hashtable)<br> <span class="hljs-keyword">return</span> [] <br></code></pre></td></tr></table></figure><h2 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h2><ul><li><p><strong>是否会报超出索引异常</strong></p><blockquote><p>在方法一的双层for循环中,假设<code>nums</code>为5个元素,当for的外层循环遍历到最后一个元素时,<code>i</code>为4,内层循环涉及到<code>for j in range(5,5)</code>,生成的序列将是空的。因此,<code>for j in range(5,5)</code> 实际上不会执行循环体内的任何代码,也不存在报错。在 Python 中,尝试访问超出数组(列表)索引的元素会引发错误。具体来说,如果尝试访问一个不存在的索引位置,Python 会抛出 <code>IndexError</code> 异常。</p></blockquote></li><li><p><strong>时间与空间复杂度</strong></p><blockquote><p>1、使用暴力枚举,时间复杂度为O($n^2$),因为需要使用两层循环来检查数组中每对不同的元素,看它们的和是否等于 <code>target</code>;空间复杂度为O(1),因为除了输入和输出之外,只需要有限的额外空间。</p><p>2、使用哈希表,时间复杂度为O(n),因为只需要遍历数组一次,对于每个元素,可以在 O(1) 的时间内通过哈希表检查 <code>target - num</code> 是否存在;空间复杂度为O(n),因为最坏的情况下,可能需要将数组中的所有元素都存储在哈希表中。</p></blockquote></li></ul>]]></content>
<categories>
<category>LeetCode</category>
</categories>
<tags>
<tag>Python</tag>
<tag>题库</tag>
<tag>哈希表</tag>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title>Test</title>
<link href="/2024/02/28/Test/"/>
<url>/2024/02/28/Test/</url>
<content type="html"><![CDATA[<h1 id="欢迎你"><a href="#欢迎你" class="headerlink" title="欢迎你"></a>欢迎你</h1><p>这是一篇测试文章。</p><p>我是一个很懒的人,做到这一步已经很棒了。</p><p><img src="https://an-hexo-blog.oss-cn-beijing.aliyuncs.com/img/202402281629110.jpeg" alt="有什么特别可爱猫猫的动态图或表情包吗? - 知乎"></p>]]></content>
<categories>
<category>其他</category>
</categories>
<tags>
<tag>乱七八糟</tag>
</tags>
</entry>
</search>