-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
1006 lines (784 loc) · 158 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
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"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Lennybai' Blog</title>
<link href="/atom.xml" rel="self"/>
<link href="http://lennybai.cn/"/>
<updated>2017-01-03T06:05:00.438Z</updated>
<id>http://lennybai.cn/</id>
<author>
<name>Lenny Bai</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>effective stl</title>
<link href="http://lennybai.cn/2016/12/30/effective-stl/"/>
<id>http://lennybai.cn/2016/12/30/effective-stl/</id>
<published>2016-12-30T03:59:27.000Z</published>
<updated>2017-01-03T06:05:00.438Z</updated>
<content type="html"><![CDATA[<h1 id="序"><a href="#序" class="headerlink" title="序"></a>序</h1><p> 使用c++不可避免的要去使用和钻研stl。effective stl是教我们如何有效(更安全,更具有运行效率)的去使用stl的书,让我们成为更高产的程序员。<br><a id="more"></a></p>
<p>术语</p>
<p>标准序列容器: vector string deque list<br>标准关联容器: set multiset map multimap</p>
<p>remove 算法描述:查找的得到第一个元素的位置,然后从此位置开始遍历容器,将后面的元素依次前移,跳过和value相同值的元素,也就是说,所有和value相同值的元素都会被覆盖,而其他的元素都会依次前移。最后remove返回”指向最后一个 ‘有用’ 元素的iterator”,但是在remove算法过程中,并没有修改原容器的size,以及end()。但是从逻辑角度看,最后的[ 从remove得到的iterator_result, 容器的结尾end() ) 这个区间里面的元素已经没有意义了。所以这些元素不应该属于该容器了。remove算法能做的仅此而已,并没有删除这些无用的元素。<br> 结论:移除容器里面的元素不应该使用remove算法,而是容器自己的方法erase()。</p>
]]></content>
<summary type="html">
<h1 id="序"><a href="#序" class="headerlink" title="序"></a>序</h1><p> 使用c++不可避免的要去使用和钻研stl。effective stl是教我们如何有效(更安全,更具有运行效率)的去使用stl的书,让我们成为更高产的程序员。<br>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="effective stl" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/effective-stl/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="effective stl" scheme="http://lennybai.cn/tags/effective-stl/"/>
</entry>
<entry>
<title>Third Party Applications of WineHQ </title>
<link href="http://lennybai.cn/2016/12/28/Third-Party-Applications-of-WineHQ/"/>
<id>http://lennybai.cn/2016/12/28/Third-Party-Applications-of-WineHQ/</id>
<published>2016-12-28T02:05:18.000Z</published>
<updated>2016-12-29T07:15:05.813Z</updated>
<content type="html"><![CDATA[<h1 id="序"><a href="#序" class="headerlink" title="序"></a>序</h1><p> 工作需要,简单调研一下WineHQ相关的内容。主要是摘要记录,不做更多思考。</p>
<h1 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h1><p> Wine (“Wine Is Not an Emulator” 的首字母缩写)是一个能够在多种 POSIX-compliant 操作系统(诸如 Linux,Mac OSX 及 BSD 等)上运行 Windows 应用的兼容层。 Wine 不是像虚拟机或者模拟器一样模仿内部的 Windows 逻辑,而是將 Windows API 调用翻译成为动态的 POSIX 调用,免除了性能和其他一些行为的内存占用,让你能够干净地集合 Windows 应用到你的桌面。[1]</p>
<a id="more"></a>
<p> Wine 项目由 Bob Amstadt 于 1993 年发起,旨在寻求一种在 Linux 上运行 Windows 3.1 程序的办法。不久之后,Alexandre Julliard 开始接手领导 Wine 的开发,从此由他管理这个项目。 多年以来,随着 Windows API 和应用为了适应新硬件及软件而不断演变,Wine 也一直不断发展来支持新的特性,移植到更多其他系统,并且更加稳定,提供着更好的用户体验。[1]</p>
<p> 为了让WINE变得更强大并且更容易被使用,有很多第三方的应用对它进行支持和扩展,本文主要对官网列举出来的部分第三方应用进行简略说明。</p>
<h1 id="二、Wine第三方应用"><a href="#二、Wine第三方应用" class="headerlink" title="二、Wine第三方应用"></a>二、Wine第三方应用</h1><p> 在wine的官网列举出两大类三方软件:仍在维护的和不再更新的。在仍在维护的三方软件中,我们最耳熟能详的当然就是crossover。不过我们关注的重点是除它之外的软件,看能否发现一些独特的特性。</p>
<h2 id="gnome-exe-thumbnailer"><a href="#gnome-exe-thumbnailer" class="headerlink" title="gnome-exe-thumbnailer"></a>gnome-exe-thumbnailer</h2><p> 在ubuntu软件包中我们可以找到这个软件。同样可以通过apt-get gnome-exe-thumbnailer来进行安装。这个三方应用主要的作用是将windows的exe按照原有的图标进行显示。详细的说,比如我们常用的qq图标是一个小企鹅。而ubuntu默认会将exe识别为同一种类型文件而显示默认的类型图标。安装这个三方应用后,它会提取原有的window图标加以显示。更多可以查看<a href="https://www.youtube.com/watch?v=9YXhNNCSwv8" target="_blank" rel="external">这个视频</a>.</p>
<h2 id="q4wine"><a href="#q4wine" class="headerlink" title="q4wine"></a>q4wine</h2><p> q4wine是一个用来安装和管理wine程序的kde工具。我们可以用q4wine去安装程序。同样可以去管理wine安装的应用程序。更多效果可以查看<a href="https://www.youtube.com/watch?v=951nVQQJhks&t=244s" target="_blank" rel="external">这个视频</a>.</p>
<h2 id="Winetricks"><a href="#Winetricks" class="headerlink" title="Winetricks"></a>Winetricks</h2><p> winetricks整体上看起来更像是一个包依赖管理器。通过运行winetricks脚本,为wine应用提供相应的动态库支持。更多效果可以查看<a href="https://www.youtube.com/watch?v=tqrVR1QjDPQ" target="_blank" rel="external">这个视频</a>.</p>
<h1 id="三、其他"><a href="#三、其他" class="headerlink" title="三、其他"></a>三、其他</h1><p> 这些三方库都可以在github或者google code上找到相应的源码,如果想要深入了解,可以进行源码阅读。<br> 令人遗憾的是,这些三方库的参考文档并不丰富,所以想要了解,还是需要看看别人的使用视频或者亲身感受一下。</p>
<p> </p>
<hr>
<h1 id="3-参考文献"><a href="#3-参考文献" class="headerlink" title="3 参考文献"></a>3 参考文献</h1><ul>
<li>[1]: <a href="http://www.oschina.net/p/wine/?fromerr=eLEvCq6E" target="_blank" rel="external">wine中文社区</a></li>
<li>[2]: <a href="https://wiki.winehq.org/Third_Party_Applications" target="_blank" rel="external">WINEHQ</a></li>
</ul>
]]></content>
<summary type="html">
<h1 id="序"><a href="#序" class="headerlink" title="序"></a>序</h1><p> 工作需要,简单调研一下WineHQ相关的内容。主要是摘要记录,不做更多思考。</p>
<h1 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h1><p> Wine (“Wine Is Not an Emulator” 的首字母缩写)是一个能够在多种 POSIX-compliant 操作系统(诸如 Linux,Mac OSX 及 BSD 等)上运行 Windows 应用的兼容层。 Wine 不是像虚拟机或者模拟器一样模仿内部的 Windows 逻辑,而是將 Windows API 调用翻译成为动态的 POSIX 调用,免除了性能和其他一些行为的内存占用,让你能够干净地集合 Windows 应用到你的桌面。[1]</p>
</summary>
</entry>
<entry>
<title>leetcode-ReverseInteger</title>
<link href="http://lennybai.cn/2016/12/21/leetcode-ReverseInteger/"/>
<id>http://lennybai.cn/2016/12/21/leetcode-ReverseInteger/</id>
<published>2016-12-21T07:13:37.000Z</published>
<updated>2016-12-21T07:25:27.377Z</updated>
<content type="html"><![CDATA[<h3 id="Reverse-Integer"><a href="#Reverse-Integer" class="headerlink" title="Reverse Integer"></a><a href="https://leetcode.com/problems/reverse-integer/" target="_blank" rel="external">Reverse Integer</a></h3><p>Reverse digits of an integer.</p>
<blockquote>
<p>Example1: x = 123, return 321</p>
<p>Example2: x = -123, return -321</p>
</blockquote>
<a id="more"></a>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 本题其实思路很简单,我个人认为只是问题的考察点,应该是对人们对边界的认识。简单的翻转我们都能想到,通过按10取余来获取最后一位,通过除以10来进行移位。一定要记得考虑int的边界。</p>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"limits.h"</span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> <span class="function"><span class="keyword">int</span> <span class="title">reverse</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</div><div class="line"> <span class="keyword">long</span> <span class="keyword">long</span> result = <span class="number">0</span>;</div><div class="line"> <span class="keyword">while</span>(x != <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> result = result * <span class="number">10</span> + x % <span class="number">10</span>;</div><div class="line"> x = x/<span class="number">10</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> (result > INT_MAX || result < INT_MIN) ? <span class="number">0</span> : result ;</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> Solution s;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">123456</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">1000</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">1001</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">0</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">-123</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">-1234</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.reverse(<span class="number">1534236469</span>) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << <span class="number">9646324350</span>+<span class="number">1</span> << <span class="built_in">endl</span>;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="Reverse-Integer"><a href="#Reverse-Integer" class="headerlink" title="Reverse Integer"></a><a href="https://leetcode.com/problems/reverse-integer/">Reverse Integer</a></h3><p>Reverse digits of an integer.</p>
<blockquote>
<p>Example1: x = 123, return 321</p>
<p>Example2: x = -123, return -321</p>
</blockquote>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/leetcode/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>c++11条件变量</title>
<link href="http://lennybai.cn/2016/12/20/c-11%E6%9D%A1%E4%BB%B6%E5%8F%98%E9%87%8F/"/>
<id>http://lennybai.cn/2016/12/20/c-11条件变量/</id>
<published>2016-12-20T08:11:20.000Z</published>
<updated>2016-12-20T08:19:23.309Z</updated>
<content type="html"><![CDATA[<p> 写了个条件变量的小程序。感觉还是挺方便的。<br><a id="more"></a><br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><map></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><thread></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><mutex></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><condition_variable></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><chrono></span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line">mutex m_mtxCv;</div><div class="line"></div><div class="line">condition_variable m_Cv;</div><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">()</span></span></div><div class="line">{</div><div class="line"> <span class="keyword">while</span>(<span class="literal">true</span>)</div><div class="line"> {</div><div class="line"> unique_lock<mutex> lk(m_mtxCv);</div><div class="line"> <span class="built_in">cout</span> << <span class="string">" 1 "</span> << <span class="built_in">endl</span>;</div><div class="line"> m_Cv.wait_for(lk,chrono::milliseconds(<span class="number">5000</span>));</div><div class="line"> <span class="built_in">cout</span> << <span class="string">" 2 "</span> << <span class="built_in">endl</span>;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></div><div class="line">{</div><div class="line"> <span class="function">thread <span class="title">t</span><span class="params">(print)</span></span>;</div><div class="line"> <span class="keyword">while</span>(<span class="literal">true</span>)</div><div class="line"> { </div><div class="line"> <span class="built_in">cin</span>.get();</div><div class="line"> m_Cv.notify_one();</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>编译</p>
<blockquote>
<p>c++ test.cc -std=c++11 -lpthread</p>
</blockquote>
]]></content>
<summary type="html">
<p> 写了个条件变量的小程序。感觉还是挺方便的。<br>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="c++11" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/c-11/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="c++11" scheme="http://lennybai.cn/tags/c-11/"/>
<category term="条件变量" scheme="http://lennybai.cn/tags/%E6%9D%A1%E4%BB%B6%E5%8F%98%E9%87%8F/"/>
</entry>
<entry>
<title>leetcode-LongestPalindromicSubstring</title>
<link href="http://lennybai.cn/2016/12/20/leetcode-LongestPalindromicSubstring/"/>
<id>http://lennybai.cn/2016/12/20/leetcode-LongestPalindromicSubstring/</id>
<published>2016-12-20T06:30:01.000Z</published>
<updated>2016-12-20T06:36:53.265Z</updated>
<content type="html"><![CDATA[<h3 id="LongestPalidrmicSubstring"><a href="#LongestPalidrmicSubstring" class="headerlink" title="LongestPalidrmicSubstring"></a><a href="https://leetcode.com/problems/longest-palindromic-substring/" target="_blank" rel="external">LongestPalidrmicSubstring</a></h3><p>Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.<br><a id="more"></a></p>
<h3 id="example"><a href="#example" class="headerlink" title="example"></a>example</h3><blockquote>
<p>Input: “babad”</p>
<p>Output: “bab”</p>
<p>Note: “aba” is also a valid answer.</p>
<p>Input: “cbbd”</p>
<p>Output: “bb”</p>
</blockquote>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 这个题我的答案并不巧妙,只能说是完成了任务。不过还是要说一下注意点:</p>
<ol>
<li>对连续的相同字符的处理</li>
<li>如果a[p..q]是palidrmic串,如果a[p-1]=a[q+1],那么a[p-1..q+1]也是palidrmic串</li>
</ol>
<p> 在leetcode的discuss专栏里有很多出色的解答,希望大家移步讨论区去自行学习。</p>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">void</span> <span class="title">GetInitSbutString</span><span class="params">(<span class="built_in">string</span> s, <span class="keyword">int</span> n, <span class="keyword">int</span> &start, <span class="keyword">int</span>& end)</span></span></div><div class="line"> {</div><div class="line"> <span class="keyword">while</span>(start - <span class="number">1</span> >= <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( s.at(start - <span class="number">1</span> ) == s.at(n) )</div><div class="line"> start = start <span class="number">-1</span>;</div><div class="line"> <span class="keyword">else</span> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">while</span>(end + <span class="number">1</span> < s.length())</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( s.at(end+<span class="number">1</span>) == s.at(n) )</div><div class="line"> end = end+<span class="number">1</span>;</div><div class="line"> <span class="keyword">else</span> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">int</span> <span class="title">getSubstring</span><span class="params">(<span class="built_in">string</span> s, <span class="keyword">int</span>& start)</span></span></div><div class="line"> {</div><div class="line"> <span class="keyword">int</span> tempStart = start, tempEnd = start;</div><div class="line"></div><div class="line"> GetInitSbutString(s, start, tempStart, tempEnd);</div><div class="line"> <span class="keyword">while</span>( (tempStart - <span class="number">1</span> >= <span class="number">0</span> ) && (tempEnd + <span class="number">1</span> < s.length() ) )</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( s.at(tempStart<span class="number">-1</span>) == s.at(tempEnd+<span class="number">1</span>))</div><div class="line"> {</div><div class="line"> tempStart = tempStart - <span class="number">1</span>;</div><div class="line"> tempEnd = tempEnd + <span class="number">1</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> start = tempStart;</div><div class="line"> <span class="keyword">return</span> tempEnd-tempStart +<span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="built_in">string</span> <span class="title">longestPalindrome</span><span class="params">(<span class="built_in">string</span> s)</span> </span>{</div><div class="line"> <span class="keyword">int</span> start = <span class="number">0</span>,length=<span class="number">0</span>;</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i =<span class="number">0</span>; i < s.length(); i++)</div><div class="line"> {</div><div class="line"> <span class="keyword">int</span> tempStart = i;</div><div class="line"> <span class="keyword">int</span> l = getSubstring(s,tempStart);</div><div class="line"> <span class="keyword">if</span> (length <= l)</div><div class="line"> {</div><div class="line"> length = l;</div><div class="line"> start = tempStart;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> s.substr(start, length);</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> Solution s;</div><div class="line"> <span class="built_in">string</span> temp = <span class="string">"babad"</span>;</div><div class="line"> <span class="built_in">cout</span> << s.longestPalindrome(temp) << <span class="built_in">endl</span>;</div><div class="line"> temp = <span class="string">"cbbd"</span>;</div><div class="line"> <span class="built_in">cout</span> << s.longestPalindrome(temp) << <span class="built_in">endl</span>;</div><div class="line"> temp = <span class="string">"aba"</span>;</div><div class="line"> <span class="built_in">cout</span> << s.longestPalindrome(temp) << <span class="built_in">endl</span>;</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="LongestPalidrmicSubstring"><a href="#LongestPalidrmicSubstring" class="headerlink" title="LongestPalidrmicSubstring"></a><a href="https://leetcode.com/problems/longest-palindromic-substring/">LongestPalidrmicSubstring</a></h3><p>Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.<br>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>leetcode-MedianOfTwoSortedArrays</title>
<link href="http://lennybai.cn/2016/12/19/leetcode-MedianOfTwoSortedArrays/"/>
<id>http://lennybai.cn/2016/12/19/leetcode-MedianOfTwoSortedArrays/</id>
<published>2016-12-19T03:04:34.000Z</published>
<updated>2016-12-19T03:12:39.470Z</updated>
<content type="html"><![CDATA[<h3 id="MedianOfTwoSortedArrays"><a href="#MedianOfTwoSortedArrays" class="headerlink" title="MedianOfTwoSortedArrays"></a><a href="https://leetcode.com/problems/median-of-two-sorted-arrays/" target="_blank" rel="external">MedianOfTwoSortedArrays</a></h3><p>There are two sorted arrays nums1 and nums2 of size m and n respectively.</p>
<p>Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).</p>
<a id="more"></a>
<h3 id="example"><a href="#example" class="headerlink" title="example"></a>example</h3><blockquote>
<p>nums1 = [1, 3]<br>nums2 = [2]</p>
<p>The median is 2.0</p>
<p>nums1 = [1, 2]<br>nums2 = [3, 4]</p>
<p>The median is (2 + 3)/2 = 2.5</p>
</blockquote>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 本体对时间复杂度有要求。当我看到这个题目的时候,有两点引起我的注意,第一个就是两个数组都是有序的,第二个就是时间复杂度为log(n)。这是我想到了归并排序。就这样我按照归并排序的思路完成了本题。</p>
<p>部分细节:</p>
<ol>
<li>中位数并不总是一个。</li>
<li>遍历数组不需要全部遍历。</li>
<li>注意归并排序的代码实现。</li>
</ol>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><limits.h></span></span></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> <span class="function"><span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums1, <span class="built_in">vector</span><<span class="keyword">int</span>>& nums2)</span> </span>{</div><div class="line"> <span class="keyword">int</span> size = nums1.size()+nums2.size();</div><div class="line"> <span class="keyword">int</span> mid1 = size/<span class="number">2</span>;</div><div class="line"> <span class="keyword">int</span> mid2 = mid1 - (size%<span class="number">2</span>==<span class="number">0</span>?<span class="number">1</span>:<span class="number">0</span>);</div><div class="line"> <span class="keyword">int</span> temp, mid1num=<span class="number">0</span>,mid2num=<span class="number">0</span>,i=<span class="number">0</span>,j=<span class="number">0</span>;</div><div class="line"> nums1.push_back(INT_MAX);</div><div class="line"> nums2.push_back(INT_MAX);</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> k = <span class="number">0</span> ; k < size; k++)</div><div class="line"> {</div><div class="line"> temp = <span class="number">0</span>;</div><div class="line"> <span class="keyword">if</span>( nums1[i] < nums2[j] )</div><div class="line"> {</div><div class="line"> temp = nums1[i];</div><div class="line"> i++;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> temp = nums2[j];</div><div class="line"> j++;</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span>( k == mid2 )</div><div class="line"> {</div><div class="line"> mid2num = temp;</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span>( k == mid1 )</div><div class="line"> {</div><div class="line"> mid1num = temp;</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> (mid1num + mid2num) / <span class="number">2.0</span>;</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> Solution s;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> nums1 = {<span class="number">1</span>,<span class="number">3</span>};</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> nums2 = {<span class="number">2</span>};</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> nums3 = {<span class="number">1</span>,<span class="number">2</span>};</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> nums4 = {<span class="number">3</span>,<span class="number">4</span>};</div><div class="line"></div><div class="line"> <span class="built_in">cout</span> << s.findMedianSortedArrays(nums1, nums2) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << s.findMedianSortedArrays(nums3, nums4) << <span class="built_in">endl</span>;</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="MedianOfTwoSortedArrays"><a href="#MedianOfTwoSortedArrays" class="headerlink" title="MedianOfTwoSortedArrays"></a><a href="https://leetcode.com/problems/median-of-two-sorted-arrays/">MedianOfTwoSortedArrays</a></h3><p>There are two sorted arrays nums1 and nums2 of size m and n respectively.</p>
<p>Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).</p>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/leetcode/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>ActiveMQ使用记录</title>
<link href="http://lennybai.cn/2016/12/15/ActiveMQ%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95/"/>
<id>http://lennybai.cn/2016/12/15/ActiveMQ使用记录/</id>
<published>2016-12-15T05:14:16.000Z</published>
<updated>2016-12-20T02:50:58.003Z</updated>
<content type="html"><![CDATA[<p> 今天简单的浏览了一些招聘需求,其中对消息队列所需的技术要求一般都是”熟悉ActiveMQ”。虽然之前做项目,使用过celery+rabbitmq的异步消息机制。这里还是为了给自己的简历贴一些金,来上手练一下ActiveMQ的使用。</p>
<h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><h3 id="开发运行环境"><a href="#开发运行环境" class="headerlink" title="开发运行环境"></a>开发运行环境</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">> lennybai@lennybai~$ lsb_release <span class="_">-a</span></div><div class="line">> No LSB modules are available.</div><div class="line">> Distributor ID: Ubuntu</div><div class="line">> Description: Ubuntu 16.04.1 LTS</div><div class="line">> Release: 16.04</div><div class="line">> Codename: xenial</div></pre></td></tr></table></figure>
<a id="more"></a>
<p> 对于工具的使用,用心去研读一下官方文档还是很有必要的。在参考文献中我列出了官网的链接,感兴趣的朋友可以阅读一下。ActiveMQ的环境要求,在官方文档中指出为:JRE和JDK。当然我是个懒汉,在这里不太希望用源码去安装ActiveMQ。我是这么干的:</p>
<ol>
<li><p>安装java</p>
<blockquote>
<p>sudo add-apt-repository ppa:webupd8team/java<br>sudo apt-get update<br>sudo apt-get install oracle-java8-installer</p>
</blockquote>
</li>
<li><p>安装ActiveMQ</p>
<blockquote>
<p><a href="http://activemq.apache.org/download.html" target="_blank" rel="external">官网下载</a>并解压,在bin目录下运行自己系统相同的activemq程序,执行./activemq start</p>
</blockquote>
</li>
</ol>
<p> 在web控制台打开<a href="http://127.0.0.1:8161/admin/" target="_blank" rel="external">http://127.0.0.1:8161/admin/</a>。初始用户名:admin 密码:admin。[activemq_install_dir]/data/activemq.log”中可以查看运行日志。netstat -an | grep 61616可以查看端口运行情况。<br> activemq我认为比较好的有三点:开源,漂亮控制台和没有繁琐的配置。</p>
<h1 id="试用"><a href="#试用" class="headerlink" title="试用"></a>试用</h1><hr>
<h1 id="3-参考文献"><a href="#3-参考文献" class="headerlink" title="3 参考文献"></a>3 参考文献</h1><ul>
<li>[1]: <a href="http://activemq.apache.org/version-5-getting-started.html#Version5GettingStarted-DocumentOrganization" target="_blank" rel="external">ActiveMQ Document</a></li>
</ul>
]]></content>
<summary type="html">
<p> 今天简单的浏览了一些招聘需求,其中对消息队列所需的技术要求一般都是”熟悉ActiveMQ”。虽然之前做项目,使用过celery+rabbitmq的异步消息机制。这里还是为了给自己的简历贴一些金,来上手练一下ActiveMQ的使用。</p>
<h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><h3 id="开发运行环境"><a href="#开发运行环境" class="headerlink" title="开发运行环境"></a>开发运行环境</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">&gt; lennybai@lennybai~$ lsb_release <span class="_">-a</span></div><div class="line">&gt; No LSB modules are available.</div><div class="line">&gt; Distributor ID: Ubuntu</div><div class="line">&gt; Description: Ubuntu 16.04.1 LTS</div><div class="line">&gt; Release: 16.04</div><div class="line">&gt; Codename: xenial</div></pre></td></tr></table></figure>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="ActiveMQ" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/ActiveMQ/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="ActiveMQ" scheme="http://lennybai.cn/tags/ActiveMQ/"/>
</entry>
<entry>
<title>leetcode-longestSubStringWithOutRepeatingCharacters</title>
<link href="http://lennybai.cn/2016/12/13/leetcode-longestSubStringWithOutRepeatingCharacters/"/>
<id>http://lennybai.cn/2016/12/13/leetcode-longestSubStringWithOutRepeatingCharacters/</id>
<published>2016-12-13T07:20:24.000Z</published>
<updated>2016-12-14T00:50:54.760Z</updated>
<content type="html"><![CDATA[<h3 id="longest-substring-without-repeating-characters"><a href="#longest-substring-without-repeating-characters" class="headerlink" title="longest-substring-without-repeating-characters"></a><a href="https://leetcode.com/problems/longest-substring-without-repeating-characters/" target="_blank" rel="external">longest-substring-without-repeating-characters</a></h3><p>Given a string, find the length of the longest substring without repeating characters.</p>
<a id="more"></a>
<h3 id="example"><a href="#example" class="headerlink" title="example"></a>example</h3><blockquote>
<p>Given “abcabcbb”, the answer is “abc”, which the length is 3.</p>
<p>Given “bbbbb”, the answer is “b”, with the length of 1.</p>
<p>Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.</p>
</blockquote>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 阅读本题后,都会有大致的概念应该怎么去处理。大题思路就是从头到位遍历字符串,记录所有的没有出现重复字符的子字符串,并记录其长度。最后选出最大长度输出。这个思路理论上应该可以解决我们的问题,但是如何写出漂亮解答,还是需要我们稍作思考的。<br> 让我们再重新审阅一下这个题目。如果我们假设子字符串s[i..j]为无重复子字符串,其长度为l。如果s[j+1]也不存在在s[i..j]中,那么s[i..j+1]也是无重复子字符串,其长度更新为l+1。根据这种设计,我们完全可以套用动态规划来解决这个问题。(前面的文章有介绍)<br> 那么我们进而去丰富我们的动态规划设计:</p>
<ol>
<li>标记子字符串起点substringstart。若s[j+1]与s[i..j]中无重复字符,那么s[i..j+1]的子字符串起点也为i;如果与r(i≤r≤j)重复,则其起点变为r+1;</li>
<li>记录最大长度longest。当前长度[i..j]为j-i+1,与longest做比较,则其较大的更新longest。</li>
<li>因为使用hashmap来优化记录存储。</li>
</ol>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> <span class="function"><span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(<span class="built_in">string</span> s)</span> </span>{</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> hashMap(<span class="number">256</span>, <span class="number">-1</span>);</div><div class="line"> <span class="keyword">int</span> longest = <span class="number">0</span>, subStringStart = <span class="number">0</span>;</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++)</div><div class="line"> {</div><div class="line"> subStringStart = subStringStart >= hashMap[s[i]] + <span class="number">1</span> ? subStringStart : hashMap[s[i]] + <span class="number">1</span>;</div><div class="line"> hashMap[s[i]] = i;</div><div class="line"> longest = longest >= i-subStringStart +<span class="number">1</span> ? longest : i - subStringStart + <span class="number">1</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> longest;</div><div class="line"> }</div><div class="line"></div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> <span class="built_in">string</span> s1 = <span class="string">"abcabcbb"</span>;</div><div class="line"> <span class="built_in">string</span> s2 = <span class="string">"a"</span>;</div><div class="line"> <span class="built_in">string</span> s3 = <span class="string">"abc"</span>;</div><div class="line"> <span class="built_in">string</span> s4 = <span class="string">"aab"</span>;</div><div class="line"> Solution solution;</div><div class="line"> <span class="built_in">cout</span> << solution.lengthOfLongestSubstring(s1) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << solution.lengthOfLongestSubstring(s2) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << solution.lengthOfLongestSubstring(s3) << <span class="built_in">endl</span>;</div><div class="line"> <span class="built_in">cout</span> << solution.lengthOfLongestSubstring(s4) << <span class="built_in">endl</span>;</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="longest-substring-without-repeating-characters"><a href="#longest-substring-without-repeating-characters" class="headerlink" title="longest-substring-without-repeating-characters"></a><a href="https://leetcode.com/problems/longest-substring-without-repeating-characters/">longest-substring-without-repeating-characters</a></h3><p>Given a string, find the length of the longest substring without repeating characters.</p>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/leetcode/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>算法导论-动态规划</title>
<link href="http://lennybai.cn/2016/12/13/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA-%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
<id>http://lennybai.cn/2016/12/13/算法导论-动态规划/</id>
<published>2016-12-13T02:24:22.000Z</published>
<updated>2016-12-13T03:41:17.991Z</updated>
<content type="html"><![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> 前面我们已经介绍了分治思想。分治思想是将问题划分为<strong>互不相交的子问题</strong>,递归的求解子问题,再将它们的解组合起来,求出原问题的解。这一篇文章我们将一起来讨论一下动态规划。它是算法中另一个重要的思想。 <br> 动态规划的思想与分治思想相反,动态规划是用于<strong>子问题重叠</strong>的情况,即不同的子问题具有相同的子子问题。在这种情况下,动态规划相对于分治算法的优势在于,分治算法会重复的计算本是相同的子子问题,导致运算时间的浪费,而动态规划则只会计算一次。<br> 动态规划常常用于解决最优解的问题。这类问题常常有很多可行的解,我们希望的是从这些解中找到最优解。<br><a id="more"></a></p>
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p> 类似于分治算法的三个步骤,动态规划的思考和设计层面也具有四个步骤。</p>
<ol>
<li>刻画一个最优解结构</li>
<li>递归定义最优解的值</li>
<li>计算最优解的值,通常使用自底向上的方法</li>
<li>利用计算出来的信息构造最优解</li>
</ol>
<h1 id="实践"><a href="#实践" class="headerlink" title="实践"></a>实践</h1><p> 这里我们通过一个简单的例子对动态规划的思想进行一下实践。</p>
<h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><table>
<thead>
<tr>
<th>长度i</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>价格Pi</strong></td>
<td>1</td>
<td>5</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>17</td>
<td>17</td>
<td>20</td>
<td>24</td>
<td>30</td>
</tr>
</tbody>
</table>
<p> 上述表格描述的是一个钢条公司的钢条长度和价格的关系。它们希望得到给定长度为n的钢条,如何切割才能达到利益最大化。</p>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p> 我们用n表示钢条的长度,i表示切割的长度,Pi表示切割长度对应的收益,Rn代表长度为n的钢条对应的最大收益。<br> 则我们可以得出Rn=max(Pi + Rn-1)。这个推倒式的表明的是对于n长的钢条。进行i(i从1到n)的长度的切割,获得的切割收益与剩余收益的和。再从i=1到i=n中选取最大的值,就是该n长钢条能获取的最大收益。</p>
<h3 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h3><p> 动态规划有两种等价的实现方法,分别为带备忘的自顶向下法和自底向上法。带备忘的自顶向下法,是按照自然的递归形式编写过程,但是过程中会保存没格子问题的解。自底向上法则需要恰当的定义子问题的规模,使得任何子问题都只依赖更小的子问题求解。<br>下面列出两种实现的伪代码。</p>
<p>自顶向下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">MEMOIZED-CUT-ROD(p,n)</div><div class="line"> let r[0..n] be a new array</div><div class="line"> for i = 0 to n</div><div class="line"> r[i]=-∞</div><div class="line"> return MEMOIZED-CUT-ROD-AUX(p,n,r)</div><div class="line"></div><div class="line">MEMOIZED-CUT-ROD-AUX(p,n,r)</div><div class="line"> if r[n]≥0</div><div class="line"> return r[n]</div><div class="line"> if n== 0</div><div class="line"> q = 0</div><div class="line"> else q = -∞</div><div class="line"> for i = 1 to n</div><div class="line"> q = max(q, p[i] + MEMOIZED-CUT-ROD-AUX(p, n-i, r))</div><div class="line"> r[n]=q</div><div class="line"> return q</div></pre></td></tr></table></figure></p>
<p>自底向上:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">BOTTOM-UP-CUT-ROD(p,n)</div><div class="line"> let r[0..n] be a new array</div><div class="line"> r[0]=0</div><div class="line"> for j = 1 to n</div><div class="line"> q = -∞</div><div class="line"> for i = 1 to j</div><div class="line"> q=max(q,p[i]+r[j-i])</div><div class="line"> r[j]=q</div><div class="line"> return r[n]</div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> 前面我们已经介绍了分治思想。分治思想是将问题划分为<strong>互不相交的子问题</strong>,递归的求解子问题,再将它们的解组合起来,求出原问题的解。这一篇文章我们将一起来讨论一下动态规划。它是算法中另一个重要的思想。 <br> 动态规划的思想与分治思想相反,动态规划是用于<strong>子问题重叠</strong>的情况,即不同的子问题具有相同的子子问题。在这种情况下,动态规划相对于分治算法的优势在于,分治算法会重复的计算本是相同的子子问题,导致运算时间的浪费,而动态规划则只会计算一次。<br> 动态规划常常用于解决最优解的问题。这类问题常常有很多可行的解,我们希望的是从这些解中找到最优解。<br>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/tags/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
<category term="动态规划" scheme="http://lennybai.cn/tags/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
</entry>
<entry>
<title>leetcode-AddTwoNum</title>
<link href="http://lennybai.cn/2016/12/12/leetcode-AddTwoNum/"/>
<id>http://lennybai.cn/2016/12/12/leetcode-AddTwoNum/</id>
<published>2016-12-12T09:18:20.000Z</published>
<updated>2016-12-12T10:31:41.966Z</updated>
<content type="html"><![CDATA[<h3 id="AddTwoNum"><a href="#AddTwoNum" class="headerlink" title="AddTwoNum"></a><a href="https://leetcode.com/problems/add-two-numbers/" target="_blank" rel="external">AddTwoNum</a></h3><p>You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.</p>
<a id="more"></a>
<h3 id="example"><a href="#example" class="headerlink" title="example"></a>example</h3><blockquote>
<p>Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)<br>Output: 7 -> 0 -> 8</p>
</blockquote>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 思路不算复杂,就是按照我们正常的加法竖式计算的方式来完成此题就可以。需要注意的细节有两点:</p>
<ol>
<li>进位值</li>
<li>判断list结尾</li>
</ol>
<p> 关于进位值(程序中定义为extra变量)在本题中,如果是list最后两个数字相加的进位,往往会被忽略。第二点,两个list不一定是等长的,所以在遍历的过程中,需要对list结尾进行判断,防止运行时空指针错误。注意这两点,可能就可以正确完成本题了。</p>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">struct</span> ListNode {</div><div class="line"> <span class="keyword">int</span> val;</div><div class="line"> ListNode *next;</div><div class="line"> ListNode(<span class="keyword">int</span> x) : val(x), next(<span class="literal">NULL</span>) {}</div><div class="line">};</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> <span class="function">ListNode* <span class="title">addTwoNumbers</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>{</div><div class="line"> <span class="function">ListNode <span class="title">result</span><span class="params">(<span class="number">0</span>)</span></span>;</div><div class="line"> ListNode* tempResult = &result;</div><div class="line"> <span class="keyword">int</span> l1Value, l2Value, extra;</div><div class="line"> l1Value = l2Value = extra = <span class="number">0</span>;</div><div class="line"> <span class="keyword">while</span>(l1 != <span class="literal">NULL</span> || l2 != <span class="literal">NULL</span> || extra != <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> l1Value = (l1!=<span class="literal">NULL</span>)?l1->val : <span class="number">0</span>;</div><div class="line"> l2Value = (l2!=<span class="literal">NULL</span>)?l2->val : <span class="number">0</span>;</div><div class="line"> tempResult->next = <span class="keyword">new</span> ListNode((l1Value+l2Value+extra)%<span class="number">10</span>);</div><div class="line"> extra = (l1Value+l2Value+extra) / <span class="number">10</span>;</div><div class="line"></div><div class="line"> l1 != <span class="literal">NULL</span> ? l1 = l1->next : l1 = <span class="literal">NULL</span>;</div><div class="line"> l2 != <span class="literal">NULL</span> ? l2 = l2->next : l2 = <span class="literal">NULL</span>;</div><div class="line"> tempResult = tempResult->next;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> result.next;</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> ListNode* l1 = <span class="keyword">new</span> ListNode(<span class="number">2</span>);</div><div class="line"> l1->next = <span class="keyword">new</span> ListNode(<span class="number">4</span>);</div><div class="line"> l1->next->next = <span class="keyword">new</span> ListNode(<span class="number">3</span>);</div><div class="line"></div><div class="line"> ListNode* l2 = <span class="keyword">new</span> ListNode(<span class="number">5</span>);</div><div class="line"> l2->next = <span class="keyword">new</span> ListNode(<span class="number">6</span>);</div><div class="line"> l2->next->next = <span class="keyword">new</span> ListNode(<span class="number">4</span>);</div><div class="line"> <span class="comment">//l2->next->next = new ListNode(7);</span></div><div class="line"></div><div class="line"> Solution s;</div><div class="line"> ListNode* result = s.addTwoNumbers(l1,l2);</div><div class="line"></div><div class="line"> <span class="keyword">while</span>(result)</div><div class="line"> {</div><div class="line"> <span class="built_in">cout</span> << result->val << <span class="built_in">endl</span>;</div><div class="line"> result = result->next;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="AddTwoNum"><a href="#AddTwoNum" class="headerlink" title="AddTwoNum"></a><a href="https://leetcode.com/problems/add-two-numbers/">AddTwoNum</a></h3><p>You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.</p>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/leetcode/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>算法导论--分治策略</title>
<link href="http://lennybai.cn/2016/12/12/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA-%E5%88%86%E6%B2%BB%E7%AD%96%E7%95%A5/"/>
<id>http://lennybai.cn/2016/12/12/算法导论-分治策略/</id>
<published>2016-12-12T02:09:14.000Z</published>
<updated>2016-12-14T00:51:53.498Z</updated>
<content type="html"><![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> 算法中有两个非常重要的思想分别是:分治策略和动态规划。它们通常可以将处理复杂的问题,转化为处理N个相关的子问题。通过这种方式,给予人们清晰的思路的同时,降低处理问题的难度。这一篇文章我们来介绍分治策略,并给出几个经典的算法来进行展示。</p>
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p> 分治策略中,往往是通过递归去求解问题,并在每层递归中应用如下三个步骤:</p>
<ol>
<li>分解:将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小。</li>
<li>解决:递归的求解子问题,如果子问题的规模足够小,则停止递归,直接求解。</li>
<li>合并:讲子问题的解组合成原问题的解。</li>
</ol>
<a id="more"></a>
<h1 id="算法举例"><a href="#算法举例" class="headerlink" title="算法举例"></a>算法举例</h1><p> 在上一篇文章里,我们看到的归并排序其实使用的就是分治思想。这里我们再列举两个常用的,并且使用分治思想的算法:堆排序和快速排序。</p>
<h2 id="堆排序"><a href="#堆排序" class="headerlink" title="堆排序"></a>堆排序</h2><p> 堆排序的时间复杂度为O(nlogn),并且所需的额外存储数量固定。堆通常使用数组进行存储,它可以被看成一个近似的完全二叉树,它的每一个节点对应着数组中的一个元素。接下来我们试着去实现堆排序。<br> 首先我们来理解一下最大堆。如果按照刚才我们所提到的,将堆看做成二叉树。那么如果是最大堆,其特点是A[PARENT(i)]>=A[i]。这个公示代表着,任何一个节点不大于其父节点。这里我们用伪代码表示一下父节点和左右子节点的关系。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">PARENT(i)</div><div class="line"> return [i/2]</div><div class="line">LEFT(i)</div><div class="line"> return 2i</div><div class="line">RIGHT(i)</div><div class="line"> return 2i+1</div></pre></td></tr></table></figure></p>
<p> 接下来我们讨论一下堆排序算法。堆排序的一个重要环节是调节堆。详细的说,比如我们目标是构建最大堆,在N个节点的树中总会有不满足最大堆要求的父子节点关系,那么我们就要进行调整。<br> 堆排序的第一个环节就是构建最大堆。这里我们假设某个节点的两个子节点都已经是最大树的根节点,在这种情况下,再对该节点进行调整是最容易的。所以我们构建最大堆的思路是先讲子树构建成最大堆,然后开始父节点构建。这样我们将会完成最大堆的构造。然而,这里大家一定要注意,最大堆构建完成并不代表着数组已经排序完成。比如(16,14,10,8,7,9,3)就是最大堆,但是并不是有序的。它只保证了其父节点不小于该节点。<br> 最后我们来完成排序工作。具体的步骤就是,讲根节点与最后一个节点交换,并从树种去除,然后对树进行调整。不断的迭代这个过程,完成最终的排序工作。<br> 这里开始为自己的表达能力感到捉急。我们还是来看伪代码吧。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">//第一步,调整堆</div><div class="line">MAX-HEAPIFY(A,i)</div><div class="line"> l = LEFT(i)</div><div class="line"> r = RIGHT(i)</div><div class="line"> largest = i</div><div class="line"> if l <= heapsize and A[l] > A[i]</div><div class="line"> largest = l</div><div class="line"> if r <= heapsize and A[r] > A[i]</div><div class="line"> largest = r</div><div class="line"> if largest != i</div><div class="line"> exchange(A[i],a[largest])</div><div class="line"> MAX-HEAPIFY(A,largest)</div></pre></td></tr></table></figure></p>
<p> 第一步,通过递归来调整以i为根节点的子树为最大堆。以此为基础,我们讲堆从子节点向上遍历,不断地调整子树为最大树来完成最大堆的构建。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">//第二步,构建最大堆</div><div class="line">BUILD-MAX-HEAP(A)</div><div class="line"> A.heapsize = A.length</div><div class="line"> for i = [A.length/2] downto 1</div><div class="line"> MAX-HEAPIFY(A,i)</div></pre></td></tr></table></figure></p>
<p> 在完成最大堆的构建之后,我们已经完成了堆排序最核心的两个步骤,那么我们现在完成堆排序。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">//堆排序</div><div class="line">HEAP-SORT(A)</div><div class="line"> BUILD-MAX-HEAP(A)</div><div class="line"> for i = A.length downto 2</div><div class="line"> exchange A[i] with a[i]</div><div class="line"> A.heapsize = A.heapsize-1</div><div class="line"> MAX-HEAPIFY(A,1)</div></pre></td></tr></table></figure></p>
<p> 锵锵锵锵,堆排序完成。</p>
<h2 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h2><p> 另一个使用分治思想的常用算法就是快速排序。快速排序的期望时间复杂度是O(nlogn)。但是最坏情况的时间复杂度又O(n*n)。虽然看起来最坏情况的时间复杂度很差,但是实际排序应用中它往往是最好的选择,因为它的平均性很好,而且O(nlogn)的常数因子非常小。<br> 快速排序的三步分治过程:</p>
<ol>
<li>分解: 将数组A[p..r],以A[q]为界换分为两个子数组,子数组可以为空,q可以自由选择。使得A[p..q-1]中的元素都小于A[q],A[q+1..r]中的元素都大于A[q]。</li>
<li>解决: 通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序</li>
<li>合并: 因为子数组都是原址排序,所以不需要合并操作:数组A[p..r]已经有序</li>
</ol>
<p> 来看具体的伪代码实现:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">PARTITION(A,p,r)</div><div class="line"> x = A[r]</div><div class="line"> i = p - 1</div><div class="line"> for j = p to r - 1</div><div class="line"> if A[j] <= x</div><div class="line"> i = i + 1</div><div class="line"> exchange A[i] with A[j]</div><div class="line"> exchage A[i+1] with A[r]</div><div class="line"> return i + 1</div></pre></td></tr></table></figure></p>
<p> 在快速排序中,PARTITION是非常关键的部分,它的作用有两个,第一个是选定界限值q,第二个就是对输入数组进行原址重排。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">QUICKSORT(A,p,r)</div><div class="line"> if p < r</div><div class="line"> q = PARTITION(A,p,r)</div><div class="line"> QUICKSORT(A,p,q-1)</div><div class="line"> QUICKSORT(A,q+1,r)</div></pre></td></tr></table></figure></p>
<p> 快速排序完成</p>
]]></content>
<summary type="html">
<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> 算法中有两个非常重要的思想分别是:分治策略和动态规划。它们通常可以将处理复杂的问题,转化为处理N个相关的子问题。通过这种方式,给予人们清晰的思路的同时,降低处理问题的难度。这一篇文章我们来介绍分治策略,并给出几个经典的算法来进行展示。</p>
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p> 分治策略中,往往是通过递归去求解问题,并在每层递归中应用如下三个步骤:</p>
<ol>
<li>分解:将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小。</li>
<li>解决:递归的求解子问题,如果子问题的规模足够小,则停止递归,直接求解。</li>
<li>合并:讲子问题的解组合成原问题的解。</li>
</ol>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/tags/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
<category term="分治策略" scheme="http://lennybai.cn/tags/%E5%88%86%E6%B2%BB%E7%AD%96%E7%95%A5/"/>
<category term="快速排序" scheme="http://lennybai.cn/tags/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F/"/>
<category term="堆排序" scheme="http://lennybai.cn/tags/%E5%A0%86%E6%8E%92%E5%BA%8F/"/>
</entry>
<entry>
<title>leetcode-two sum</title>
<link href="http://lennybai.cn/2016/12/09/leetcode-twosum/"/>
<id>http://lennybai.cn/2016/12/09/leetcode-twosum/</id>
<published>2016-12-09T07:56:03.000Z</published>
<updated>2016-12-12T09:19:30.138Z</updated>
<content type="html"><![CDATA[<h3 id="twoSum"><a href="#twoSum" class="headerlink" title="twoSum"></a><a href="https://leetcode.com/problems/two-sum/" target="_blank" rel="external">twoSum</a></h3><p>Given an array of integers, return indices of the two numbers such that they add up to a specific target.</p>
<p>You may assume that each input would have exactly one solution.</p>
<a id="more"></a>
<h3 id="example"><a href="#example" class="headerlink" title="example"></a>example</h3><blockquote>
<p>Given nums = [2, 7, 11, 15], target = 9,</p>
<p>Because nums[0] + nums[1] = 2 + 7 = 9,<br>return [0, 1].</p>
</blockquote>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p> 本题思路并不难。可以从第一个数开始遍历,与后面的所有剩余的数字进行加法运算,如果符合预期则返回。否则继续遍历。这里有一个很明显的问题就是增加了很多不必要的运算。算法时间复杂度较高。<br> 一个很巧妙的算法是通过map存储已经遍历过的数字。key存储其值,value存储其索引。通过对数字从头到尾遍历。计算目标值(target-当前值),并到map中查找,如果存在则返回,若不存在,将当前值存储到map中继续遍历。这样只需遍历一边数组就可完成整个算法。</p>
<h3 id="coding"><a href="#coding" class="headerlink" title="coding"></a>coding</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unordered_map></span></span></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> twoSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums, <span class="keyword">int</span> target)</div><div class="line"> {</div><div class="line"> <span class="built_in">unordered_map</span><<span class="keyword">int</span>,<span class="keyword">int</span>> record;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> result;</div><div class="line"> <span class="keyword">for</span>( <span class="keyword">int</span> i = <span class="number">0</span>; i < nums.size(); i++)</div><div class="line"> {</div><div class="line"> <span class="keyword">int</span> numberToFind = target - nums[i];</div><div class="line"> <span class="keyword">if</span>(record.find(numberToFind) != record.end())</div><div class="line"> {</div><div class="line"> result.push_back(record[numberToFind]);</div><div class="line"> result.push_back(i);</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"> record[nums[i]]=i;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"> Solution s;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> test = {<span class="number">2</span>,<span class="number">7</span>,<span class="number">11</span>,<span class="number">15</span>};</div><div class="line"> <span class="keyword">int</span> target = <span class="number">9</span>;</div><div class="line"></div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i : s.twoSum(test, target))</div><div class="line"> <span class="built_in">cout</span> << i << <span class="built_in">endl</span>;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><p><a href="https://github.com/geeklenny/leetcode" target="_blank" rel="external">github代码链接</a></p>
]]></content>
<summary type="html">
<h3 id="twoSum"><a href="#twoSum" class="headerlink" title="twoSum"></a><a href="https://leetcode.com/problems/two-sum/">twoSum</a></h3><p>Given an array of integers, return indices of the two numbers such that they add up to a specific target.</p>
<p>You may assume that each input would have exactly one solution.</p>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/leetcode/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="leetcode" scheme="http://lennybai.cn/tags/leetcode/"/>
</entry>
<entry>
<title>编程珠玑</title>
<link href="http://lennybai.cn/2016/12/06/%E7%BC%96%E7%A8%8B%E7%8F%A0%E7%8E%91/"/>
<id>http://lennybai.cn/2016/12/06/编程珠玑/</id>
<published>2016-12-06T02:27:32.000Z</published>
<updated>2016-12-23T06:02:51.835Z</updated>
<content type="html"><![CDATA[<h1 id="一、绪论"><a href="#一、绪论" class="headerlink" title="一、绪论"></a>一、绪论</h1><p> 编程珠玑是一本很有影响力的书籍。它是作者对自己在长期的计算机程序设计实践中积累下来的宝贵经验的总结。行文生动形象,可读性高。在美国,它被作为低年级数据结构与算法的教材,同时,也作为高年级的算法辅助教材。它涵盖了算法课程和数据结构课程的大部分内容。不同于其他教材,他不强调单纯的从数学上分析,而是强调结合实际问题进行分析、应用和实现。话不多说,开卷有益。<br><a id="more"></a></p>
<h1 id="二、概述"><a href="#二、概述" class="headerlink" title="二、概述"></a>二、概述</h1><p> 这是第二次翻开本书。虽然被很多人推荐,但阅读一遍后,我并没有抓到什么重点。这次边读边记录,希望能够做到讲本书融会贯通。主要是记录为主,可能每一段都没有核心,也可能上下文没有逻辑性,强迫症或者性情暴躁者,慎读。</p>
<h3 id="准确的问题描述"><a href="#准确的问题描述" class="headerlink" title="准确的问题描述"></a>准确的问题描述</h3><p> 在程序员的日常工作中,更多的工作更像是通过程序解决问题的过程。所以更好的描述问题,或者说是自己能够对需求更准确的转化成为问题,会对后续的程序设计帮助十足。将复杂的问题简单化,模块化。同时,能否准确的描述问题,也决定这你是否将要解决一个“正确”的问题。<br> 一般情况下,对问题的描述可以概括为三个方面:</p>
<blockquote>
<p>准确的输入 </p>
<p>准确的输出 </p>
<p>准确的约束条件</p>
</blockquote>
<h3 id="算法,灵机一动"><a href="#算法,灵机一动" class="headerlink" title="算法,灵机一动"></a>算法,灵机一动</h3><p> 先进的算法有时候对软件系统影响很大——减少开发时间,同时使得执行效率更快。在算法中所谓的灵机一动,看似是“看起来很困难的问题也可以有一个简单的、意想不到的答案”。算法的灵机一动,并非只有大量的研究以后才能出现,需要的是编程之前、之中和之后进行认真的思考。伴随着这种思考,往往就能捕获到这灵机一动。</p>
<h3 id="数据决定数据结构"><a href="#数据决定数据结构" class="headerlink" title="数据决定数据结构"></a>数据决定数据结构</h3><p> 恰当的数据视图实际上决定了程序的结构。通过重新组织内部数据是程序变得更好。在我们工作中,很多时候是可以用小程序完成任务的情况下,程序员往往最终写出了又大又纯的程序。其主要原因就是惰性:不去尝试思考,而急于完成最初的想法。<br> 程序员在节省空间方面无计可施时,将自己从代码中解脱出来,退回起点并集中心机去研究数据,常常会有奇效。数据的表示形式是程序设计的根本。退回起点的原则:</p>
<ol>
<li>使用数组代替重复的代码</li>
<li>封装复杂结构</li>
<li>尽可能使用高级工具</li>
<li>从数据得出程序结构</li>
</ol>
<h3 id="编写正确的程序"><a href="#编写正确的程序" class="headerlink" title="编写正确的程序"></a>编写正确的程序</h3><p> 必须引起注意的是,编程技巧仅仅是编写正确程序的很小一部分,大部分内容还是:问题定义、算法设计和数据结构的选择。遵循这几点的话,编写正常的程序通常是很容易的。除此之外,要记得使用测试用例和断言等去验证程序的正确性。</p>
<h3 id="让编写的程序真正可用"><a href="#让编写的程序真正可用" class="headerlink" title="让编写的程序真正可用"></a>让编写的程序真正可用</h3><p> 程序员都是乐观主义者,他们总是认为讲编写完的程序,插入系统中就可以正常运行。在大部分时间是可行的,但是有的时候确实灾难性的存在,我们不得不需要在庞大的系统中,去寻找这个错误的小小的程序。<br> 良好的使用断言,可以知道程序的开发,同时也可以用来判断程序的正确性。这里作者提到了一个对于断言使用的一个小嘲讽:在测试时使用断言,而产品发布时将断言关闭的程序员,就好比在岸上操练时穿着救生衣,而下海时将救生衣脱下的水手。<br> 为了程序的可用性,往往自动测试和时间计数也显得至关重要。具有完整且完善边界测试用例能够保证程序的准确性,而且可以提高测试效率。同时,时间计数可以直观的观察程序的运行时间复杂度。</p>
<h3 id="来聊聊性能"><a href="#来聊聊性能" class="headerlink" title="来聊聊性能"></a>来聊聊性能</h3><p> 一个简单而又功能强大的程序,往往令用户欣喜而不令开发者烦恼,这是程序的终极目标。而其中一个重要的元素就是效率。低效率的程序往往令用户沮丧。等待的时间越长,也就意味着越高的概率会失去用户。而如何提高效率我们往往考虑以下途径:</p>
<ol>
<li>通过积累经验,选择恰当的方法</li>
<li>粗略估算运行时间</li>
<li>算法设计</li>
<li>代码调优</li>
</ol>
<h3 id="性能分析"><a href="#性能分析" class="headerlink" title="性能分析"></a>性能分析</h3><p> 而在真正进行效率优化的时候,从计算机系统的层面我们应该从以下方面进行:</p>
<ol>
<li>问题定义</li>
<li>系统结构:模块化;性能分析在系统设计阶段至关重要</li>
<li>算法和数据结构:快速的模块是基于其良好的表示的数据结构和操纵这些数据结构的算法</li>
<li>代码调优</li>
<li>系统软件</li>
<li>硬件</li>
</ol>
<h3 id="粗略评估"><a href="#粗略评估" class="headerlink" title="粗略评估"></a>粗略评估</h3><blockquote>
<p> 任何事都应尽量简单,但不易于过于简单 —— 爱因斯坦</p>
</blockquote>
<p> 我们知道简单的计算并不简单,因为我们为了补偿估算参数时的错误和对问题的了解不足,我们往往会选定和包含安全系数。</p>
<h3 id="算法设计技术"><a href="#算法设计技术" class="headerlink" title="算法设计技术"></a>算法设计技术</h3><p> 几个重要的算法设计技术</p>
<ol>
<li>保存状态,避免重复计算</li>
<li>将信息预处理至数据结构中</li>
<li>分治算法</li>
<li>扫描算法</li>
<li>累加算法</li>
<li>下界</li>
</ol>
<h3 id="代码调优"><a href="#代码调优" class="headerlink" title="代码调优"></a>代码调优</h3><p> 代码调优很重要的一点是把握调优的尺度。有些程序猿过于关注程序的效率,由于太在乎细小的“优化”,它们编写出的程序过于精妙,难以维护。而一些程序员很少关注程序的效率,它们编写的程序有着清晰漂亮的结构,但效率极低以至于毫无用处。往往获取更多的可用内存空间,需要在程序的性能、功能或者可维护性上做出牺牲,所以优化的前提永远是正确的决策。<br> 代码调优是一个在程序中需要做整体考虑的工作项目,但其根本目的是解决程序中开销过大的部分,对其进行少量修改,以提高运行效率。所谓开销包括CPU时间和程序存储空间。<br> 作者在文中给出了代码调优的原理:</p>
<blockquote>
<p>代码调优的最重要远离就是尽量少用它 </p>
<ol>
<li>效率的角色: 没有坏的话就不要修</li>
<li>设计层面: 只有确定没有更好的解决方案时,才考虑进行代码调优</li>
<li>双刃剑</li>
</ol>
</blockquote>
<h3 id="节省空间"><a href="#节省空间" class="headerlink" title="节省空间"></a>节省空间</h3><p> 努力的考虑一下空间紧凑的程序是很有意义的。在节省空间的同时,我们往往会得到运行时间上产生的副作用:程序小意味着加载更快,也更容易填入高速缓存中,操作的数据变少意味着操作时间变少等等。<br> 简单性可以衍生出功能性、健壮性以及速度和空间。<br> 这里列出一些较少程序所需数据的存储空间的技术:</p>
<ol>
<li>不存储、重新计算</li>
<li>稀疏数据结构</li>
<li>数据压缩</li>
<li>分配策略</li>
<li>垃圾回收</li>
</ol>
<h3 id="排序"><a href="#排序" class="headerlink" title="排序"></a>排序</h3><p> 将一些列记录排成有序的,最后也是最容易的办法就是使用排序函数库。但是并非总是有效的,这时我们别无选择,只能编写自己的排序函数。</p>
<h3 id="堆"><a href="#堆" class="headerlink" title="堆"></a>堆</h3><p> 采用堆排序不会超过O(nlogn),并且只需要几个额外的字节。</p>
<hr>
<h1 id="写到最后"><a href="#写到最后" class="headerlink" title="写到最后"></a>写到最后</h1><p> 读者用实践和经验去讲述程序中的问题,其实也是对我们工作和学习方法的一种提示。勿要死读书,读死书,要结合实际灵活运用。</p>
]]></content>
<summary type="html">
<h1 id="一、绪论"><a href="#一、绪论" class="headerlink" title="一、绪论"></a>一、绪论</h1><p> 编程珠玑是一本很有影响力的书籍。它是作者对自己在长期的计算机程序设计实践中积累下来的宝贵经验的总结。行文生动形象,可读性高。在美国,它被作为低年级数据结构与算法的教材,同时,也作为高年级的算法辅助教材。它涵盖了算法课程和数据结构课程的大部分内容。不同于其他教材,他不强调单纯的从数学上分析,而是强调结合实际问题进行分析、应用和实现。话不多说,开卷有益。<br>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="编程珠玑" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/%E7%BC%96%E7%A8%8B%E7%8F%A0%E7%8E%91/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="编程珠玑" scheme="http://lennybai.cn/tags/%E7%BC%96%E7%A8%8B%E7%8F%A0%E7%8E%91/"/>
</entry>
<entry>
<title>网站浏览记录</title>
<link href="http://lennybai.cn/2016/12/05/%E7%BD%91%E7%AB%99%E6%B5%8F%E8%A7%88%E8%AE%B0%E5%BD%95/"/>
<id>http://lennybai.cn/2016/12/05/网站浏览记录/</id>
<published>2016-12-05T07:04:18.000Z</published>
<updated>2017-10-13T08:56:20.595Z</updated>
<content type="html"><![CDATA[<p> 我习惯每天花上一些时间,根据今天的疑问去搜索一些博客读一读。经常会看到一些让人为之振奋的讲解,但也因为读的多读的泛,让自己很难记起某些知识点的具体位置。这让自己想再次翻阅的时候很是焦灼。现在想想何不记录一番,方便以后查阅呢?</p>
<a id="more"></a>
<h3 id="大型网站架构"><a href="#大型网站架构" class="headerlink" title="大型网站架构"></a>大型网站架构</h3><ol>
<li><a href="http://www.cnblogs.com/elves/p/4259188.html" target="_blank" rel="external">大型网站改进历程</a></li>
<li><a href="http://www.cnblogs.com/itfly8/p/5006197.html" target="_blank" rel="external">大型网站架构案例</a></li>
</ol>
<h3 id="数据库缓存"><a href="#数据库缓存" class="headerlink" title="数据库缓存"></a>数据库缓存</h3><ol>
<li><a href="http://www.360sdn.com/architect/2015/0504/8691.html" target="_blank" rel="external">mysql+memcached</a></li>
<li><a href="http://www.voidcn.com/blog/bantiaomichong/article/p-6158870.html" target="_blank" rel="external">mysql+redis</a></li>
<li><a href="http://storage.ctocio.com.cn/394/12737894.shtml" target="_blank" rel="external">redis应用</a></li>
</ol>
<h3 id="编程珠玑"><a href="#编程珠玑" class="headerlink" title="编程珠玑"></a>编程珠玑</h3><ol>
<li><a href="http://www.hawstein.com/posts/make-thiner-programming-pearls.html" target="_blank" rel="external">把编程珠玑读薄</a></li>
<li><a href="http://mingyangshang.github.io/2016/01/01/%E7%BC%96%E7%A8%8B%E7%8F%A0%E7%8E%91/" target="_blank" rel="external">编程珠玑</a></li>
</ol>
<h3 id="elasticsearch"><a href="#elasticsearch" class="headerlink" title="elasticsearch"></a>elasticsearch</h3><ol>
<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" target="_blank" rel="external">官方文档</a></li>
<li><a href="http://udn.yyuap.com/doc/mastering-elasticsearch/index.html" target="_blank" rel="external">mastering elasticsearch(中文版)</a></li>
</ol>
<h3 id="机器学习"><a href="#机器学习" class="headerlink" title="机器学习"></a>机器学习</h3><ol>
<li><a href="http://www.aboutyun.com/thread-19304-1-1.html" target="_blank" rel="external">用户在线广告点击行为预测的深度学习模型</a></li>
<li><a href="http://blog.csdn.net/han_xiaoyang/article/details/50469334" target="_blank" rel="external">机器学习算法</a></li>
<li><a href="https://www.zhihu.com/question/26726794" target="_blank" rel="external">机器学习算法及其应用场景</a></li>
<li><a href="http://download.csdn.net/detail/jkhere/6438773" target="_blank" rel="external">机器学习十大算法</a></li>
</ol>
<h3 id="CAS-SSO"><a href="#CAS-SSO" class="headerlink" title="CAS SSO"></a>CAS SSO</h3><ol>
<li><a href="http://blog.csdn.net/zhurhyme/article/category/2362091/3" target="_blank" rel="external">cas入门</a></li>
</ol>
]]></content>
<summary type="html">
<p> 我习惯每天花上一些时间,根据今天的疑问去搜索一些博客读一读。经常会看到一些让人为之振奋的讲解,但也因为读的多读的泛,让自己很难记起某些知识点的具体位置。这让自己想再次翻阅的时候很是焦灼。现在想想何不记录一番,方便以后查阅呢?</p>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="网站地址" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/%E7%BD%91%E7%AB%99%E5%9C%B0%E5%9D%80/"/>
<category term="网址推荐" scheme="http://lennybai.cn/tags/%E7%BD%91%E5%9D%80%E6%8E%A8%E8%8D%90/"/>
<category term="学习笔记" scheme="http://lennybai.cn/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>effective c++小记</title>
<link href="http://lennybai.cn/2016/12/02/effective-c-%E5%B0%8F%E8%AE%B0/"/>
<id>http://lennybai.cn/2016/12/02/effective-c-小记/</id>
<published>2016-12-02T08:51:35.000Z</published>
<updated>2016-12-06T02:30:28.958Z</updated>
<content type="html"><![CDATA[<p>more effective c++</p>
]]></content>
<summary type="html">
<p>more effective c++</p>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="more effective c++" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/more-effective-c/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="more effective c++" scheme="http://lennybai.cn/tags/more-effective-c/"/>
</entry>
<entry>
<title>算法导论(1)——写好伪代码</title>
<link href="http://lennybai.cn/2016/12/02/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA1/"/>
<id>http://lennybai.cn/2016/12/02/算法导论1/</id>
<published>2016-12-02T08:51:00.000Z</published>
<updated>2016-12-19T02:01:53.945Z</updated>
<content type="html"><![CDATA[<p> 在学习各种编程语言的时候,数据结构与算法一般都会作为重点课程来指出。而谈到算法,算法导论一书又常常被大家提起。然而作为一个编程界的老鸟,技术层面的菜鸟,最近才开始啃算法导论,实属令自己汗颜。不过拾起总比放下的要好,所以这里根据自己的理解做一些记录。并在阅读初期就设定了一些目标,包括理解并学习各种常用算法及其设计思路,<strong><em>学习并写好伪代码</em></strong>等。</p>
<a id="more"></a>
<h3 id="什么是算法"><a href="#什么是算法" class="headerlink" title="什么是算法"></a>什么是算法</h3><p> 书中讲到,算法就是任何良定义的计算过程。算法的目的是解决问题。问题陈述说明了期望的输入和输出,而算法则描述一个特定的计算过程来实现输入输出的关系。</p>
<h3 id="算法的描述(伪代码)"><a href="#算法的描述(伪代码)" class="headerlink" title="算法的描述(伪代码)"></a>算法的描述(伪代码)</h3><p> 算法可以使用英语说明,也可以用中文说明,当然也可以说明成计算机程序。它的唯一要求是这个说明必须精确的描述所需要遵循的计算过程。<br> 我个人更欣赏将算法描述为用一种伪代码书写的程序。它的优势在于,能够使用最清晰最简洁的方法来说明给定的算法。并且根据伪代码可以将算法转化成各种所需的编程语言。</p>
<h3 id="如何写好伪代码"><a href="#如何写好伪代码" class="headerlink" title="如何写好伪代码"></a>如何写好伪代码</h3><p> 在我们常用的编程语言中,通常按照所需的命名规范和运算逻辑的使用,讲所想的用该语言展示出来。伪代码同样也可以按照相似的方法展示。其实伪代码并没有明确的规范要求,但是在算法导论一书中,他列出了一些所谓的约定。当然,这些约定我们可以不去遵守。但是如果按着约定去书写伪代码的话,会使我们的伪代码变得清晰易懂,何乐不为。</p>
<ul>
<li>缩进表示块结构。参考python的语言结构。 </li>
<li>while,for,if-else等结构具有和c语言等相同的解释。但是方便理解,我们去除额外的细节,表示重点。比如当一个for循环时,当循环上升时使用to,下降时使用downto,步数使用by。</li>
<li>//表示注释</li>
<li>变量直接使用无需声明。一般变量默认为局部变量。</li>
<li>数据访问通过数组名和下标的方式访问。</li>
<li>使用error表示过程中出现错误。</li>
</ul>
<p> 伪代码的使用方法和约定都比较宽松,目的都是能够写出清晰易懂的伪代码。</p>
<h3 id="伪代码实践"><a href="#伪代码实践" class="headerlink" title="伪代码实践"></a>伪代码实践</h3><p> 这里列举一个插入排序的算法的伪代码实现,大家一起来感受一下气场。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">INSERT-SORT(A)</div><div class="line"> for j=2 to A.length</div><div class="line"> key=A[j]</div><div class="line"> // Insert A[j] into the sorted sequence A[1..j-1].</div><div class="line"> i = j-1;</div><div class="line"> while i>0 and A[i]>key</div><div class="line"> A[i+1]=A[j]</div><div class="line"> i = i-1</div><div class="line"> A[i+1]=key</div></pre></td></tr></table></figure></p>
<h3 id="归并排序-merge-sort"><a href="#归并排序-merge-sort" class="headerlink" title="归并排序(merge sort)"></a>归并排序(merge sort)</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line">MERGE(A,p,q,r)</div><div class="line"> n1=q-p+1</div><div class="line"> n2=r-q</div><div class="line"> let L[0..n1] and R[0..n2] be a new array</div><div class="line"> for i = 0 to n1-1</div><div class="line"> L[i]=A[p+i]</div><div class="line"> for j = 0 to n2-1</div><div class="line"> R[j]=A[q+1+j]</div><div class="line"> L[n1]=∞</div><div class="line"> L[n2]=∞</div><div class="line"> i=0</div><div class="line"> j=0</div><div class="line"> for k = p to r</div><div class="line"> if L[i] < R[j]</div><div class="line"> A[k]=L[i]</div><div class="line"> i = i + 1</div><div class="line"> else</div><div class="line"> A[k]=R[j]</div><div class="line"> j = j +1</div><div class="line"></div><div class="line">MERGE-SORT(A,p,r)</div><div class="line"> if(p<r)</div><div class="line"> q=[(p+r)/2]</div><div class="line"> MERGE-SORT(A,p,q)</div><div class="line"> MERGE-SORT(A,q+1,r)</div><div class="line"> MERGE(A,p,q,r)</div></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<p> 在学习各种编程语言的时候,数据结构与算法一般都会作为重点课程来指出。而谈到算法,算法导论一书又常常被大家提起。然而作为一个编程界的老鸟,技术层面的菜鸟,最近才开始啃算法导论,实属令自己汗颜。不过拾起总比放下的要好,所以这里根据自己的理解做一些记录。并在阅读初期就设定了一些目标,包括理解并学习各种常用算法及其设计思路,<strong><em>学习并写好伪代码</em></strong>等。</p>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
<category term="读书笔记" scheme="http://lennybai.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="算法导论" scheme="http://lennybai.cn/tags/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
</entry>
<entry>
<title>elasticsearch上手练</title>
<link href="http://lennybai.cn/2016/12/02/elasticsearch%E4%B8%8A%E6%89%8B%E7%BB%83/"/>
<id>http://lennybai.cn/2016/12/02/elasticsearch上手练/</id>
<published>2016-12-02T08:50:07.000Z</published>
<updated>2016-12-20T03:03:11.121Z</updated>
<content type="html"><![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> elasticsearch现在在企业应用中很是火爆。快速日志检索,简单高校的分布式支持等等都是它的优势所在。ELK的组合使用也是经典的使用场景。<br><a id="more"></a></p>
<h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><p> elasticsearch的官方文档非常清晰,不论是对其原理的介绍,还有api的讲解。希望大家还是耐心阅读一番。除此之外,这里还有一个我看到的中文版本的连接,有作者的自己思考,也很不错。</p>
<ol>
<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" target="_blank" rel="external">elasticsearch官方文档</a></li>
<li><a href="http://udn.yyuap.com/doc/mastering-elasticsearch/index.html" target="_blank" rel="external">Mastering Elasticsearch(中文版)</a></li>
</ol>
<h1 id="我的实践"><a href="#我的实践" class="headerlink" title="我的实践"></a>我的实践</h1><p> <a href="https://github.com/geeklenny/elasticsearch-restful-javaee-spring-django-rabitmq" target="_blank" rel="external">实践代码</a><br> 这里我提供了一个简单的elasticsearch的实现。主要是通过spring实现了一套restful的后台接口。后台使用elasticsearch进行持久化。同时,使用django提供了一套前端系统。实现比较粗糙,跪在理解和使用练习。</p>
]]></content>
<summary type="html">
<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p> elasticsearch现在在企业应用中很是火爆。快速日志检索,简单高校的分布式支持等等都是它的优势所在。ELK的组合使用也是经典的使用场景。<br>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="elasticsearch" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/elasticsearch/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="elasticsearch" scheme="http://lennybai.cn/tags/elasticsearch/"/>
</entry>
<entry>
<title>数据库线程池(c++)</title>
<link href="http://lennybai.cn/2016/12/02/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0(c++)/"/>
<id>http://lennybai.cn/2016/12/02/数据库连接池(c++)/</id>
<published>2016-12-02T08:48:44.000Z</published>
<updated>2016-12-19T08:55:37.869Z</updated>
<content type="html"><![CDATA[<h1 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h1><p> 对于每一次的数据库访问,都需要有一个承载该次访问操作的数据库连接。现在的应用系统往往伴随着大量的数据库访问。可想而知,如果频繁的建立和关闭链接,会极大的降低系统的性能。</p>
<p> 数据库连接池是针对数据库连接的性能优化而产生的。它的核心思想是连接复用,并通过连接池高效并安全的维护连接池内的连接,并按需分配到各个调用者,以减少重复创建和删除连接造成的系统资源浪费。</p>
<a id="more"></a>
<h2 id="1-1-源代码链接"><a href="#1-1-源代码链接" class="headerlink" title="1.1 源代码链接"></a>1.1 源代码链接</h2><p><a href="https://github.com/geeklenny/databaseConnPool" target="_blank" rel="external">数据库连接池</a></p>
<h1 id="二、源代码讲解"><a href="#二、源代码讲解" class="headerlink" title="二、源代码讲解"></a>二、源代码讲解</h1><p> 希望你已经下载了源代码,这里开始对源代码进行讲解。这一份源代码我并没有做过多的性能测试,只是按照数据库连接池的基本思想和原理提供的一份实现。我希望这篇文章可以覆盖到数据库连接池的核心内容。</p>
<h2 id="2-1-连接池只是连接池"><a href="#2-1-连接池只是连接池" class="headerlink" title="2.1 连接池只是连接池"></a>2.1 连接池只是连接池</h2><p> 我们编写连接池的目的是用来维护连接,减少系统资源浪费。所以我们避免将连接池设计和实现成通用的带数据库连接优化的数据库访问类。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> T></div><div class="line"><span class="keyword">class</span> CommonDbConnPool{...}</div></pre></td></tr></table></figure>
<p> 我们使用模板类来弱化数据库的具体类型,而更关系如何去维护其链接。对于具体的数据库操作,还是沿用使用的数据库提供的接口去访问。记住,数据库连接池只提供可用的连接,或者无可用连接时的错误提示。</p>
<h2 id="2-2-连接的初始化"><a href="#2-2-连接的初始化" class="headerlink" title="2.2 连接的初始化"></a>2.2 连接的初始化</h2><p> 提高数据库链接的初始化,核心的问题是启动多少连接合适。启动太少,不能满足应用的需求;启动太多,对系统资源也是一种浪费。实际上,在什么样配置的服务器上,启动多少个连接合适并没有一个明确的参考数据。它们都需要进行测试,调整到最优的连接数。<br> 这里提供一个普遍适用于连接池的方法。它可以尽可能的保证系统资源的合理使用。这个方法是通常提供一个最小连接数和最大连接数。最小连接数为启动时默认启动的链接数目。如果最小连接数在被完全使用的时候,又进入一个新连接,那么连接池将为它新建一个连接。新建连接的前提是,连接总数没有超过最大连接数。否则返回连接池已满类似的错误信息。超出最小连接数的这些连接,会被定期回收释放。<br> 初始化的同时,启动监控线程,用于定期检测连接是否正常连接。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> T></div><div class="line"><span class="keyword">int</span> CommonDbConnPool<T>::InitPool( <span class="keyword">int</span> minConn, <span class="keyword">int</span> maxConn )</div><div class="line">{</div><div class="line"> ...</div><div class="line"> ...</div><div class="line"> <span class="keyword">for</span> ( <span class="keyword">int</span> i =<span class="number">0</span> ; i < minConn; i++ )</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( (t = createDBConn()) != <span class="literal">nullptr</span> )</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( (bConnectionAvilable(t)) )</div><div class="line"> {</div><div class="line"> m_poolMap[t] = DB_CONN_FREE;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> releaseDBConn(t);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> ...</div><div class="line"> ...</div><div class="line"> <span class="function">thread <span class="title">th</span><span class="params">(&CommonDbConnPool<T>::PoolConnMonitor, <span class="keyword">this</span>)</span></span>;</div><div class="line"> swap(th, m_trdConnMonitor);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="2-3-连接的管理"><a href="#2-3-连接的管理" class="headerlink" title="2.3 连接的管理"></a>2.3 连接的管理</h2><p> 存在与连接池中的连接有三种状态。空闲,占用和临时连接。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">enum</span> DBCONNSTATS</div><div class="line">{</div><div class="line"> DB_CONN_FREE,</div><div class="line"> DB_CONN_USED,</div><div class="line"> DB_CONN_TEMP_USED</div><div class="line"></div><div class="line">};</div></pre></td></tr></table></figure></p>
<p> 最小连接数内的连接,初始化为free,占用时为used。而超过最小链接,并未超过最大连接数的这些连接为临时连接,定期会被回收。当然什么时候回收由你来定,我的是现实,当连接被用户释放回连接池时,直接回收。很多的数据库连接池对于临时连接处理会巧妙的多。比如超过最小链接后,扩容一倍等等。<br> <strong>需要强调的一点是,为了保证多线程的安全访问,请记得加锁。</strong></p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">template</span> <<span class="keyword">typename</span> T></div><div class="line">T* CommonDbConnPool<T>::GetDBConnFromPool()</div><div class="line">{</div><div class="line"> ...</div><div class="line"> lock_guard<mutex> locker(m_mtxPool);</div><div class="line"> ...</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">auto</span> &iter : m_poolMap)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>(iter.second == DB_CONN_FREE){</div><div class="line"> iter.second = DB_CONN_USED;</div><div class="line"> t = iter.first;</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (t == <span class="literal">nullptr</span>){</div><div class="line"> <span class="keyword">if</span>(m_poolMap.size() < m_maxConn)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( (t = createDBConn()) != <span class="literal">nullptr</span> )</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( (bConnectionAvilable(t)) )</div><div class="line"> {</div><div class="line"> m_poolMap[t] = DB_CONN_TEMP_USED;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> releaseDBConn(t);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> t;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> <<span class="keyword">typename</span> T></div><div class="line"><span class="keyword">void</span> CommonDbConnPool<T>::ReleaseDbConnToPool(T* t)</div><div class="line">{</div><div class="line"> lock_guard<mutex> locker(m_mtxPool);</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> &iter : m_poolMap)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>(iter.first == t)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>(iter.second == DB_CONN_USED)</div><div class="line"> {</div><div class="line"> iter.second = DB_CONN_FREE;</div><div class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (iter.second == DB_CONN_TEMP_USED)</div><div class="line"> {</div><div class="line"> releaseDBConn(iter.first);</div><div class="line"> m_poolMap.erase(iter.first);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="2-4-释放连接池"><a href="#2-4-释放连接池" class="headerlink" title="2.4 释放连接池"></a>2.4 释放连接池</h2><p> 释放连接也应该人性化,比如某个应用还在使用连接进行着访问,那我们不应该直接关闭该链接。<br> 我这里的处理是,关闭所有free的链接。并返回池内连接的大小。如果返回不为0,那么就相当于通知用户,连接并没有完全被释放,你还需要再次调用。<br> 别忘了我们还有一个监控线程在运行着呢。别忘了结束线程。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">template</span> <<span class="keyword">typename</span> T></div><div class="line"><span class="keyword">void</span> CommonDbConnPool<T>::PoolConnMonitor(){</div><div class="line"> ...</div><div class="line"> <span class="keyword">while</span>(ptrPool->m_bPoolAvailable && ! ptrPool->m_bPoolToDestroy)</div><div class="line"> {</div><div class="line"> ...</div><div class="line"> [&](){</div><div class="line"> unique_lock<mutex> lk(ptrPool->m_mtxCv);</div><div class="line"> ptrPool->m_Cv.wait_for(lk, chrono::milliseconds(ptrPool->ulTimeForCheckTimeout()));</div><div class="line"> }();</div><div class="line"> ...</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">template</span> <<span class="keyword">typename</span> T></div><div class="line"><span class="keyword">int</span> CommonDbConnPool<T>::DestroyPool(){</div><div class="line"> ...</div><div class="line"> <span class="keyword">for</span>( <span class="keyword">auto</span> &iter : m_poolMap)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span>( iter.second == DB_CONN_FREE)</div><div class="line"> {</div><div class="line"> releaseDBConn(iter.first);</div><div class="line"> m_poolMap.erase(iter.first);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> ...</div><div class="line"> ...</div><div class="line"> ptrPool->m_bPoolToDestroy = <span class="literal">true</span>;</div><div class="line"> m_Cv.notify_one();</div><div class="line"> m_trdConnMonitor.join();</div><div class="line"></div><div class="line"> ...</div><div class="line"> <span class="keyword">return</span> m_poolMap.size();</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="三、使用"><a href="#三、使用" class="headerlink" title="三、使用"></a>三、使用</h1><p> 我这里使用了mysqlcppconn的库,如果需要请自行安装下载。<br> <figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"./mysql/mysqlConn.h"</span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></div><div class="line">{</div><div class="line"></div><div class="line"> MysqlConn* mysqlpool;</div><div class="line"> <span class="keyword">try</span>{</div><div class="line"></div><div class="line"> <span class="keyword">do</span>{</div><div class="line"></div><div class="line"> <span class="comment">//连接数据库</span></div><div class="line"> mysqlpool = <span class="keyword">new</span> MysqlConn(<span class="string">"localhost"</span>, <span class="string">"root"</span>, <span class="string">"Passw0rd"</span>);</div><div class="line"></div><div class="line"> <span class="comment">//创建数据库连接池,并返回大小</span></div><div class="line"> <span class="built_in">cout</span> << <span class="string">" mysqlpool size : "</span> << mysqlpool->InitPool(<span class="number">10</span>,<span class="number">20</span>) << <span class="built_in">endl</span>;</div><div class="line"></div><div class="line"> sql::Connection *con;</div><div class="line"> sql::Statement* stmt;</div><div class="line"> sql::ResultSet* res;</div><div class="line"></div><div class="line"> <span class="comment">//获取一个连接</span></div><div class="line"> <span class="keyword">if</span>((con=mysqlpool->GetDBConnFromPool())==<span class="literal">nullptr</span>){</div><div class="line"> <span class="built_in">cout</span><<<span class="string">"reach the max availd"</span> << <span class="built_in">endl</span>;</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//执行语句</span></div><div class="line"> con->setSchema(<span class="string">"mysql"</span>);</div><div class="line"> stmt = con->createStatement();</div><div class="line"> res = stmt->executeQuery(<span class="string">"select * from user"</span>);</div><div class="line"></div><div class="line"> <span class="comment">//打印数据库连接池信息</span></div><div class="line"> <span class="built_in">cout</span><<(*mysqlpool);</div><div class="line"></div><div class="line"> <span class="comment">//释放连接到连接池</span></div><div class="line"> mysqlpool->ReleaseDbConnToPool(con);</div><div class="line"></div><div class="line"> <span class="comment">//打印数据库连接池信息</span></div><div class="line"> <span class="built_in">cout</span><<(*mysqlpool);</div><div class="line"> <span class="built_in">cin</span>.get();</div><div class="line"></div><div class="line"> } <span class="keyword">while</span>(<span class="literal">false</span>);</div><div class="line"> <span class="comment">//销毁数据库连接池</span></div><div class="line"> <span class="keyword">if</span>(mysqlpool->DestroyPool()><span class="number">0</span>){</div><div class="line"> <span class="built_in">cout</span><<<span class="string">"There are still some un-release connections in the pool\n"</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">delete</span> mysqlpool;</div><div class="line"></div><div class="line"> }<span class="keyword">catch</span>(sql::SQLException &e){</div><div class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span><<e.what();</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<h1 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h1><p> 对于每一次的数据库访问,都需要有一个承载该次访问操作的数据库连接。现在的应用系统往往伴随着大量的数据库访问。可想而知,如果频繁的建立和关闭链接,会极大的降低系统的性能。</p>
<p> 数据库连接池是针对数据库连接的性能优化而产生的。它的核心思想是连接复用,并通过连接池高效并安全的维护连接池内的连接,并按需分配到各个调用者,以减少重复创建和删除连接造成的系统资源浪费。</p>
</summary>
<category term="程序设计" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="数据库连接池" scheme="http://lennybai.cn/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0/"/>
<category term="程序设计" scheme="http://lennybai.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="c++" scheme="http://lennybai.cn/tags/c/"/>
<category term="数据库连接池" scheme="http://lennybai.cn/tags/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0/"/>
</entry>
<entry>
<title>redis学习之参考文档</title>
<link href="http://lennybai.cn/2016/12/02/redis%E5%AD%A6%E4%B9%A0%E4%B9%8B%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3/"/>
<id>http://lennybai.cn/2016/12/02/redis学习之参考文档/</id>
<published>2016-12-02T02:21:38.000Z</published>
<updated>2016-12-13T08:28:04.673Z</updated>
<content type="html"><![CDATA[<h1 id="1-认识redis"><a href="#1-认识redis" class="headerlink" title="1. 认识redis"></a>1. 认识redis</h1><p> redis是一个key-value的存储系统。它支持网络、可基于内存亦可持久化的日志型、key-value数据库。value值可支持string,map,list,sets和sorted sets等类型。<br> 详细的说,redis相对其它key-value缓存产品(如memcached)有三个特点:</p>
<ul>
<li>支持持久化,可将内存中的数据保持到磁盘中,重启时可再次加载进行使用。</li>
<li>不仅仅支持简单的key-value类型的数据,同事还提供list,set,zset,hash等数据结构的存储</li>
<li>支持数据备份,master-slave模式</li>
</ul>
<a id="more"></a>
<p> 除此之外,redis还具备一下特点:</p>
<ul>
<li>极高的性能: 读110000次/s, 写的速度81000次/s</li>
<li>丰富的数据类型</li>
<li>原子性:所有操作都是原子性的。</li>
<li>丰富的特性: 支持通知、key过期,publish/subscribe等</li>
</ul>
<h1 id="2-使用redis"><a href="#2-使用redis" class="headerlink" title="2.使用redis"></a>2.使用redis</h1><p> 对于一个工具,我们更关心的是如何使用。这里我从官方的文档中摘录出一些我自己比较感性去的部分罗列与此。和大家分享。</p>
<h2 id="2-1-配置Redis"><a href="#2-1-配置Redis" class="headerlink" title="2.1 配置Redis"></a>2.1 配置Redis</h2><p> 如何正确的使用配置文件,有利于我们更好的使用redis。这里我们认识一下常用命令。我安装了redis-cli,这里直接使用。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">lennybai@lennybai:~$ redis-cli</div><div class="line">127.0.0.1:6379> CONFIG GET loglevel</div><div class="line">1) <span class="string">"loglevel"</span></div><div class="line">2) <span class="string">"notice"</span></div><div class="line">127.0.0.1:6379> config get *</div><div class="line"> 1) <span class="string">"dbfilename"</span></div><div class="line"> 2) <span class="string">"dump.rdb"</span></div><div class="line"> 3) <span class="string">"requirepass"</span></div><div class="line"> 4) <span class="string">""</span></div><div class="line"> 5) <span class="string">"masterauth"</span></div><div class="line"> 6) <span class="string">""</span></div><div class="line"> 7) <span class="string">"unixsocket"</span></div><div class="line"> 8) <span class="string">""</span></div><div class="line"> 9) <span class="string">"logfile"</span></div><div class="line"> 10) <span class="string">"/var/log/redis/redis-server.log"</span></div><div class="line"> 11) <span class="string">"pidfile"</span></div><div class="line">..........后面省略</div></pre></td></tr></table></figure></p>
<p> 我们可以通过config get key获取配置文件中某项配置的值。并可以通过config set config_string_name new_config_value来更新其值。<br> 下面对一些常用的配置项进行说明:</p>
<table>
<thead>
<tr>
<th>命令</th>
<th> 说明 </th>
</tr>
</thead>
<tbody>
<tr>
<td>daemonize</td>
<td>是否设为守护进程</td>
</tr>
<tr>
<td>pidfile</td>
<td>设置守护进程pid存储文件的位置</td>
</tr>
<tr>
<td>port</td>
<td>指定redis端口(默认6379)</td>
</tr>
<tr>
<td>databases</td>
<td>设置redis内置数据库的数量。通过select切换</td>
</tr>
<tr>
<td>save</td>
<td>指定同步到文件的规则</td>
</tr>
<tr>
<td>maxclient</td>
<td>最大客户连接数,0为不设限制</td>
</tr>
<tr>
<td>maxmemory</td>
<td>最大分配内存</td>
</tr>
</tbody>
</table>
<p>对于命令还有很多,大家可以在需要时自行查看。</p>
<h2 id="2-2-redis数据类型"><a href="#2-2-redis数据类型" class="headerlink" title="2.2 redis数据类型"></a>2.2 redis数据类型</h2><p> 数据类型对于redis相对其他缓存产品而言,其丰富的数据格式是它的一大特色。这里做一下简单的介绍。</p>
<h3 id="string字符串类型"><a href="#string字符串类型" class="headerlink" title="string字符串类型"></a>string字符串类型</h3><p> string类型是最基本的类型,它和memcached一样的类型.一个key对应一个value。redis中,string是二进制安全的,也就是说它可以存储任何数据(如图片或者序列化的对象)。一个键的最大存储为512MB.<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> SET name <span class="string">"redis.net.cn"</span></div><div class="line">OK</div><div class="line">redis 127.0.0.1:6379> GET name</div><div class="line"><span class="string">"redis.net.cn"</span></div></pre></td></tr></table></figure></p>
<h3 id="hash(哈希"><a href="#hash(哈希" class="headerlink" title="hash(哈希)"></a>hash(哈希)</h3><p>Redis hash是一个键值组合,它是一个string类型的field和value的映射表。特别适合存储对象。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> HMSET user:1 username redis.net.cn password redis.net.cn points 200</div><div class="line">OK</div><div class="line">redis 127.0.0.1:6379> HGETALL user:1</div><div class="line">1) <span class="string">"username"</span></div><div class="line">2) <span class="string">"redis.net.cn"</span></div><div class="line">3) <span class="string">"password"</span></div><div class="line">4) <span class="string">"redis.net.cn"</span></div><div class="line">5) <span class="string">"points"</span></div><div class="line">6) <span class="string">"200"</span></div></pre></td></tr></table></figure></p>
<p>每个 hash 可以存储 232 - 1 键值对(40多亿)。</p>
<h3 id="list-列表"><a href="#list-列表" class="headerlink" title="list(列表)"></a>list(列表)</h3><p> redis list列表是简单的string类型列表。可以添加一个元素在列表的头部或者尾部。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> lpush redis.net.cn redis</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> lpush redis.net.cn mongodb</div><div class="line">(<span class="built_in">integer</span>) 2</div><div class="line">redis 127.0.0.1:6379> lpush redis.net.cn rabitmq</div><div class="line">(<span class="built_in">integer</span>) 3</div><div class="line">redis 127.0.0.1:6379> lrange redis.net.cn 0 10</div><div class="line">1) <span class="string">"rabitmq"</span></div><div class="line">2) <span class="string">"mongodb"</span></div><div class="line">3) <span class="string">"redis"</span></div><div class="line">redis 127.0.0.1:6379></div></pre></td></tr></table></figure></p>
<p>列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。</p>
<h3 id="set-集合"><a href="#set-集合" class="headerlink" title="set(集合)"></a>set(集合)</h3><p> Redis的set是string类型的无序集合。它是通过hash表实现的。增添和查找的复杂度为O(1).</p>
<blockquote>
<p>sadd key member</p>
</blockquote>
<p>实例</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> sadd redis.net.cn redis</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> sadd redis.net.cn mongodb</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> sadd redis.net.cn rabitmq</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> sadd redis.net.cn rabitmq</div><div class="line">(<span class="built_in">integer</span>) 0</div><div class="line">redis 127.0.0.1:6379> smembers redis.net.cn</div><div class="line"></div><div class="line">1) <span class="string">"rabitmq"</span></div><div class="line">2) <span class="string">"mongodb"</span></div><div class="line">3) <span class="string">"redis"</span></div></pre></td></tr></table></figure>
<h3 id="zset(有序集合"><a href="#zset(有序集合" class="headerlink" title="zset(有序集合)"></a>zset(有序集合)</h3><p> zset是一个有序的string集合,且不允许成员重复。每个成员会关联一个double类型的分数。通过分数进行排序。成员唯一,但是分数可以重复。</p>
<blockquote>
<p>zadd key score member</p>
</blockquote>
<p>实例</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> zadd redis.net.cn 0 redis</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> zadd redis.net.cn 0 mongodb</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> zadd redis.net.cn 0 rabitmq</div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line">redis 127.0.0.1:6379> zadd redis.net.cn 0 rabitmq</div><div class="line">(<span class="built_in">integer</span>) 0</div><div class="line">redis 127.0.0.1:6379> ZRANGEBYSCORE redis.net.cn 0 1000</div><div class="line"></div><div class="line">1) <span class="string">"redis"</span></div><div class="line">2) <span class="string">"mongodb"</span></div><div class="line">3) <span class="string">"rabitmq"</span></div></pre></td></tr></table></figure>
<h2 id="2-3-Redis命令"><a href="#2-3-Redis命令" class="headerlink" title="2.3 Redis命令"></a>2.3 Redis命令</h2><p> 通过介绍redis的命令,了解redis的使用</p>
<h3 id="PING"><a href="#PING" class="headerlink" title="PING"></a>PING</h3><p> redis可以通过ping命令检测redis的运行情况。若正常运行,则返回pung<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> PING</div><div class="line"></div><div class="line">PONG</div></pre></td></tr></table></figure></p>
<h3 id="key相关命令"><a href="#key相关命令" class="headerlink" title="key相关命令"></a>key相关命令</h3><table>
<thead>
<tr>
<th>命令 </th>
<th> 说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Set key</td>
<td>插入一个key-value</td>
</tr>
<tr>
<td>del key</td>
<td>删除一个key-value.正确返回1,错误返回0</td>
</tr>
<tr>
<td>dump key</td>
<td>序列化key。正确返回序列化后字符串,错误返回nil</td>
</tr>
</tbody>
</table>
<p>exists key | 检测键值是否存在<br>expire key seconds | 设置键值过期时间,时间到了自动删除<br>move key db | 将当前数据库的key移动到其他数据库<br>persist key | 移除过期时间,永久保存<br>rename key new key | 重命名key<br>type key | 返回key的类型</p>
<h3 id="publish-subscribe命令"><a href="#publish-subscribe命令" class="headerlink" title="publish\subscribe命令"></a>publish\subscribe命令</h3><p> pub\sub是一个消息通信模式。通过subscribe订阅消息,然后通过publish发送消息。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#订阅者</span></div><div class="line">redis 127.0.0.1:6379> SUBSCRIBE redisChat</div><div class="line"></div><div class="line">Reading messages... (press Ctrl-C to quit)</div><div class="line">1) <span class="string">"subscribe"</span></div><div class="line">2) <span class="string">"redisChat"</span></div><div class="line">3) (<span class="built_in">integer</span>) 1</div></pre></td></tr></table></figure></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#发送者</span></div><div class="line">redis 127.0.0.1:6379> PUBLISH redisChat <span class="string">"Redis is a great caching technique"</span></div><div class="line"></div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> PUBLISH redisChat <span class="string">"Learn redis by w3cschool.cc"</span></div><div class="line"></div><div class="line">(<span class="built_in">integer</span>) 1</div><div class="line"></div><div class="line"><span class="comment"># 订阅者的客户端会显示如下消息</span></div><div class="line">1) <span class="string">"message"</span></div><div class="line">2) <span class="string">"redisChat"</span></div><div class="line">3) <span class="string">"Redis is a great caching technique"</span></div><div class="line">1) <span class="string">"message"</span></div><div class="line">2) <span class="string">"redisChat"</span></div><div class="line">3) <span class="string">"Learn redis by w3cschool.cc"</span></div></pre></td></tr></table></figure>
<p> 通过unsubscribe退订频道。</p>
<h3 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h3><p> Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:</p>
<ul>
<li>事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。</li>
<li>事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。</li>
</ul>
<p>一个事务从开始到执行会经历以下三个阶段:</p>
<ul>
<li>开始事务。</li>
<li>命令入队。</li>
<li>执行事务。</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">redis 127.0.0.1:6379> MULTI</div><div class="line">OK</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> SET book-name <span class="string">"Mastering C++ in 21 days"</span></div><div class="line">QUEUED</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> GET book-name</div><div class="line">QUEUED</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> SADD tag <span class="string">"C++"</span> <span class="string">"Programming"</span> <span class="string">"Mastering Series"</span></div><div class="line">QUEUED</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> SMEMBERS tag</div><div class="line">QUEUED</div><div class="line"></div><div class="line">redis 127.0.0.1:6379> EXEC</div><div class="line">1) OK</div><div class="line">2) <span class="string">"Mastering C++ in 21 days"</span></div><div class="line">3) (<span class="built_in">integer</span>) 3</div><div class="line">4) 1) <span class="string">"Mastering Series"</span></div><div class="line"> 2) <span class="string">"C++"</span></div><div class="line"> 3) <span class="string">"Programming"</span></div></pre></td></tr></table></figure>
<p> discard取消事务执行。</p>
<h3 id="INFO"><a href="#INFO" class="headerlink" title="INFO "></a>INFO </h3><p>查看当前redis所有信息</p>
<h3 id="脚本支持"><a href="#脚本支持" class="headerlink" title="脚本支持"></a>脚本支持</h3><p> redis内置lua解析器</p>
<h2 id="2-4-Redis为什么不能取代关系型数据库"><a href="#2-4-Redis为什么不能取代关系型数据库" class="headerlink" title="2.4 Redis为什么不能取代关系型数据库"></a>2.4 Redis为什么不能取代关系型数据库</h2><ol>
<li>复杂的数据结构不好维护</li>
<li>存储于内存虽然访问速度较快,但是关系体现不出来。</li>
<li>存储成本高</li>
</ol>
<h1 id="3-参考文献"><a href="#3-参考文献" class="headerlink" title="3 参考文献"></a>3 参考文献</h1><ul>
<li>[1]: <a href="http://www.redis.net.cn/tutorial/3501.html" target="_blank" rel="external">redis官方文档</a></li>
<li>[2]: <a href="https://www.teakki.com/p/57dbd374d7d770e81877c75a" target="_blank" rel="external">redis为什么不能取代关系数据库</a></li>
</ul>
]]></content>
<summary type="html">
<h1 id="1-认识redis"><a href="#1-认识redis" class="headerlink" title="1. 认识redis"></a>1. 认识redis</h1><p> redis是一个key-value的存储系统。它支持网络、可基于内存亦可持久化的日志型、key-value数据库。value值可支持string,map,list,sets和sorted sets等类型。<br> 详细的说,redis相对其它key-value缓存产品(如memcached)有三个特点:</p>
<ul>
<li>支持持久化,可将内存中的数据保持到磁盘中,重启时可再次加载进行使用。</li>
<li>不仅仅支持简单的key-value类型的数据,同事还提供list,set,zset,hash等数据结构的存储</li>
<li>支持数据备份,master-slave模式</li>
</ul>
</summary>
<category term="读书笔记" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="redis官方文档" scheme="http://lennybai.cn/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/redis%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3/"/>
<category term="redis" scheme="http://lennybai.cn/tags/redis/"/>
</entry>
<entry>
<title>g++ template class</title>
<link href="http://lennybai.cn/2016/11/25/g-template-class/"/>
<id>http://lennybai.cn/2016/11/25/g-template-class/</id>
<published>2016-11-25T05:31:50.000Z</published>
<updated>2016-12-20T03:27:45.923Z</updated>
<content type="html"><![CDATA[<p>g++模板类,定义不能与声明分离。其原因是,模板类的实现不是在编译时,直接对cpp文件进行编译,而是在函数或者模板类在定义时,根据类型实现特定的源文件代码。其实,如果强行讲实现与声明分离也有方法,比如在头文件a.h中引用a.cpp,这样就可以做到定义与实现分离。但是这导致每次使用模板都会对源文件进行编译,造成编译时浪费。</p>
]]></content>
<summary type="html">
<p>g++模板类,定义不能与声明分离。其原因是,模板类的实现不是在编译时,直接对cpp文件进行编译,而是在函数或者模板类在定义时,根据类型实现特定的源文件代码。其实,如果强行讲实现与声明分离也有方法,比如在头文件a.h中引用a.cpp,这样就可以做到定义与实现分离。但是这导致每