-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
1058 lines (509 loc) · 434 KB
/
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
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>【个人代码及思路】PAT甲级:1066 Root of AVL Tree (25分)</title>
<link href="/2020/10/08/PAT-AdvancedLevel1066/"/>
<url>/2020/10/08/PAT-AdvancedLevel1066/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1066-Root-of-AVL-Tree-25分"><a href="#1066-Root-of-AVL-Tree-25分" class="headerlink" title="1066 Root of AVL Tree (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805404939173888" target="_blank" rel="noopener">1066 Root of AVL Tree (25分)</a></h2><p>An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.</p><p><img src="https://images.ptausercontent.com/31" alt="img"> <img src="https://images.ptausercontent.com/32" alt="img"></p><p><img src="https://images.ptausercontent.com/33" alt="img"> <img src="https://images.ptausercontent.com/34" alt="img"></p><p>Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. For each case, the first line contains a positive integer <em>N</em> (≤20) which is the total number of keys to be inserted. Then <em>N</em> distinct integer keys are given in the next line. All the numbers in a line are separated by a space.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, print the root of the resulting AVL tree in one line.</p><h3 id="Sample-Input-1"><a href="#Sample-Input-1" class="headerlink" title="Sample Input 1:"></a>Sample Input 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">5</span><br><span class="line">88 70 61 96 120</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-1"><a href="#Sample-Output-1" class="headerlink" title="Sample Output 1:"></a>Sample Output 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">70</span><br></pre></td></tr></table></figure><h3 id="Sample-Input-2"><a href="#Sample-Input-2" class="headerlink" title="Sample Input 2:"></a>Sample Input 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">7</span><br><span class="line">88 70 61 96 120 90 65</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-2"><a href="#Sample-Output-2" class="headerlink" title="Sample Output 2:"></a>Sample Output 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">88</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="comment">// #define LOCAL</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">AVLNode</span> {</span> <span class="comment">//AVL树结点</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">height</span>, val;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">AVLNode</span> *<span class="title">lchild</span>, *<span class="title">rchild</span>, *<span class="title">parent</span>;</span></span><br><span class="line">} AVLNode, *AVLTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">// void InitAVLTree (AVLTree &T) { //初始化</span></span><br><span class="line"><span class="comment">// T -> lheight = 0;</span></span><br><span class="line"><span class="comment">// T -> rheight = 0;</span></span><br><span class="line"><span class="comment">// T -> lchild = NULL;</span></span><br><span class="line"><span class="comment">// T -> rchlid = NULL;</span></span><br><span class="line"><span class="comment">// T -> parent = NULL;</span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line"></span><br><span class="line"><span class="function">AVLNode *<span class="title">AVLTreeInsert</span> <span class="params">(AVLTree &T, <span class="keyword">int</span> val)</span> </span>{ <span class="comment">//插入新的结点</span></span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>) {</span><br><span class="line"> T = (AVLTree)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(AVLNode));</span><br><span class="line"> T->val = val;</span><br><span class="line"> T->lchild = <span class="literal">NULL</span>;</span><br><span class="line"> T->rchild = <span class="literal">NULL</span>;</span><br><span class="line"> T->parent = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">return</span> T;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (val < T->val) {</span><br><span class="line"> <span class="keyword">return</span> AVLTreeInsert(T->lchild, val);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> AVLTreeInsert(T->rchild, val);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">AVLTreeHeight</span> <span class="params">(AVLTree &T)</span> </span>{ <span class="comment">//求高度</span></span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">int</span> lheight, rheight;</span><br><span class="line"> lheight = AVLTreeHeight(T->lchild);</span><br><span class="line"> rheight = AVLTreeHeight(T->rchild);</span><br><span class="line"> T-><span class="built_in">height</span> = <span class="built_in">max</span>(lheight + <span class="number">1</span>, rheight + <span class="number">1</span>);</span><br><span class="line"> <span class="comment">// printf("%d*\n", T -> height);</span></span><br><span class="line"> <span class="keyword">return</span> T-><span class="built_in">height</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SetParent</span> <span class="params">(AVLTree &T)</span> </span>{ <span class="comment">//设置双亲结点</span></span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>) {</span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (T->lchild != <span class="literal">NULL</span>) {</span><br><span class="line"> T->lchild->parent = T;</span><br><span class="line"> SetParent(T->lchild);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (T->rchild != <span class="literal">NULL</span>) {</span><br><span class="line"> T->rchild->parent = T;</span><br><span class="line"> SetParent(T->rchild);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">AVLTreeLrevov</span> <span class="params">(AVLTree &p, AVLTree &T)</span> </span>{ <span class="comment">//左旋操作</span></span><br><span class="line"> <span class="keyword">if</span> (p->parent->parent != <span class="literal">NULL</span>) { <span class="comment">//首先判断需要旋转的结点的双亲结点的双亲结点是否为空</span></span><br><span class="line"> <span class="keyword">if</span> (p->parent->val < p->parent->parent->val) { <span class="comment">//若不为空,则需要将其指针指向需要旋转的结点</span></span><br><span class="line"> p->parent->parent->lchild = p; <span class="comment">//根据大小规则判断是更改其祖先的左孩子指针还是右孩子指针</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> p->parent->parent->rchild = p;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> p->parent->rchild = p->lchild; <span class="comment">//将需要旋转的结点的双亲结点的右孩子指向将需要旋转的结点的左孩子</span></span><br><span class="line"> p->lchild = p->parent; <span class="comment">//将需要旋转的结点的左孩子指向该结点原来的双亲结点</span></span><br><span class="line"> <span class="keyword">if</span> (p->lchild->val == T->val) { <span class="comment">//如果需要旋转的结点变成新的根结点,则移动根结点指针指向它并将根结点的双亲指针清空</span></span><br><span class="line"> T = p; </span><br><span class="line"> T->parent = <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">AVLTreeRrevov</span> <span class="params">(AVLTree &p, AVLTree &T)</span> </span>{ <span class="comment">//右旋操作</span></span><br><span class="line"> <span class="keyword">if</span> (p->parent->parent != <span class="literal">NULL</span>) { <span class="comment">//首先判断需要旋转的结点的双亲结点的双亲结点是否为空</span></span><br><span class="line"> <span class="keyword">if</span> (p->parent->val < p->parent->parent->val) { <span class="comment">//若不为空,则需要将其指针指向需要旋转的结点</span></span><br><span class="line"> p->parent->parent->lchild = p; <span class="comment">//根据大小规则判断是更改其祖先的左孩子指针还是右孩子指针</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> p->parent->parent->rchild = p;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> p->parent->lchild = p->rchild; <span class="comment">//将需要旋转的结点的双亲结点的左孩子指向将需要旋转的结点的右孩子</span></span><br><span class="line"> p->rchild = p->parent; <span class="comment">//将需要旋转的结点的右孩子指向该结点原来的双亲结点</span></span><br><span class="line"> <span class="keyword">if</span> (p->rchild->val == T->val) { <span class="comment">//如果需要旋转的结点变成新的根结点,则移动根结点指针指向它并将根结点的双亲指针清空</span></span><br><span class="line"> T = p;</span><br><span class="line"> T->parent = <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// void visit (AVLTree T) { //前序遍历</span></span><br><span class="line"><span class="comment">// if (T != NULL) {</span></span><br><span class="line"><span class="comment">// printf("T->val=%d,T->height=%d--\n",T->val, T->height);</span></span><br><span class="line"><span class="comment">// visit (T->lchild);</span></span><br><span class="line"><span class="comment">// visit (T->rchild);</span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> LOCAL</span></span><br><span class="line"> freopen(<span class="string">"./in.txt"</span>, <span class="string">"r"</span>, <span class="built_in">stdin</span>);</span><br><span class="line"> <span class="comment">// freopen("./out.txt", "w", stdout);</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> AVLTree T = <span class="literal">NULL</span>;</span><br><span class="line"> AVLNode *p = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="comment">// InitAVLTree (T);</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">int</span> lheight = <span class="number">0</span>, rheight = <span class="number">0</span>, value = <span class="number">0</span>; <span class="comment">//左子树高度、右子树高度、值</span></span><br><span class="line"> <span class="keyword">int</span> revov = <span class="number">0</span>; <span class="comment">//标志需要进行的旋转操作,0-4代表结点类型,不操作,LL,LR,RL,RR</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &value);</span><br><span class="line"> p = AVLTreeInsert(T, value);</span><br><span class="line"> AVLTreeHeight(T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> <span class="keyword">while</span> (p != <span class="literal">NULL</span>) { <span class="comment">//找到第一个不平衡结点</span></span><br><span class="line"> <span class="keyword">if</span> (p->lchild != <span class="literal">NULL</span>) { <span class="comment">//左子树高度</span></span><br><span class="line"> lheight = p->lchild-><span class="built_in">height</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> lheight = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (p->rchild != <span class="literal">NULL</span>) { <span class="comment">//右子树高度</span></span><br><span class="line"> rheight = p->rchild-><span class="built_in">height</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> rheight = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">abs</span>(lheight - rheight) < <span class="number">2</span>) { <span class="comment">//从插入点往上寻找双亲结点,使p为第一个不平衡结点</span></span><br><span class="line"> p = p->parent;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">abs</span>(lheight - rheight) >= <span class="number">2</span>) { <span class="comment">//p可能为NULL,可能为第一个不平衡结点</span></span><br><span class="line"> <span class="keyword">if</span> (value < p->val) {</span><br><span class="line"> p = p->lchild; <span class="comment">//需要进行LL/LR旋转操作</span></span><br><span class="line"> <span class="keyword">if</span> (value < p->val) {</span><br><span class="line"> revov = <span class="number">1</span>; <span class="comment">//LL旋转操作</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> revov = <span class="number">2</span>; <span class="comment">//LR旋转操作</span></span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> p = p->rchild; <span class="comment">//需要进行RL/RR旋转操作</span></span><br><span class="line"> <span class="keyword">if</span> (value < p->val) {</span><br><span class="line"> revov = <span class="number">3</span>; <span class="comment">//RL旋转操作</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> revov = <span class="number">4</span>; <span class="comment">//RR旋转操作</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">switch</span> (revov) { <span class="comment">//根据不平衡点类型选择旋转操作,旋转后注意重新设置双亲结点</span></span><br><span class="line"> <span class="keyword">case</span> <span class="number">0</span>: <span class="comment">//不是不平衡点,不进行操作</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">1</span>: <span class="comment">//LL类型进行右旋操作,旋转的对象是不平衡结点的左结点即p</span></span><br><span class="line"> AVLTreeRrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">2</span>: <span class="comment">//LR类型先进行左旋操作再进行右旋操作,旋转的对象是不平衡结点的左结点的右结点即p->rchild</span></span><br><span class="line"> p = p->rchild;</span><br><span class="line"> AVLTreeLrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> AVLTreeRrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">3</span>: <span class="comment">//RL类型先进行右旋操作再进行左旋操作,旋转的对象是不平衡结点的右结点的左结点即p->lchild</span></span><br><span class="line"> p = p->lchild; </span><br><span class="line"> AVLTreeRrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> AVLTreeLrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">4</span>: <span class="comment">//RR类型进行左旋操作,旋转的对象是不平衡结点的右结点即p</span></span><br><span class="line"> AVLTreeLrevov(p, T);</span><br><span class="line"> SetParent(T);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// visit(T); //遍历一遍AVL树,检查是否正确</span></span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, T->val); <span class="comment">//已经成功构建AVL树,选择自己的操作</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>建立AVL树的步骤如下:</p><ul><li>首先定义AVL树的结点,包含高度、值、指向孩子结点和双亲结点的指针等信息</li><li>每读入一个结点,就要将他按照BST的排序规则插入AVL树中</li><li>每个结点插入后,检查AVL树中每个结点是否满足左右子树高度相差的绝对值不超过1,方法是从刚插入的结点往上找他的双亲结点(设置双亲结点的好处)</li><li>找到最近的一个不满足平衡条件的结点,根据LL、LR、RL、RR四种类型确定需要进行旋转的操作和对象</li><li>注意,当树的高度和双亲节点变化后,需要及时的通过函数更新</li></ul>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1060 Are They Equal (25分)</title>
<link href="/2020/09/25/PAT-AdvancedLevel1060/"/>
<url>/2020/09/25/PAT-AdvancedLevel1060/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1060-Are-They-Equal-25分"><a href="#1060-Are-They-Equal-25分" class="headerlink" title="1060 Are They Equal (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805413520719872" target="_blank" rel="noopener">1060 Are They Equal (25分)</a></h2><p>If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123×105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case which gives three numbers <em>N</em>, <em>A</em> and <em>B</em>, where <em>N</em> (<100) is the number of significant digits, and <em>A</em> and <em>B</em> are the two float numbers to be compared. Each float number is non-negative, no greater than 10100, and that its total digit number is less than 100.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, print in a line <code>YES</code> if the two numbers are treated equal, and then the number in the standard form <code>0.d[1]...d[N]*10^k</code> (<code>d[1]</code>>0 unless the number is 0); or <code>NO</code> if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.</p><p>Note: Simple chopping is assumed without rounding.</p><h3 id="Sample-Input-1"><a href="#Sample-Input-1" class="headerlink" title="Sample Input 1:"></a>Sample Input 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3 12300 12358.9</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-1"><a href="#Sample-Output-1" class="headerlink" title="Sample Output 1:"></a>Sample Output 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">YES 0.123*10^5</span><br></pre></td></tr></table></figure><h3 id="Sample-Input-2"><a href="#Sample-Input-2" class="headerlink" title="Sample Input 2:"></a>Sample Input 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3 120 128</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-2"><a href="#Sample-Output-2" class="headerlink" title="Sample Output 2:"></a>Sample Output 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NO 0.120*10^3 0.128*10^3</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> n, indexA, indexB; <span class="comment">//记录标准输出的指数</span></span><br><span class="line"><span class="built_in">string</span> strA, strB;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">indexLen</span> <span class="params">(<span class="built_in">string</span> &str)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> lens = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">string</span>::iterator it = str.<span class="built_in">begin</span>();</span><br><span class="line"> <span class="comment">//去除前导0</span></span><br><span class="line"> <span class="keyword">while</span> (*it == <span class="string">'0'</span>) {</span><br><span class="line"> <span class="keyword">if</span> (str.length() != <span class="number">1</span>) {</span><br><span class="line"> str.erase(it);</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">//0</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (*it == <span class="string">'.'</span>) { <span class="comment">//0.---</span></span><br><span class="line"> str.erase(it); <span class="comment">//去除小数点</span></span><br><span class="line"> <span class="keyword">if</span> (*it != <span class="string">'0'</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; <span class="comment">//0.k(k!=0)</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">//去除0.类的小数点后面的连续0</span></span><br><span class="line"> <span class="keyword">while</span> (str.length() != <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">if</span> (*it == <span class="string">'0'</span>) {</span><br><span class="line"> i++;</span><br><span class="line"> str.erase(it);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (*it == <span class="string">'0'</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; <span class="comment">//0.0</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> -i; <span class="comment">//0.0k(k!=0)</span></span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">//k或者k.---(k!=0)</span></span><br><span class="line"> <span class="keyword">if</span> (str.<span class="built_in">find</span>(<span class="string">"."</span>) == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">return</span> str.length(); <span class="comment">//k</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">int</span> flo = str.<span class="built_in">find</span>(<span class="string">"."</span>);</span><br><span class="line"> str.erase(it + str.<span class="built_in">find</span>(<span class="string">"."</span>) );</span><br><span class="line"> <span class="keyword">return</span> flo; <span class="comment">//k.---</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="built_in">string</span> str)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> len = str.length();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span> (i < len) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c"</span>, *(str.<span class="built_in">begin</span>() + i));</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"0"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">cin</span> >> n >> strA >> strB;</span><br><span class="line"> <span class="comment">//确定指数</span></span><br><span class="line"> indexA = indexLen(strA);</span><br><span class="line"> indexB = indexLen(strB);</span><br><span class="line"> <span class="keyword">bool</span> flag = <span class="literal">true</span>; <span class="comment">//判断YESorNO</span></span><br><span class="line"> <span class="keyword">if</span> (indexA != indexB) {</span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span> (*(i + strA.<span class="built_in">begin</span>()) != *(i + strB.<span class="built_in">begin</span>())) {</span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (flag) { <span class="comment">//输出</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"YES 0."</span>);</span><br><span class="line"> <span class="built_in">print</span>(strA);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"*10^%d"</span>, indexA);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"NO 0."</span>);</span><br><span class="line"> <span class="built_in">print</span>(strA);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"*10^%d 0."</span>, indexA);</span><br><span class="line"> <span class="built_in">print</span>(strB);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"*10^%d"</span>, indexB);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>本题的构思并不复杂,但是坑很多,特别是0开头的数据。由于题目的提示不是很多,所以需要自己去尝试。</p><p>建议将一个数分为这几类:0、0.0、0.0k、k、k.k,这样易于理解。其中0代表的是一连串的0,k代表的是不为0的数。</p><p>可以看出由0开头的数据最为复杂且容易出错,因此需要仔细一点!</p><p>建议是先得出指数,然后把连续的0和小数点处理掉。</p><p>再最后打印时,如果有数位不够的情况需要补0.</p><p>另外,这题代码的很多部分都可以复用,这样可以减少代码量,让代码更简洁。</p><h3 id="测试用例"><a href="#测试用例" class="headerlink" title="测试用例:"></a>测试用例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">3 12300 12358.9</span><br><span class="line">3 120 128</span><br><span class="line">5 0.00001 0.00001</span><br><span class="line">1 0.001 0.2000</span><br><span class="line">2 005.06 0.230</span><br><span class="line">1 00.020 0</span><br></pre></td></tr></table></figure><h3 id=""><a href="#" class="headerlink" title=" "></a> </h3>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】常用头文件下的函数介绍:algorithm</title>
<link href="/2020/09/23/headerFile-algorithm/"/>
<url>/2020/09/23/headerFile-algorithm/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="常用头文件下的函数介绍:algorithm"><a href="#常用头文件下的函数介绍:algorithm" class="headerlink" title="常用头文件下的函数介绍:algorithm"></a>常用头文件下的函数介绍:algorithm</h1><p>C语言提供了很多实用的数学函数,如果要使用,需要在程序开头添加头文件cmath或者math.h。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-max-、min-和abs"><a href="#1-max-、min-和abs" class="headerlink" title="1. max()、min()和abs()"></a>1. max()、min()和abs()</h2><p> max(x, y)和min(x, y)分别用来返回x和y(同类型)中的最大值和最小值,且参数必须是两个;</p><p>abs(x) 用来返回整数x的绝对值,浮点型的绝对值则使用头文件camth下面的fabs。</p><h2 id="2-swap"><a href="#2-swap" class="headerlink" title="2. swap()"></a>2. swap()</h2><p> swap(x, y)用来交换x和y的值</p><h2 id="3-reverse"><a href="#3-reverse" class="headerlink" title="3. reverse()"></a>3. reverse()</h2><p> reverse(it1, it2)用来将数组在指针[it1, it2)之间的元素或者容器在迭代器[it1, it2)范围内的元素进行反转(倒序)。</p><h2 id="4-next-permutation"><a href="#4-next-permutation" class="headerlink" title="4. next_permutation()"></a>4. next_permutation()</h2><p>next_permutation(a, a+i)用于将数组在指针[a, a+i)之间的元素或者容器(vector, string等)在迭代器[a, a+i)范围内的元素重新排列,得到全排列中的下一个序列</p><p>注:关于全排列是如何实现的,可以参考:<a href="https://www.cnblogs.com/luruiyuan/p/5914909.html" target="_blank" rel="noopener">全排列</a></p><h2 id="5-fill"><a href="#5-fill" class="headerlink" title="5. fill()"></a>5. fill()</h2><p>fill(a, a+i, num)用于将数组在指针[a, a+i)之间的元素或者容器在迭代器[a, a+i)范围内的元素赋为某个相同的值num,这个值可以是数据类型中对应范围内的任意值。</p><p>注:memset(a, num, sizeof(a))一般用来将数组(a是数组名)赋值为0或者-1。因为memset是按字节赋值的,0的二进制补码为全0,-1的二进制补码为全1,因此超过一个字节的数据类型只有赋值0,-1不容易出错。</p><h2 id="6-sort"><a href="#6-sort" class="headerlink" title="6. sort()"></a>6. sort()</h2><p>sort就是用来排序的函数,效率较高。基本数据类型的数组、结构体数组和STL容器都可以用sort进行排序。</p><p><strong>(1)如何使用sort排序</strong></p><p>sort(a, a+i, cmp)用于将数组在指针[a, a+i)之间的元素或者容器在迭代器[a, a+i)范围内的元素按照cmp函数的排序规则进行排序,其中cmp函数是可选参数,若没有cmp函数则默认增序排序。如需要自己制定排序规则(比如数值大小、字符字典序、字符串长度等等),则需要自己写cmp函数</p><p><strong>(2)如何实现比较函数cmp</strong></p><p>如上,cmp函数实现的就是自己想制定的排序规则。所以,cmp()函数需要表明这个规则。</p><p>cmp()函数的具体内容是返回值bool类型,接收两个同类型(基本数据类型的数组、结构体数组和STL容器)的参数,函数体中只包含return语句。return语句中包含的是一个比较表达式如”a>b”, “a<b"。">“代表着从大到小排序,”<”代表着从小到大排序。下面举例说明:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//基本数据类型的数组</span></span><br><span class="line"><span class="keyword">int</span> a[<span class="number">5</span>];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span> <span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> a < b; <span class="comment">//根据数值从小到大排序</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">sort(a, a+<span class="number">4</span>, cmp); <span class="comment">//将数组a的[0,4)即a[0], a[1], a[2], [3]进行从小到大排序</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//结构体数组</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">node</span> {</span></span><br><span class="line"> <span class="keyword">int</span> x, y;</span><br><span class="line">}ssd[<span class="number">10</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span> <span class="params">(node a, node b)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(a.x != b.x) <span class="keyword">return</span> a.x > b.x; <span class="comment">//先根据x属性从大到小排序</span></span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">return</span> a.y < b.y; <span class="comment">//若x属性相同,再根据y属性从小到大排序</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">sort(ssd, ssd+<span class="number">5</span> cmp); <span class="comment">//将结构体数组ssd的[0,5)进行排序</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//STL容器</span></span><br><span class="line"><span class="built_in">string</span> str[<span class="number">3</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span> <span class="params">(<span class="built_in">string</span> str1, <span class="built_in">string</span> str2)</span> </span>{ <span class="comment">//如果是对单个字符串排序,那么参数类型为char,相当于字符数组</span></span><br><span class="line"> <span class="keyword">return</span> str1.length() < str2length(); <span class="comment">//根据长度从小到大排序</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">sort(str, str3, cmp); <span class="comment">//将string数组的[0,3)进行排序</span></span><br></pre></td></tr></table></figure><p>注: </p><ul><li><p>字符类型的原则是字典序。</p></li><li><p>对于结构体数组来说,若按照某属性值排序会出现两个值相同的情况,那么需要先用if规定值不相同的情况,相同的情况再根据其他属性去规定。</p></li><li>STL容器中,只有vector, string, deque是可以使用sort的</li></ul><h2 id="7-lower-bound-和upper-bound"><a href="#7-lower-bound-和upper-bound" class="headerlink" title="7. lower_bound()和upper_bound()"></a>7. lower_bound()和upper_bound()</h2><p>lower_bound(first, last, val)用来返回<strong>第一个值大于等于val</strong>数组在指针[first, last)之间的元素的指针或者容器在迭代器[first, last)范围内的元素的迭代器</p><p>upper_bound(first, last, val)用来返回<strong>第一个值大于val</strong>数组在指针[first, last)之间的元素的指针或者容器在迭代器[first, last)范围内的元素的迭代器</p><hr><p>欢迎访问我的常用头文件下的函数介绍系列:</p><p>常用头文件下的函数介绍:目录</p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】常用头文件下的函数介绍:目录</title>
<link href="/2020/09/23/headerFile-Catalog/"/>
<url>/2020/09/23/headerFile-Catalog/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="常用头文件下的函数介绍:目录"><a href="#常用头文件下的函数介绍:目录" class="headerlink" title="常用头文件下的函数介绍:目录"></a>常用头文件下的函数介绍:目录</h1><p>很多常用的函数通常需要添加头文件,下面进行总结常用的头文件下的函数。</p><p>本文参考并总结了晴神的《算法笔记》与刘神的《算法竞赛入门经典》中的精华内容,并加入了自己的理解,以实用第一的目的来撰写此文。</p><h2 id="1-cmath-math-h"><a href="#1-cmath-math-h" class="headerlink" title="1. cmath/math.h"></a>1. cmath/math.h</h2><p>【C/C++全套入门攻略】常用头文件下的函数介绍:cmath/math.h</p><h2 id="2-cstring-string-h"><a href="#2-cstring-string-h" class="headerlink" title="2. cstring/string.h"></a>2. cstring/string.h</h2><p>【C/C++全套入门攻略】常用头文件下的函数介绍:cstring/string.h</p><h2 id="3-algorithm"><a href="#3-algorithm" class="headerlink" title="3. algorithm"></a>3. algorithm</h2><p>【C/C++全套入门攻略】常用头文件下的函数介绍:algorithm</p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】常用头文件下的函数介绍:cstring/string.h</title>
<link href="/2020/09/23/headerFile-cstring/"/>
<url>/2020/09/23/headerFile-cstring/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="常用头文件下的函数介绍:cstring-string-h"><a href="#常用头文件下的函数介绍:cstring-string-h" class="headerlink" title="常用头文件下的函数介绍:cstring/string.h"></a>常用头文件下的函数介绍:cstring/string.h</h1><p>C语言提供了很多实用的关于字符数组的函数,如果要使用,需要在程序开头添加头文件cstring或者string.h。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//二者选一</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string.h></span></span></span><br></pre></td></tr></table></figure><h2 id="1-strlen"><a href="#1-strlen" class="headerlink" title="1. strlen()"></a>1. strlen()</h2><p>strlen(str)用于得到字符数组中第一个\0前的字符个数</p><h2 id="2-strcmp"><a href="#2-strcmp" class="headerlink" title="2. strcmp()"></a>2. strcmp()</h2><p>strcmp(str1, str2)用于返回两个字符串大小的比较结果,比较原则是按字典序。</p><p>若str1<str2则返回一个负整数</p><p>若str1=str2则返回0</p><p>若str1>str2则返回一个正整数</p><h2 id="3-strcpy"><a href="#3-strcpy" class="headerlink" title="3. strcpy()"></a>3. strcpy()</h2><p>strcpy(str1, str2)用于将str2复制给str1,包括了结束符\0</p><h2 id="4-strcat"><a href="#4-strcat" class="headerlink" title="4. strcat()"></a>4. strcat()</h2><p>strcat(str1, str2)用于str2接到str1后面</p><h2 id="5-memset"><a href="#5-memset" class="headerlink" title="5. memset()"></a>5. memset()</h2><p>memset(a, num, sizeof(a))一般用来将数组(a是数组名)赋值为0或者-1。因为memset是按字节赋值的,0的二进制补码为全0,-1的二进制补码为全1,因此超过一个字节的数据类型只有赋值0,-1不容易出错。</p><hr><p>欢迎访问我的常用头文件下的函数介绍系列:</p><p>常用头文件下的函数介绍:目录</p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】常用头文件下的函数介绍:cmath/math.h</title>
<link href="/2020/09/23/headerFile-cmath/"/>
<url>/2020/09/23/headerFile-cmath/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="常用头文件下的函数介绍:cmath-math-h"><a href="#常用头文件下的函数介绍:cmath-math-h" class="headerlink" title="常用头文件下的函数介绍:cmath/math.h"></a>常用头文件下的函数介绍:cmath/math.h</h1><p>C语言提供了很多实用的数学函数,如果要使用,需要在程序开头添加头文件cmath或者math.h。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//二者选一</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><math.h></span></span></span><br></pre></td></tr></table></figure><h2 id="1-fabs-double-x"><a href="#1-fabs-double-x" class="headerlink" title="1. fabs(double x)"></a>1. fabs(double x)</h2><p>用于返回double型变量的绝对值,返回值为double型</p><h2 id="2-floor-double-x-和ceil-double-x"><a href="#2-floor-double-x-和ceil-double-x" class="headerlink" title="2. floor(double x)和ceil(double x)"></a>2. floor(double x)和ceil(double x)</h2><p>分别用于返回double型变量向下取整和向上取整,返回值为double型</p><p>注:分别相当于在数轴的左边和右边取最接近的整数</p><h2 id="3-pow-double-r-double-p"><a href="#3-pow-double-r-double-p" class="headerlink" title="3. pow(double r, double p)"></a>3. pow(double r, double p)</h2><p> 用于返回r^p(r的p次方),返回值为double型</p><h2 id="4-sqrt-double-x"><a href="#4-sqrt-double-x" class="headerlink" title="4. sqrt(double x)"></a>4. sqrt(double x)</h2><p>用于返回double型变量的算术平方根,返回值为double型</p><h2 id="5-log-double-x"><a href="#5-log-double-x" class="headerlink" title="5. log(double x)"></a>5. log(double x)</h2><p>用于返回double型变量以自然对数e为底的对数即ln(x),返回值为double型</p><p>注:C语言中没有对任意底数求对数的函数,因此必须使用换底公式</p><h2 id="6-sin-double-x-、cos-double-x-和tan-double-x"><a href="#6-sin-double-x-、cos-double-x-和tan-double-x" class="headerlink" title="6. sin(double x)、cos(double x)和tan(double x)"></a>6. sin(double x)、cos(double x)和tan(double x)</h2><p>分别用于返回double型变量的正弦值、余弦值和正切值,参数要求是弧度制,返回值为double型</p><p>注:将角度转换为弧度Π*(α/180),Π可用精确值acos(-1.0)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>); <span class="comment">//pi代表Π</span></span><br></pre></td></tr></table></figure><h2 id="7-asin-double-x-、acos-double-x-和atan-double-x"><a href="#7-asin-double-x-、acos-double-x-和atan-double-x" class="headerlink" title="7. asin(double x)、acos(double x)和atan(double x)"></a>7. asin(double x)、acos(double x)和atan(double x)</h2><p>分别用于返回double型变量的正弦值、余弦值和正切值,返回值为double型</p><h2 id="8-round-double-x"><a href="#8-round-double-x" class="headerlink" title="8. round(double x)"></a>8. round(double x)</h2><p>用于返回double型变量小数部分四舍五入后的值,返回值为double型</p><hr><p>欢迎访问我的常用头文件下的函数介绍系列:</p><p>常用头文件下的函数介绍:目录</p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:pair</title>
<link href="/2020/09/23/STL-pair/"/>
<url>/2020/09/23/STL-pair/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:pair"><a href="#C-标准模板库-STL-用法介绍:pair" class="headerlink" title="C++标准模板库(STL)用法介绍:pair"></a>C++标准模板库(STL)用法介绍:pair</h1><p>pair:可以看作是一个内部有两个元素的结构体,STL容器之一,可以将两个任何基本类型(包括STL容器)绑在一起而不用定义结构体。</p><p>使用pair前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><utility></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><p>注:由于map的内部实现中涉及pair,因此可以用map头文件来代替utility</p><h2 id="1-pair声明"><a href="#1-pair声明" class="headerlink" title="1. pair声明"></a>1. pair声明</h2><p>pair是一个模板类,所以使用前需要声明。</p><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><span class="line"><span class="comment">//声明</span></span><br><span class="line">pair<typename1, typename2> p;</span><br><span class="line"><span class="comment">//初始化</span></span><br><span class="line">pair<typename1, typename2> p(a, b); //a, b是想要初始化的元素</span><br></pre></td></tr></table></figure><p>typename1, typename2可以是任何基本类型,也可以是STL标准容器</p><p>如果只是想临时构建一个pair(通常可作为键值对插入map),可通过如下两种方法:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//直接跟在类型定义后面</span></span><br><span class="line">pair<typename1, typename2> (a, b); <span class="comment">//a, b是想要初始化的元素</span></span><br><span class="line"><span class="comment">//make_pair函数</span></span><br><span class="line">make_pair(a, b); <span class="comment">//a, b是想要初始化的元素</span></span><br></pre></td></tr></table></figure><h2 id="2-pair访问"><a href="#2-pair访问" class="headerlink" title="2. pair访问"></a>2. pair访问</h2><p>pair的结构相当于下面这个二元结构体:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//pair</span></span><br><span class="line">pair<typename1, typename2> p;</span><br><span class="line"><span class="comment">//等价二元结构体</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">p</span> {</span></span><br><span class="line"> typename1 first;</span><br><span class="line"> typename2 second; </span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>pair中只有两个元素,分别是first, second,只需要按正常结构体的方式去访问即可</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cout</span> << p.first << <span class="string">" "</span> << p.second << <span class="built_in">endl</span>;</span><br></pre></td></tr></table></figure><h2 id="3-pair用途"><a href="#3-pair用途" class="headerlink" title="3. pair用途"></a>3. pair用途</h2><p><strong>(1)代替二元结构体及其构造函数</strong></p><p><strong>(2)作为map的键值对来进行插入</strong></p><p>注:两个pair类型数据可以直接使用==, !=, <, <=, >, >=比较大小,比较规则是先以first的大小作为标准,只有当first相等时才去判别second的大小</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:stack</title>
<link href="/2020/09/23/STL-stack/"/>
<url>/2020/09/23/STL-stack/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:stack"><a href="#C-标准模板库-STL-用法介绍:stack" class="headerlink" title="C++标准模板库(STL)用法介绍:stack"></a>C++标准模板库(STL)用法介绍:stack</h1><p>stack:栈,在STL中主要则是实现了一个后进先出的容器。</p><p>使用stack前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stack></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-stack声明"><a href="#1-stack声明" class="headerlink" title="1. stack声明"></a>1. stack声明</h2><p>stack是一个模板类,所以使用前需要声明。</p><p><strong>声明</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">stack</span><<span class="keyword">typename</span>> st;</span><br></pre></td></tr></table></figure><p>typename可以是任何基本类型,也可以是STL标准容器</p><h2 id="2-stack访问"><a href="#2-stack访问" class="headerlink" title="2. stack访问"></a>2. stack访问</h2><p>由于栈本身就是一种后进先出的限制性数据结构,因此在STL中只能通过top()来访问栈顶元素</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">"%d"</span>, st.top());</span><br></pre></td></tr></table></figure><h2 id="3-stack常用函数"><a href="#3-stack常用函数" class="headerlink" title="3. stack常用函数"></a>3. stack常用函数</h2><p><strong>(1) push()</strong></p><p>st.push(x)用来将x送入栈</p><p><strong>(2) top()</strong></p><p>st.top()用来获得栈顶元素</p><p><strong>(3) pop()</strong></p><p>st.pop()用来令栈顶元素弹出</p><p><strong>(4) empty()</strong></p><p>st.empty()用来检测栈是否为空,空则返回true,否则返回false</p><p>注:使用st.top()之前,必须用empty()判断栈是否为空,否则可能因为栈空出错</p><p><strong>(5) size()</strong></p><p>st.size()用来返回栈内元素的个数</p><h2 id="4-stack用途"><a href="#4-stack用途" class="headerlink" title="4. stack用途"></a>4. stack用途</h2><p><strong>模拟实现一些递归</strong></p><p>一般来说,程序的栈内存很小,如果递归程序的层数过深,容易导致程序崩溃。使用栈来模拟递归算法的实现,可以防止程序对栈内存的限制而导致运行出错(这种应用较少)</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:priority_queue</title>
<link href="/2020/09/23/STL-priority-queue/"/>
<url>/2020/09/23/STL-priority-queue/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:priority-queue"><a href="#C-标准模板库-STL-用法介绍:priority-queue" class="headerlink" title="C++标准模板库(STL)用法介绍:priority_queue"></a>C++标准模板库(STL)用法介绍:priority_queue</h1><p>priority_queue:优先队列,STL容器之一,底层基于堆进行实现。</p><p>使用priority_queue前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><queue></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-priority-queue声明"><a href="#1-priority-queue声明" class="headerlink" title="1. priority_queue声明"></a>1. priority_queue声明</h2><p>priority_queue是一个模板类,所以使用前需要声明。</p><p><strong>声明</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">priority_queue<<span class="keyword">typename</span>> q;</span><br></pre></td></tr></table></figure><p>typename可以是任何基本类型,也可以是STL标准容器</p><h2 id="2-priority-queue访问"><a href="#2-priority-queue访问" class="headerlink" title="2. priority_queue访问"></a>2. priority_queue访问</h2><p>不同于队列,优先队列没有front()和back(),只能通过top()函数来访问队首元素(堆顶元素),也就是优先级最高的元素</p><h2 id="3-priority-queue常用函数"><a href="#3-priority-queue常用函数" class="headerlink" title="3. priority_queue常用函数"></a>3. priority_queue常用函数</h2><p><strong>(1) push()</strong></p><p>q.push(x)用来将x送入队列</p><p><strong>(2) top()</strong></p><p>q.top()用来访问队首元素(堆顶元素)</p><p><strong>(3) pop()</strong></p><p>q.pop()用来令队首元素出队</p><p><strong>(4) empty()</strong></p><p>q.empty()用来检测queue是否为空,空则返回true,否则返回false</p><p>注:使用top()之前,必须用empty()判断队列是否为空,否则可能因为队空出错</p><p><strong>(5) size()</strong></p><p>q.size()用来返回queue内元素的个数</p><h2 id="4-priority-queue内元素优先级的设置"><a href="#4-priority-queue内元素优先级的设置" class="headerlink" title="4. priority_queue内元素优先级的设置"></a>4. priority_queue内元素优先级的设置</h2><p>如何定义优先队列内元素的优先级是运用好优先队列的关键</p><p><strong>(1)基本数据类型的优先级设置</strong></p><p>此处基本数据类型就是int型、double型、char型等可以直接使用的数据类型。默认的优先级设置一般是(数值、字典序)大的优先,less\<int>表示大的优先,greater\<int>表示小的优先,方法如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//大的优先</span></span><br><span class="line">priority_queue<<span class="keyword">typename</span>, <span class="built_in">vector</span><<span class="keyword">typename</span>>, less<<span class="keyword">typename</span>> > q;</span><br><span class="line"><span class="comment">//小的优先</span></span><br><span class="line">priority_queue<<span class="keyword">typename</span>, <span class="built_in">vector</span><<span class="keyword">typename</span>>, greater<<span class="keyword">typename</span>> > q;</span><br><span class="line"><span class="comment">//默认相当于大的优先</span></span><br><span class="line">priority_queue<<span class="keyword">typename</span>> q;</span><br></pre></td></tr></table></figure><p>注:>>之间需要加空格,否则可能会被判定为右移操作</p><p>另外,基本数据类型也可以使用结构体的优先级设置方法,只不过第三个参数的写法不一样。</p><p><strong>(2)结构体类型的优先级设置</strong></p><p>设置结构体类型的优先级需要重载小于号”<”(规定不能是大于号”>”):在结构体中添加一个友元函数。写法如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">structTypename</span> {</span></span><br><span class="line"> <span class="built_in">string</span> name;</span><br><span class="line"> <span class="keyword">int</span> x;</span><br><span class="line"> <span class="comment">//设置属性x大的为优先级高的</span></span><br><span class="line"> <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span> < (structTypename name1, structTypename name2) {</span><br><span class="line"> <span class="keyword">return</span> name1.x < name2.x; <span class="comment">//如果要设置属性x小的为优先级高的,将"<"换成">"即可</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">priority_queue<structTypename> q;</span><br></pre></td></tr></table></figure><p>该设置优先级的重载小于号函数的形式类似于sort的cmp函数:两个参数,return了ture或者false。<strong>然而实现的效果却相反</strong>:对于”return name1.x < name2.x;”,在sort的cmp中每个前面元素的属性x都小于后面元素的属性x即根据属性x从小到大排序;而在优先队列的设置优先级函数中则是将属性x最大的放在队首即设置x属性大的为优先级高的</p><p><strong>记忆方法:</strong></p><p>由于两者作用效果相反,所以记住两者之一 的原则即可</p><ul><li><p>sort的cmp函数中return的表达式意味着排序后在前面的元素与在后面的元素符合该表达式。故”<”:小的在前面即从小到大;”>”:大的在前面即从大到小</p></li><li><p>优先队列的设置优先级函数中return的表达式意味着优先级低的元素(后面的元素)与优先级高的元素(前面的元素)符合该表达式。故”<”:大的是优先级高的;”>”:小的是优先级高的</p></li></ul><p>另外,优先队列的设置优先级函数也能像cmp函数一样写在结构体外面。这种写法不仅适合结构体类型,也适合所有基本数据类型或者STL容器来定义优先级。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">cmp1</span> {</span></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">operator</span> <span class="params">()</span> <span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> a < b;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">cmp2</span> {</span></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">operator</span> <span class="params">()</span> <span class="params">(structTypename a, structTypename b)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> a.x < b.x;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">priority_queue<<span class="keyword">int</span>, <span class="built_in">vector</span><<span class="keyword">int</span>>, cmp1></span><br><span class="line"> </span><br><span class="line">priority_queue<structTypename, <span class="built_in">vector</span><structTypename>, cmp2></span><br></pre></td></tr></table></figure><p>注:当结构体内的数据较为庞大时,比如出现了字符串或者数组,建议使用引用来提高效率,此时比较类的参数中需要加上”const”和”&”,写法如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">structTypename</span> {</span></span><br><span class="line"> <span class="built_in">string</span> name;</span><br><span class="line"> <span class="keyword">int</span> x;</span><br><span class="line"> <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span> < (<span class="keyword">const</span> structTypename &a, <span class="keyword">const</span> structTypename &b) {</span><br><span class="line"> <span class="keyword">return</span> name1.x < name2.x; </span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">cmp</span> {</span></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">operator</span> <span class="params">()</span> <span class="params">(<span class="keyword">const</span> structTypename &a, <span class="keyword">const</span> structTypename &b)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> a.x < b.x;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="5-priority-queue用途"><a href="#5-priority-queue用途" class="headerlink" title="5. priority_queue用途"></a>5. priority_queue用途</h2><p><strong>(1)解决贪心问题</strong></p><p><strong>(2)优化Dijkstra算法</strong></p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:queue</title>
<link href="/2020/09/22/STL-queue/"/>
<url>/2020/09/22/STL-queue/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:queue"><a href="#C-标准模板库-STL-用法介绍:queue" class="headerlink" title="C++标准模板库(STL)用法介绍:queue"></a>C++标准模板库(STL)用法介绍:queue</h1><p>queue:队列,在STL中主要则是实现了一个先进先出的容器。</p><p>使用queue前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><queue></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-queue声明"><a href="#1-queue声明" class="headerlink" title="1. queue声明"></a>1. queue声明</h2><p>queue是一个模板类,所以使用前需要声明。</p><p><strong>声明</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">queue</span><<span class="keyword">typename</span>> q;</span><br></pre></td></tr></table></figure><p>typename可以是任何基本类型,也可以是STL标准容器</p><h2 id="2-queue访问"><a href="#2-queue访问" class="headerlink" title="2. queue访问"></a>2. queue访问</h2><p>由于队列本身就是一种先进先出的限制性数据结构,因此在STL中只能通过front()来访问队首元素,或是通过back()来访问队尾元素。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">"%d %d"</span>, q.front(), q.back());</span><br></pre></td></tr></table></figure><h2 id="3-queue常用函数"><a href="#3-queue常用函数" class="headerlink" title="3. queue常用函数"></a>3. queue常用函数</h2><p><strong>(1) push()</strong></p><p>q.push(x)用来将x送入队列</p><p><strong>(2) front()、back()</strong></p><p>q.front()、q.back()分别用来获得队首元素和队尾元素</p><p><strong>(3) pop()</strong></p><p>q.pop()用来令队首元素出队</p><p><strong>(4) empty()</strong></p><p>q.empty()用来检测queue是否为空,空则返回true,否则返回false</p><p>注:使用front()和pop()之前,必须用empty()判断队列是否为空,否则可能因为队空出错</p><p><strong>(5) size()</strong></p><p>q.size()用来返回queue内元素的个数</p><h2 id="4-queue用途"><a href="#4-queue用途" class="headerlink" title="4. queue用途"></a>4. queue用途</h2><p>实现广度优先搜索</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:map</title>
<link href="/2020/09/22/STL-map/"/>
<url>/2020/09/22/STL-map/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:map"><a href="#C-标准模板库-STL-用法介绍:map" class="headerlink" title="C++标准模板库(STL)用法介绍:map"></a>C++标准模板库(STL)用法介绍:map</h1><p>map:映射,STL容器之一,可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)。</p><p>使用map前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><map></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-map声明"><a href="#1-map声明" class="headerlink" title="1. map声明"></a>1. map声明</h2><p>map是一个模板类,所以使用前需要声明。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span><typename1, typename2> mp;</span><br></pre></td></tr></table></figure><p>typename1, typename2可以是任何基本类型,也可以是STL标准容器</p><p>typename1代表键的类型,typename2代表值的类型,这样便会构成键-值映射</p><p>如果键值类型都是int,那么就相当于普通的int型数组</p><p>注:如果是字符串做映射时,必须使用string,而不能用char数组(因为数组不能作为键值)</p><h2 id="2-map访问"><a href="#2-map访问" class="headerlink" title="2. map访问"></a>2. map访问</h2><p>一般有两种访问map内元素的方法:通过下标或者map的迭代器</p><p><strong>(1)通过下标访问</strong></p><p>类似于访问数组,map通过键作为下标访问值,所以键值是<strong>唯一</strong>的</p><p><strong>(2)通过迭代器访问</strong></p><p>迭代器(iterator)理解为类似指针的东西,定义为:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span><typename1, typename2>::iterator it;</span><br></pre></td></tr></table></figure><p>it是vector\<typename\>::iterator类型的变量,<em>it用来访问vector里的元素。迭代器都支持支持自增自减,但只有vector和string支持加减整数的操作。因此,map只能通过迭代器的自增迭代去访问元素,不支持\</em>(it + i)的访问方式。map的每个元素由键-值构成,于是使用it->first访问键,使用it->second访问值。map会以键的增序自动排序,类似于set。</p><p>假设现在有一个map容器mp,那么,mp.begin()和mp.end()标志着迭代器的开头(首元素的地址)和结尾(尾元素地址的下一个地址)。</p><p>注:对于不是vector或string的容器,用*(it + i)访问失去了意义,但可用下标访问元素</p><h2 id="3-map常用函数"><a href="#3-map常用函数" class="headerlink" title="3. map常用函数"></a>3. map常用函数</h2><p><strong>(1) find()</strong></p><p>mp.find(key)用来返回键为key的映射的迭代器</p><p><strong>(2) erase()</strong></p><ul><li><p>删除单个元素</p><ul><li>mp.erase(it)用来删除迭代器it处的映射</li><li>mp.erase(key)用来删除键为key的映射</li></ul></li><li><p>删除一个区间内的所有元素</p><p>mp.erase(first, last)用来删除迭代器[first, last)内的所有元素</p></li></ul><p><strong>(3) size()</strong></p><p>size()用来获得map中映射的对数</p><p><strong>(4) clear()</strong></p><p>clear()用来将map中的所有元素清空</p><h2 id="4-map用途"><a href="#4-map用途" class="headerlink" title="4. map用途"></a>4. map用途</h2><p><strong>(1)字符串与整数之间的映射</strong></p><p><strong>(2)当做bool数组</strong></p><p>判断大整数或者其他类型数据是否存在</p><p><strong>(3)字符串和字符串的映射</strong></p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:string</title>
<link href="/2020/09/22/STL-string/"/>
<url>/2020/09/22/STL-string/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:string"><a href="#C-标准模板库-STL-用法介绍:string" class="headerlink" title="C++标准模板库(STL)用法介绍:string"></a>C++标准模板库(STL)用法介绍:string</h1><p>string:字符串,STL容器之一,类似字符数组,但比比字符数组更容易处理。</p><p>使用string前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-string声明"><a href="#1-string声明" class="headerlink" title="1. string声明"></a>1. string声明</h2><p>string是一个模板类,所以使用前需要声明。</p><p><strong>声明</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">string</span> str;</span><br></pre></td></tr></table></figure><p><strong>初始化</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">string</span> str = <span class="string">"string"</span>;</span><br></pre></td></tr></table></figure><h2 id="2-string访问"><a href="#2-string访问" class="headerlink" title="2. string访问"></a>2. string访问</h2><p>一般有两种访问string内元素的方法:通过下标或者string的迭代器</p><p><strong>(1)通过下标访问</strong></p><p>同访问字符数组,注意访问范围不要超出最后一个元素下标</p><p>可通过cin和cout输入和输出整个字符串,若想使用printf来输出string,则需要用c_str()将string类型转换为字符数组进行输出</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">"%c"</span>, str[i]);</span><br><span class="line"></span><br><span class="line"><span class="built_in">cin</span> >> str;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> << str;</span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%s"</span>, str.c_str());</span><br></pre></td></tr></table></figure><p>注:一般都可以通过下标访问满足要求</p><p><strong>(2)通过迭代器访问</strong></p><p>迭代器(iterator)理解为类似指针的东西,定义为:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">string</span>::iterator it;</span><br></pre></td></tr></table></figure><p>it是string::iterator类型的变量,<em>it用来访问string里的元素。迭代器都支持支持自增自减,但只有vector和string支持加减整数的操作。因此,string既可以通过迭代器的自增迭代去访问元素,也支持\</em>(it + i)的访问方式。</p><p>假设现在有一个string容器str,那么,str.begin()和str.end()标志着迭代器的开头(首元素的地址)和结尾(尾元素地址的下一个地址)。</p><p>注:str[i]与*(str.begin() + i)等价。</p><h2 id="3-string常用函数"><a href="#3-string常用函数" class="headerlink" title="3. string常用函数"></a>3. string常用函数</h2><p><strong>(1) length()/size()</strong></p><p>str.length()用来返回string的长度,str.size()用来获得string中的元素个数,两者基本相同</p><p><strong>(2) insert()</strong></p><ul><li>str.insert(pos, string)用来在pos号位置插入字符串string</li><li>str.insert(it, it2, it3)用来将起始位置迭代器为it2, it3的子串[it2, it3)插入str的it位置</li></ul><p><strong>(3) erase()</strong></p><ul><li><p>删除单个元素</p><p>str.erase(it)用来删除迭代器it处的元素</p></li><li><p>删除一个区间内的所有元素</p><ul><li>str.erase(first, last)用来删除迭代器[first, last)内的所有元素</li><li>str.erase(pos, length)用来删除从pos号位置开始,长度为length的子串</li></ul></li></ul><p><strong>(4) clear()</strong></p><p>str.clear()用来将string中的所有元素清空</p><p><strong>(5) substr()</strong></p><p>str.substr(pos, len)用来返回从pos号位置开始,长度为len的子串</p><p><strong>(6) find()</strong></p><ul><li>str.find(str2)用来返回str2在str中第一次出现的位置,如果不是str的子串则返回string::npos</li><li>str.find(str2, pos)用来返回str2在str的pos号位置开始第一次出现的位置,如果没有匹配则返回string::npos</li></ul><p>注:string::npos是一个常数,本身值为-1,但由于是unsigned_int类型,因此也可认为是unsigned_int类型的最大值2^32(4294967295)。通常用作find函数匹配失败时的返回值。</p><p><strong>(7) replace()</strong></p><ul><li>str.replace(pos, len, str2)用来把str从pos号位置开始、长度为len的子串替换str2</li><li>str.replace(it1, it2, str2)用来把str的迭代器[it1, it2)范围内的子串替换为str2</li></ul><h2 id="4-string用途"><a href="#4-string用途" class="headerlink" title="4. string用途"></a>4. string用途</h2><p>用来处理字符串,操作方便</p><p>其重载了符号+, +=用来拼接字符串,==, !=, <, <=, >, >=用来根据字典序比较字符串</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:set</title>
<link href="/2020/09/22/STL-set/"/>
<url>/2020/09/22/STL-set/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:set"><a href="#C-标准模板库-STL-用法介绍:set" class="headerlink" title="C++标准模板库(STL)用法介绍:set"></a>C++标准模板库(STL)用法介绍:set</h1><p>set:集合,STL容器之一,可以理解成一个<strong>内部自动有序且不含重复元素</strong>的容器。</p><p>使用set前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><set></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-set声明"><a href="#1-set声明" class="headerlink" title="1. set声明"></a>1. set声明</h2><p>set是一个模板类,所以使用前需要声明。</p><p><strong>定义</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">set</span><<span class="keyword">typename</span>> st;</span><br></pre></td></tr></table></figure><p>typename可以是任何基本类型,也可以是STL标准容器</p><p><strong>二维</strong></p><ul><li>两个维都是容器<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">set</span><<span class="built_in">set</span><<span class="keyword">typename</span>> > name;</span><br></pre></td></tr></table></figure></li></ul><p>注:>>之间需要加空格,否则可能会被判定为右移操作</p><ul><li>set数组<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">set</span><<span class="keyword">typename</span>> Arrayname[arraySize];</span><br></pre></td></tr></table></figure></li></ul><h2 id="2-set访问"><a href="#2-set访问" class="headerlink" title="2. set访问"></a>2. set访问</h2><p>访问set内元素只能通过set的迭代器</p><p><strong>通过迭代器访问</strong></p><p>迭代器(iterator)理解为类似指针的东西,定义为:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">set</span><<span class="keyword">typename</span>>::iterator it;</span><br></pre></td></tr></table></figure><p>it是set\<typename\>::iterator类型的变量,<em>it用来访问set里的元素。迭代器都支持支持自增自减,但只有vector和string支持加减整数的操作。因此,set只能通过迭代器的自增迭代去访问元素,不支持\</em>(it + i)的访问方式。</p><p>假设现在有一个set容器st,那么,st.begin()和st.end()标志着迭代器的开头(首元素的地址)和结尾(尾元素地址的下一个地址)。</p><p>注:对于不是vector或string的容器,按下标访问包括*(it + i),都失去了意义</p><h2 id="3-set常用函数"><a href="#3-set常用函数" class="headerlink" title="3. set常用函数"></a>3. set常用函数</h2><p><strong>(1) insert()</strong></p><p>insert(x)用来在set的里面添加新元素x,并自动增序排列和去重</p><p><strong>(2) find()</strong></p><p>find(value)用来返回set中对应值为value的迭代器</p><p><strong>(3) erase()</strong></p><ul><li><p>删除单个元素</p><ul><li><p>erase(it)用来删除迭代器it处的元素,可以结合find函数使用</p></li><li><p>erase(value)用来直接删除值为value的元素</p></li></ul></li><li><p>删除一个区间内的所有元素</p><p>erase(first, last)用来删除迭代器[first, last)内的所有元素</p></li></ul><p><strong>(4) size()</strong></p><p>size()用来获得set中的元素个数</p><p><strong>(5) clear()</strong></p><p>clear()用来将set中的所有元素清空</p><h2 id="4-set用途"><a href="#4-set用途" class="headerlink" title="4. set用途"></a>4. set用途</h2><p>set最重要的作用就是自动去重并按升序排序</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:vector</title>
<link href="/2020/09/21/STL-vector/"/>
<url>/2020/09/21/STL-vector/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:vector"><a href="#C-标准模板库-STL-用法介绍:vector" class="headerlink" title="C++标准模板库(STL)用法介绍:vector"></a>C++标准模板库(STL)用法介绍:vector</h1><p>vector:向量,STL容器之一,可以理解成一个封装了多种操作变长数组。</p><p>使用vector前需要添加:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br></pre></td></tr></table></figure><h2 id="1-vector声明"><a href="#1-vector声明" class="headerlink" title="1. vector声明"></a>1. vector声明</h2><p>vector是一个模板类,所以使用前需要声明。用变长数组来理解它:</p><p><strong>一维数组</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span><<span class="keyword">typename</span>> vi;</span><br></pre></td></tr></table></figure><p>typename可以是任何基本类型,也可以是STL标准容器</p><p><strong>二维数组</strong></p><ul><li>两个维数都可变长<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">typename</span>> > name;</span><br></pre></td></tr></table></figure></li></ul><p>注:>>之间需要加空格,否则可能会被判定为右移操作</p><ul><li>第一维定长,第二维可变<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span><<span class="keyword">typename</span>> Arrayname[arraySize];</span><br></pre></td></tr></table></figure></li></ul><h2 id="2-vector访问"><a href="#2-vector访问" class="headerlink" title="2. vector访问"></a>2. vector访问</h2><p>一般有两种访问vector内元素的方法:通过下标或者vector的迭代器</p><p><strong>(1)通过下标访问</strong></p><p>同访问数组,注意访问范围不要超出最后一个元素下标</p><p><strong>(2)通过迭代器访问</strong></p><p>迭代器(iterator)理解为类似指针的东西,定义为:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span><<span class="keyword">typename</span>>::iterator it;</span><br></pre></td></tr></table></figure><p>it是vector\<typename\>::iterator类型的变量,<em>it用来访问vector里的元素。迭代器都支持支持自增自减,但只有vector和string支持加减整数的操作。因此,vector既可以通过迭代器的自增迭代去访问元素,也支持\</em>(it + i)的访问方式。</p><p>假设现在有一个vector容器vi,那么,vi.begin()和vi.end()标志着迭代器的开头(首元素的地址)和结尾(尾元素地址的下一个地址)。</p><p>注:vi[i]与*(vi.begin() + i)等价。</p><h2 id="3-vector常用函数"><a href="#3-vector常用函数" class="headerlink" title="3. vector常用函数"></a>3. vector常用函数</h2><p><strong>(1) push_back()</strong></p><p>push_back(x)用来在vector的后面添加新元素x</p><p><strong>(2) pop_back()</strong></p><p>pop_back()用来删除vector的尾元素</p><p><strong>(3) size()</strong></p><p>size()用来获得vector中的元素个数</p><p><strong>(4) clear()</strong></p><p>clear()用来将vector中的所有元素清空</p><p><strong>(5) insert()</strong></p><p>insert(it, x)用来向vector的迭代器it处插入一个元素x</p><p><strong>(6) erase()</strong></p><ul><li>删除单个元素</li></ul><p>erase(it)用来删除迭代器it处的元素</p><ul><li>删除一个区间内的所有元素</li></ul><p>erase(first, last)用来删除迭代器[first, last)内的所有元素</p><h2 id="4-vector用途"><a href="#4-vector用途" class="headerlink" title="4. vector用途"></a>4. vector用途</h2><p><strong>(1)储存数据</strong></p><p>将vector作为数组使用,在元素个数不确定的场合很方便</p><p><strong>(2)用邻接表存储图</strong></p><p>用vector实现邻接表比较方便</p><hr><p>欢迎访问我的STL系列:</p><p><a href="https://colin-jay.cn/2020/09/11/STL-Catalog/"><strong>C++标准模板库(STL)用法介绍:目录</strong></a></p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1023 Have Fun with Numbers (20分)</title>
<link href="/2020/09/13/PAT-AdvancedLevel1023/"/>
<url>/2020/09/13/PAT-AdvancedLevel1023/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1023-Have-Fun-with-Numbers-20分"><a href="#1023-Have-Fun-with-Numbers-20分" class="headerlink" title="1023 Have Fun with Numbers (20分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805478658260992" target="_blank" rel="noopener">1023 Have Fun with Numbers (20分)</a></h2><p>Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!</p><p>Now you are suppose to check if there are more numbers with this property. That is, double a given number with <em>k</em> digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input contains one test case. Each case contains one positive integer with no more than 20 digits.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, first print in a line “Yes” if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or “No” if not. Then in the next line, print the doubled number.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1234567899</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Yes</span><br><span class="line">2469135798</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">char</span> str[<span class="number">30</span>]; <span class="comment">//先以字符的形式读入大整数</span></span><br><span class="line"><span class="keyword">int</span> bigN[<span class="number">30</span>], doubN[<span class="number">30</span>]; <span class="comment">//存放大整数与它的两倍</span></span><br><span class="line"><span class="keyword">int</span> hashB[<span class="number">20</span>], hashD[<span class="number">20</span>]; <span class="comment">//映射大整数每个数位的个数</span></span><br><span class="line"><span class="keyword">int</span> lenb, lend;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">doubBig</span><span class="params">()</span> </span>{ <span class="comment">//大整数翻倍</span></span><br><span class="line"> <span class="keyword">int</span> len = <span class="number">0</span>, carry = <span class="number">0</span>; <span class="comment">//len记录翻倍后的位数,carry是运算时的进位</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < lenb; i++) {</span><br><span class="line"> <span class="keyword">int</span> temp = <span class="number">2</span> * bigN[i] + carry;</span><br><span class="line"> carry = temp / <span class="number">10</span>;</span><br><span class="line"> doubN[len++] = temp % <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (carry) {</span><br><span class="line"> doubN[len++] = carry % <span class="number">10</span>;</span><br><span class="line"> carry /= <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> len;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> flag)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (flag) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Yes\n"</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < lend; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, doubN[lend - i <span class="number">-1</span>]);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"No\n"</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < lend; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, doubN[lend - i <span class="number">-1</span>]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(hashB, <span class="number">0</span>, <span class="keyword">sizeof</span>(hashB)); </span><br><span class="line"> <span class="built_in">memset</span>(hashD, <span class="number">0</span>, <span class="keyword">sizeof</span>(hashD));</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>, str);</span><br><span class="line"> lenb = <span class="built_in">strlen</span>(str);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < lenb; i++) { <span class="comment">//将大整数放入数组中并记录每个数位的个数</span></span><br><span class="line"> bigN[i] = str[lenb - i - <span class="number">1</span>] - <span class="string">'0'</span>;</span><br><span class="line"> <span class="keyword">int</span> temp = bigN[i];</span><br><span class="line"> hashB[temp]++;</span><br><span class="line"> }</span><br><span class="line"> lend = doubBig(); <span class="comment">//调用函数将大整数翻倍</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < lend; i++) { <span class="comment">//记录翻倍后的大整数每个数位的个数</span></span><br><span class="line"> <span class="keyword">int</span> temp = doubN[i];</span><br><span class="line"> hashD[temp]++;</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="keyword">bool</span> flag = <span class="literal">true</span>; <span class="comment">//flag标志是否满足要求</span></span><br><span class="line"> <span class="keyword">if</span> (lenb != lend) { <span class="comment">//如果翻倍后有进位,那么直接不满足</span></span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line"> <span class="built_in">print</span>(flag);</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">//没有进位则判断翻倍后大整数每个数位的个数是否改变</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">10</span>; i++) {</span><br><span class="line"> <span class="keyword">if</span> (hashB[i] != hashD[i]) {</span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">print</span>(flag);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>将一个大整数翻倍</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:目录</title>
<link href="/2020/09/11/STL-Catalog/"/>
<url>/2020/09/11/STL-Catalog/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="C-标准模板库-STL-用法介绍:目录"><a href="#C-标准模板库-STL-用法介绍:目录" class="headerlink" title="C++标准模板库(STL)用法介绍:目录"></a>C++标准模板库(STL)用法介绍:目录</h1><p>相信很多人跟我一样,在没了解STL之前,听到这么高大上的名字,以为是一个很难触及的神秘知识。但其实,STL并没有想象中那么难。相反,STL十分简单。</p><p>那么,为什么我们要学习STL 呢?STL(Standard Template Library)即标准模板库,是C++高效的程序库。它是一个工具的存在,能帮助我们简化很多程序,免得我们自己去实现(比如变长数组、数组排序等等)。</p><p>所以,把STL当成一个美化你程序的工具来看待。本文参考并总结了晴神的《算法笔记》与刘神的《算法竞赛入门经典》中的精华内容,并加入了自己的理解,以实用第一的目的来撰写此文。</p><p>请耐心往下看,一天时间足够你学完这些并且灵活运用STL了!</p><h2 id="1-vector-向量(变长数组)"><a href="#1-vector-向量(变长数组)" class="headerlink" title="1. vector 向量(变长数组)"></a>1. vector 向量(变长数组)</h2><p><a href="https://colin-jay.cn/2020/09/21/STL-vector/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:vector</a></p><h2 id="2-set-集合"><a href="#2-set-集合" class="headerlink" title="2. set 集合"></a>2. set 集合</h2><p><a href="https://colin-jay.cn/2020/09/22/STL-set/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:set</a></p><h2 id="3-string-字符串"><a href="#3-string-字符串" class="headerlink" title="3. string 字符串"></a>3. string 字符串</h2><p><a href="https://colin-jay.cn/2020/09/22/STL-string/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:string</a></p><h2 id="4-map-映射"><a href="#4-map-映射" class="headerlink" title="4. map 映射"></a>4. map 映射</h2><p><a href="https://colin-jay.cn/2020/09/22/STL-map/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:map</a></p><h2 id="5-queue-队列"><a href="#5-queue-队列" class="headerlink" title="5. queue 队列"></a>5. queue 队列</h2><p><a href="https://colin-jay.cn/2020/09/22/STL-queue/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:queue</a></p><h2 id="6-priority-queue-优先队列"><a href="#6-priority-queue-优先队列" class="headerlink" title="6. priority_queue 优先队列"></a>6. priority_queue 优先队列</h2><p><a href="https://colin-jay.cn/2020/09/23/STL-priority-queue/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:priority_queue</a></p><h2 id="7-stack-栈"><a href="#7-stack-栈" class="headerlink" title="7. stack 栈"></a>7. stack 栈</h2><p><a href="https://colin-jay.cn/2020/09/23/STL-stack/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:stack</a></p><h2 id="8-pair"><a href="#8-pair" class="headerlink" title="8. pair"></a>8. pair</h2><p><a href="https://colin-jay.cn/2020/09/23/STL-pair/">【C/C++全套入门攻略】C++标准模板库(STL)用法介绍:pair</a></p><h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><p>(1)迭代器一定要在容器结构(size)确定后再初始化,否则会出错!因为它指向的容器头部位置可能会变化。</p>]]></content>
<categories>
<category> C/C++ </category>
</categories>
<tags>
<tag> note </tag>
<tag> C/C++ </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1024 Palindromic Number (25分)</title>
<link href="/2020/09/07/PAT-AdvancedLevel1024/"/>
<url>/2020/09/07/PAT-AdvancedLevel1024/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1024-Palindromic-Number-25分"><a href="#1024-Palindromic-Number-25分" class="headerlink" title="1024 Palindromic Number (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805476473028608" target="_blank" rel="noopener">1024 Palindromic Number (25分)</a></h2><p>A number that will be the same when it is written forwards or backwards is known as a <strong>Palindromic Number</strong>. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.</p><p>Non-palindromic numbers can be paired with palindromic ones via a series of operations. First, the non-palindromic number is reversed and the result is added to the original number. If the result is not a palindromic number, this is repeated until it gives a palindromic number. For example, if we start from 67, we can obtain a palindromic number in 2 steps: 67 + 76 = 143, and 143 + 341 = 484.</p><p>Given any positive integer <em>N</em>, you are supposed to find its paired palindromic number and the number of steps taken to find it.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. Each case consists of two positive numbers <em>N</em> and <em>K</em>, where <em>N</em> (≤1010) is the initial numer and <em>K</em> (≤100) is the maximum number of steps. The numbers are separated by a space.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, output two numbers, one in each line. The first number is the paired palindromic number of <em>N</em>, and the second number is the number of steps taken to find the palindromic number. If the palindromic number is not found after <em>K</em> steps, just output the number obtained at the <em>K</em>th step and <em>K</em> instead.</p><h3 id="Sample-Input-1"><a href="#Sample-Input-1" class="headerlink" title="Sample Input 1:"></a>Sample Input 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">67 3</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-1"><a href="#Sample-Output-1" class="headerlink" title="Sample Output 1:"></a>Sample Output 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">484</span><br><span class="line">2</span><br></pre></td></tr></table></figure><h3 id="Sample-Input-2"><a href="#Sample-Input-2" class="headerlink" title="Sample Input 2:"></a>Sample Input 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">69 3</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-2"><a href="#Sample-Output-2" class="headerlink" title="Sample Output 2:"></a>Sample Output 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1353</span><br><span class="line">3</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> pNum[<span class="number">1000</span>];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">BigNum</span> {</span></span><br><span class="line"> <span class="keyword">int</span> P[<span class="number">1000</span>];</span><br><span class="line"> <span class="keyword">int</span> len;</span><br><span class="line"> BigNum () {</span><br><span class="line"> <span class="built_in">memset</span>(P, <span class="number">0</span>, <span class="keyword">sizeof</span>(P));</span><br><span class="line"> len = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">} bigN;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isPalin</span> <span class="params">()</span> </span>{ <span class="comment">//判断是否是Palin</span></span><br><span class="line"> <span class="keyword">bool</span> flag = <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">int</span> left = <span class="number">0</span>, right = bigN.len - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (left < right) {</span><br><span class="line"> <span class="keyword">if</span> (bigN.P[left] != bigN.P[right]) {</span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> left ++;</span><br><span class="line"> right --;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> flag;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span> <span class="params">()</span> </span>{ <span class="comment">//将一个数与其本身倒序相加,暂存在pNum中</span></span><br><span class="line"> <span class="keyword">int</span> carry = <span class="number">0</span>; <span class="comment">//进位</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < bigN.len; i++) {</span><br><span class="line"> <span class="keyword">int</span> temp = bigN.P[i] + bigN.P[bigN.len - <span class="number">1</span> - i] + carry;</span><br><span class="line"> carry = temp / <span class="number">10</span>;</span><br><span class="line"> pNum[i] = temp % <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (carry) {</span><br><span class="line"> pNum[bigN.len] = carry;</span><br><span class="line"> bigN.len ++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < bigN.len; i++) { <span class="comment">//将pNum复制给bigN.P</span></span><br><span class="line"> bigN.P[i] = pNum[i];</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> k, <span class="built_in">step</span> = <span class="number">0</span>; <span class="comment">//规定步骤和已经进行的步骤</span></span><br><span class="line"> <span class="keyword">char</span> str[<span class="number">20</span>];</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s %d"</span>, str, &k);</span><br><span class="line"> bigN.len = <span class="built_in">strlen</span>(str);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < bigN.len; i++) { <span class="comment">//按地位到高位将数字字符串存入数组P中</span></span><br><span class="line"> bigN.P[bigN.len - <span class="number">1</span> - i] = str[i] - <span class="string">'0'</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">bool</span> flag; <span class="comment">//1代表是Palin</span></span><br><span class="line"> flag = isPalin ();</span><br><span class="line"> <span class="keyword">while</span> (flag == <span class="number">0</span> && <span class="built_in">step</span> < k) {</span><br><span class="line"> add ();</span><br><span class="line"> flag = isPalin ();</span><br><span class="line"> <span class="built_in">step</span> ++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < bigN.len; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, bigN.P[bigN.len - <span class="number">1</span> - i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n%d"</span>, <span class="built_in">step</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>需要用数组写,并且数组需要开大一点。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1059 Prime Factors (25分)</title>
<link href="/2020/09/06/PAT-AdvancedLevel1059/"/>
<url>/2020/09/06/PAT-AdvancedLevel1059/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1059-Prime-Factors-25分"><a href="#1059-Prime-Factors-25分" class="headerlink" title="1059 Prime Factors (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805415005503488" target="_blank" rel="noopener">1059 Prime Factors (25分)</a></h2><p>Given any positive integer <em>N</em>, you are supposed to find all of its prime factors, and write them in the format <em>N</em> = <em>p</em>1<em>k</em>1×<em>p</em>2<em>k</em>2×⋯×<em>p<strong>m</strong>k**m</em>.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case which gives a positive integer <em>N</em> in the range of <strong>long int</strong>.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>Factor <em>N</em> in the format <em>N</em> <code>=</code> <em>p</em>1<code>^</code><em>k</em>1<code>*</code><em>p</em>2<code>^</code><em>k</em>2<code>*</code>…<code>*</code><em>p**m</em><code>^</code><em>k**m</em>, where <em>p**i</em>‘s are prime factors of <em>N</em> in increasing order, and the exponent <em>k**i</em> is the number of <em>p**i</em> — hence when there is only one <em>p**i</em>, <em>k**i</em> is 1 and must <strong>NOT</strong> be printed out.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">97532468</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">97532468=2^2*11*17*101*1291</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cmath></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"><span class="keyword">int</span> prime[MAXN], pNum = <span class="number">0</span>; <span class="comment">//素数表,素数个数</span></span><br><span class="line"><span class="keyword">bool</span> isPrime[MAXN] = {<span class="number">0</span>}; <span class="comment">//0代表下标对应的数是素数</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">factor</span> {</span></span><br><span class="line"> <span class="keyword">int</span> p, k;</span><br><span class="line">} fac[<span class="number">10</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">pTable</span> <span class="params">(<span class="keyword">int</span> sqr)</span> </span>{ <span class="comment">//素数表</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>; i < MAXN; i++) { <span class="comment">//埃氏筛法</span></span><br><span class="line"> <span class="keyword">if</span> (prime[pNum] > sqr) <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">if</span> (!(isPrime[i])) { <span class="comment">//如果是素数,加入素数表并开始表晒</span></span><br><span class="line"> prime[pNum++] = i;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j < MAXN; j += i) {</span><br><span class="line"> isPrime[j] = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">findPrime</span> <span class="params">(<span class="keyword">int</span> n)</span> </span>{ <span class="comment">//找出所有质因数</span></span><br><span class="line"> <span class="keyword">int</span> cnt = <span class="number">0</span>; <span class="comment">//不同质因数的个数</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < pNum; i++) {</span><br><span class="line"> <span class="keyword">if</span> (n % prime[i] == <span class="number">0</span>) { <span class="comment">//若该素数为因子,则指数加一</span></span><br><span class="line"> fac[cnt].p = prime[i];</span><br><span class="line"> fac[cnt].k = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (n % prime[i] == <span class="number">0</span>) {</span><br><span class="line"> (fac[cnt].k)++; </span><br><span class="line"> n /= prime[i];</span><br><span class="line"> }</span><br><span class="line"> cnt++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>) <span class="keyword">break</span>; <span class="comment">//已经找到全部质因子</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (n != <span class="number">1</span>) { <span class="comment">//还存在一个大于根号n的质因子</span></span><br><span class="line"> fac[cnt].k = n;</span><br><span class="line"> fac[cnt].p = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < cnt; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, fac[i].p);</span><br><span class="line"> <span class="keyword">if</span> (fac[i].k != <span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%s%d"</span>, <span class="string">"^"</span>, fac[i].k);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(i == cnt<span class="number">-1</span>) <span class="keyword">break</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"*"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">int</span> sqrtn = (<span class="keyword">int</span>)<span class="built_in">sqrt</span>(n * <span class="number">1.0</span>);</span><br><span class="line"> <span class="comment">//调用素数表</span></span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"1=1"</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> pTable(sqrtn);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d="</span>, n);</span><br><span class="line"> <span class="comment">//2到根号n判断找出其所有质因数</span></span><br><span class="line"> findPrime(n);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>n最多有一个大于根号n的质因数</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1013 数素数 (20分)</title>
<link href="/2020/09/05/PAT-BasicLevel1013/"/>
<url>/2020/09/05/PAT-BasicLevel1013/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1013-数素数-20分"><a href="#1013-数素数-20分" class="headerlink" title="1013 数素数 (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805309963354112" target="_blank" rel="noopener">1013 数素数 (20分)</a></h2><p>令 <em>P**i</em> 表示第 <em>i</em> 个素数。现任给两个正整数 <em>M</em>≤<em>N</em>≤104,请输出 <em>P**M</em> 到 <em>P**N</em> 的所有素数。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在一行中给出 <em>M</em> 和 <em>N</em>,其间以空格分隔。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>输出从 <em>P**M</em> 到 <em>P**N</em> 的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">5 27</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">11 13 17 19 23 29 31 37 41 43</span><br><span class="line">47 53 59 61 67 71 73 79 83 89</span><br><span class="line">97 101 103</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">200000</span>;</span><br><span class="line"><span class="keyword">int</span> prime[MAXN], pNum = <span class="number">0</span>; <span class="comment">//素数表,素数个数</span></span><br><span class="line"><span class="keyword">bool</span> pTable[MAXN] = {<span class="number">0</span>}; <span class="comment">//false表示是该下标对应的数字素数</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">primeTable</span><span class="params">()</span> </span>{ <span class="comment">//埃氏筛法</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>; i < MAXN; i++) { <span class="comment">//从2开始遍历</span></span><br><span class="line"> <span class="keyword">if</span> (!(pTable[i])) { <span class="comment">//如果该数字是素数,那么开始筛去它的倍数</span></span><br><span class="line"> prime[pNum++] = i;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i + i; j < MAXN; j += i) {</span><br><span class="line"> pTable[j] = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> m, n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %d"</span>, &m, &n);</span><br><span class="line"> primeTable();</span><br><span class="line"> <span class="keyword">int</span> cnt = <span class="number">0</span>; <span class="comment">//判断打印是否换行</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = m; i <= n; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d%s"</span>, prime[i - <span class="number">1</span>], (++cnt % <span class="number">10</span>) && (i < n) ? <span class="string">" "</span> : <span class="string">"\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>注意数据范围和打印格式</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1019 数字黑洞 (20分)</title>
<link href="/2020/09/04/PAT-BasicLevel1019/"/>
<url>/2020/09/04/PAT-BasicLevel1019/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1019-数字黑洞-20分"><a href="#1019-数字黑洞-20分" class="headerlink" title="1019 数字黑洞 (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805302786899968" target="_blank" rel="noopener">1019 数字黑洞 (20分)</a></h2><p>给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 <code>6174</code>,这个神奇的数字也叫 Kaprekar 常数。</p><p>例如,我们从<code>6767</code>开始,将得到</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">7766 - 6677 = 1089</span><br><span class="line">9810 - 0189 = 9621</span><br><span class="line">9621 - 1269 = 8352</span><br><span class="line">8532 - 2358 = 6174</span><br><span class="line">7641 - 1467 = 6174</span><br><span class="line">... ...</span><br></pre></td></tr></table></figure><p>现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入给出一个 (0,104) 区间内的正整数 <em>N</em>。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>如果 <em>N</em> 的 4 位数字全相等,则在一行内输出 <code>N - N = 0000</code>;否则将计算的每一步在一行内输出,直到 <code>6174</code> 作为差出现,输出格式见样例。注意每个数字按 <code>4</code> 位数格式输出。</p><h3 id="输入样例-1:"><a href="#输入样例-1:" class="headerlink" title="输入样例 1:"></a>输入样例 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">6767</span><br></pre></td></tr></table></figure><h3 id="输出样例-1:"><a href="#输出样例-1:" class="headerlink" title="输出样例 1:"></a>输出样例 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">7766 - 6677 = 1089</span><br><span class="line">9810 - 0189 = 9621</span><br><span class="line">9621 - 1269 = 8352</span><br><span class="line">8532 - 2358 = 6174</span><br></pre></td></tr></table></figure><h3 id="输入样例-2:"><a href="#输入样例-2:" class="headerlink" title="输入样例 2:"></a>输入样例 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2222</span><br></pre></td></tr></table></figure><h3 id="输出样例-2:"><a href="#输出样例-2:" class="headerlink" title="输出样例 2:"></a>输出样例 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2222 - 2222 = 0000</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">Partition</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> bHole[])</span> </span>{<span class="comment">//将一个数的每个数位存进数组中</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">4</span>; i++) {</span><br><span class="line"> bHole[i] = a % <span class="number">10</span>;</span><br><span class="line"> a /= <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">toMaxNum</span><span class="params">(<span class="keyword">int</span> bHole[])</span></span>{<span class="comment">//得到first</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">max</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">3</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="built_in">max</span> = <span class="built_in">max</span> * <span class="number">10</span> + bHole[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">max</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">toMinNum</span><span class="params">(<span class="keyword">int</span> bHole[])</span></span>{<span class="comment">//得到second</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">min</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">4</span>; i++) {</span><br><span class="line"> <span class="built_in">min</span> = <span class="built_in">min</span> * <span class="number">10</span> + bHole[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">min</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">holePrintf</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> bHole[])</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> first, second;</span><br><span class="line"> Partition(n, bHole);</span><br><span class="line"> sort(bHole, bHole+<span class="number">4</span>);</span><br><span class="line"> first = toMaxNum(bHole);</span><br><span class="line"> second = toMinNum(bHole);</span><br><span class="line"> n = first - second;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%04d - %04d = %04d"</span>, first, second, n); <span class="comment">//打印结果</span></span><br><span class="line"> <span class="comment">//只要不是0或者6174就递归调用打印程序</span></span><br><span class="line"> <span class="keyword">if</span>(n != <span class="number">6174</span> && n) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> holePrintf(n, bHole);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="keyword">int</span> bHole[<span class="number">10</span>];</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> holePrintf(n, bHole); <span class="comment">//调用打印程序</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>题目本身很简单,注意打印格式中不足补0</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1069 The Black Hole of Numbers (20分)</title>
<link href="/2020/09/04/PAT-AdvancedLevel1069/"/>
<url>/2020/09/04/PAT-AdvancedLevel1069/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1069-The-Black-Hole-of-Numbers-20分"><a href="#1069-The-Black-Hole-of-Numbers-20分" class="headerlink" title="1069 The Black Hole of Numbers (20分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805400954585088" target="_blank" rel="noopener">1069 The Black Hole of Numbers (20分)</a></h2><p>For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in non-increasing order first, and then in non-decreasing order, a new number can be obtained by taking the second number from the first one. Repeat in this manner we will soon end up at the number <code>6174</code> — the <strong>black hole</strong> of 4-digit numbers. This number is named Kaprekar Constant.</p><p>For example, start from <code>6767</code>, we’ll get:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">7766 - 6677 = 1089</span><br><span class="line">9810 - 0189 = 9621</span><br><span class="line">9621 - 1269 = 8352</span><br><span class="line">8532 - 2358 = 6174</span><br><span class="line">7641 - 1467 = 6174</span><br><span class="line">... ...</span><br></pre></td></tr></table></figure><p>Given any 4-digit number, you are supposed to illustrate the way it gets into the black hole.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case which gives a positive integer <em>N</em> in the range (0,104).</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>If all the 4 digits of <em>N</em> are the same, print in one line the equation <code>N - N = 0000</code>. Else print each step of calculation in a line until <code>6174</code> comes out as the difference. All the numbers must be printed as 4-digit numbers.</p><h3 id="Sample-Input-1"><a href="#Sample-Input-1" class="headerlink" title="Sample Input 1:"></a>Sample Input 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">6767</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-1"><a href="#Sample-Output-1" class="headerlink" title="Sample Output 1:"></a>Sample Output 1:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">7766 - 6677 = 1089</span><br><span class="line">9810 - 0189 = 9621</span><br><span class="line">9621 - 1269 = 8352</span><br><span class="line">8532 - 2358 = 6174</span><br></pre></td></tr></table></figure><h3 id="Sample-Input-2"><a href="#Sample-Input-2" class="headerlink" title="Sample Input 2:"></a>Sample Input 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2222</span><br></pre></td></tr></table></figure><h3 id="Sample-Output-2"><a href="#Sample-Output-2" class="headerlink" title="Sample Output 2:"></a>Sample Output 2:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2222 - 2222 = 0000</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">Partition</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> bHole[])</span> </span>{<span class="comment">//将一个数的每个数位存进数组中</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">4</span>; i++) {</span><br><span class="line"> bHole[i] = a % <span class="number">10</span>;</span><br><span class="line"> a /= <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">toMaxNum</span><span class="params">(<span class="keyword">int</span> bHole[])</span></span>{<span class="comment">//得到first</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">max</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">3</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="built_in">max</span> = <span class="built_in">max</span> * <span class="number">10</span> + bHole[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">max</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">toMinNum</span><span class="params">(<span class="keyword">int</span> bHole[])</span></span>{<span class="comment">//得到second</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">min</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">4</span>; i++) {</span><br><span class="line"> <span class="built_in">min</span> = <span class="built_in">min</span> * <span class="number">10</span> + bHole[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">min</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">holePrintf</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> bHole[])</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> first, second;</span><br><span class="line"> Partition(n, bHole);</span><br><span class="line"> sort(bHole, bHole+<span class="number">4</span>);</span><br><span class="line"> first = toMaxNum(bHole);</span><br><span class="line"> second = toMinNum(bHole);</span><br><span class="line"> n = first - second;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%04d - %04d = %04d"</span>, first, second, n); <span class="comment">//打印结果</span></span><br><span class="line"> <span class="comment">//只要不是0或者6174就递归调用打印程序</span></span><br><span class="line"> <span class="keyword">if</span>(n != <span class="number">6174</span> && n) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> holePrintf(n, bHole);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="keyword">int</span> bHole[<span class="number">10</span>];</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> holePrintf(n, bHole); <span class="comment">//调用打印程序</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>题目本身很简单,注意打印格式中不足补0</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1045 快速排序 (25分)</title>
<link href="/2020/08/27/PAT-BasicLevel1045/"/>
<url>/2020/08/27/PAT-BasicLevel1045/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1045-快速排序-25分"><a href="#1045-快速排序-25分" class="headerlink" title="1045 快速排序 (25分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192" target="_blank" rel="noopener">1045 快速排序 (25分)</a></h2><p>著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 <em>N</em> 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?</p><p>例如给定 $N = 5$, 排列是1、3、2、4、5。则:</p><ul><li>1 的左边没有元素,右边的元素都比它大,所以它可能是主元;</li><li>尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;</li><li>尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;</li><li>类似原因,4 和 5 都可能是主元。</li></ul><p>因此,有 3 个元素可能是主元。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在第 1 行中给出一个正整数 <em>N</em>(≤105); 第 2 行是空格分隔的 <em>N</em> 个不同的正整数,每个数不超过 109。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">5</span><br><span class="line">1 3 2 4 5</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">3</span><br><span class="line">1 4 5</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ChoosePivot</span> {</span></span><br><span class="line"> <span class="keyword">int</span> num;</span><br><span class="line"> <span class="keyword">int</span> Lflag; <span class="comment">//是否满足num左边都比它小</span></span><br><span class="line"> <span class="keyword">int</span> Rflag; <span class="comment">//是否满足num右边都比它大</span></span><br><span class="line"> <span class="keyword">int</span> flag; <span class="comment">//是否同时满足条件</span></span><br><span class="line">} Pivot[MAXN];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, cntPivot = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> Lmax = <span class="number">0</span>, Rmin = <span class="number">0</span>; <span class="comment">//记录当前数字左边的最大值和右边的最小值</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) { <span class="comment">//输入并记录左边的Lflag</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &Pivot[i].num);</span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].num > Lmax) {</span><br><span class="line"> Pivot[i].Lflag = <span class="number">1</span>;</span><br><span class="line"> Lmax = Pivot[i].num;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Pivot[i].Lflag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> Pivot[n<span class="number">-1</span>].Rflag = <span class="number">1</span>;</span><br><span class="line"> Pivot[n<span class="number">-1</span>].flag = Pivot[n<span class="number">-1</span>].Lflag;</span><br><span class="line"> Rmin = Pivot[n<span class="number">-1</span>].num;</span><br><span class="line"> <span class="keyword">if</span>(Pivot[n<span class="number">-1</span>].flag) cntPivot++;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = n<span class="number">-2</span>; i >= <span class="number">0</span>; i--) { <span class="comment">//倒着遍历一遍num,记录Rflag和flag</span></span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].num < Rmin) {</span><br><span class="line"> Pivot[i].Rflag = <span class="number">1</span>;</span><br><span class="line"> Rmin = Pivot[i].num;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Pivot[i].Rflag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> Pivot[i].flag = Pivot[i].Lflag * Pivot[i].Rflag;</span><br><span class="line"> <span class="keyword">if</span> (Pivot[i].flag == <span class="number">1</span>) {</span><br><span class="line"> cntPivot++;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> temp = cntPivot;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, cntPivot);</span><br><span class="line"> <span class="keyword">if</span>(cntPivot == <span class="number">0</span>) <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].flag == <span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, Pivot[i]);</span><br><span class="line"> temp--;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">if</span>(temp) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">" "</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>测试点2,注意0的时候要再换行一次。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1101 Quick Sort (25分)</title>
<link href="/2020/08/27/PAT-AdvancedLevel1101/"/>
<url>/2020/08/27/PAT-AdvancedLevel1101/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1101-Quick-Sort-25分"><a href="#1101-Quick-Sort-25分" class="headerlink" title="1101 Quick Sort (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805366343188480" target="_blank" rel="noopener">1101 Quick Sort (25分)</a></h2><p>There is a classical process named <strong>partition</strong> in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its left and those larger than the pivot to its right. Given <em>N</em> distinct positive integers after a run of partition, could you tell how many elements could be the selected pivot for this partition?</p><p>For example, given <em>N</em>=5 and the numbers 1, 3, 2, 4, and 5. We have:</p><ul><li>1 could be the pivot since there is no element to its left and all the elements to its right are larger than it;</li><li>3 must not be the pivot since although all the elements to its left are smaller, the number 2 to its right is less than it as well;</li><li>2 must not be the pivot since although all the elements to its right are larger, the number 3 to its left is larger than it as well;</li><li>and for the similar reason, 4 and 5 could also be the pivot.</li></ul><p>Hence in total there are 3 pivot candidates.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. For each case, the first line gives a positive integer <em>N</em> (≤105). Then the next line contains <em>N</em> distinct positive integers no larger than 109. The numbers in a line are separated by spaces.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, output in the first line the number of pivot candidates. Then in the next line print these candidates in increasing order. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">5</span><br><span class="line">1 3 2 4 5</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">3</span><br><span class="line">1 4 5</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ChoosePivot</span> {</span></span><br><span class="line"> <span class="keyword">int</span> num;</span><br><span class="line"> <span class="keyword">int</span> Lflag; <span class="comment">//是否满足num左边都比它小</span></span><br><span class="line"> <span class="keyword">int</span> Rflag; <span class="comment">//是否满足num右边都比它大</span></span><br><span class="line"> <span class="keyword">int</span> flag; <span class="comment">//是否同时满足条件</span></span><br><span class="line">} Pivot[MAXN];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, cntPivot = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> Lmax = <span class="number">0</span>, Rmin = <span class="number">0</span>; <span class="comment">//记录当前数字左边的最大值和右边的最小值</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) { <span class="comment">//输入并记录左边的Lflag</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &Pivot[i].num);</span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].num > Lmax) {</span><br><span class="line"> Pivot[i].Lflag = <span class="number">1</span>;</span><br><span class="line"> Lmax = Pivot[i].num;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Pivot[i].Lflag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> Pivot[n<span class="number">-1</span>].Rflag = <span class="number">1</span>;</span><br><span class="line"> Pivot[n<span class="number">-1</span>].flag = Pivot[n<span class="number">-1</span>].Lflag;</span><br><span class="line"> Rmin = Pivot[n<span class="number">-1</span>].num;</span><br><span class="line"> <span class="keyword">if</span>(Pivot[n<span class="number">-1</span>].flag) cntPivot++;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = n<span class="number">-2</span>; i >= <span class="number">0</span>; i--) { <span class="comment">//倒着遍历一遍num,记录Rflag和flag</span></span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].num < Rmin) {</span><br><span class="line"> Pivot[i].Rflag = <span class="number">1</span>;</span><br><span class="line"> Rmin = Pivot[i].num;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Pivot[i].Rflag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> Pivot[i].flag = Pivot[i].Lflag * Pivot[i].Rflag;</span><br><span class="line"> <span class="keyword">if</span> (Pivot[i].flag == <span class="number">1</span>) {</span><br><span class="line"> cntPivot++;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> temp = cntPivot;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, cntPivot);</span><br><span class="line"> <span class="keyword">if</span>(cntPivot == <span class="number">0</span>) <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span>(Pivot[i].flag == <span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, Pivot[i]);</span><br><span class="line"> temp--;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">if</span>(temp) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">" "</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>测试点2,注意0的时候要再换行一次。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1040 有几个PAT (25分)</title>
<link href="/2020/08/27/PAT-BasicLevel1040/"/>
<url>/2020/08/27/PAT-BasicLevel1040/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1040-有几个PAT-25分"><a href="#1040-有几个PAT-25分" class="headerlink" title="1040 有几个PAT (25分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805282389999616" target="_blank" rel="noopener">1040 有几个PAT (25分)</a></h2><p>字符串 <code>APPAPT</code> 中包含了两个单词 <code>PAT</code>,其中第一个 <code>PAT</code> 是第 2 位(<code>P</code>),第 4 位(<code>A</code>),第 6 位(<code>T</code>);第二个 <code>PAT</code> 是第 3 位(<code>P</code>),第 4 位(<code>A</code>),第 6 位(<code>T</code>)。</p><p>现给定字符串,问一共可以形成多少个 <code>PAT</code>?</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入只有一行,包含一个字符串,长度不超过105,只包含 <code>P</code>、<code>A</code>、<code>T</code> 三种字母。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>在一行中输出给定字符串中包含多少个 <code>PAT</code>。由于结果可能比较大,只输出对 1000000007 取余数的结果。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">APPAPT</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MOD = <span class="number">1000000007</span>;</span><br><span class="line"><span class="keyword">char</span> PATs[MAXN];</span><br><span class="line"><span class="keyword">int</span> PA[MAXN], AT[MAXN]; <span class="comment">//记录每个A之前的P的个数A之后的T的个数</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>, PATs);</span><br><span class="line"> <span class="keyword">int</span> len = <span class="built_in">strlen</span>(PATs);</span><br><span class="line"> <span class="keyword">int</span> cntP = <span class="number">0</span>, cntA = <span class="number">0</span>, cntT = <span class="number">0</span>, cntPAT = <span class="number">0</span>; <span class="comment">//分别记录P,A,T,PAT的总数</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//先确定每个A之前的P的个数</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < len; i++) {</span><br><span class="line"> <span class="keyword">if</span>(PATs[i] == <span class="string">'P'</span>) {</span><br><span class="line"> cntP++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(PATs[i] == <span class="string">'A'</span>) {</span><br><span class="line"> PA[cntA] = cntP;</span><br><span class="line"> <span class="comment">// printf("PA[%d]=%d\n", cntA, PA[cntA]);</span></span><br><span class="line"> cntA++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//先确定每个A之后的T的个数</span></span><br><span class="line"> <span class="keyword">int</span> temp = cntA - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = len - <span class="number">1</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="keyword">if</span>(PATs[i] == <span class="string">'T'</span>) {</span><br><span class="line"> cntT++;</span><br><span class="line"> <span class="comment">// printf("cntT=%d\n",cntT);</span></span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(PATs[i] == <span class="string">'A'</span>) {</span><br><span class="line"> <span class="comment">// printf("cntT=%d\n",cntT);</span></span><br><span class="line"> AT[temp] = cntT;</span><br><span class="line"> <span class="comment">// printf("AT[%d]=%d\n", temp, AT[temp]);</span></span><br><span class="line"> temp--;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将PA与AT的下标0-cntA每位相乘,然后求和即得cntPAT</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < cntA; i++) {</span><br><span class="line"> <span class="comment">// printf("PA[%d]=%d\n", i, PA[i]);</span></span><br><span class="line"> <span class="comment">// printf("AT[%d]=%d\n", i, AT[i]);</span></span><br><span class="line"> cntPAT += PA[i] * AT[i];</span><br><span class="line"> cntPAT %= MOD;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// cntPAT %= MOD;</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, cntPAT);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>第一遍最后两个测试点没过,原因是只在输出前取模会溢出,因此每轮循环都要取模。另外,最后一次循环可以放在计算T的时候。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1093 Count PAT's (25分)</title>
<link href="/2020/08/27/PAT-AdvancedLevel1093/"/>
<url>/2020/08/27/PAT-AdvancedLevel1093/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1093-Count-PAT’s-25分"><a href="#1093-Count-PAT’s-25分" class="headerlink" title="1093 Count PAT’s (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805373582557184" target="_blank" rel="noopener">1093 Count PAT’s (25分)</a></h2><p>The string <code>APPAPT</code> contains two <code>PAT</code>‘s as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters.</p><p>Now given any string, you are supposed to tell the number of <code>PAT</code>‘s contained in the string.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. For each case, there is only one line giving a string of no more than 105 characters containing only <code>P</code>, <code>A</code>, or <code>T</code>.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, print in one line the number of <code>PAT</code>‘s contained in the string. Since the result may be a huge number, you only have to output the result moded by 1000000007.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">APPAPT</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MOD = <span class="number">1000000007</span>;</span><br><span class="line"><span class="keyword">char</span> PATs[MAXN];</span><br><span class="line"><span class="keyword">int</span> PA[MAXN], AT[MAXN]; <span class="comment">//记录每个A之前的P的个数A之后的T的个数</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>, PATs);</span><br><span class="line"> <span class="keyword">int</span> len = <span class="built_in">strlen</span>(PATs);</span><br><span class="line"> <span class="keyword">int</span> cntP = <span class="number">0</span>, cntA = <span class="number">0</span>, cntT = <span class="number">0</span>, cntPAT = <span class="number">0</span>; <span class="comment">//分别记录P,A,T,PAT的总数</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//先确定每个A之前的P的个数</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < len; i++) {</span><br><span class="line"> <span class="keyword">if</span>(PATs[i] == <span class="string">'P'</span>) {</span><br><span class="line"> cntP++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(PATs[i] == <span class="string">'A'</span>) {</span><br><span class="line"> PA[cntA] = cntP;</span><br><span class="line"> <span class="comment">// printf("PA[%d]=%d\n", cntA, PA[cntA]);</span></span><br><span class="line"> cntA++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//先确定每个A之后的T的个数</span></span><br><span class="line"> <span class="keyword">int</span> temp = cntA - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = len - <span class="number">1</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="keyword">if</span>(PATs[i] == <span class="string">'T'</span>) {</span><br><span class="line"> cntT++;</span><br><span class="line"> <span class="comment">// printf("cntT=%d\n",cntT);</span></span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(PATs[i] == <span class="string">'A'</span>) {</span><br><span class="line"> <span class="comment">// printf("cntT=%d\n",cntT);</span></span><br><span class="line"> AT[temp] = cntT;</span><br><span class="line"> <span class="comment">// printf("AT[%d]=%d\n", temp, AT[temp]);</span></span><br><span class="line"> temp--;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将PA与AT的下标0-cntA每位相乘,然后求和即得cntPAT</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < cntA; i++) {</span><br><span class="line"> <span class="comment">// printf("PA[%d]=%d\n", i, PA[i]);</span></span><br><span class="line"> <span class="comment">// printf("AT[%d]=%d\n", i, AT[i]);</span></span><br><span class="line"> cntPAT += PA[i] * AT[i];</span><br><span class="line"> cntPAT %= MOD;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// cntPAT %= MOD;</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, cntPAT);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>第一遍最后两个测试点没过,原因是只在输出前取模会溢出,因此每轮循环都要取模。另外,最后一次循环可以放在计算T的时候。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1023 组个最小数 (20分)</title>
<link href="/2020/08/22/PAT-BasicLevel1023/"/>
<url>/2020/08/22/PAT-BasicLevel1023/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1023-组个最小数-20分"><a href="#1023-组个最小数-20分" class="headerlink" title="1023 组个最小数 (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805298269634560" target="_blank" rel="noopener">1023 组个最小数 (20分)</a></h2><p>给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就是 10015558。</p><p>现给定数字,请编写程序输出能够组成的最小的数。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非 0 的数字。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>在一行中输出能够组成的最小的数。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2 2 0 0 0 3 0 0 1 0</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">10015558</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bool cmp(int a, int b) {</span></span><br><span class="line"><span class="comment">// return a < b;</span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">minNum</span><span class="params">(<span class="keyword">int</span> *num, <span class="keyword">int</span> sum)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> temp = <span class="number">0</span>;<span class="comment">//保存第一个不为0的数字的下标</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < sum; i++) {</span><br><span class="line"> <span class="keyword">if</span>(num[i]) {</span><br><span class="line"> temp = i;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, num[i]);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < sum; i++) {</span><br><span class="line"> <span class="keyword">if</span>(i != temp){</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, num[i]);</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> numCnt[<span class="number">10</span>], num[<span class="number">50</span>], sum = <span class="number">0</span>;<span class="comment">//分别代表每个数字的次数,将数字从小到大排序,数字的总个数</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">10</span>; i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &numCnt[i]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = sum; (j - sum) < numCnt[i]; j++) {<span class="comment">//根据次数将每个数字依次保存到num中</span></span><br><span class="line"> num[j] = i;</span><br><span class="line"> }</span><br><span class="line"> sum += numCnt[i];</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// for(int i = 0; i < sum; i++) { </span></span><br><span class="line"> <span class="comment">// printf("num[%d]=%d\n", i, num[i]);</span></span><br><span class="line"> <span class="comment">// }</span></span><br><span class="line"> <span class="comment">// sort(num, num+sum, cmp);</span></span><br><span class="line"> minNum(num, sum);</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>第一遍看错题目了,所以写复杂了点</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1020 月饼 (25分)</title>
<link href="/2020/08/22/PAT-BasicLevel1020/"/>
<url>/2020/08/22/PAT-BasicLevel1020/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1020-月饼-25分"><a href="#1020-月饼-25分" class="headerlink" title="1020 月饼 (25分)"></a><strong><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805301562163200" target="_blank" rel="noopener">1020 月饼 (25分)</a></strong></h2><p>月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。</p><p>注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 <em>N</em> 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 <em>D</em> 表示市场最大需求量。随后一行给出 <em>N</em> 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 <em>N</em> 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">3 20</span><br><span class="line">18 15 10</span><br><span class="line">75 72 45</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">94.50</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">mooncake</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">double</span> sum;</span><br><span class="line"> <span class="keyword">double</span> sumPrice;</span><br><span class="line"> <span class="keyword">double</span> price;</span><br><span class="line">} cake[<span class="number">1010</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span><span class="params">(mooncake a, mooncake b)</span></span></span><br><span class="line"><span class="function"></span>{<span class="comment">//按照单价将月饼排序</span></span><br><span class="line"> <span class="keyword">return</span> a.price > b.price;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> n; <span class="comment">//种类</span></span><br><span class="line"> <span class="keyword">double</span> d; <span class="comment">//需求量</span></span><br><span class="line"> <span class="keyword">double</span> maxPfit = <span class="number">0</span>; <span class="comment">//利润</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %lf"</span>, &n, &d);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> { </span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lf"</span>, &cake[i].sum);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lf"</span>, &cake[i].sumPrice);</span><br><span class="line"> cake[i].price = cake[i].sumPrice / cake[i].sum;</span><br><span class="line"> }</span><br><span class="line"> sort(cake, cake + n, cmp);</span><br><span class="line"> <span class="keyword">double</span> temp = d; <span class="comment">//剩余需求</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> {<span class="comment">//第二个条件i<n不能是temp>0,当d足够大可能段错误</span></span><br><span class="line"> <span class="keyword">if</span> (temp >= cake[i].sum)</span><br><span class="line"> {</span><br><span class="line"> maxPfit += cake[i].sumPrice;</span><br><span class="line"> temp -= cake[i].sum;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> maxPfit += temp * cake[i].price;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%.2f"</span>, maxPfit);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>最后一个循环的第二个条件i<n不能是temp>0,因为当d足够大可能发生段错误(丢人),第一次提交这里错了hhh;另外,注意D也要用double。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1025 PAT Ranking (25分)</title>
<link href="/2020/06/03/PAT-AdvancedLevel1025/"/>
<url>/2020/06/03/PAT-AdvancedLevel1025/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1025-PAT-Ranking-25分"><a href="#1025-PAT-Ranking-25分" class="headerlink" title="1025 PAT Ranking (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805474338127872" target="_blank" rel="noopener">1025 PAT Ranking (25分)</a></h2><p>Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. For each case, the first line contains a positive number <em>N</em> (≤100), the number of test locations. Then <em>N</em> ranklists follow, each starts with a line containing a positive integer <em>K</em> (≤300), the number of testees, and then <em>K</em> lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">registration_number final_rank location_number local_rank</span><br></pre></td></tr></table></figure><p>The locations are numbered from 1 to <em>N</em>. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">2</span><br><span class="line">5</span><br><span class="line">1234567890001 95</span><br><span class="line">1234567890005 100</span><br><span class="line">1234567890003 95</span><br><span class="line">1234567890002 77</span><br><span class="line">1234567890004 85</span><br><span class="line">4</span><br><span class="line">1234567890013 65</span><br><span class="line">1234567890011 25</span><br><span class="line">1234567890014 100</span><br><span class="line">1234567890012 85</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">9</span><br><span class="line">1234567890005 1 1 1</span><br><span class="line">1234567890014 1 2 1</span><br><span class="line">1234567890001 3 1 2</span><br><span class="line">1234567890003 3 1 2</span><br><span class="line">1234567890004 5 1 4</span><br><span class="line">1234567890012 5 2 2</span><br><span class="line">1234567890002 7 1 5</span><br><span class="line">1234567890013 8 2 3</span><br><span class="line">1234567890011 9 2 4</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Student</span> {</span></span><br><span class="line"> <span class="keyword">char</span> reg_num[<span class="number">13</span>];</span><br><span class="line"> <span class="keyword">int</span> score;</span><br><span class="line"> <span class="keyword">int</span> finR, locN, locR; </span><br><span class="line">} stu[<span class="number">30010</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span><span class="params">(Student a, Student b)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(a.score != b.score) <span class="keyword">return</span> a.score > b.score;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">return</span> <span class="built_in">strcmp</span>(a.reg_num, b.reg_num) < <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, k, num = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="comment">//loc is location_number</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> loc = <span class="number">1</span>; loc <= n; loc++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &k);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < k; i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s %d"</span>, &stu[num+i].reg_num, &stu[num+i].score);</span><br><span class="line"> stu[num+i].locN = loc;</span><br><span class="line"> }</span><br><span class="line"> num += k;</span><br><span class="line"> <span class="comment">//对每个local的location进行排名</span></span><br><span class="line"> sort(stu + num - k, stu + num, cmp);</span><br><span class="line"> <span class="comment">// for(int i = 0; i < k; i++) {</span></span><br><span class="line"> <span class="comment">// printf("%d", stu[num-k+i].score);</span></span><br><span class="line"> <span class="comment">// }</span></span><br><span class="line"> <span class="comment">//得到locR</span></span><br><span class="line"> stu[num-k].locR = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j < k; j++) {</span><br><span class="line"> <span class="keyword">if</span>(stu[num-k+j].score != stu[num-k+j<span class="number">-1</span>].score) {</span><br><span class="line"> stu[num-k+j].locR = j+<span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> stu[num-k+j].locR = stu[num-k+j<span class="number">-1</span>].locR;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//整个学生进行排名</span></span><br><span class="line"> sort(stu, stu+num, cmp);</span><br><span class="line"> <span class="comment">// for(int i = 0; i < num; i++) {</span></span><br><span class="line"> <span class="comment">// printf("%d\n", stu[i].score);</span></span><br><span class="line"> <span class="comment">// }</span></span><br><span class="line"> <span class="comment">//得到finR</span></span><br><span class="line"> stu[<span class="number">0</span>].finR = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i < num; i++) {</span><br><span class="line"> <span class="keyword">if</span>(stu[i].score != stu[i<span class="number">-1</span>].score) {</span><br><span class="line"> stu[i].finR = i+<span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> stu[i].finR = stu[i<span class="number">-1</span>].finR;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// for(int i = 0; i < num; i++) {</span></span><br><span class="line"> <span class="comment">// printf("%d\n", stu[i].score);</span></span><br><span class="line"> <span class="comment">// }</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//print</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, num);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < num; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%s %d %d %d\n"</span>, stu[i].reg_num, stu[i].finR, stu[i].locN, stu[i].locR);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>通过sort进行排名,注意比较学号的时候要用cstring的strcmp</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>软件工程笔记</title>
<link href="/2020/05/22/SoftwareEngineering/"/>
<url>/2020/05/22/SoftwareEngineering/</url>
<content type="html"><![CDATA[<h1 id="Software-Engineering"><a href="#Software-Engineering" class="headerlink" title="Software Engineering"></a>Software Engineering</h1><h2 id="The-Nature-of-Software"><a href="#The-Nature-of-Software" class="headerlink" title="The Nature of Software"></a>The Nature of Software</h2><p><strong>Software</strong></p><p>软件是:(1)指令的集合(计算机程序),通过执行这些指令可以满足预期的特性、功能和性能需求;(2)数据结构,使得程序可以合理利用信息;(3)软件描述信息,它以硬拷贝和虚拟形式存在,用来描述程序的操作和使用。</p><p><strong>Softwatre Characteristics(The differences between software and hardware)</strong></p><p>软件是被开发或设计的,而不是传统意义上的制造。</p><p>软件不会磨损(最根本的不同)</p><p>软件是定制的,而不是由组件构成</p><p>软件是退化的(不断的变更是软件退化的根本原因)</p><h2 id="Software-Engineering-1"><a href="#Software-Engineering-1" class="headerlink" title="Software Engineering"></a>Software Engineering</h2><p><strong>Software process</strong></p><p>软件过程是工作产品构建时所执行的一系列活动、动作和任务的集合。</p><p><strong>Software engineering</strong></p><p>软件工程是:(1)将系统化的、规范的、可量化的方法应用于软件的开发、运行和维护,即将工程化方法应用于软件;(2)对(1)中所述方法的研究。</p><h2 id="Software-Process-Structure"><a href="#Software-Process-Structure" class="headerlink" title="Software Process Structure"></a>Software Process Structure</h2><p><strong>Software Engineering Layers</strong></p><p>工具、方法、过程、质量关注点</p><p><strong>Generic Software Engineering Framwork Activities</strong></p><p>沟通、策划、建模、构建、部署</p><p><strong>Process Assessment and Improvement</strong></p><p>用于过程改进的CMMI标准评估方法:启动、诊断、建立、执行、学习</p><p>用于组织内部过程改进的CMM评估</p><p><strong>Process Flow</strong></p><p>过程流描述了在执行顺序和执行时间上如何阻止框架中的活动、动作和任务。</p><p>线性过程流从沟通到部署顺序执行五个框架活动。</p><p>迭代过程流在执行下一个活动前重复执行之前的一个或多个活动。</p><p>演化过程流采用循环的方式执行各个活动,每次循环都能产生更为完善的软件版本。</p><p>并行过程流将一个或多个活动与其他活动并行执行。</p><h2 id="Process-Models"><a href="#Process-Models" class="headerlink" title="Process Models"></a>Process Models</h2><p><strong>惯用过程模型:</strong></p><p>瀑布模型(线性模型)</p><p>增量过程模型(核心产品、瀑布模型)</p><p>原型模型(演化过程模型、需求模糊、抛弃):沟通、快速策划、建模快速设计、构建原型、部署交付及反馈</p><p>螺旋模型(演化过程模型、原型、瀑布)</p><p>并发开发模型</p><p><strong>专用过程模型:</strong></p><p>基于构建的开发模型</p><p>形式化方法模型</p><p>面向方面的软件开发模型</p><p><strong>统一过程</strong></p><p>起始、细化、构建、转换、生产</p><p><strong>个人过程模型和团队过程模型</strong></p><h2 id="Agile-Development"><a href="#Agile-Development" class="headerlink" title="Agile Development"></a>Agile Development</h2><p><strong>Agile</strong></p><p>对软件生产率的高度重视,主要适用于需求模糊或快速变化下的、小型项目组的开发。在满足所需的软件质量要求的前提下,力求提高开发效率。</p><p><strong>Agility</strong></p><p>快速交付产品、对变更的有效响应、所有利益相关者之间有效沟通、灵活的项目计划、小而高度自主的团队</p><p><strong>The Manifesto for Agile</strong>:</p><p>个人和他们之间交流胜过了开发过程和工具</p><p>可运行的软件胜过了宽泛的文档</p><p>客户合作胜过了合同谈判</p><p>对变更的良好响应胜过了按部就班地遵循计划</p><p><strong>Extreme Programming(XP)</strong></p><p>四个框架活动:策划、设计、编码、测试</p><p>关键点:用户故事、KIS、结对编程、重构、连续集成、增量交付</p><p><strong>Other agile process</strong></p><p>Scrum</p><p>动态系统开发方法(DSDM)</p><p>敏捷建模(AM)</p><p>敏捷统一过程(AUP)</p><h2 id="Understanding-Requirements"><a href="#Understanding-Requirements" class="headerlink" title="Understanding Requirements"></a>Understanding Requirements</h2><p><strong>The definition of requirements engineering</strong></p><p>需求工程是指致力于不断理解需求的大量任务和技术。</p><p>从软件过程的角度来看,需求工程是一个软件工程动作,开始于沟通活动并持续到建模活动。</p><p>需求工程在设计和构建之间建立起联系的桥梁。</p><p><strong>Requirements Engineering Tasks</strong></p><p>Inception(起始)、Elicitation(获取)、Elaboration(细化)、Negotiation(协商)、Specification(规格说明)、Validation(确认)、Requirements management(需求管理)</p><p><strong>质量功能部署Quality Function Deployment(QFD)</strong></p><p>常规Normal/期望Expected/兴奋Exciting</p><p><strong>ERD</strong></p><p><strong>Use-case</strong></p><p>场景通常称为用例,它描述了人们将如何使用某一系统。</p><p><strong>Elicitation Work Products</strong>(Requirement Specification…)</p><p>(1)要求和可行性陈述;</p><p>(2)系统或产品范围的界限说明;</p><p>(3)参与需求获取的客户、用户和其他相关利益者的名单;</p><p>(4)系统技术环境的说明;</p><p>(5)需求列表以及每个需求适用的领域限制;</p><p>(6)一系列使用场景,有助于深入了解系统或产品在不同运行环境下的使用;</p><p>(7)任何能够更好地定义需求的原型。</p><h2 id="Requirements-Modeling:Scenario-Based-Methods"><a href="#Requirements-Modeling:Scenario-Based-Methods" class="headerlink" title="Requirements Modeling:Scenario-Based Methods"></a>Requirements Modeling:Scenario-Based Methods</h2><p><strong>Objectives of Requirements Model</strong> </p><p>需求模型必须实现三个主要目标:(1)描述客户需要什么;(2)为软件设计奠定基础;(3)定义在软件完成后可以被确认的一组需求。</p><p><strong>Rules of Thumb(需求分析建模原则)</strong></p><p>模型应关注在问题域或业务域内可见的需求,抽象的级别应该相对高一些。(不要陷入细节)</p><p>需求模型的每个元素都应能增加对软件需求的理解,并提供对信息域、功能和系统行为的深入理解。(增加对软件需求主体的理解)</p><p>关于基础结构和其他非功能的模型应推延到设计阶段再考虑。</p><p>最小化整个系统内的关联。(低耦合)</p><p>确认需求模型为所有利益相关者都带来价值。</p><p>尽可能保持模型简洁。</p><p><strong>Elements of Requirements Analysis</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/22/SoftwareEngineering/Rmodel.png" alt="需求模型的元素"></p><p><strong>UML</strong></p><p>统一建模语言</p><p><strong>Diagrams of UML for analysis modeling</strong></p><p>Use-case diagram</p><p>Activity diagram</p><p>Class diagram</p><p>Collaboration diagram </p><p>State diagram</p><p>Sequence diagram </p><p>Deploment diagram</p><h2 id="Requirements-Modeling:Class-Based-Methods"><a href="#Requirements-Modeling:Class-Based-Methods" class="headerlink" title="Requirements Modeling:Class-Based Methods"></a>Requirements Modeling:Class-Based Methods</h2><p><strong>CRC</strong></p><p>类-职责-协作者</p><p>类是系统操作的对象</p><p>职责是和类相关的属性和操作</p><p>协作者是提供完成某个职责所需要信息的类</p><h2 id="Design-Concepts"><a href="#Design-Concepts" class="headerlink" title="Design Concepts"></a>Design Concepts</h2><p><strong>Design conceptions</strong></p><p>关注点分离</p><p>模块化</p><p>信息隐蔽</p><p>重构</p><p>内聚</p><p>耦合</p><p><strong>Object-oriented Design conceptions</strong></p><p>类、属性、操作</p><p>多态Polymorphism</p><p>封装Encapsulation</p><p>继承Inheritance</p><p><strong>Quality attributes-FURPS</strong></p><p>功能性、易用性、可靠性、性能、可支持性</p><p><strong>DFD</strong></p><p><strong>Four Design Models Elements</strong></p><p><u>数据设计元素、体系结构设计元素、接口设计元素、构件级设计元素</u>、部署级设计元素</p><h2 id="Architectural-Design"><a href="#Architectural-Design" class="headerlink" title="Architectural Design"></a>Architectural Design</h2><p><strong>Software Architecture</strong></p><p>程序或计算系统的软件体系结构是指系统的一个或者多个结构,它包括软件构件、构件的外部可见属性以及它们之间的相互关系。</p><p><strong>Why is Architecture important?</strong></p><p>软件体系结构提供了一种表示,有助于对计算机系统开发感兴趣的所有利益相关者开展交流</p><p>体系结构突出了早期的设计决策,这些决策对随后所有的软件工程工作有深远的影响</p><p>体系结构”构建了一个相对小的、易于理解的模型,该模型描述了系统如何构成以及其构件如何一起工作“</p><p><strong>Architectural Styles</strong></p><p>以数据为中心的体系结构</p><p>数据流体系结构</p><p>调用和返回体系结构</p><p>面向对象体系结构</p><p>层次体系结构</p><h2 id="Component-level-Design"><a href="#Component-level-Design" class="headerlink" title="Component-level Design"></a>Component-level Design</h2><p><strong>Component definiton</strong></p><p>系统中模块化的、可部署的和可替换的部件,该部件封装了实现并对外提供一组接口</p><p><strong>Component-level(class-based) 基本设计原则</strong></p><p>开闭原则(OCP)</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/22/SoftwareEngineering/OCP.png" alt="OCP"></p><p>Liskov 替换原则(LSP)</p><p>依赖倒置原则(DIP)</p><p>接口分离原则(ISP)</p><h2 id="Interface-Design"><a href="#Interface-Design" class="headerlink" title="Interface Design"></a>Interface Design</h2><p><strong>Golden Rules</strong></p><p>把控制权交给用户</p><p>减轻用户的记忆负担</p><p>保持界面一致</p><p><strong>User Interface Design Models</strong></p><p>用户模型</p><p>设计模型</p><p>心理模型(系统感知)</p><p>实现模型</p><p><strong>User Interface Design Process</strong></p><p>(1)界面分析和建模;(2)界面设计;(3)界面构建;(4)界面确认。</p><p><strong>Interface analysis and modeling</strong></p><p>用户分析</p><p>任务分析和建模</p><p>显示内容分析</p><p>工作环境分析</p><p><strong>Interface design</strong></p><p>(1)定义界面对象和动作(操作);(2)确定事件(用户动作),即会导致用户界面状态发生变化的事件;(3)描述每个状态的表示形式;(4)说明用户如何利用界面提供的信息来解释每个状态。</p><h2 id="Software-Testing-Strategies"><a href="#Software-Testing-Strategies" class="headerlink" title="Software Testing Strategies"></a>Software Testing Strategies</h2><p><strong>Objective of Software Testing</strong></p><p>测试的目的是为了发现软件设计和实现过程中的疏忽所造成的错误</p><p><strong>Testing Strategies 特征</strong></p><p>为完成有效的测试,应该进行有效的、正式的技术评审。通过评审,许多错误可以在测试开始之前排除。</p><p>测试开始于构件层,然后向外“延伸”到整个计算机系统的集成中。</p><p>不同的测试技术适用于不用的软件工程方法和不同的时间点。</p><p>测试由软件开发人员和(对大型项目而言)独立的测试组执行。</p><p>测试和调试是不同的活动,但任何测试策略都必须包括调试。</p><p><strong>Test Strategy</strong></p><p>单元测试Unit Test</p><p>集成测试Integration Test</p><p>确认测试Validation Test</p><p>系统测试System Test</p><p><strong>Unit Test</strong></p><p>驱动程序Driver:驱动程序是一个主程序,它接收测试用例数据,将这些数据传递给(将要测试的构件)构件,并打印相关结果;</p><p>桩程序Stub:桩程序的作用是替换那些从属于被测构件(或被其调用)的模块。</p><p><strong>Integration Test</strong></p><p>自顶向下集成、自底向上集成、三明治测试、回归测试、冒烟测试</p><p><strong>Validation Test</strong></p><p>确认测试准则:软件确认是通过一系列表明软件功能与软件需求相符合的测试而获得。设计的特定测试用例用于确保软件满足所有的功能需求,具有所有的行为特征,所有内容都准确无误且正确显示,达到所有的性能需求,文档是正确的、可用的,且满足其他需求。</p><p>配置评审:评审的目的是确保所有的软件配置元素已正确开发、编目,且具有改善支持活动的必要细节。</p><p>验收测试:α测试和β测试。</p><p><strong>System Test</strong></p><p>恢复测试、安全测试、压力测试、性能测试、部署测试、配置测试</p><p><strong>Debugging</strong></p><p>测试发现错误,调试诊断错误出现的原因和位置,以便于消除错误</p><p><strong>Debugging Techniques</strong></p><p>蛮干法</p><p>回溯法</p><p>原因排除法</p><h2 id="Testing-Conventional-Applications"><a href="#Testing-Conventional-Applications" class="headerlink" title="Testing Conventional Applications"></a>Testing Conventional Applications</h2><p><strong>White-box Test</strong></p><p>白盒测试,也叫玻璃盒测试或结构化测试,是基于过程细节的封闭测试,检查构件内部处理逻辑、数据结构和构件间的协作(接口)的正确性。(内部测试)</p><p><u>基本路径测试</u></p><p><u>控制结构测试</u></p><p><strong>Black-box Test</strong></p><p>黑盒测试,也称行为测试或功能测试,从外部(软件接口处)执行测试用例,用以验证待测功能的正确性,而不考虑软件内部处理逻辑。(外部测试)</p><p><u>等价类划分</u></p><p><u>边界值分析</u></p><h2 id="Testing-Object-Oriented-Application"><a href="#Testing-Object-Oriented-Application" class="headerlink" title="Testing Object-Oriented Application"></a>Testing Object-Oriented Application</h2><p><strong>OO Test</strong></p><p><strong>OO Test Strategy</strong></p><p><u>OO Unit Testing</u></p><p><u>OO Integration Testing</u></p>]]></content>
<categories>
<category> SoftwareEngineering </category>
</categories>
<tags>
<tag> note </tag>
<tag> SoftwareEngineering </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1009 说反话 (20分)</title>
<link href="/2020/05/18/PAT-BasicLevel1009/"/>
<url>/2020/05/18/PAT-BasicLevel1009/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1009-说反话-20分"><a href="#1009-说反话-20分" class="headerlink" title="1009 说反话 (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805314941992960" target="_blank" rel="noopener"><strong>1009</strong> <strong>说反话</strong> <strong>(20</strong>分)</a></h2><p>给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>每个测试用例的输出占一行,输出倒序后的句子。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Hello World Here I Come</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Come I Here World Hello</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> num = <span class="number">0</span>; <span class="comment">//单词个数</span></span><br><span class="line"> <span class="keyword">char</span> <span class="keyword">word</span>[<span class="number">90</span>][<span class="number">90</span>];</span><br><span class="line"> <span class="keyword">while</span>(<span class="built_in">scanf</span>(<span class="string">"%s"</span>, <span class="keyword">word</span>[num]) != EOF) {</span><br><span class="line"> num++;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//倒着输出</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = num - <span class="number">1</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%s"</span>, <span class="keyword">word</span>[i]);</span><br><span class="line"> <span class="keyword">if</span>(i > <span class="number">0</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">" "</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>无</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1022 D进制的A+B (20分)</title>
<link href="/2020/05/18/PAT-BasicLevel1022/"/>
<url>/2020/05/18/PAT-BasicLevel1022/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1022-D进制的A-B-20分"><a href="#1022-D进制的A-B-20分" class="headerlink" title="1022 D进制的A+B (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805299301433344" target="_blank" rel="noopener"><strong>1022</strong> <strong>D进制的A+B</strong> <strong>(20</strong>分)</a></h2><p>输入两个非负 10 进制整数 <em>A</em> 和 <em>B</em> (≤230−1),输出 <em>A</em>+<em>B</em> 的 <em>D</em> (1<<em>D</em>≤10)进制数。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在一行中依次给出 3 个整数 <em>A</em>、<em>B</em> 和 <em>D</em>。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>输出 <em>A</em>+<em>B</em> 的 <em>D</em> 进制数。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">123 456 8</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1103</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> A, B, D, sum;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &A, &B, &D);</span><br><span class="line"> sum = A + B;</span><br><span class="line"> <span class="keyword">int</span> ans[<span class="number">31</span>]; <span class="comment">//保留结果</span></span><br><span class="line"> <span class="keyword">int</span> num = <span class="number">0</span>; <span class="comment">//数组下标</span></span><br><span class="line"> <span class="keyword">do</span> {</span><br><span class="line"> ans[num++] = sum % D;</span><br><span class="line"> sum /= D;</span><br><span class="line"></span><br><span class="line"> } <span class="keyword">while</span>(sum != <span class="number">0</span>);</span><br><span class="line"> <span class="comment">// 逆向输出D</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = num - <span class="number">1</span>; i >= <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, ans[i]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>无</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1036 跟奥巴马一起编程 (15分)</title>
<link href="/2020/05/17/PAT-BasicLevel1036/"/>
<url>/2020/05/17/PAT-BasicLevel1036/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1036-跟奥巴马一起编程-15分"><a href="#1036-跟奥巴马一起编程-15分" class="headerlink" title="1036 跟奥巴马一起编程 (15分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805285812551680" target="_blank" rel="noopener"><strong>1036</strong> <strong>跟奥巴马一起编程</strong> <strong>(15分)</strong></a></h2><p>美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014 年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在一行中给出正方形边长 <em>N</em>(3≤<em>N</em>≤20)和组成正方形边的某种字符 C,间隔一个空格。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>输出由给定字符 C 画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的 50%(四舍五入取整)。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">10 a</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">aaaaaaaaaa</span><br><span class="line">a a</span><br><span class="line">a a</span><br><span class="line">a a</span><br><span class="line">aaaaaaaaaa</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="keyword">char</span> c;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %c"</span>, &n, &c);</span><br><span class="line"> <span class="keyword">double</span> y = round((<span class="keyword">double</span>)n * <span class="number">0.5</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < (<span class="keyword">int</span>)y; i++) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">0</span>; j < n; j++) {</span><br><span class="line"> <span class="keyword">if</span>(i == <span class="number">0</span> || i == <span class="keyword">int</span>(y) - <span class="number">1</span> || j == <span class="number">0</span> || j == n - <span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c"</span>, c);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">" "</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>无</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1032 挖掘机技术哪家强 (20分)</title>
<link href="/2020/05/17/PAT-BasicLevel1032/"/>
<url>/2020/05/17/PAT-BasicLevel1032/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1032-挖掘机技术哪家强-20分"><a href="#1032-挖掘机技术哪家强-20分" class="headerlink" title="1032 挖掘机技术哪家强 (20分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805289432236032" target="_blank" rel="noopener"><strong>1032</strong> <strong>挖掘机技术哪家强</strong> <strong>(20</strong>分)</a></h2><p>为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>输入在第 1 行给出不超过 105 的正整数 <em>N</em>,即参赛人数。随后 <em>N</em> 行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从 1 开始连续编号)、及其比赛成绩(百分制),中间以空格分隔。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。题目保证答案唯一,没有并列。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">6</span><br><span class="line">3 65</span><br><span class="line">2 80</span><br><span class="line">1 100</span><br><span class="line">2 70</span><br><span class="line">3 40</span><br><span class="line">3 0</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2 150</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn = <span class="number">100000</span>; <span class="comment">//最大人数</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, sno, grade;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">int</span> score[maxn] = {};</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i <= n; i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %d"</span>, &sno, &grade);</span><br><span class="line"> score[sno<span class="number">-1</span>] += grade;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> Max_s = <span class="number">1</span>, Max_g = score[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span>(score[i] > Max_g) {</span><br><span class="line"> Max_s = i + <span class="number">1</span>;</span><br><span class="line"> Max_g = score[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d %d\n"</span>, Max_s, Max_g);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>无</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT乙级:1001 害死人不偿命的(3n+1)猜想 (15分)</title>
<link href="/2020/05/16/PAT-BasicLevel1001/"/>
<url>/2020/05/16/PAT-BasicLevel1001/</url>
<content type="html"><![CDATA[<h1 id="PAT-Basic-Level-Practice"><a href="#PAT-Basic-Level-Practice" class="headerlink" title="PAT (Basic Level) Practice"></a>PAT (Basic Level) Practice</h1><h2 id="1001-害死人不偿命的-3n-1-猜想-15分"><a href="#1001-害死人不偿命的-3n-1-猜想-15分" class="headerlink" title="1001 害死人不偿命的(3n+1)猜想 (15分)"></a><a href="https://pintia.cn/problem-sets/994805260223102976/problems/994805325918486528" target="_blank" rel="noopener"><strong>1001</strong> <strong>害死人不偿命的(3n+1)猜想</strong> <strong>(15分)</strong></a></h2><p>卡拉兹(Callatz)猜想:</p><p>对任何一个正整数 <em>n</em>,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3<em>n</em>+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 <em>n</em>=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3<em>n</em>+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……</p><p>我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 <em>n</em>,简单地数一下,需要多少步(砍几下)才能得到 <em>n</em>=1?</p><h3 id="输入格式:"><a href="#输入格式:" class="headerlink" title="输入格式:"></a>输入格式:</h3><p>每个测试输入包含 1 个测试用例,即给出正整数 <em>n</em> 的值。</p><h3 id="输出格式:"><a href="#输出格式:" class="headerlink" title="输出格式:"></a>输出格式:</h3><p>输出从 <em>n</em> 计算到 1 需要的步数。</p><h3 id="输入样例:"><a href="#输入样例:" class="headerlink" title="输入样例:"></a>输入样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3</span><br></pre></td></tr></table></figure><h3 id="输出样例:"><a href="#输出样例:" class="headerlink" title="输出样例:"></a>输出样例:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">5</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, <span class="built_in">step</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">while</span>(n != <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">if</span>(n % <span class="number">2</span> == <span class="number">0</span>) {</span><br><span class="line"> n /= <span class="number">2</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> n = (<span class="number">3</span> * n + <span class="number">1</span>) / <span class="number">2</span>; </span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">step</span>++;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, <span class="built_in">step</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>无</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_B </category>
</categories>
<tags>
<tag> pat </tag>
</tags>
</entry>
<entry>
<title>编译原理笔记</title>
<link href="/2020/05/11/CompilerPrinciple/"/>
<url>/2020/05/11/CompilerPrinciple/</url>
<content type="html"><![CDATA[<h1 id="编译原理笔记"><a href="#编译原理笔记" class="headerlink" title="编译原理笔记"></a>编译原理笔记</h1><p>[TOC]</p><h2 id="第一章-引论"><a href="#第一章-引论" class="headerlink" title="第一章 引论"></a>第一章 引论</h2><h3 id="1-1-语言处理器"><a href="#1-1-语言处理器" class="headerlink" title="1.1 语言处理器"></a>1.1 语言处理器</h3><p><strong>编译器</strong></p><p>阅读以某一种语言(源代码)编写的程序,并把该程序翻译成为一个等价的、用另一种语言(目标语言)编写的程序。</p><p><strong>解释器</strong></p><p>另一种常见的语言处理器,并不通过翻译的方式生成目标程序,直接利用用户提供的输入执行源程序中指定的操作。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/1.png" alt=""></p><p>预处理器:一个源程序可能被分割成多个模块,并存放于独立的文件中,把源程序聚合在一起的任务有时会由一个被成为预处理器的程序独立完成。</p><p>汇编器:对编译器产生的汇编语言程序进行处理,并生成可重定位的机器代码。</p><p>链接器/加载器:一个文件中的代码可能指向另一个文件中的位置,而链接器能够解决外部内存地址的问题。最后,加载器把所有的可执行目标文件放到内存中执行。</p><h3 id="1-2-一个编译器的结构"><a href="#1-2-一个编译器的结构" class="headerlink" title="1.2 一个编译器的结构"></a>1.2 一个编译器的结构</h3><p>编译器的两个组成部分:分析部分和综合部分。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/2.png" alt=""></p><p>一个编译器的各个步骤:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/3.png" alt=""></p><ul><li>词法分析</li></ul><p>词法分析/扫描:词法分析器读入组成源程序的字符流,并且将它们组织成为有意义的词素的序列。每个词素都被映射成如下语法单元,传送给语法分析:</p><token-name, attribute-value><p>分隔词素的空格会被词法分析器忽略掉。</p><ul><li>语法分析</li></ul><p>语法分析/解析:语法分析器使用由词法分析器生成的各个词法单元的第一个分量来创建树形的中间表示。</p><ul><li>语义分析</li></ul><p>语义分析器使用语法树和符号表中的信息来检查源程序是否和语言定义的语义一致。它同时也收集类型信息,并把这些信息存放在语法树或者符号表中,以便在随后的中间代码生成过程中使用。</p><ul><li>中间代码生成</li></ul><p>三地址代码的中间表示形式。</p><ul><li><p>代码优化</p></li><li><p>代码生成</p></li></ul><p>代码生成器以源程序的中间表示形式作为输入,并把它映射到目标语言。</p><ul><li>符号表管理</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/5.png" alt=""></p><ul><li><p>将多个步骤组合成趟</p></li><li><p>编译器构造工具</p></li></ul><p>一个赋值语句的翻译:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/4.png" alt=""></p><h2 id="第二章-一个简单的语法制导翻译器"><a href="#第二章-一个简单的语法制导翻译器" class="headerlink" title="第二章 一个简单的语法制导翻译器"></a>第二章 一个简单的语法制导翻译器</h2><h3 id="2-7-符号表"><a href="#2-7-符号表" class="headerlink" title="2.7 符号表"></a>2.7 符号表</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/6.png" alt=""></p><h4 id="2-7-1-为每个作用域设置一个符号表"><a href="#2-7-1-为每个作用域设置一个符号表" class="headerlink" title="2.7.1 为每个作用域设置一个符号表"></a>2.7.1 为每个作用域设置一个符号表</h4><p><strong>最近嵌套规则</strong></p><p>一个标识符x在最近声明x的作用域中,也就是说,从x出现的块开始,从内向外检查各个块时找到的第一个对x的声明。</p><p><strong>符号表支持的三种操作:</strong></p><ul><li>创建一个新符号表</li><li>在当前表中加入一个新的条目(键-值对)</li><li>得到一个标识符的条目</li></ul><h4 id="2-7-2-符号表的使用"><a href="#2-7-2-符号表的使用" class="headerlink" title="2.7.2 符号表的使用"></a>2.7.2 符号表的使用</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/7.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/8.png" alt=""></p><h2 id="第三章-词法分析"><a href="#第三章-词法分析" class="headerlink" title="第三章 词法分析"></a>第三章 词法分析</h2><h3 id="3-1-词法分析器的作用"><a href="#3-1-词法分析器的作用" class="headerlink" title="3.1 词法分析器的作用"></a>3.1 词法分析器的作用</h3><p>词法分析是编译的第一阶段。词法分析器的主要任务是读入源程序的输入字符、将它们组成词素,生成并输出一个词法单元序列,每个词法单元序列对应于一个词素。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/9.png" alt=""></p><p>词法分析器在编译器中负责读取源程序,因此还会完成一些识别词素之外的其他任务。</p><ul><li>任务一:过滤源程序中的注释和空白</li><li>任务二:将编译器生成的错误信息和源程序的位置联系起来</li></ul><p>有时,词法分析器也可以分成两个级联的处理阶段</p><ul><li>扫描阶段主要负责完成一些不需要生成词法单元的简单处理,比如删除注释和将多个连续的空白字符压缩成一个字符</li><li>词法分析阶段是较为复杂的部分,它处理扫描阶段的输出并生成词法单元</li></ul><h4 id="3-1-1-词法分析及语法分析"><a href="#3-1-1-词法分析及语法分析" class="headerlink" title="3.1.1 词法分析及语法分析"></a>3.1.1 词法分析及语法分析</h4><p>编译的分析部分划分为词法分析和语法分析阶段的原因:</p><ul><li>最重要的考虑是简化编译器的设计</li><li>提高编译器的效率</li><li>增强编译器的可移植性</li></ul><h4 id="3-1-2-词法单元、模式和词素"><a href="#3-1-2-词法单元、模式和词素" class="headerlink" title="3.1.2 词法单元、模式和词素"></a>3.1.2 词法单元、模式和词素</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/10.png" alt=""></p><h4 id="3-1-3-词法单元的属性"><a href="#3-1-3-词法单元的属性" class="headerlink" title="3.1.3 词法单元的属性"></a>3.1.3 词法单元的属性</h4><p>一个标识符(id)的属性值是一个指向符号表中该标识符对应条目的指针。</p><h4 id="3-1-4-词法错误"><a href="#3-1-4-词法错误" class="headerlink" title="3.1.4 词法错误"></a>3.1.4 词法错误</h4><p>“恐慌模式”恢复:从剩余的输入中不断删除字符,直到词法分析器能够在剩余输入的开头发现一个正确的词法单元为止。</p><p>其他错误恢复动作:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/11.png" alt=""></p><h3 id="3-2-输入缓冲"><a href="#3-2-输入缓冲" class="headerlink" title="3.2 输入缓冲"></a>3.2 输入缓冲</h3><p>加快源程序读入速度</p><h4 id="3-2-1-缓冲区对"><a href="#3-2-1-缓冲区对" class="headerlink" title="3.2.1 缓冲区对"></a>3.2.1 缓冲区对</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/12.png" alt=""></p><h4 id="3-2-2-哨兵标记"><a href="#3-2-2-哨兵标记" class="headerlink" title="3.2.2 哨兵标记"></a>3.2.2 哨兵标记</h4><p>每次对于forward指针需要检查两步:是否到达缓冲区末尾;确定读入字符是什么。(eof只能代表缓冲区末尾)</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/13.png" alt=""></p><p>就是说,<strong>引入哨兵标记后每次只要检查forward指针的读入字符是什么即可。</strong></p><h3 id="3-3-词法单元的规约"><a href="#3-3-词法单元的规约" class="headerlink" title="3.3 词法单元的规约"></a>3.3 词法单元的规约</h3><p>正则表达式是一种用来描述词素模式的重要表示方法。</p><h4 id="3-3-1-串和语言"><a href="#3-3-1-串和语言" class="headerlink" title="3.3.1 串和语言"></a>3.3.1 串和语言</h4><p>字母表:一个有限的符号集合</p><p>串:某个字母表中符号的一个有穷序列</p><p>空串:长度为0的串,用ε表示</p><p>语言:某个给定字母表上一个任意的可数的串集合</p><h4 id="3-3-2-语言上的运算"><a href="#3-3-2-语言上的运算" class="headerlink" title="3.3.2 语言上的运算"></a>3.3.2 语言上的运算</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/14.png" alt=""></p><h4 id="3-3-3-正则表达式"><a href="#3-3-3-正则表达式" class="headerlink" title="3.3.3 正则表达式"></a>3.3.3 正则表达式</h4><p>letter_表示任一字母或下划线,digit表示数位(任一单个数字)</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/15.png" alt=""></p><h4 id="3-3-4-正则定义"><a href="#3-3-4-正则定义" class="headerlink" title="3.3.4 正则定义"></a>3.3.4 正则定义</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/16.png" alt=""></p><p>前面的d为后面的d铺垫,方便后面使用,从而达到最后的d可以用∑和前面的d表示</p><h4 id="3-3-5-正则表达式的扩展"><a href="#3-3-5-正则表达式的扩展" class="headerlink" title="3.3.5 正则表达式的扩展"></a>3.3.5 正则表达式的扩展</h4><ul><li>一个或多个实例:单目后缀运算符+</li><li>零个或一个实例:单目后缀运算符?</li><li>字符类:[ ]</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/17.png" alt=""></p><h3 id="3-4-词法单元的识别"><a href="#3-4-词法单元的识别" class="headerlink" title="3.4 词法单元的识别"></a>3.4 词法单元的识别</h3><h4 id="3-4-1-状态转换图"><a href="#3-4-1-状态转换图" class="headerlink" title="3.4.1 状态转换图"></a>3.4.1 状态转换图</h4><ul><li>圆圈或结点表示状态</li><li>边表示从一个状态指向另一个状态</li><li>边的标号包含了一个或多个符合,表示从某个状态经过某下个输入符合进入边指向的另一端状态</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/52.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/53.png" alt=""></p><h4 id="3-4-2-保留字和标识符的识别"><a href="#3-4-2-保留字和标识符的识别" class="headerlink" title="3.4.2 保留字和标识符的识别"></a>3.4.2 保留字和标识符的识别</h4><p>我们可以使用两种方法来处理那些看起来像标识符的保留字:</p><ul><li>初始化时就将各个保留字填入符号表中</li><li>为每个关键字建立单独的状态转换图</li></ul><h4 id="3-4-4-基于状态转换图的词法分析器的体系结构"><a href="#3-4-4-基于状态转换图的词法分析器的体系结构" class="headerlink" title="3.4.4 基于状态转换图的词法分析器的体系结构"></a>3.4.4 基于状态转换图的词法分析器的体系结构</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/54.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/55.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/56.png" alt=""></p><h3 id="3-6-有穷自动机"><a href="#3-6-有穷自动机" class="headerlink" title="3.6 有穷自动机"></a>3.6 有穷自动机</h3><p>Lex(词法分析器生成工具)将它的输入程序变成一个词法分析器转换的核心是被称为有穷自动机的表示方法。这些自动机在本质上是与状态转换图类似的图,但有如下几点不同:</p><ul><li>有穷自动机是识别器,它们只能对每个可能的输入串简单地回答“是”或“否”</li><li>有穷自动机分为两类:<ul><li>不确定的有穷自动机(NFA):对其边上的标号没有任何限制。一个符号标记离开同一状态的多条边,并且空串ε也可以作为标号的边</li><li>确定的有穷自动机(DFA):对于每个状态及自动机输入字母表中的每个符号,有且只有一条离开该状态、以该符号为标号的边</li></ul></li></ul><p>确定的和不确定的有穷自动机能识别的语言的集合是相同的。事实上,这些语言的集合正好是能够用正则表达式描述的语言的集合。这个集合中的语言称为正则语言。</p><h4 id="3-6-1-不确定的有穷自动机"><a href="#3-6-1-不确定的有穷自动机" class="headerlink" title="3.6.1 不确定的有穷自动机"></a>3.6.1 不确定的有穷自动机</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/57.png" alt=""></p><p>示例:</p><p>状态0可以由a到达状态0或状态1</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/58.png" alt=""></p><h4 id="3-6-2-转换表"><a href="#3-6-2-转换表" class="headerlink" title="3.6.2 转换表"></a>3.6.2 转换表</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/59.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/60.png" alt=""></p><h4 id="3-6-3-自动机中输入字符串的接受"><a href="#3-6-3-自动机中输入字符串的接受" class="headerlink" title="3.6.3 自动机中输入字符串的接受"></a>3.6.3 自动机中输入字符串的接受</h4><p>只要存在某条[其标号序列为某符号串的]路径能够从开始状态到达某个接受状态,NFA就接受这个串。</p><p>路径中的ε标号将被忽略</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/61.png" alt=""></p><h4 id="3-6-4-确定的有穷自动机"><a href="#3-6-4-确定的有穷自动机" class="headerlink" title="3.6.4 确定的有穷自动机"></a>3.6.4 确定的有穷自动机</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/62.png" alt=""></p><p>DFA相比NFA,NFA的符号有空串ε且同一个符号可以由同个状态出发到达多个状态,DFA的符号没有空串符号ε且每个状态的每个符号的出边存在且唯一</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/63.png" alt=""></p><h3 id="3-7-从正则表达式到自动机"><a href="#3-7-从正则表达式到自动机" class="headerlink" title="3.7 从正则表达式到自动机"></a>3.7 从正则表达式到自动机</h3><p>NFA对于一个输入符号可以选择不同的转换,它还可以执行输入ε上的转换,甚至可以选择是对ε或是对真实的输入符号执行转换,因此对NFA的模拟不如对DFA的模拟直接。于是,我们需要将一个NFA转换为一个识别相同语言的DFA。</p><h4 id="3-7-1-从NFA到DFA的转换"><a href="#3-7-1-从NFA到DFA的转换" class="headerlink" title="3.7.1 从NFA到DFA的转换"></a>3.7.1 从NFA到DFA的转换</h4><p><strong>子集构造法</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/73.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/74.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/75.png" alt=""></p><p>将NFA转换为DFA,通过子集构造法构造<strong>转换表Dtran</strong>得到DFA:</p><ul><li>Dtran各行:NFA状态集—DFA状态—DFA各个出边</li><li><p>Dstates初始为ε-closure(s0),且未标记</p></li><li><p>当Dstates中没用未标记的状态时,即DFA的状态都被确定,停止循环就得到了DFA:</p><ul><li>将Dstates中未标记的状态通过出边达到的状态集{ε-closure[move(T,a)]}构成新的状态,如果不在Dstates中,则加入Dstates中</li></ul></li><li>通过DFA的每个状态和其对应的出边即可画出DFA</li></ul><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/76.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/77.png" alt=""></p><h4 id="3-7-2-NFA的模拟"><a href="#3-7-2-NFA的模拟" class="headerlink" title="3.7.2 NFA的模拟"></a>3.7.2 NFA的模拟</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/64.png" alt=""></p><h4 id="3-7-3-NFA模拟的效率"><a href="#3-7-3-NFA模拟的效率" class="headerlink" title="3.7.3 NFA模拟的效率"></a>3.7.3 NFA模拟的效率</h4><p>算法总效率:O(k(n + m))</p><h4 id="3-7-4-从正则表达式构造NFA"><a href="#3-7-4-从正则表达式构造NFA" class="headerlink" title="3.7.4 从正则表达式构造NFA"></a>3.7.4 从正则表达式构造NFA</h4><p>将正则表达式转化为一个NFA的<strong>McMaughton-Yamada-Thompson</strong>算法</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/68.png" alt=""></p><p><strong>基本规则:</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/69.png" alt=""></p><p><strong>归纳规则:</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/70.png" alt=""></p><p>将正则表达式转化为NFA,先画出由表达式构成的语法分析树,最小到每个表达式不能再划分。每个最小的表达式由基本规则构造出NFA,然后四种情况(并、连接、闭包、括号)根据归纳规则合成最终表达式的NFA。</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/71.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/72.png" alt=""></p><h3 id="3-9-基于DFA的模式匹配器的优化"><a href="#3-9-基于DFA的模式匹配器的优化" class="headerlink" title="3.9 基于DFA的模式匹配器的优化"></a>3.9 基于DFA的模式匹配器的优化</h3><h4 id="3-9-6-最小化一个DFA的状态数"><a href="#3-9-6-最小化一个DFA的状态数" class="headerlink" title="3.9.6 最小化一个DFA的状态数"></a>3.9.6 最小化一个DFA的状态数</h4><p>我们总是希望使用的DFA的状态数量尽可能地少。</p><p>只需要改变状态名字就可以将一个自动机转换成另一个自动机,我们就说这两个自动机是同构的。</p><p><strong>任何正则语言都有一个唯一的(不计同构)状态数目最少的DFA。</strong></p><p><strong>从任意一个接受相同语言的DFA出发,通过分组合并等价的状态,我们总是可以构建得到这个状态数最少的DFA。</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/78.png" alt=""></p><p><strong>算法:</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/79.png" alt=""></p><p>最小化一个DFA的状态数量,进行以下步骤:</p><ul><li>将DFA划分为Π,包含两组:接受状态组和非接受状态组</li><li>对于Π的每个组分别进行如下判断<ul><li>该组的每个状态经过相同的输入符号(每个符号都有进行判断)都能到达当前Π的相同组,若到达不同的组,则根据到达的组是否相同划分当前分组</li><li>将这些更小的组形成新的划分Π,直至Π不变</li></ul></li><li>再最后的Π中,每个组选取一个状态作为代表构建D’,其中:<ul><li>D’的开始状态是包含了D的开始状态的组的代表</li><li>D’的接受状态是<strong>那些</strong>包含了D的接受状态的组的代表</li></ul></li></ul><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/80.png" alt=""></p><h3 id="补充:用程序实现DFA"><a href="#补充:用程序实现DFA" class="headerlink" title="补充:用程序实现DFA"></a>补充:用程序实现DFA</h3><p>示例1:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/201.png" alt=""></p><p>示例2:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/204.png" alt=""></p><p>用代码的位置来表示所处的状态,只能用于简单的情况,情况复杂时使用以下两种方法。注意:中括号[]的字符在程序中不要更新输入缓冲。</p><h4 id="方法一-双层case的实现"><a href="#方法一-双层case的实现" class="headerlink" title="方法一 双层case的实现"></a>方法一 双层case的实现</h4><p>示例1:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/202.png" alt=""></p><p>示例2:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/203.png" alt=""></p><p>当终态还能接受字符时,通过改写DFA实现:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/205.png" alt=""></p><h4 id="方法二-表驱动的实现"><a href="#方法二-表驱动的实现" class="headerlink" title="方法二 表驱动的实现"></a>方法二 表驱动的实现</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/206.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/207.png" alt=""></p><p>表驱动方法的优缺点:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/208.png" alt="208"></p><h2 id="第四章-语法分析"><a href="#第四章-语法分析" class="headerlink" title="第四章 语法分析"></a>第四章 语法分析</h2><h3 id="4-1-引论"><a href="#4-1-引论" class="headerlink" title="4.1 引论"></a>4.1 引论</h3><h4 id="4-1-1-语法分析器的作用"><a href="#4-1-1-语法分析器的作用" class="headerlink" title="4.1.1 语法分析器的作用"></a>4.1.1 语法分析器的作用</h4><p>语法分析器构造出一棵语法分析树,并把它传递给编译器的其他部分近一步处理。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/18.png" alt=""></p><h3 id="4-2-上下无关文法"><a href="#4-2-上下无关文法" class="headerlink" title="4.2 上下无关文法"></a>4.2 上下无关文法</h3><h4 id="4-2-1-上下无关文法的正式定义"><a href="#4-2-1-上下无关文法的正式定义" class="headerlink" title="4.2.1 上下无关文法的正式定义"></a>4.2.1 上下无关文法的正式定义</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/19.png" alt=""></p><h4 id="4-2-3-推导"><a href="#4-2-3-推导" class="headerlink" title="4.2.3 推导"></a>4.2.3 推导</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/20.png" alt=""></p><p>句型:可能包含终结符号又包含非终结符号,也可能是空串</p><p>句子:不包含非终结符号的句型</p><p>上下文无关语言:由文法生成的语言</p><p>文法等价:两个文法生成相同语言</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/21.png" alt=""></p><p>最右推导有时也称为规范推导。</p><h4 id="4-2-4-语法分析树和推导"><a href="#4-2-4-语法分析树和推导" class="headerlink" title="4.2.4 语法分析树和推导"></a>4.2.4 语法分析树和推导</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/22.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/66.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/67.png" alt=""></p><p>语法分析树和最左推导/最右推导之间存在着一种一对一的关系。每一个语法分析树都和唯一的最左推导及最右推导相关联。(1对1+1)</p><h4 id="4-2-5-二义性"><a href="#4-2-5-二义性" class="headerlink" title="4.2.5 二义性"></a>4.2.5 二义性</h4><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/23.png" alt=""></p><p>即一个没有二义性的文法对一个句子只能有一个语法分析树、一个最左推导和一个最右推导。</p><h4 id="4-2-7-上下文无关文法和正则表达式"><a href="#4-2-7-上下文无关文法和正则表达式" class="headerlink" title="4.2.7 上下文无关文法和正则表达式"></a>4.2.7 上下文无关文法和正则表达式</h4><p>文法是比正则表达式表达能力更强的表示方法。</p><p>每个可以使用正则表达式描述的构造都可以使用文法来描述,但是反之不成立。</p><h3 id="4-3-设计文法"><a href="#4-3-设计文法" class="headerlink" title="4.3 设计文法"></a>4.3 设计文法</h3><h4 id="4-3-1-词法分析和语法分析"><a href="#4-3-1-词法分析和语法分析" class="headerlink" title="4.3.1 词法分析和语法分析"></a>4.3.1 词法分析和语法分析</h4><p>正则表达式最适合描述诸如标识符、常量、关键字、空白等语言构造的结构。文法最适合描述嵌套结构,比如对称的括号对,匹配的begin-end,相互对应的if-then-else等。这些嵌套结构不能使用正则表达式描述。</p><h4 id="4-3-2-消除二义性"><a href="#4-3-2-消除二义性" class="headerlink" title="4.3.2 消除二义性"></a>4.3.2 消除二义性</h4><p><strong>优先级</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/47.png" alt=""></p><p><strong>结合性</strong></p><p>左递归表示了左结合性,右递归表示了右结合性。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/48.png" alt=""></p><p><strong>悬挂else</strong></p><p>采用就近匹配原则,有else就会和前面没有被匹配的if进行匹配</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/49.png" alt=""></p><h4 id="4-3-3-左递归的消除"><a href="#4-3-3-左递归的消除" class="headerlink" title="4.3.3 左递归的消除"></a>4.3.3 左递归的消除</h4><p>自顶向下语法分析方法不能处理左递归文法,因此使用将左递归转换为右递归来消除左递归</p><ul><li>立即(直接)左递归</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/24.png" alt=""></p><ul><li>没有环或者ε产生式的文法G(间接左递归)</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/25.png" alt=""></p><p>就是把每个非终结符的产生式右侧的【每个序号在这个非终结符前面的非终结符】用它(序号在前的那个非终结符)的产生式替换掉它</p><h4 id="4-3-4-提取左公因子"><a href="#4-3-4-提取左公因子" class="headerlink" title="4.3.4 提取左公因子"></a>4.3.4 提取左公因子</h4><p>提取左公因子是一种文法转换方法,它可以产生适用于预测分析技术或自顶向下分析技术的文法。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/26.png" alt=""></p><p>间接左因子常采用代入法:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/51.png" alt=""></p><h3 id="4-4-自顶向下的语法分析"><a href="#4-4-自顶向下的语法分析" class="headerlink" title="4.4 自顶向下的语法分析"></a>4.4 自顶向下的语法分析</h3><p>自顶向下语法分析可以被看作是输入串构造语法分析树的问题,它从语法分析树的根节点开始,按照先根次序(深度优先),创建这棵语法分析树的各个节点。自顶向下语法分析也可以被看作寻找输入串的最左推导的过程。</p><p>自顶向下分析算法:</p><ul><li>回溯分析(功能强大,但通常较慢,不适合实际构造编译器)</li><li>预测分析(利用一个或多个输入记号来预测在多个产生式中怎么选择)【本章讨论】<ul><li>递归下降</li><li>LL(k)分析(向前看k个输入符号的预测,本章学习LL(1)文法)</li></ul></li></ul><h4 id="4-4-1-递归下降的语法分析"><a href="#4-4-1-递归下降的语法分析" class="headerlink" title="4.4.1 递归下降的语法分析"></a>4.4.1 递归下降的语法分析</h4><p><strong>递归下降分析</strong></p><p>将一个非终结符的文法规则看作是识别A的一个过程的定义。</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/27.png" alt=""></p><p>就是说对文法中的每个非终结符都有一个(使用它的产生式右侧作为规则)识别它的程序,该程序中每个终结符都对应了match()函数进行输入匹配的检查;每个非终结符都对应了调用相应非终结符的程序;产生式中的选择对应程序代码中的case或者if结构。</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/28.png" alt=""></p><p>由于<strong>左递归</strong>会使得程序不停的递归下去,所以需要使用EBNF{ }对文法进行改写才能使用自顶向下的分析方法</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/29.png" alt=""></p><p>当有<strong>左因子</strong>时,通过EBNF[ ]改写文法</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/30.png" alt=""></p><p>使用EBNF后通过程序处理运算顺序</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/31.png" alt=""></p><p>在程序中构建语法树</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/32.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/33.png" alt=""></p><h4 id="4-4-2-FIRST和FOLLOW"><a href="#4-4-2-FIRST和FOLLOW" class="headerlink" title="4.4.2 FIRST和FOLLOW"></a>4.4.2 FIRST和FOLLOW</h4><p><strong>FIRST集</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/34.png" alt=""></p><p><strong>计算文法非终结符的First集算法:</strong></p><ul><li>将所有非终结符的First集置为空集</li><li>重复下面的步骤直到所有非终结符的First集不发生变化<ul><li>对每个非终结符的产生式(不含选择,有选择就拆分)A→X1X2…Xn进行下面的操作</li><li>Xi从X1开始,将First(Xi)-{ε}加入First(A)中。如果Xi可推出空集,继续找X(i+1);如果Xi不可以推出空集,则停止操作</li><li>如果X1X2…Xn都可以推出空集,则将ε加入First(A)中。</li></ul></li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/35.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/36.png" alt=""></p><p><strong>FOLLOW集</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/37.png" alt=""></p><p><strong>计算FOLLOW集算法:</strong></p><ul><li>开始符号的Follow集初始化为{$},其他非终结符的Follow集置为空</li><li>重复下面的步骤直到所有非终结符的Follow集不发生变化<ul><li>对每个非终结符的产生式(不含选择,有选择就拆分)A→X1X2…Xn进行下面的操作</li><li>对每个非终结符Xi,将Xi后的串(Xi+1…Xn)的First集除去{ε}加入Xi的Follow集中</li><li>如果串(Xi+1…Xn)的First集中包含空集,则将A的Follow集加入Xi的Follow集中</li></ul></li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/38.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/39.png" alt=""></p><p><strong>注意:</strong></p><ul><li>First集中没有$,Follow集中没有ε。</li><li>First集是找产生式左侧非终结符的,Follow集是找产生式右侧非终结符的。</li></ul><h4 id="4-4-3-LL-1-文法"><a href="#4-4-3-LL-1-文法" class="headerlink" title="4.4.3 LL(1)文法"></a>4.4.3 LL(1)文法</h4><p>判断一个串是否符合某LL(1)文法,通常使用LL(1)分析方法。LL(1)分析方法需要用到LL(1)分析表,而LL(1)分析表可以通过First集和Follow集构造。</p><p><strong>LL(1)分析表</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/42.png" alt=""></p><p>分析表中横向为所有的非终结符,$表示串结束符;纵向为所有终结符。</p><p><strong>简单文法的LL(1)分析表构造:</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/43.png" alt=""></p><p>即如果A不能推出空集,则只考虑第一条;如果可以推出空集,那么观察S$经若干步推导后非终结符A可以出现在终结符a<strong>(包括$)</strong>的前面,则将对应的A→α填入[A,a]中。</p><p><strong>一般文法的LL(1)分析表构造(采用First和Follow集):</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/45.png" alt=""></p><p>注意是观察First(α)</p><p><strong>LL(1)文法</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/44.png" alt=""></p><p>等价于:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/46.png" alt=""></p><p>LL(1)文法不允许一个格子包含两条产生式(即二义性),可以在表格标注采用一条产生式来消除二义性,使得文法能用LL(1)方法进行分析。</p><h4 id="4-4-4-非递归的预测分析"><a href="#4-4-4-非递归的预测分析" class="headerlink" title="4.4.4 非递归的预测分析"></a>4.4.4 非递归的预测分析</h4><p><strong>LL(1)分析</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/40.png" alt=""></p><p><strong>LL(1)分析过程</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/41.png" alt=""></p><p>通常利用LL(1)分析表进行分析</p><ul><li>accept</li></ul><p>栈和输入都只剩下$代表串是该文法可以接受的串。</p><ul><li>error</li></ul><p>LL(1)出错:栈顶与输入不匹配;串空栈不空。</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/50.png" alt=""></p><h3 id="4-5-自底向上的语法分析"><a href="#4-5-自底向上的语法分析" class="headerlink" title="4.5 自底向上的语法分析"></a>4.5 自底向上的语法分析</h3><p><strong>自底向上的分析方法</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/81.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/82.png" alt="82"></p><p>自底向上分析的四个动作:</p><ul><li>移进shift</li><li>归约reduce</li><li>接受accept</li><li>报错error</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/83.png" alt="83"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/84.png" alt="84"></p><p><strong>句柄</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/85.png" alt="85"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/86.png" alt="86"></p><p>通过分析树找句柄:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/87.png" alt="87"></p><p>用句柄来对句型进行归约:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/88.png" alt="88"></p><p>归约过程就是依次找出分析树中的最左子树并去除叶子节点</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/89.png" alt="89"></p><h3 id="4-6-LR语法分析技术介绍:简单LR技术"><a href="#4-6-LR语法分析技术介绍:简单LR技术" class="headerlink" title="4.6 LR语法分析技术介绍:简单LR技术"></a>4.6 LR语法分析技术介绍:简单LR技术</h3><p><strong>LR(0)项</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/90.png" alt="90"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/91.png" alt="91"></p><p>“.”表示当前分析时符号在栈还是在输入串的情况</p><p>根据”.”位置的不同将LR(0)项分四类:</p><ul><li>归约项:”.”在右侧结尾,且”.”前面不是开始符号</li><li>接受项:”.”在右侧结尾,且”.”前面是开始符号</li><li>移进项:”.”后面是终结符</li><li>待归约项:”.”后面是非终结符</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/92.png" alt="92"></p><p><strong>LR(0)项的有限自动机</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/93.png" alt="93"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/94.png" alt="94"></p><p>同时,还要有.X→X.的Goto连接</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/95.png" alt="95"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/96.png" alt="96"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/97.png" alt="97"></p><p>子集法构造DFA:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/98.png" alt="98"></p><p>直接得到DFA:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/99.png" alt="99"></p><p>总结</p><p>由文法得到NFA的步骤:</p><ul><li>改写文法,得出所有的LR(0)项</li><li>NFA的初始状态为S’→.S</li><li>对于每个状态,判断”.”后面的符号<ul><li>如果是终结符,则接受该终结符指向下一状态</li><li>如果是非终结符S,则通过ε连接分别到达S→.α的所有状态,另外还要通过S的Goto连接到”.”在S后的状态</li></ul></li><li>所有状态都不能再指向新状态时,即得到NFA</li></ul><p>NFA没用结束状态,由分析程序决定结束</p><p>由文法得到DFA的两种方法:</p><p>Ⅰ.构造NFA,由子集构造法得到DFA</p><p>Ⅱ.不通过NFA,直接得到DFA:</p><ul><li>改写文法,得出所有的LR(0)项</li><li>DFA的初始状态为S’→.S</li><li>对于DFA中每个状态,若”.”后面是非终结符S,那么需要将S→.α的项都加进该状态</li><li>通过接受”.”后面的符号,到达新的状态,立马对新状态用第三步</li><li>所有状态都不能再指向新状态时,即得到DFA</li></ul><p>注意DFA中的状态需要指明包含的NFA状态(LR(0)项)</p><p><strong>LR(0)分析算法</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/100.png" alt="100"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/101.png" alt="101"></p><p>LR(0)文法不允许某个状态中同时包含移进项和归约项(移进-归约冲突),也不允许包含两个归约项(归约-归约冲突)。移进-移进并不会冲突,因为会先移进再根据移进的字符判断转向下一个状态。</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/102.png" alt="102"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/103.png" alt="103"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/104.png" alt="104"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/105.png" alt="105"></p><p>总结</p><p>用LR(0)方法分析一个串是否是某文法可识别的串,步骤为:</p><ul><li>改写文法,得出所有LR(0)项,构造DFA</li><li>通过DFA 构造分析表<ul><li>State:DFA中的状态</li><li>Action:DFA状态对应的动作(看其包含的LR(0)项)</li><li>Rule:若动作为归约,则写出对应的产生式</li><li>Input:包含所有的终结符</li><li>Goto:包含产生式右侧所有的非终结符</li><li>每行中一个状态对应一个动作<ul><li>若动作是移进,则[State, Input]和[State, Goto]填入接受该字符后进入的状态(由DFA得出)</li><li>若动作是归约,则[State, Rule]唯一对应了一条产生式</li></ul></li></ul></li><li>建表进行LR(0)分析<ul><li>Steps:步骤</li><li>Stack:栈,初始化为$和初始状态</li><li>Input:输入串和$</li><li>Action:栈顶状态对应的动作</li></ul></li><li>通过分析表进行LR(0)分析<ul><li>每一步,根据栈顶状态得到动作<ul><li>若动作是移进(Goto连接也是),则在下一步将输入串最左侧的符号移入栈顶,并通过分析表得到移入后的状态,放入栈顶</li><li>若动作是归约,则在下一步将归约串对应的符号和状态在栈顶都出栈,将产生式左侧的非终结符移入栈顶,并通过分析表得到移入后的状态,放入栈顶</li></ul></li><li>若在某一步移入的串与栈顶状态不匹配,不能得到新的栈顶状态,则报错</li><li>若栈为$和初始状态+开始符号,输入串为空串和$,则代表该串为该文法可以识别的串</li></ul></li></ul><p><strong>SLR(1)分析算法</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/106.png" alt="106"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/107.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/108.png" alt=""></p><p>SLR(1)文法不允许某个状态中同时存在满足条件的移进项和归约项,也不允许同时存在满足条件的两个归约项。</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/109.png" alt=""></p><p>总结</p><p>用LR(0)方法分析一个串是否是某文法可识别的串,步骤为:</p><ul><li>改写文法,得出所有LR(0)项,构造DFA</li><li>通过DFA 构造分析表<ul><li>State:DFA中的状态</li><li>Input:包含所有的终结符和$</li><li>Goto:包含产生式右侧所有的非终结符</li><li>每个状态都根据DFA,对其所有LR(0)项进行判断:<ul><li>移进项在对应终结符的格子中填入s和到达的状态</li><li>归约项在对应Follow集的格子中填入r(产生式),若产生式是开始符合推出,则填入accept</li><li>Goto连接直接填入转换的状态即可</li></ul></li></ul></li><li>建表进行SLR(1)分析<ul><li>Steps:步骤</li><li>Stack:栈,初始化为$和初始状态</li><li>Input:输入串和$</li><li>Action:栈顶状态对应的动作</li></ul></li><li>每一步,根据栈顶状态和输入串第一个符号得到动作<ul><li>若动作是移进(Goto连接也是),则在下一步将输入串最左侧的符号移入栈顶,并通过分析表得到移入后的状态,放入栈顶</li><li>若动作是归约,则在下一步将归约串对应的符号和状态在栈顶都出栈,将产生式左侧的非终结符移入栈顶,并通过分析表得到移入后的状态,放入栈顶</li></ul></li><li>若在某一步移入的串与栈顶状态不匹配,不能得到新的栈顶状态,则报错</li><li>若栈为$和初始状态+开始符号+某状态,输入串为空串和$,若在分析表中该状态和$对应的格子为accept,则代表该串为该文法可以识别的串</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/110.png" alt=""></p><p>练习:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/111.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/112.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/113.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/114.png" alt=""></p><h2 id="第五章-语法制导的翻译"><a href="#第五章-语法制导的翻译" class="headerlink" title="第五章 语法制导的翻译"></a>第五章 语法制导的翻译</h2><h3 id="5-1-语法制导定义"><a href="#5-1-语法制导定义" class="headerlink" title="5.1 语法制导定义"></a>5.1 语法制导定义</h3><p><strong>语法制导翻译</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/115.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/116.png" alt=""></p><p><strong>语法制导定义SDD</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/117.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/118.png" alt=""></p><p><strong>语法制导翻译方案SDT</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/119.png" alt=""></p><p>SDD与SDT</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/120.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/121.png" alt=""></p><p><strong>综合属性和继承属性</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/122.png" alt=""></p><p><strong>S属性的SDD</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/123.png" alt=""></p><p><strong>注释语法分析树</strong></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/124.png" alt=""></p><h3 id="5-2-SDD的求值顺序"><a href="#5-2-SDD的求值顺序" class="headerlink" title="5.2 SDD的求值顺序"></a>5.2 SDD的求值顺序</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/125.png" alt=""></p><p><strong>依赖图</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/126.png" alt=""></p><p>通常综合属性在文法符合右边,继承属性在文法符合左边,操作对应于虚节点</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/127.png" alt=""></p><p><strong>拓扑排序</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/128.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/129.png" alt="129"></p><p><strong>属性求值顺序</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/130.png" alt=""></p><p>S属性的SDD</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/131.png" alt=""></p><p>L属性的SDD</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/132.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/133.png" alt=""></p><p>注:不形成环路</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/134.png" alt=""></p><h3 id="5-3-语法制导翻译的应用"><a href="#5-3-语法制导翻译的应用" class="headerlink" title="5.3 语法制导翻译的应用"></a>5.3 语法制导翻译的应用</h3><ul><li>抽象语法树的构造</li></ul><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/136.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/137.png" alt="137"></p><ul><li>类型的结构</li></ul><h3 id="5-4-语法制导的翻译方案"><a href="#5-4-语法制导的翻译方案" class="headerlink" title="5.4 语法制导的翻译方案"></a>5.4 语法制导的翻译方案</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/135.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/138.png" alt=""></p><p><strong>后缀翻译方案</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/139.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/140.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/141.png" alt="141"></p><p><strong>产生式内部带有语义动作的SDT</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/142.png" alt=""></p><p>插入动作的语法分析树</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/143.png" alt=""></p><p><strong>将L-SDD转换为SDT</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/144.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/145.png" alt="145"></p><p><strong>L属性定义的SDT实现</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/146.png" alt=""></p><p><strong>在递归下降语法分析过程中进行翻译</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/147.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/148.png" alt="148"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/149.png" alt="149"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/150.png" alt="150"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/151.png" alt="151"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/152.png" alt="152"></p><h2 id="第六章-中间代码生成"><a href="#第六章-中间代码生成" class="headerlink" title="第六章 中间代码生成"></a>第六章 中间代码生成</h2><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/153.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/154.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/155.png" alt=""></p><h3 id="6-1-语法树的变体"><a href="#6-1-语法树的变体" class="headerlink" title="6.1 语法树的变体"></a>6.1 语法树的变体</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/156.png" alt=""></p><h3 id="6-2-三地址代码"><a href="#6-2-三地址代码" class="headerlink" title="6.2 三地址代码"></a>6.2 三地址代码</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/157.png" alt=""></p><p>三地址代码中不能有双目以上的运算,也不允许出现组合运算(每条只能有一个运算)</p><p><strong>常见三地址指令形式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/158.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/159.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/160.png" alt=""></p><p>三地址代码是中间代码的一种抽象形式,具体实现包括四元式、 三元式和间接三元式。</p><p><strong>四元式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/161.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/162.png" alt="162"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/163.png" alt=""></p><p><strong>三元式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/164.png" alt=""></p><p><strong>间接三元式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/165.png" alt=""></p><h3 id="6-3-类型和声明"><a href="#6-3-类型和声明" class="headerlink" title="6.3 类型和声明"></a>6.3 类型和声明</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/166.png" alt=""></p><p><strong>类型表达式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/167.png" alt="167"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/168.png" alt=""></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/169.png" alt=""></p><p><strong>类型等价</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/170.png" alt=""></p><p><strong>类型的声明</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/171.png" alt=""></p><p><strong>局部变量名的存储布局</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/172.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/173.png" alt="173"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/174.png" alt=""></p><p><strong>声明的序列</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/175.png" alt=""></p><h3 id="6-4-表达式的翻译"><a href="#6-4-表达式的翻译" class="headerlink" title="6.4 表达式的翻译"></a>6.4 表达式的翻译</h3><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/176.png" alt=""></p><p><strong>表达式中的运算</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/177.png" alt=""></p><p>“||”是连接的作用</p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/178.png" alt=""></p><h3 id="6-5-类型检查"><a href="#6-5-类型检查" class="headerlink" title="6.5 类型检查"></a>6.5 类型检查</h3><p><strong>类型检查规则</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/179.png" alt=""></p><p><strong>类型转换</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/180.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/181.png" alt="181"></p><p><strong>拓宽函数的适应</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/182.png" alt=""></p><h3 id="6-6-控制流"><a href="#6-6-控制流" class="headerlink" title="6.6 控制流"></a>6.6 控制流</h3><p><strong>布尔表达式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/183.png" alt=""></p><p><strong>短路代码</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/184.png" alt=""></p><p><strong>控制流语句</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/185.png" alt=""></p><p><strong>控制流语句的代码布局方案</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/186.png" alt=""></p><p><strong>布尔表达式的控制流翻译</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/187.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/188.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/189.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/190.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/191.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/192.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/193.png" alt="193"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/194.png" alt="194"></p><p>示例:</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/195.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/196.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/197.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/198.png" alt="198"></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/199.png" alt=""></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/05/11/CompilerPrinciple/200.png" alt="200"></p>]]></content>
<categories>
<category> CompilerPrinciple </category>
</categories>
<tags>
<tag> note </tag>
<tag> CompilerPrinciple </tag>
</tags>
</entry>
<entry>
<title>数据库系统概论笔记</title>
<link href="/2020/04/27/Database/"/>
<url>/2020/04/27/Database/</url>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="数据库系统概论"><a href="#数据库系统概论" class="headerlink" title="数据库系统概论"></a>数据库系统概论</h1><h2 id="绪论"><a href="#绪论" class="headerlink" title="绪论"></a>绪论</h2><p><strong>数据库DB</strong></p><p>数据库是长期储存在计算机内、有组织的、可共享的大量数据的集合。</p><p><strong>数据库管理系统DBMS</strong></p><p>数据库管理系统是位于用户与操作系统之间的一层数据管理软件(计算机的基础软件)</p><p>(1)数据定义功能</p><p>(2)数据组织、存储和管理</p><p>(3)数据操纵功能</p><p>(4)数据库的事务管理和运行管理</p><p>(5)数据库的建立和维护功能</p><p>(6)其他功能</p><p><strong>数据库系统</strong></p><p>数据库系统是由数据库、数据库管理系统(及其应用开发工具)、应用程序和数据库管理员(DBA)组成的存储、管理、处理和维护数据的系统。</p><p><strong>数据库系统的特点</strong></p><p>(1)数据结构化</p><p>数据库系统实现整体数据的结构化,这是数据库系统的主要特征之一,也是数据库系统与文件系统的本质区别。</p><p>(2)数据独立性高</p><p>数据独立性是由数据库管理系统提供的二级映像功能来保证的。</p><p>a.物理独立性是指用户的应用程序与数据库中数据的物理存储是相互独立的。</p><p>b.逻辑独立性是指用户的应用程序与数据库的逻辑结构是相互独立的。</p><p><strong>概念模型</strong></p><p>(1)信息世界中的基本概念</p><p>a.实体</p><p>b.属性</p><p>c.码</p><p>d.实体型</p><p>e.实体集</p><p>f.联系</p><p>(2)概念模型的一种表示方法:实体-联系方法(E-R方法/E-R模型)</p><p><strong>数据库系统的三级模式结构</strong></p><p>(1)模式</p><p>模式也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。</p><p>一个数据库只有一个模式。</p><p>(2)外模式</p><p>外模式也称子模式或用户模式,它是数据库用户能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。</p><p>(3)内模式</p><p>内模式也称存储模式,一个数据库只有一个内模式。它是数据物理结构的存储方式的描述,是数据在数据库内部的组织方式。</p><p><strong>数据库系统的二级映像功能与数据独立性</strong></p><p>(1)外模式/模式映像</p><p>当模式改变时,由数据库管理员对各个外模式/模式的映像作相应改变,可以使模式保持不变,从而应用程序也不必改变。保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。</p><p>(2)模式/内模式映像</p><p>当数据库的存储结构改变时,由数据库管理员对模式/内模式映像作相应改变,可以使模式保持不变,从而应用程序也不必改变。保证了数据与程序的物理独立性,简称数据的物理独立性。</p><h2 id="关系数据库"><a href="#关系数据库" class="headerlink" title="关系数据库"></a>关系数据库</h2><p><strong>关系</strong></p><p>候选码、主码、主属性、非主属性(非码属性)</p><p>基本关系的六条性质:</p><p>(1)列是同质的</p><p>(2)不同列可出自同一个域,每一列为一个属性,不同属性(列)给不同属性名</p><p>(3)列的顺序可任意交换</p><p>(4)任意两个元组不能完全相同</p><p>(5)行的顺序可任意交换</p><p>(6)每一分量是不可分的数据项</p><p>关系模式:关系的描述R(U, D, dom, F),简记为R(U)或R(A1, A2, …, An)</p><p><strong>关系操作</strong></p><p>查询操作和插入、删除、修改操作两部分</p><p><strong>关系的完整性</strong></p><p>(1)实体完整性</p><p>(2)参照完整性</p><p>(3)用户定义的完整性</p><p><strong>关系代数</strong></p><p>(1)传统的集合运算(前三者都有n个属性且相应属性取自同一个域)</p><p>并(合并)</p><p>差(去除)</p><p>交(共同)</p><p>笛卡尔积(元组连接)</p><p>(2)专门的关系运算</p><p>选择(满足条件的行)</p><p>投影(列的组合)</p><p>连接(元组连接且满足条件θ)</p><p>a.等值连接(条件θ为相等)</p><p>b.自然连接(等值连接去除重复列,默认舍弃悬浮元组)</p><p>除(R÷S,R中公共属性在非公共属性上的象集包含了S中公共属性投影集合,R÷S结果为这些满足条件的非公共属性的元组集合)</p><h2 id="关系数据库标准语言SQL"><a href="#关系数据库标准语言SQL" class="headerlink" title="关系数据库标准语言SQL"></a>关系数据库标准语言SQL</h2><p><strong>数据定义</strong></p><p>对模式SCHEMA、基本表TABLE、视图VIEW、索引INDEX的创建CREATE、删除DROP和修改ALTER(9种组合,不能修改模式、视图和索引)(10种组合,不能修改模式和视图)</p><p><strong>数据查询</strong></p><ul><li>单表查询</li></ul><p>查询所有*</p><p>消除重复行DISTINCT,默认是全部行ALL</p><p>范围闭区间(NOT) BETWEEN AND</p><p>属性值的集合(NOT) IN</p><p> 字符匹配LIKE+通配符(任意长度% 任意单个字符_)(+ 转义符ESCAPE)</p><p>空值IS (NOT) NULL</p><p>按属性列排序ORDER BY + 升序ASC(默认,空值最后)/降序DESC(空值最先)</p><p>元组个数COUNT(*) (遇到空值不影响)</p><p>某列中值的:个数COUNT(),总和SUM(),平均值AVG(),最大值MAX(),最小值MIN() (遇到空值跳过)</p><p>分组GROUP BY (+ HAVING)</p><ul><li>连接查询</li></ul><p>自身连接FIRST,SECOND</p><p>外连接LEFT/RIGHR/FULL OUTER JOIN ON()</p><ul><li>嵌套查询</li></ul><p>子查询结果属性值的集合(NOT) IN</p><p>子查询结果的某个值ANY</p><p>子查询结果的所有值ALL</p><p>返回查询结果(NOT) EXISTS</p><p>多层嵌套</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/04/27/Database/sjk2.jpg" alt=""></p><ul><li>集合查询</li></ul><p>查询结果是元组的集合,可以进行集合操作并UNION、交INTERSECT、差EXCEPT</p><ul><li>基于派生表查询</li></ul><p>子查询生成的临时派生表作为主查询的对象,AS设置别名</p><p><strong>数据更新</strong></p><ul><li>插入</li></ul><p>INSERT</p><p>INTO</p><p>VALUES</p><ul><li>修改</li></ul><p>UPDATE</p><p>SET</p><p>WHERE</p><ul><li>删除</li></ul><p>DELETE</p><p>FROM</p><p>WHERE</p><p><strong>空值</strong></p><p>空值与其他值算术运算为空值,比较运算为UNKNOWN</p><p><strong>视图的作用</strong></p><ul><li>视图能够简化用户的操作</li><li>视图使用户能以多种角度看待同一数据</li><li>视图对重构数据库提供了一定程度的逻辑独立性</li><li>视图能够对机密数据提供安全保护</li><li>适当利用视图可以更清晰地表达查询</li></ul><h2 id="数据库安全性"><a href="#数据库安全性" class="headerlink" title="数据库安全性"></a>数据库安全性</h2><p><strong>数据库的安全性</strong></p><p>是指保护数据库以防止不合法使用所造成的数据泄漏、更改或破坏。</p><p><strong>TCSEC/TDI(四组七个等级)</strong></p><p>C1级(自主安全保护):该级只提供了非常初级的自主安全保护,能实现对用户和数据的分离。进行自主存取控制(DAC),保护或限制用户权限的传播。现有的商业系统往往稍作改进即可满足要求。</p><p>B1级(标记安全保护):对系统的数据加以标记,并对标记的主体和客体实施强制存取控制(MAC)以及审计等安全机制。B1级别的产品才被认为是真正意义上的安全产品。</p><p><strong>自主存取控制</strong></p><p>用户对于不同的数据库对象有不同的存取权限,不同的用户对同一对象也有不同的权限,而且用户还可将其拥有的存取权限转授给其他用户。</p><p>因此自主存取控制非常灵活。</p><p><strong>强制存取控制</strong></p><p>每一个数据库对象被标记以一定的密级,每一个用户也被授予某一个级别的许可证。对于任意一个对象,只有具有合法许可证的用户才可以存取。</p><p>因此强制存取控制相对比较严格。</p><h2 id="数据库完整性"><a href="#数据库完整性" class="headerlink" title="数据库完整性"></a>数据库完整性</h2><p><strong>(1)实体完整性</strong></p><p>说明方法:在列级定义(只适合单属性构成的码)、在表级定义</p><p>检查:主码值是否唯一、主码的各个属性是否为空</p><p>处理:拒绝插入或修改</p><p><strong>(2)参照完整性</strong></p><p>检查:参照表插入、修改;被参照表删除、修改</p><p>处理:拒绝执行、级联删除、设置为空值</p><p><strong>(3)用户定义的完整性</strong></p><p>a.属性上约束条件</p><p>检查:列值非空、列值唯一、检查列值是否满足一个条件表达式(CHECK短语)</p><p>处理:拒绝执行</p><p>b.元组上的约束条件(不同属性之间的约束条件)</p><p>检查:CHECK语句定义约束条件</p><p>处理:拒绝执行</p><h2 id="关系数据库理论"><a href="#关系数据库理论" class="headerlink" title="关系数据库理论"></a>关系数据库理论</h2><p><strong>函数依赖</strong></p><p>设R(U)是属性集U上的关系模式。X,Y是U的子集。若对于R的任何一个可能的关系r,r中不可能存在两个元组在X属性值上相等而在Y属性值上不等,则称X函数确定Y或Y函数依赖于X,记作:X→Y。</p><p><strong>完全函数依赖</strong></p><p>在R(U)中如果X→Y,并且对X的任何一个真子集X’,都有X’→Y,则称Y对X完全函数依赖,记作:X → Y</p><p><strong>部分函数依赖</strong></p><p>若X → Y,但Y不完全函数依赖于X,则称Y对X部分函数依赖,记作:X → Y</p><p><strong>传递函数依赖</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/04/27/Database/s4.png" alt="在这里插入图片描述"></p><p><strong>候选码</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/04/27/Database/s5.png" alt="在这里插入图片描述"></p><p><strong>主属性</strong></p><p>包含在任何候选码中的属性。</p><p><strong>非主属性(非码属性)</strong></p><p>不包含在任何候选码中的属性。 </p><p><strong>外码</strong></p><p>关系模式R中的属性或属性组X并非R的码,但X是另一个关系模式的码,则称X是R的外部码,简称外码。</p><p><strong>1NF</strong></p><ul><li>每一个分量必须是不可分的数据项</li></ul><p><strong>2NF</strong></p><ul><li>若R∈1NF,对R的每一个非平凡的函数依赖X→Y,要么Y是主属性,要么X不是任何码的真子集,则R∈2NF。</li><li>若R∈1NF,且每一个非主属性完全函数依赖于任何一个候选码,则R∈2NF。</li></ul><p>2NF在1NF基础上消除了非主属性对码的部分函数依赖。</p><p><strong>3NF</strong></p><ul><li>若R∈1NF,对R中的每一个非平凡的函数依赖X→Y,要么Y是主属性,要么X中含有码,则R∈3NF。</li></ul><p>3NF在2NF的基础上消除了非主属性对码的传递函数依赖,不存在非主属性对非主属性的函数依赖。</p><p><strong>BCNF</strong></p><ul><li>若R∈1NF,对R中的每一个非平凡的函数依赖X→Y,X中均含有码,则R∈BCNF。</li></ul><p>不允许主属性对码的部分和传递函数依赖。</p><p><strong>多值依赖</strong></p><p>设有关系模式R(U),X, Y, Z是U的非空子集。对于R的任一关系r,给定一对(x, z)值,就有一组Y的值与之对应,这组值仅仅决定于x值而与z值无关,则称“Y多值依赖于X”或“X多值决定Y”。记作X→→Y。</p><p><strong>4NF</strong></p><p>若关系模式R(U,F)∈1NF,如果对于R的每个非平凡多值依赖X →→ Y(Y不包含于X),X都含有码,则称R(U,F)∈4NF。</p><p>4NF消除了多值依赖。</p><p><strong>模式分解</strong></p><p>无损连接性和函数依赖</p><p>具有无损连接性:分解后的(几个)小模式可自然连接恢复位原来的模式</p><p>保持函数依赖:分解前后函数依赖集等价</p><p><strong>分解为一组具有无损连接性,保持函数依赖,且满足3NF的关系范式</strong></p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/04/27/Database/sjk1.jpg" alt="在这里插入图片描述"></p><h2 id="数据库设计"><a href="#数据库设计" class="headerlink" title="数据库设计"></a>数据库设计</h2><p><strong>数据库设计基本步骤</strong></p><p>需求分析</p><p>概念结构设计 构造ER模型</p><p>逻辑结构设计 生成一组关系模式</p><p>物理结构设计 设计具体DBMS下的表、视图、索引</p><p>数据库实施</p><p>数据库运行和维护</p><p><strong>ER方法</strong></p><p>实体、联系以及它们的属性,关系是一对一,一对多还是多对多,是否存在弱实体型。</p><p>如果一个实体型的存在依赖于其他实体型的存在,则这个实体型叫做弱实体型,否则叫做强实体型。一般地讲,如果不能从一个实体型的属性中找出可以作为码的属性,则这个实体型是弱实体型。</p><p><strong>ER模型到关系模型的9步映射算法(前七步)</strong></p><p>S1: 每一强实体用一个新表表示</p><ul><li>对ER模型中的每一实体E创建对应的新表T</li><li>确定新表T的属性:<ol><li>E的所有简单属性转换为对应的表T的属性</li><li>对于E的复合属性,直接从其简单成分转换</li></ol></li><li>确定T的主码和Unique码<ol><li>E的码转换为候选码,选定一个(意义最明显的)为主码,其余作Unique码</li></ol></li></ul><p>S2: 处理ER模型中所有参与1:1标识联系的弱实体W</p><ul><li>找出W所依赖的强实体对应的表T</li><li>在T表中加入W的所有简单属性和复合属性的简单成分</li></ul><p>S3: 处理ER模型中所有参与1:N或M:N标识联系的弱实体W</p><ul><li>为W创建对应的新表T</li><li>确定新表T的属性:<ol><li>E的所有简单属性转换为对应的表T的属性</li><li>对于E的复合属性,直接从其简单成分转换</li></ol></li><li>确定T的主码<ol><li>对于1:N联系,T中增加W所依赖的强实体对应表的主码为外码,T的主码为该外码+W的鉴别器(部分码)</li><li>如果是M:N联系,构建新列(具有惟一值)为主码</li></ol></li></ul><p>S4: 处理ER模型中每一二元1:1联系R</p><ul><li>确定参与该联系的实体型转换的表S和T</li><li>选定S(最好是全参与的一方,推广到参与程度高的一方)<ol><li>将T的主码作为外码加入S</li></ol></li><li>将联系R的所有简单属性和复合属性成分作为列加入S</li></ul><p>S5: 处理ER模型中每一二元1:N联系R</p><ul><li>确定处于N端的实体表S和1端的实体表T</li><li>将T的主码作为外码加入S</li><li>将R的所有简单属性和复合属性成分作为列加入S</li></ul><p>S6: 处理ER模型中的每一多元联系和二元(M:N联系)R</p><ul><li>为R创建对应的新表T</li><li>将R的所有简单属性和复合属性成分作为列加入T</li><li>将参与联系的(强、弱)实体型的主码作为外码加入T</li><li>将(上步得到的)所有外码组合,共同构成T的主码</li></ul><p>S7: 处理ER模型中的每一多值属性A</p><ul><li>为A创建对应的新表T</li><li>将A的所有简单属性和复合属性成分作为列加入T</li><li>将A所属的实体或联系转换得到的表的主码作为外码加入T</li><li>将(上步得到的)外码和A对应的全部属性确定为T的主码</li></ul><h2 id="关系查询处理和查询优化"><a href="#关系查询处理和查询优化" class="headerlink" title="关系查询处理和查询优化"></a>关系查询处理和查询优化</h2><p>1.选择变串连</p><p>2.尽可能先做选择</p><p>3.尽可能先做投影</p><p>4.同时执行多个选择和投影</p><p>5.分组</p><h2 id="数据库恢复技术"><a href="#数据库恢复技术" class="headerlink" title="数据库恢复技术"></a>数据库恢复技术</h2><p><strong>事务</strong></p><p>事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。</p><p>事务是恢复和并发控制的基本单位。</p><p>保证事务ACID特性是事务处理的重要任务。</p><p><strong>事务的特性(ACID)</strong></p><ul><li><p>原子性(Atomicity) :最小工作单位</p></li><li><p>一致性(Consistency): 一个正确状态到另一个正确状态</p></li><li><p>隔离性(Isolation) :事务不相互干扰</p></li><li><p>持续性(Durability) :事务提交对数据库影响是永久性的 </p></li></ul><p><strong>事务ACID特性可能遭到破坏的因素</strong></p><ul><li>多个事务并行运行时,不同事物的操作交叉执行</li><li>事务在运行过程中被强制停止</li></ul><p><strong>数据库恢复</strong></p><p>数据库管理系统必须具有把数据库从错误状态恢复到某一已知的正确状态的功能</p><p>恢复的基本原理:冗余</p><p>建立冗余数据最常用的技术是数据转储和登记日志文件。</p><p><strong>数据转储</strong></p><p>按照状态:动态转储、静态转储</p><p>按照方式:海量转储、增量转储</p><p><strong>登记日志文件</strong></p><p>日志文件的作用</p><ul><li>事务故障恢复和系统恢复必须用日志文件</li><li>在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库</li><li>在静态转储方式中也可以建立日志文件,当数据库毁坏后可重新装入后援副本把数据库恢复到转储结束时刻的正确状态,然后利用日志文件把已完成的事务进行重做处理,对故障发生时尚未完成的事务进行撤销处理。这样不必重新运行那些已完成的事务程序就可把数据库恢复到故障前某一时刻的正确状态。</li></ul><p><strong>事务内部的故障</strong></p><p>事务故障是指事务在运行至正常终点前被终止,这时恢复子系统应利用日志文件撤销(UNDO)此事务已对数据库进行的修改。</p><p>事务故障的恢复是由系统自动完成的,对用户是透明的。</p><p>恢复步骤:</p><ul><li><p>反向扫描日志文件,查找未完成事务的更新操作</p></li><li><p>对该事务的更新操作做逆操作</p></li><li><p>继续反向扫描,查找该事务的其他更新操作,并做同样处理</p></li><li><p>直至该事务的开始标记为止</p></li></ul><p><strong>系统故障(软故障)</strong></p><p>系统故障是指造成系统停止运转的任何事件,使得系统要重新启动。</p><p>系统故障的恢复是由系统在重新启动时自动完成的,不需要用户干预。</p><p>系统故障造成数据库不一致状态的原因</p><ul><li>未完成事务对数据库的更新可能已写入数据库</li><li>已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库</li></ul><p>恢复步骤</p><ul><li>正向扫描日志文件,将已提交事务(故障发生前已COMMIT)标志记入REDO队列,未完成事务,将其事务标志记入UNDO队列</li><li>对UNDO队列中的事务进行UNDO处理</li><li>对REDO队列中的事务进行REDO处理</li></ul><p><strong>介质故障(硬故障)</strong></p><p>介质故障是指外存故障,这类故障将破坏数据库或部分数据库,并影响正在存取这部分数据的所有事务。</p><p>介质故障的恢复需要数据库管理员介入,具体的恢复操作仍由数据库管理系统完成。</p><p>恢复方法</p><p>重装数据库,然后重做已完成的事务</p><p>恢复步骤</p><ul><li>装入最新的数据库后备副本,使数据库恢复到故障发生前最近转储时的一致性状态</li><li>装入日志文件副本,利用日志文件进行REDO。</li></ul><h2 id="并发控制"><a href="#并发控制" class="headerlink" title="并发控制"></a>并发控制</h2><p><strong>并发控制</strong></p><p>DBMS必须提供并发控制机制来协调并发用户的并发操作以保证并发事务的隔离性和一致性</p><p><strong>封锁</strong></p><p>事务T在对某个数据对象例如表、记录等操作之前,先向系统发出加锁请求,在获得封锁后,事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。</p><p>排它锁(写锁,Exclusive Locks,简称X锁)</p><p>共享锁(读锁,Share Locks,简称S锁)</p><p><strong>封锁协议</strong></p><p>三级锁协议</p><p><img src="https://raw.githubusercontent.com/Colin-Jay/Colin-Jay.github.io/master/2020/04/27/Database/sjk.jpg" alt="在这里插入图片描述" style="zoom:17%;transform:rotate(270deg);" /></p><p><strong>并发调度的可串行性</strong></p><p>多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,称这种调度策略为可串行化(Serializable)的调度。</p><p>可串行性是并发事务正确调度的准则</p><p><strong>冲突操作</strong></p><p>不同的事务对同一个数据的读写操作和写写操作是冲突操作</p><ul><li>Ri(x)与Wj(x)冲突</li><li>Wi(x)与Wj(x)冲突 </li></ul><p>其他操作不是冲突操作</p><p><strong>可串行化调度的充分条件</strong></p><p>若一个调度是冲突可串行化的,则一定是可串行的调度。</p><p><strong>两段锁协议</strong></p><p>所有事务必须分两个阶段对数据项加锁和解锁:</p><ul><li><p>在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁</p></li><li><p>在释放一个封锁之后,事务不再申请和获得任何其他封锁</p></li></ul><p>两段锁协议是实现并发控制的主要方法。</p><p>两段锁协议就是保证并发调度可串行性的封锁协议。</p><p>若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。</p><p>两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。</p><p><strong>封锁的粒度</strong></p><p>封锁对象的大小称为封锁粒度</p><p><strong>多粒度封锁</strong></p><p>如果在一个系统中同时支持多种封锁粒度供不同的事务选择是比较理想的,这种封锁方法称为多粒度封锁</p><p>多粒度树的根结点是整个数据库,表示最大的数据粒度,叶结点表示最小的数据粒度。</p><p>三级粒度树:数据库、关系、元组</p><p>四级粒度树:数据库、数据分区、数据文件、数据记录</p><p>多粒度封锁协议允许多粒度树中的每个结点被独立的加锁。对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁。因此,在多粒度封锁中一个数据对象可能以两种方式封锁,显示封锁和隐式封锁。</p><ul><li><p>显式封锁是应事务的要求直接加到数据对象上的封锁</p></li><li><p>隐式封锁是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁</p></li></ul><p><strong>意向锁</strong></p><p>如果对一个结点加意向锁,则说明该结点的下层结点正在被(准备)加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。 </p><p>IS锁 </p><p>如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。</p><p>IX锁<br>如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。</p><p>SIX锁<br>如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX。</p>]]></content>
<categories>
<category> Database </category>
</categories>
<tags>
<tag> note </tag>
<tag> Database </tag>
</tags>
</entry>
<entry>
<title>【个人代码及思路】PAT甲级:1002 A+B for Polynomials (25分)</title>
<link href="/2020/02/15/PAT-AdvancedLevel1002/"/>
<url>/2020/02/15/PAT-AdvancedLevel1002/</url>
<content type="html"><![CDATA[<h1 id="PAT-Advanced-Level-Practice"><a href="#PAT-Advanced-Level-Practice" class="headerlink" title="PAT (Advanced Level) Practice"></a>PAT (Advanced Level) Practice</h1><h2 id="1002-A-B-for-Polynomials-25分"><a href="#1002-A-B-for-Polynomials-25分" class="headerlink" title="1002 A+B for Polynomials (25分)"></a><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805526272000000" target="_blank" rel="noopener">1002 A+B for Polynomials (25分)</a></h2><p>This time, you are supposed to find <em>A</em>+<em>B</em> where <em>A</em> and <em>B</em> are two polynomials.</p><h3 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a>Input Specification:</h3><p>Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:</p><p><em>K</em> <em>N</em>1 <em>a</em> <em>N</em> 1 <em>N</em>2 <em>a</em> <em>N</em>2 … <em>N</em> <em>K</em> <em>a</em> <em>N</em> <em>K</em></p><p>where <em>K</em> is the number of nonzero terms in the polynomial, <em>N</em> <em>i</em> and <em>a</em> <em>N</em> <em>i</em> (<em>i</em>=1,2,⋯,<em>K</em>) are the exponents and coefficients, respectively. It is given that 1≤<em>K</em>≤10,0≤<em>N</em> <em>K</em><⋯<<em>N</em>2<<em>N</em>1≤1000.</p><h3 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a>Output Specification:</h3><p>For each test case you should output the sum of <em>A</em> and <em>B</em> in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.</p><h3 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a>Sample Input:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">2 1 2.4 0 3.2</span><br><span class="line">2 2 1.5 1 0.5</span><br></pre></td></tr></table></figure><h3 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a>Sample Output:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3 2 1.5 1 2.9 0 3.2</span><br></pre></td></tr></table></figure><h3 id="个人代码"><a href="#个人代码" class="headerlink" title="个人代码:"></a>个人代码:</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="comment">//C为最后的输出</span></span><br><span class="line"> <span class="keyword">int</span> Ak, Bk, Ck; <span class="comment">//K值</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">//输入参数</span></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &Ak);</span><br><span class="line"> <span class="keyword">int</span> An[Ak<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">double</span> Aa[Ak<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < Ak; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %lf"</span>, &An[i], &Aa[i]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &Bk);</span><br><span class="line"> <span class="keyword">int</span> Bn[Ak<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">double</span> Ba[Bk<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < Bk; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %lf"</span>, &Bn[i], &Ba[i]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//确定Ck</span></span><br><span class="line"> Ck = Ak;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < Bk; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> Ckplus = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">0</span>; j < Ak; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Bn[i] == An[j])</span><br><span class="line"> {</span><br><span class="line"> Ckplus = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> Ck += Ckplus;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//构造Dn合并An和Bn,便于确定Cn</span></span><br><span class="line"> <span class="keyword">int</span> Dk = Ak + Bk;</span><br><span class="line"> <span class="keyword">int</span> Dn[Dk<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i< Dk; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(i < Ak)</span><br><span class="line"> {</span><br><span class="line"> Dn[i] = An[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> Dn[i] = Bn[i-Ak];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//确定Cn</span></span><br><span class="line"> <span class="keyword">int</span> Cn[Ck<span class="number">-1</span>];</span><br><span class="line"> Cn[<span class="number">0</span>] = <span class="number">1001</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < Ck; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">//每轮循环确定一次Dn中未确定的最大值</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">max</span> = <span class="number">-1</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">0</span>; j < Dk; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(i == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Dn[j] > <span class="built_in">max</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">max</span> = Dn[j];</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>((Dn[j] > <span class="built_in">max</span>) && (Dn[j] < Cn[i<span class="number">-1</span>]))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">max</span> = Dn[j];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> Cn[i] = <span class="built_in">max</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//确定Ca</span></span><br><span class="line"> <span class="keyword">double</span> Ca[Ck<span class="number">-1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < Ck; i++)</span><br><span class="line"> {</span><br><span class="line"> Ca[i] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">0</span>; j < Ak; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Cn[i] == An[j])</span><br><span class="line"> {</span><br><span class="line"> Ca[i] += Aa[j];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">0</span>; j < Bk; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Cn[i] == Bn[j])</span><br><span class="line"> {</span><br><span class="line"> Ca[i] += Ba[j];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//输出</span></span><br><span class="line"> <span class="keyword">int</span> Cksub = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span> ; i < Ck; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Ca[i] == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> Cksub++;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> Cksub = Ck - Cksub;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, Cksub);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span> ; i < Ck; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(Ca[i] == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">" %d %.1f"</span>, Cn[i], Ca[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="思路提示"><a href="#思路提示" class="headerlink" title="思路提示:"></a>思路提示:</h3><p>代码虽然很长,但是内容很简单,可以简化代码,这里就不简化了。说下解题的思路:</p><ul><li><p>存放好输入参数后,先看需要输出的第一个数字Ck,通过An和Bn中不同数值个数的和来确定;</p></li><li><p>有了Ck之后便是输出一个指数,输出一个系数。指数确定好,系数就通过对应的Aa和Ba数组相加就可以了。指数Cn可以通过构造数组Dn(Dn是An和Bn的合并),每次循环找出Dn中的最大值即可确定Cn;</p></li><li>Cn中对应指数的系数Aa+Ba即得到Ca;</li><li>按照格式输出即可</li></ul><p>提交答案后发现只通过了三个,仔细一想这样输出会把系数是0的指数也输出了,而实际上不应该输出系数为0的项,同理对应Ck也要减小,于是有了最终代码。另外,代码很多地方可以简化,强迫症原因,暂时不修改。</p>]]></content>
<categories>
<category> Code </category>
<category> PAT_A </category>
</categories>
<tags>
<tag> pat </tag>
</tags>