-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
273 lines (129 loc) · 177 KB
/
Copy pathsearch.xml
File metadata and controls
273 lines (129 loc) · 177 KB
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>算法练习7</title>
<link href="/2017/06/13/suan-fa-lian-xi-7/"/>
<url>/2017/06/13/suan-fa-lian-xi-7/</url>
<content type="html"><![CDATA[<h1 id="算法练习7"><a href="#算法练习7" class="headerlink" title="算法练习7"></a>算法练习7</h1><p> </p>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>算法练习6</title>
<link href="/2017/06/10/suan-fa-lian-xi-6/"/>
<url>/2017/06/10/suan-fa-lian-xi-6/</url>
<content type="html"><![CDATA[<h1 id="算法练习6"><a href="#算法练习6" class="headerlink" title="算法练习6"></a>算法练习6</h1><h2 id="Maximum-Subarray"><a href="#Maximum-Subarray" class="headerlink" title="Maximum Subarray"></a>Maximum Subarray</h2><p>Find the contiguous subarray within an array (containing at least one number) which has the largest sum.</p><p>For example, given the array <code>[-2,1,-3,4,-1,2,1,-5,4]</code>,<br>the contiguous subarray <code>[4,-1,2,1]</code> has the largest sum = <code>6</code>.</p><h3 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:寻找最大连续子数组和</p><p>最近在练dp,这道题可以用dp来解,首先定义状态,dp[i]是以元素i结尾的和最大的子数组。接下来定义状态转移方程:<code>dp[i] = nums[i] + (dp[i - 1] > 0 ? dp[i -1] : 0);</code></p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxSubArray</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span>[] dp = <span class="keyword">new</span> <span class="keyword">int</span>[nums.length];</span><br><span class="line"> dp[<span class="number">0</span>] = nums[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">int</span> max = dp[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < nums.length; i++) {</span><br><span class="line"> dp[i] = nums[i] + (dp[i - <span class="number">1</span>] > <span class="number">0</span> ? dp[i - <span class="number">1</span>] : <span class="number">0</span>);</span><br><span class="line"> max = max > dp[i] ? max : dp[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> max;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="Climbing-Stairs"><a href="#Climbing-Stairs" class="headerlink" title="Climbing Stairs"></a>Climbing Stairs</h2><p>You are climbing a stair case. It takes <em>n</em> steps to reach to the top.</p><p>Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?</p><p><strong>Note:</strong> Given <em>n</em> will be a positive integer.</p><h3 id="解题思路-1"><a href="#解题思路-1" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:爬n步楼梯,一次可以爬一步或者两步,求有几种方法爬到n层</p><p>设<code>dp[i]</code>为爬i层的方法数,那么可以得到状态转移方程:<code>dp[i] = dp[i - 1] + dp [i - 2]; (i>2)</code>特殊的:<code>dp[1]=1</code>、<code>dp[2]=2</code> 。</p><h3 id="代码-1"><a href="#代码-1" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">climbStairs</span><span class="params">(<span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">2</span>) <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">int</span>[] dp = <span class="keyword">new</span> <span class="keyword">int</span>[n + <span class="number">1</span>];</span><br><span class="line"> dp[<span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line"> dp[<span class="number">2</span>] = <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">3</span>;i < n + <span class="number">1</span>; i++) {</span><br><span class="line"> dp[i] = dp[i - <span class="number">1</span>] + dp[i - <span class="number">2</span>];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> dp[n];</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="Best-Time-to-Buy-and-Sell-Stock"><a href="#Best-Time-to-Buy-and-Sell-Stock" class="headerlink" title="Best Time to Buy and Sell Stock"></a>Best Time to Buy and Sell Stock</h2><p>Say you have an array for which the <em>i</em>th element is the price of a given stock on day <em>i</em>.</p><p>If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.</p><p><strong>Example 1:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Input: [7, 1, 5, 3, 6, 4]</span><br><span class="line">Output: 5</span><br><span class="line"></span><br><span class="line">max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)</span><br></pre></td></tr></table></figure><p><strong>Example 2:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Input: [7, 6, 4, 3, 1]</span><br><span class="line">Output: 0</span><br><span class="line"></span><br><span class="line">In this case, no transaction is done, i.e. max profit = 0.</span><br></pre></td></tr></table></figure><h3 id="解题思路-2"><a href="#解题思路-2" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:给定股票每日的售价,求 一次买进和一次卖出最多可以获取多大利润。</p><p>每次更新最大差价和最小价格。</p><h3 id="代码-2"><a href="#代码-2" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="keyword">int</span>[] prices)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (prices == <span class="keyword">null</span> || prices.length == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> ans = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> money = prices[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < prices.length; i++) {</span><br><span class="line"> ans = Math.max(ans, prices[i] - money);</span><br><span class="line"> money = Math.min(prices[i], money);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="House-Robber"><a href="#House-Robber" class="headerlink" title="House Robber"></a>House Robber</h2><p>You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and <strong>it will automatically contact the police if two adjacent houses were broken into on the same night</strong>.</p><p>Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight <strong>without alerting the police</strong>.</p><h3 id="解题思路-3"><a href="#解题思路-3" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:一排房子,不能在一晚同时抢劫相邻的房子,求一晚最大收益。</p><p>思路:对于每个房子,都有两个状态,抢或者不抢。如果抢当前房子,那么收益为不抢上一个房子的收益加当前房子的收益;如果不抢,那么当前收益为上一个房子抢的收益和不抢的收益中大的那个。</p><h3 id="代码-3"><a href="#代码-3" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">rob</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> rob = <span class="number">0</span>; </span><br><span class="line"> <span class="keyword">int</span> notrob = <span class="number">0</span>; </span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>; i<num.length; i++) {</span><br><span class="line"> <span class="keyword">int</span> currob = notrob + num[i]; </span><br><span class="line"> notrob = Math.max(notrob, rob); </span><br><span class="line"> rob = currob;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> Math.max(rob, notrob);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="Range-Sum-Query-Immutable"><a href="#Range-Sum-Query-Immutable" class="headerlink" title="Range Sum Query - Immutable"></a>Range Sum Query - Immutable</h2><p>Given an integer array <em>nums</em>, find the sum of the elements between indices <em>i</em> and <em>j</em> (<em>i</em> ≤ <em>j</em>), inclusive.</p><p><strong>Example:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Given nums = [-2, 0, 3, -5, 2, -1]</span><br><span class="line"></span><br><span class="line">sumRange(0, 2) -> 1</span><br><span class="line">sumRange(2, 5) -> -1</span><br><span class="line">sumRange(0, 5) -> -3</span><br></pre></td></tr></table></figure><h3 id="解题思路-4"><a href="#解题思路-4" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:给定一个数组,求sum(i,j)。</p><p>由于对象实例化之后数组是不会变的,所以定义sum[i]是前i个元素的和,<code>sum[i] = sum[i - 1] + nums[i];</code></p><h3 id="代码-4"><a href="#代码-4" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">NumArray</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span>[] sum;</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">NumArray</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>{</span><br><span class="line"> sum = <span class="keyword">new</span> <span class="keyword">int</span>[nums.length + <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < nums.length; i++) {</span><br><span class="line"> sum[i + <span class="number">1</span>] = sum[i] + nums[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">sumRange</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> sum[j + <span class="number">1</span>] - sum[i];</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>算法练习5</title>
<link href="/2017/05/26/suan-fa-lian-xi-5/"/>
<url>/2017/05/26/suan-fa-lian-xi-5/</url>
<content type="html"><![CDATA[<h1 id="算法练习5"><a href="#算法练习5" class="headerlink" title="算法练习5"></a>算法练习5</h1><h2 id="Regular-Expression-Matching"><a href="#Regular-Expression-Matching" class="headerlink" title="Regular Expression Matching"></a>Regular Expression Matching</h2><p>Implement regular expression matching with support for <code>'.'</code> and <code>'*'</code>.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">'.' Matches any single character.</span><br><span class="line">'*' Matches zero or more of the preceding element.</span><br><span class="line"></span><br><span class="line">The matching should cover the entire input string (not partial).</span><br><span class="line"></span><br><span class="line">The function prototype should be:</span><br><span class="line">bool isMatch(const char *s, const char *p)</span><br><span class="line"></span><br><span class="line">Some examples:</span><br><span class="line">isMatch("aa","a") ? false</span><br><span class="line">isMatch("aa","aa") ? true</span><br><span class="line">isMatch("aaa","aa") ? false</span><br><span class="line">isMatch("aa", "a*") ? true</span><br><span class="line">isMatch("aa", ".*") ? true</span><br><span class="line">isMatch("ab", ".*") ? true</span><br><span class="line">isMatch("aab", "c*a*b") ? true</span><br></pre></td></tr></table></figure><h2 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h2><p>题目大意:实现正则式中的<code>'.'</code>和<code>'*'</code> 匹配。</p><p>该问题可以具有最优子结构,所以可以用动态规划来求解。</p><p>首先分析这个问题,我们把这个问题可以看成是重复的比较字符串s的某个字符和字符串p的某个字符。在这个比较过程中有三种情况:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>, p.charAt(j) == s.charAt(i)<span class="comment">//s当前字符相等</span></span><br><span class="line"><span class="number">2</span>, p.charAt(j) == <span class="string">'.'</span><span class="comment">//s当前字符与通配符'.'匹配</span></span><br><span class="line"><span class="number">3</span>, p.charAt(j) == <span class="string">'*'</span><span class="comment">//这种情况还需要细分两种情况</span></span><br><span class="line"><span class="number">3.1</span>, p.charAt(j-<span class="number">1</span>) != s.charAt(i)<span class="comment">//s当前字符与'*'前一字符不相等</span></span><br><span class="line"><span class="number">3.2</span>, p.charAt(i-<span class="number">1</span>) == s.charAt(i) or p.charAt(i-<span class="number">1</span>) == <span class="string">'.'</span><span class="comment">//'*'前一字符与之相等或前一字符是通配符</span></span><br></pre></td></tr></table></figure><p>基于以上情况,定义<code>dp[i][j]</code>为s串前i个字符与p串前j个字符的匹配状态。那么我们可以得到每种情况对应的状态转移方程:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>, <span class="keyword">if</span> p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-<span class="number">1</span>][j-<span class="number">1</span>];</span><br><span class="line"><span class="number">2</span>, <span class="keyword">if</span> p.charAt(j) == <span class="string">'.'</span> : dp[i][j] = dp[i-<span class="number">1</span>][j-<span class="number">1</span>];</span><br><span class="line"><span class="number">3</span>, <span class="keyword">if</span> p.charAt(j) == <span class="string">'*'</span> : </span><br><span class="line"><span class="keyword">if</span> p.charAt(j-<span class="number">1</span>) != s.charAt(i) : dp[i][j] = dp[i][j-<span class="number">2</span>];</span><br><span class="line"><span class="keyword">if</span> p.charAt(i-<span class="number">1</span>) == s.charAt(i) || p.charAt(i-<span class="number">1</span>) == <span class="string">'.'</span> : </span><br><span class="line">dp[i][j] = dp[i-<span class="number">1</span>][j] || dp[i][j] = dp[i][j-<span class="number">1</span>] || dp[i][j] = dp[i][j-<span class="number">2</span>];</span><br></pre></td></tr></table></figure><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isMatch</span><span class="params">(String s, String p)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (s == <span class="keyword">null</span> || p == <span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> <span class="keyword">boolean</span>[][] dp = <span class="keyword">new</span> <span class="keyword">boolean</span>[s.length() + <span class="number">1</span>][p.length() + <span class="number">1</span>];</span><br><span class="line"> dp[<span class="number">0</span>][<span class="number">0</span>] = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < p.length(); i++) {</span><br><span class="line"> <span class="keyword">if</span> (p.charAt(i) == <span class="string">'*'</span> && dp[<span class="number">0</span>][i - <span class="number">1</span>]) {</span><br><span class="line"> dp[<span class="number">0</span>][i + <span class="number">1</span>] = <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j < p.length(); j++) {</span><br><span class="line"> <span class="keyword">if</span> (p.charAt(j) == s.charAt(i)) {</span><br><span class="line"> dp[i+<span class="number">1</span>][j+<span class="number">1</span>] = dp[i][j];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (p.charAt(j) == <span class="string">'.'</span>) {</span><br><span class="line"> dp[i+<span class="number">1</span>][j+<span class="number">1</span>] = dp[i][j];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (p.charAt(j) == <span class="string">'*'</span>) {</span><br><span class="line"> <span class="keyword">if</span> (p.charAt(j -<span class="number">1</span>) != s.charAt(i) && p.charAt(j - <span class="number">1</span>) != <span class="string">'.'</span>) {</span><br><span class="line"> dp[i + <span class="number">1</span>][j + <span class="number">1</span>] = dp[i + <span class="number">1</span>][j - <span class="number">1</span>];</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> dp[i+<span class="number">1</span>][j+<span class="number">1</span>] = (dp[i+<span class="number">1</span>][j] || dp[i][j+<span class="number">1</span>] || dp[i+<span class="number">1</span>][j-<span class="number">1</span>]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> dp[s.length()][p.length()];</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>粗读ArrayList</title>
<link href="/2017/05/20/cu-du-arraylist/"/>
<url>/2017/05/20/cu-du-arraylist/</url>
<content type="html"><![CDATA[<h1 id="粗读ArrayList"><a href="#粗读ArrayList" class="headerlink" title="粗读ArrayList"></a>粗读ArrayList</h1><h2 id="概览"><a href="#概览" class="headerlink" title="概览"></a>概览</h2><p>ArrayList大概是除了String用了最多的类了。ArrayList对数组进行封装,实现了List接口。下面是ArrayList的私有变量:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ArrayList</span><<span class="title">E</span>> <span class="keyword">extends</span> <span class="title">AbstractList</span><<span class="title">E</span>></span></span><br><span class="line"><span class="class"> <span class="keyword">implements</span> <span class="title">List</span><<span class="title">E</span>>, <span class="title">RandomAccess</span>, <span class="title">Cloneable</span>, <span class="title">java</span>.<span class="title">io</span>.<span class="title">Serializable</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = <span class="number">8683452581122892189L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Default initial capacity.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DEFAULT_CAPACITY = <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Shared empty array instance used for empty instances.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Object[] EMPTY_ELEMENTDATA = {};</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Shared empty array instance used for default sized empty instances. We</span></span><br><span class="line"><span class="comment"> * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when</span></span><br><span class="line"><span class="comment"> * first element is added.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * The array buffer into which the elements of the ArrayList are stored.</span></span><br><span class="line"><span class="comment"> * The capacity of the ArrayList is the length of this array buffer. Any</span></span><br><span class="line"><span class="comment"> * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA</span></span><br><span class="line"><span class="comment"> * will be expanded to DEFAULT_CAPACITY when the first element is added.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">transient</span> Object[] elementData; <span class="comment">// non-private to simplify nested class access</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * The size of the ArrayList (the number of elements it contains).</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@serial</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> size;</span><br><span class="line"> ......</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>从上面可以看出来,ArrayList默认大小为10,用一个对象数组存放元素,一个整性变量保存数组大小。</p><h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2><p>ArrayList提供以下几个构造方法:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Constructs an empty list with the specified initial capacity.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> initialCapacity the initial capacity of the list</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> IllegalArgumentException if the specified initial capacity</span></span><br><span class="line"><span class="comment"> * is negative</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ArrayList</span><span class="params">(<span class="keyword">int</span> initialCapacity)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (initialCapacity > <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">this</span>.elementData = <span class="keyword">new</span> Object[initialCapacity];</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (initialCapacity == <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">this</span>.elementData = EMPTY_ELEMENTDATA;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"Illegal Capacity: "</span>+</span><br><span class="line"> initialCapacity);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Constructs an empty list with an initial capacity of ten.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ArrayList</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Constructs a list containing the elements of the specified</span></span><br><span class="line"><span class="comment"> * collection, in the order they are returned by the collection's</span></span><br><span class="line"><span class="comment"> * iterator.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> c the collection whose elements are to be placed into this list</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> NullPointerException if the specified collection is null</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ArrayList</span><span class="params">(Collection<? extends E> c)</span> </span>{</span><br><span class="line"> elementData = c.toArray();</span><br><span class="line"> <span class="keyword">if</span> ((size = elementData.length) != <span class="number">0</span>) {</span><br><span class="line"> <span class="comment">// c.toArray might (incorrectly) not return Object[] (see 6260652)</span></span><br><span class="line"> <span class="keyword">if</span> (elementData.getClass() != Object[]<span class="class">.<span class="keyword">class</span>)</span></span><br><span class="line"><span class="class"> <span class="title">elementData</span> </span>= Arrays.copyOf(elementData, size, Object[]<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// replace with empty array.</span></span><br><span class="line"> <span class="keyword">this</span>.elementData = EMPTY_ELEMENTDATA;</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>一个空构造,默认大小为10初始化数组;一个传入初始大小初始化数组;还有一个用一个集合初始化数组。</p><p>//未完待续。。。</p>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>算法练习4</title>
<link href="/2017/05/18/suan-fa-lian-xi-4/"/>
<url>/2017/05/18/suan-fa-lian-xi-4/</url>
<content type="html"><![CDATA[<h1 id="算法练习4"><a href="#算法练习4" class="headerlink" title="算法练习4"></a>算法练习4</h1><h2 id="ZigZag-Conversion"><a href="#ZigZag-Conversion" class="headerlink" title="ZigZag Conversion"></a>ZigZag Conversion</h2><p>The string <code>"PAYPALISHIRING"</code> is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">P A H N</span><br><span class="line">A P L S I I G</span><br><span class="line">Y I R</span><br></pre></td></tr></table></figure><p>And then read line by line: <code>"PAHNAPLSIIGYIR"</code></p><p>Write the code that will take a string and make this conversion given a number of rows:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">string convert(string text, int nRows);</span><br></pre></td></tr></table></figure><p><code>convert("PAYPALISHIRING", 3)</code>, should return <code>"PAHNAPLSIIGYIR"</code> 。</p><h2 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h2><p>题目大意:将一个字符串以之字形方式重排列之后输出。</p><p>看到这道题很容易就想到了构建nRows个字符串,将原字符串按照之字形顺序添加在相应的字符串末尾。观察题目给出的例子,容易得出字符一个之字形周期是2 * nRows - 2,设index = i % (2 * nRows - 2),则当index大于nRows时,index=2*nRwos-index-2,index是字符串数组的下标。最后将字符串数组按顺序拼接得到解。</p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">convert</span><span class="params">(String s, <span class="keyword">int</span> numRows)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (numRows == <span class="number">1</span>) <span class="keyword">return</span> s;</span><br><span class="line"> <span class="keyword">int</span> li = numRows + (numRows - <span class="number">2</span>);</span><br><span class="line"> StringBuilder[] builders = <span class="keyword">new</span> StringBuilder[numRows];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < numRows; i++) {</span><br><span class="line"> builders[i] = <span class="keyword">new</span> StringBuilder();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++) {</span><br><span class="line"> <span class="keyword">int</span> index = i % li;</span><br><span class="line"> <span class="keyword">if</span> (index >= numRows) {</span><br><span class="line"> index = <span class="number">2</span> * numRows - index - <span class="number">2</span>;</span><br><span class="line"> }</span><br><span class="line"> builders[index].append(s.charAt(i));</span><br><span class="line"> }</span><br><span class="line"> StringBuilder res = <span class="keyword">new</span> StringBuilder();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < numRows; i++) {</span><br><span class="line"> res.append(builders[i].toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> res.toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="Reverse-Integer"><a href="#Reverse-Integer" class="headerlink" title="Reverse Integer"></a>Reverse Integer</h2><p>Reverse digits of an integer.The input is assumed to be a 32-bit signed integer. Your function should <strong>return 0 when the reversed integer overflows</strong>.</p><p><strong>Example1:</strong> x = 123, return 321<br><strong>Example2:</strong> x = -123, return -321</p><h3 id="解题思路-1"><a href="#解题思路-1" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意:反转整数,溢出返回0</p><p>对输入x每次取最后一位,然后向右移一位,然后将结果result向左移一位后加取到的最后一位。直到x为0。每次移位之后判断移位前后result是否相等,若不相等则溢出,返回0。</p><h3 id="代码-1"><a href="#代码-1" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">reverse</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> result = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (x != <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">int</span> tail = x % <span class="number">10</span>;</span><br><span class="line"> <span class="keyword">int</span> newResult = result * <span class="number">10</span> + tail;</span><br><span class="line"> <span class="keyword">if</span> ((newResult - tail) / <span class="number">10</span> != result) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> result = newResult;</span><br><span class="line"> x = x / <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>Java集合</title>
<link href="/2017/05/12/java-ji-he/"/>
<url>/2017/05/12/java-ji-he/</url>
<content type="html"><![CDATA[<h1 id="Java容器"><a href="#Java容器" class="headerlink" title="Java容器"></a>Java容器</h1><h2 id="Java容器接口"><a href="#Java容器接口" class="headerlink" title="Java容器接口"></a>Java容器接口</h2><p>Java中的容器是可以容纳其他对象的对象,始于JDK1.2。在Java容器中有两个顶层接口<code>Collection</code> 和 <code>Map</code> 。<code>Collection</code> 表示的是集合,<code>Map</code> 表示的是关联式容器。<br><code>Set</code> 、 <code>List</code> 、 <code>Queue</code> 继承自 <code>Collection</code> 。其中在JDK1.6及以后,<code>Stack</code> 被引入的 <code>Deque</code> 所取代。<code>Deque</code> 继承自 <code>Queue</code> 。</p><h2 id="迭代器-Iterator"><a href="#迭代器-Iterator" class="headerlink" title="迭代器(Iterator)"></a>迭代器(Iterator)</h2><p><code>Collection</code> 继承自 <code>Iterable</code> ,表示集合是可迭代的。而 <code>Iterable</code> 接口的iterator()方法会返回一个迭代器。迭代器提供了以下三个方法:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Iterator</span><<span class="title">E</span>> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">boolean</span> <span class="title">hasNext</span><span class="params">()</span></span>;<span class="comment">//是否有下一个对象</span></span><br><span class="line"> <span class="function">E <span class="title">next</span><span class="params">()</span></span>;<span class="comment">//取下一个对象</span></span><br><span class="line"> <span class="function"><span class="keyword">default</span> <span class="keyword">void</span> <span class="title">remove</span><span class="params">()</span> </span>{<span class="comment">//移除最近一个被返回的对象</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> UnsupportedOperationException(<span class="string">"remove"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>通过迭代器我们可以方便的通用的遍历集合,无论集合的实现是 <code>ArrayList</code> 还是 <code>HashSet</code> 。</p>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>算法练习3</title>
<link href="/2017/05/03/suan-fa-lian-xi-3/"/>
<url>/2017/05/03/suan-fa-lian-xi-3/</url>
<content type="html"><![CDATA[<h1 id="算法练习3"><a href="#算法练习3" class="headerlink" title="算法练习3"></a>算法练习3</h1><h2 id="Longest-Palindromic-Substring"><a href="#Longest-Palindromic-Substring" class="headerlink" title="Longest Palindromic Substring"></a>Longest Palindromic Substring</h2><p>Given a string <strong>s</strong>, find the longest palindromic substring in <strong>s</strong>. You may assume that the maximum length of <strong>s</strong> is 1000.</p><p><strong>Example:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Input: "babad"</span><br><span class="line"></span><br><span class="line">Output: "bab"</span><br><span class="line"></span><br><span class="line">Note: "aba" is also a valid answer.</span><br></pre></td></tr></table></figure><p><strong>Example:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Input: "cbbd"</span><br><span class="line"></span><br><span class="line">Output: "bb"</span><br></pre></td></tr></table></figure><h3 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意是求最长回文子串。对于每个回文字符串,都有它们各自的中心,奇数回文的中心是一个字符,偶数回文的中心是两个字符,从中心向两边数就可以得到回文的长度。那么以字符串的每个字符或者每两个字符作为中心向两边扩散,就可以得到每个回文子串的长度,取其中最大的作为解。</p><p>当然解决最长回文子串还有一个O(n)的算法:Manacher算法。这个算法首先用到了一个很巧妙的方式将可能是奇数或者是偶数的回文子串都转换成了奇数长度:在每个字符两边都插入一个特殊字符。如abba变成#a#b#b#a#,aba变成#a#b#a#。然后用一个数组元素P[i]来记录以字符s[i]为中心的最长回文子串向左/右扩张的长度。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">S # a # b # b # a # b # c # b # a #</span><br><span class="line">P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1</span><br><span class="line">可以看出,P[i]-1正好是原字符串中回文串的总长度, i是原字符在S中的下标</span><br></pre></td></tr></table></figure><p>然后就是这个算法的关键点,利用回文的对称性即左边是右边的镜像来计算P[i],设两个辅助变量id和mx,其中id为已知有边界最大回文子串的中心,mx为id+p[id],也就是这个子串的右边界。如果mx > i,那么p[i] >= min(P[2 * id - i], mx - i)。2*id-i是i关于id的对称点,上面的意思就是如果i在最大子串里面,mx-i是i到右边界的距离,如果i对称点的回文长度小于mx-i,那P[i]==P[2 * id - i]; 如果mx-i更小,那么意味着i的右边界超出了mx,那么P[i]>mx - i,超出部分不一定和i的对称点的那部分相同。对于mx <= i的情况,设P[i]=1,然后再去匹配。</p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//我的解法</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">longestPalindrome</span><span class="params">(String s)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> start = <span class="number">0</span>, end = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++) {</span><br><span class="line"> <span class="keyword">int</span> len1 = center(s, i, i);<span class="comment">//奇数回文</span></span><br><span class="line"> <span class="keyword">int</span> len2 = center(s, i, i + <span class="number">1</span>);<span class="comment">//偶数回文</span></span><br><span class="line"> <span class="keyword">int</span> len = len1 > len2 ? len1 : len2;</span><br><span class="line"> <span class="keyword">if</span> (len > end - start) {</span><br><span class="line"> start = i - (len - <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> end = i + len / <span class="number">2</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> s.substring(start, end + <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">center</span><span class="params">(String s, <span class="keyword">int</span> left, <span class="keyword">int</span> right)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> l = left, r = right;</span><br><span class="line"> <span class="keyword">while</span> (l >= <span class="number">0</span> && r < s.length() && s.charAt(l) == s.charAt(r)) {</span><br><span class="line"> l--;</span><br><span class="line"> r++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> r - l - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//Manacher算法,代码来自http://articles.leetcode.com/longest-palindromic-substring-part-ii</span></span><br><span class="line"><span class="comment">// Transform S into T.</span></span><br><span class="line"><span class="comment">// For example, S = "abba", T = "^#a#b#b#a#$".</span></span><br><span class="line"><span class="comment">// ^ and $ signs are sentinels appended to each end to avoid bounds checking</span></span><br><span class="line"><span class="function">string <span class="title">preProcess</span><span class="params">(string s)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n = s.length();</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">0</span>) <span class="keyword">return</span> <span class="string">"^$"</span>;</span><br><span class="line"> string ret = <span class="string">"^"</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> ret += <span class="string">"#"</span> + s.substr(i, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> ret += <span class="string">"#$"</span>;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">string <span class="title">longestPalindrome</span><span class="params">(string s)</span> </span>{</span><br><span class="line"> string T = preProcess(s);</span><br><span class="line"> <span class="keyword">int</span> n = T.length();</span><br><span class="line"> <span class="keyword">int</span> *P = <span class="keyword">new</span> <span class="keyword">int</span>[n];</span><br><span class="line"> <span class="keyword">int</span> C = <span class="number">0</span>, R = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < n-<span class="number">1</span>; i++) {</span><br><span class="line"> <span class="keyword">int</span> i_mirror = <span class="number">2</span>*C-i; <span class="comment">// equals to i' = C - (i-C)</span></span><br><span class="line"> </span><br><span class="line"> P[i] = (R > i) ? min(R-i, P[i_mirror]) : <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// Attempt to expand palindrome centered at i</span></span><br><span class="line"> <span class="keyword">while</span> (T[i + <span class="number">1</span> + P[i]] == T[i - <span class="number">1</span> - P[i]])</span><br><span class="line"> P[i]++;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// If palindrome centered at i expand past R,</span></span><br><span class="line"> <span class="comment">// adjust center based on expanded palindrome.</span></span><br><span class="line"> <span class="keyword">if</span> (i + P[i] > R) {</span><br><span class="line"> C = i;</span><br><span class="line"> R = i + P[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Find the maximum element in P.</span></span><br><span class="line"> <span class="keyword">int</span> maxLen = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> centerIndex = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < n-<span class="number">1</span>; i++) {</span><br><span class="line"> <span class="keyword">if</span> (P[i] > maxLen) {</span><br><span class="line"> maxLen = P[i];</span><br><span class="line"> centerIndex = i;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> delete[] P;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> s.substr((centerIndex - <span class="number">1</span> - maxLen)/<span class="number">2</span>, maxLen);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>编码和解码</title>
<link href="/2017/04/24/bian-ma-he-jie-ma/"/>
<url>/2017/04/24/bian-ma-he-jie-ma/</url>
<content type="html"><![CDATA[<h1 id="编码和解码"><a href="#编码和解码" class="headerlink" title="编码和解码"></a>编码和解码</h1><p> 平时开发的时候经常会遇到字符串编码和解码的问题,今天就初步探究下乱码问题,寻求解决乱码的方法。</p><h2 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h2><p>首先来分析下Java中的编码问题,文本在存储设备中是以字节的方式存储的,以特定的编码方案讲编码映射到字节数组。从存储设备中读取文本文件和写入文本就涉及到编码和解码。在JVM中,文本是以Unicode编码的形式存在的。下面先讲四个概念:</p><ul><li>字符集合(Charater set): 是一组形状的集合,比如所有汉字的集合,它体现了字符的’’形状’’。</li><li>编码字符集(Coded character set): 是一组字符对应的编码(即数字),字符集中的每一个字符对应一个数字。在Java中每一个字符可以认为是一个16位的数字。</li><li>字符编码方案(Character-encoding schema): 讲字符编码映射到一个字节数组的方案,因为在磁盘中,所有信息都是以字节的方式存储的。因此Java中的16位编码必须转换成一个字节数组才能够存储。常见的编码方案有UTF-8、GBK等。</li><li>字符集(Charset):编码字符集和字符编码方案合起来称为字符集。 </li></ul><h2 id="转换"><a href="#转换" class="headerlink" title="转换"></a>转换</h2><h3 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h3><p>从JVM中的Unicode编码到字节数组,这个转换过程被称之为编码。转换的目的是为了存储或发送信息。同一个Unicode编码采用不同的字符集进行编码会得到不同的字节数组。编码的例子如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//String的getBytes方法</span></span><br><span class="line">String s = <span class="string">"编码"</span>;</span><br><span class="line"><span class="keyword">byte</span>[] b1 = s.getBytes();<span class="comment">//getBytes会调用StringCoding类的encode方法,先用Charset的默认编码方案,如果不支持,再用ISO-8859-1,如果还不支持就exit(1).</span></span><br><span class="line"><span class="comment">//Charset的encode方法</span></span><br><span class="line">Charset charset = Charset.forName(<span class="string">"UTF-8"</span>);</span><br><span class="line">ByteBuffer byteBuffer = charset.encode(s);</span><br><span class="line"><span class="keyword">byte</span>[] b2 = <span class="keyword">new</span> <span class="keyword">byte</span>[byteBuffer.remaining()];</span><br><span class="line">byteBuffer.get(b2);</span><br></pre></td></tr></table></figure><h3 id="解码"><a href="#解码" class="headerlink" title="解码"></a>解码</h3><p>从字节数组到Unicode编码,这个转换过程被称之为解码。解码一般发生在需要从磁盘或者网络上得到的字节数组转换为字符串的场景。解码的时候一定要指定字符集,否则会使用默认的字符集进行解码。如果字符集错误,则会出现乱码。解码的例子如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用String构造方法</span></span><br><span class="line">String s1 = <span class="keyword">new</span> String(b1, <span class="string">"UTF-8"</span>);</span><br><span class="line"><span class="comment">//使用Charset的decode方法</span></span><br><span class="line">Charset cset = Charset.forName(<span class="string">"UTF-8"</span>);</span><br><span class="line">ByteBuffer buffer = ByteBuffer.wrap(b2);</span><br><span class="line">CharBuffer charBuffer = cset.decode(buffer);</span><br><span class="line">String s2 = charBuffer.toString();</span><br></pre></td></tr></table></figure><h3 id="默认字符集"><a href="#默认字符集" class="headerlink" title="默认字符集"></a>默认字符集</h3><p>Java的默认字符集有两种设置方法:</p><ul><li>在执行Java程序的时候使用-Dfile.encoding参数指定</li><li>使用Properties类指定字符集。</li></ul><p>两种方法同时使用的话,则在程序开始的时候使用参数指定的字符集,在执行Properties方法之后使用Properties指定的字符集。如果没有显式指定默认字符集,则使用操作系统默认的字符集。如果以上字符集无效,则会采用JDK中默认的字符集<code>ISO-8859-1</code>。</p><h2 id="乱码与解决方案"><a href="#乱码与解决方案" class="headerlink" title="乱码与解决方案"></a>乱码与解决方案</h2><h3 id="乱码的原因"><a href="#乱码的原因" class="headerlink" title="乱码的原因"></a>乱码的原因</h3><p>从上文可知,乱码的产生原因在于解码。采用了错误的字符集解码字节数组就会产生乱码。下面是个小例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">String before = <span class="string">"中国"</span>;</span><br><span class="line"><span class="keyword">byte</span>[] bytes = before.getBytes(<span class="string">"UTF-8"</span>);</span><br><span class="line">String after = <span class="keyword">new</span> String(bytes, <span class="string">"GBK"</span>);</span><br><span class="line">System.out.println(before);</span><br><span class="line">System.out.println(after);</span><br><span class="line"><span class="comment">//输出结果:</span></span><br><span class="line"><span class="comment">//中国</span></span><br><span class="line"><span class="comment">//涓浗</span></span><br></pre></td></tr></table></figure><h3 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h3><p> 在一般情况下我们可以得知字节数组的编码方案,在解码的时候指定正确的字符集就可以避免乱码。但有些时候我们并不能得知或者很难得知字节数组所采用的编码方案,那么按照常用的字符集进行解码的时候就很容易造成乱码。</p><p>在我们知道字节数组使用了哪几种编码方案之一的时候,我们可以判断得到的字符串在某个字符集下时候有效。日常开发中常见的字符编码方案有UTF-8、GBK、ISO-8859-1三种,其中ISO-8859-1是西欧标准,用这种编码方案编码中文等非拉丁语言的时候会得到值为63的一个字节。GBK编码中文采用的是两个字节,UTF-8采用的是变长编码方式,这两种可以采用以下方法判断具体是哪种编码方案。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">isStringValidInCharset</span><span class="params">(String s, String charset)</span> </span>{</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">// 获取字符串s在字符集charset下的编码</span></span><br><span class="line"> <span class="keyword">byte</span>[] bytes = s.getBytes(charset);</span><br><span class="line"> <span class="comment">// 把获得的编码按该字符集解码成新字符串</span></span><br><span class="line"> String ss = <span class="keyword">new</span> String(bytes, charset);</span><br><span class="line"> <span class="comment">// 解码出来的新字符串应该与原来相等</span></span><br><span class="line"> <span class="comment">// 如果s不是该字符集下有效的字符串,解码出来的会是一堆问号</span></span><br><span class="line"> <span class="keyword">return</span> s.equals(ss);</span><br><span class="line"> } <span class="keyword">catch</span> (UnsupportedEncodingException e) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">//测试用例:</span></span><br><span class="line"><span class="comment">//System.out.println(isStringValidInCharset("中文abc", "GBK"));</span></span><br><span class="line"><span class="comment">//System.out.println(isStringValidInCharset("图书", "GBK"));</span></span><br><span class="line"><span class="comment">//输出:</span></span><br><span class="line"><span class="comment">//rue</span></span><br><span class="line"><span class="comment">//false</span></span><br></pre></td></tr></table></figure><p>上述方法只能简单的判断几种编码方案,下面介绍一种基于统计学的推断编码方案的工具cpdetector。cpdetector按照谁先返回非空探测结果,就以该结果为准的原则返回探测到的字符集编码。从理论上来说,只要字符串越长,返回结果正确的概率就越大。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">File file = <span class="keyword">new</span> File(filePath);</span><br><span class="line">CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();</span><br><span class="line">detector.add(<span class="keyword">new</span> ParsingDetector(<span class="keyword">false</span>));</span><br><span class="line">detector.add(JChardetFacade.getInstance());</span><br><span class="line">detector.add(ASCIIDetector.getInstance());</span><br><span class="line">detector.add(UnicodeDetector.getInstance());</span><br><span class="line">java.nio.charset.Charset charset = <span class="keyword">null</span>;</span><br><span class="line">charset = detector.detectCodepage(file.toURI().toURL());</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>Java字符串</title>
<link href="/2017/04/15/java-zi-fu-chuan/"/>
<url>/2017/04/15/java-zi-fu-chuan/</url>
<content type="html"><![CDATA[<h1 id="Java字符串"><a href="#Java字符串" class="headerlink" title="Java字符串"></a>Java字符串</h1><p> 在平时开发的过程中,字符串操作应该是最常见的行为。而在Java中,String类大概是我们使用的最频繁的一个类了。今天我们就来初步研究下String的实现。说起看源码,就本能的感到一种对高阶程序员的一种畏惧,但当你打开源码的时候你会发现,String类3000多行代码有很多都是注释,真正的代码没有想像的多,这个也侧面说明了注释在开发当中的重要性。</p><h2 id="String类声明和属性"><a href="#String类声明和属性" class="headerlink" title="String类声明和属性"></a>String类声明和属性</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">String</span></span></span><br><span class="line"><span class="class"> <span class="keyword">implements</span> <span class="title">java</span>.<span class="title">io</span>.<span class="title">Serializable</span>, <span class="title">Comparable</span><<span class="title">String</span>>, <span class="title">CharSequence</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">char</span> value[];</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> hash; <span class="comment">// Default to 0</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = -<span class="number">6849794470754667710L</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> ObjectStreamField[] serialPersistentFields =<span class="keyword">new</span> ObjectStreamField[<span class="number">0</span>];</span><br></pre></td></tr></table></figure><p> 我们可以看到String类首先是final修饰的,所以不允许被继承和修改。其次String类实现了Serializable、Comparable、CharSequence三个接口;Serializable接口使String可序列化,Comparable接口使String类能互相比较,CharSequence接口提供了length()、charAt(int index)、subSequence(int start,int end)方法。</p><p> 接下来是String类的四个属性,一个不可变的char数组用来存放字符串,一个int型的hash存放哈希值,serialVersionUID提供序列化ID,serialPersistentFields声明了一个可序列化的字段。从这里我们可以看出,String是对char数组的封装。</p><h2 id="String构造方法"><a href="#String构造方法" class="headerlink" title="String构造方法"></a>String构造方法</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//无参构造方法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.value = <span class="string">""</span>.value;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">//用一个String对象初始化新建String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(String original)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.value = original.value;</span><br><span class="line"> <span class="keyword">this</span>.hash = original.hash;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">//用一个char数组初始化String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">char</span> value[])</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.value = Arrays.copyOf(value, value.length);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">//用char数组的一部分初始化String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">char</span> value[], <span class="keyword">int</span> offset, <span class="keyword">int</span> count)</span> </span>{<span class="comment">//offset起始点,count长度</span></span><br><span class="line"> <span class="keyword">if</span> (offset < <span class="number">0</span>) {<span class="comment">//起始点小于0,抛出越界异常</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(offset);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (count <= <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">if</span> (count < <span class="number">0</span>) {<span class="comment">//长度小于0,抛出越界异常</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(count);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (offset <= value.length) {<span class="comment">//count==0,起始点小于等于char数组长度,String为空</span></span><br><span class="line"> <span class="keyword">this</span>.value = <span class="string">""</span>.value;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// Note: offset or count might be near -1>>>1.</span></span><br><span class="line"> <span class="keyword">if</span> (offset > value.length - count) {<span class="comment">//起始点大于char数组长度减count,越界异常</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(offset + count);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">this</span>.value = Arrays.copyOfRange(value, offset, offset+count);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">//Unicode码数组的一部分初始化String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">int</span>[] codePoints, <span class="keyword">int</span> offset, <span class="keyword">int</span> count)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (offset < <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(offset);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (count <= <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">if</span> (count < <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(count);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (offset <= codePoints.length) {</span><br><span class="line"> <span class="keyword">this</span>.value = <span class="string">""</span>.value;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// Note: offset or count might be near -1>>>1.</span></span><br><span class="line"> <span class="keyword">if</span> (offset > codePoints.length - count) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> StringIndexOutOfBoundsException(offset + count);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">final</span> <span class="keyword">int</span> end = offset + count;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Pass 1: Compute precise size of char[]</span></span><br><span class="line"> <span class="keyword">int</span> n = count;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = offset; i < end; i++) {</span><br><span class="line"> <span class="keyword">int</span> c = codePoints[i];</span><br><span class="line"> <span class="keyword">if</span> (Character.isBmpCodePoint(c))<span class="comment">//是否为BMP代码点(基于多语言面),U+0000~U+FFFF</span></span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (Character.isValidCodePoint(c))<span class="comment">//是否为合法Unicode代码点,U+10000~U+10FFFF</span></span><br><span class="line"> n++;<span class="comment">//遇到增补字符长度加一</span></span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(Integer.toString(c));<span class="comment">//非法参数异常</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Pass 2: Allocate and fill in char[]</span></span><br><span class="line"> <span class="keyword">final</span> <span class="keyword">char</span>[] v = <span class="keyword">new</span> <span class="keyword">char</span>[n];<span class="comment">//用上面计算的长度来新建char数组</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = offset, j = <span class="number">0</span>; i < end; i++, j++) {</span><br><span class="line"> <span class="keyword">int</span> c = codePoints[i];</span><br><span class="line"> <span class="keyword">if</span> (Character.isBmpCodePoint(c))</span><br><span class="line"> v[j] = (<span class="keyword">char</span>)c;<span class="comment">//BMP代码点直接转换成char</span></span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> Character.toSurrogates(c, v, j++);<span class="comment">//增补字符转换成两个char</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">this</span>.value = v;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">//用一个字节数组初始化String对象,offset指定开始偏移量,length指定bytes长度,charsetName指定编码方式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[], <span class="keyword">int</span> offset, <span class="keyword">int</span> length, String charsetName)</span></span></span><br><span class="line"><span class="function"> <span class="keyword">throws</span> UnsupportedEncodingException </span>{</span><br><span class="line"> <span class="keyword">if</span> (charsetName == <span class="keyword">null</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"charsetName"</span>);</span><br><span class="line"> checkBounds(bytes, offset, length);<span class="comment">//检查是否越界</span></span><br><span class="line"> <span class="keyword">this</span>.value = StringCoding.decode(charsetName, bytes, offset, length);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//这个构造方法跟上面那个几乎一样,除了指定编码方式用的Charset对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[], <span class="keyword">int</span> offset, <span class="keyword">int</span> length, Charset charset)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (charset == <span class="keyword">null</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"charset"</span>);</span><br><span class="line"> checkBounds(bytes, offset, length);</span><br><span class="line"> <span class="keyword">this</span>.value = StringCoding.decode(charset, bytes, offset, length);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//同上,将整个字节数组转化成String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[], String charsetName)</span></span></span><br><span class="line"><span class="function"> <span class="keyword">throws</span> UnsupportedEncodingException </span>{</span><br><span class="line"> <span class="keyword">this</span>(bytes, <span class="number">0</span>, bytes.length, charsetName);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//同上</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[], Charset charset)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>(bytes, <span class="number">0</span>, bytes.length, charset);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//同上,使用系统默认的编码方式</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[], <span class="keyword">int</span> offset, <span class="keyword">int</span> length)</span> </span>{</span><br><span class="line"> checkBounds(bytes, offset, length);</span><br><span class="line"> <span class="keyword">this</span>.value = StringCoding.decode(bytes, offset, length);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//同上</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(<span class="keyword">byte</span> bytes[])</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>(bytes, <span class="number">0</span>, bytes.length);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将StringBuffer转成String对象</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(StringBuffer buffer)</span> </span>{</span><br><span class="line"> <span class="keyword">synchronized</span>(buffer) {<span class="comment">//同步锁</span></span><br><span class="line"> <span class="keyword">this</span>.value = Arrays.copyOf(buffer.getValue(), buffer.length());</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将StringBuilder转成String对象</span></span><br><span class="line"><span class="comment">//StringBuffer和StringBuilder都继承自抽象类AbstractStringBuilder,它有个叫value的字符数组,这两个构造方法就是把这个字符数组转成String对象。</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">String</span><span class="params">(StringBuilder builder)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.value = Arrays.copyOf(builder.getValue(), builder.length());</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>每个构造方法都写了注释,在此就不赘述了。</p><h2 id="String类常用方法"><a href="#String类常用方法" class="headerlink" title="String类常用方法"></a>String类常用方法</h2><h3 id="boolean-equals-Object-anObject"><a href="#boolean-equals-Object-anObject" class="headerlink" title="boolean equals(Object anObject)"></a>boolean equals(Object anObject)</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object anObject)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span> == anObject) {<span class="comment">//如果引用的是同一个对象,返回真</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (anObject <span class="keyword">instanceof</span> String) {<span class="comment">//如果不是String类型的数据,返回假</span></span><br><span class="line"> String anotherString = (String) anObject;</span><br><span class="line"> <span class="keyword">int</span> n = value.length;</span><br><span class="line"> <span class="keyword">if</span> (n == anotherString.value.length) {<span class="comment">//如果char数组长度不相等,返回假</span></span><br><span class="line"> <span class="keyword">char</span> v1[] = value;</span><br><span class="line"> <span class="keyword">char</span> v2[] = anotherString.value;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (n-- != <span class="number">0</span>) {<span class="comment">//从后往前单个字符判断,如果有不相等,返回假</span></span><br><span class="line"> <span class="keyword">if</span> (v1[i] != v2[i])</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> i++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;<span class="comment">//每个字符都相等,返回真</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>equals方法经常用到,它用来判断两个String对象中的value是否相等,判断流程如下:</p><ol><li>判断引用是否相同。如果是,则为同一个String对象,肯定相等,若不同继续判断。</li><li>判断比较对象是否是String对象,若不是,返回false, 若是,则继续判断。</li><li>判断两个String对象维护的char数组长度是否相等,不想等则返回false,相等则继续判断。</li><li>从后往前单个字符比较,若都相等,则两个String相等,否则不想等。</li></ol><h3 id="int-compareTo-String-anotherString"><a href="#int-compareTo-String-anotherString" class="headerlink" title="int compareTo(String anotherString)"></a>int compareTo(String anotherString)</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compareTo</span><span class="params">(String anotherString)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> len1 = value.length;<span class="comment">//自身对象字符串长度len1</span></span><br><span class="line"> <span class="keyword">int</span> len2 = anotherString.value.length;<span class="comment">//被比较对象字符串长度len2</span></span><br><span class="line"> <span class="keyword">int</span> lim = Math.min(len1, len2);<span class="comment">//取两个字符串长度的最小值lim</span></span><br><span class="line"> <span class="keyword">char</span> v1[] = value;</span><br><span class="line"> <span class="keyword">char</span> v2[] = anotherString.value;</span><br><span class="line"> <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">//从value的第一个字符开始到最小长度lim处为止,如果字符不相等,返回自身(对象不相等处字符减被比较对象不相等字符)</span></span><br><span class="line"> <span class="keyword">while</span> (k < lim) {</span><br><span class="line"> <span class="keyword">char</span> c1 = v1[k];</span><br><span class="line"> <span class="keyword">char</span> c2 = v2[k];</span><br><span class="line"> <span class="keyword">if</span> (c1 != c2) {</span><br><span class="line"> <span class="keyword">return</span> c1 - c2;</span><br><span class="line"> }</span><br><span class="line"> k++;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//如果前面都相等,则返回(自身长度-被比较对象长度)</span></span><br><span class="line"> <span class="keyword">return</span> len1 - len2;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这个方法利用字符相减和长度相减巧妙的判断了三种情况。</p><h3 id="int-hashCode"><a href="#int-hashCode" class="headerlink" title="int hashCode()"></a>int hashCode()</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hashCode</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> h = hash;</span><br><span class="line"> <span class="keyword">if</span> (h == <span class="number">0</span> && value.length > <span class="number">0</span>) {<span class="comment">//如果hash没有被计算过,并且字符串不为空,则进行hashCode计算</span></span><br><span class="line"> <span class="keyword">char</span> val[] = value;</span><br><span class="line"> <span class="comment">//计算过程</span></span><br><span class="line"> <span class="comment">//val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1]</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < value.length; i++) {</span><br><span class="line"> h = <span class="number">31</span> * h + val[i];</span><br><span class="line"> }</span><br><span class="line"> hash = h;<span class="comment">//hash赋值</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> h;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>String类重写了hashCode方法,采用了多项式计算得到hash值,但是两个hash相同的String也有可能不想等,这里采用这种方式只是为了尽可能减少碰撞,提高HashMap等的效率。</p><h3 id="startsWith-endsWith"><a href="#startsWith-endsWith" class="headerlink" title="startsWith()/endsWith()"></a>startsWith()/endsWith()</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">startsWith</span><span class="params">(String prefix, <span class="keyword">int</span> toffset)</span> </span>{</span><br><span class="line"> <span class="keyword">char</span> ta[] = value;</span><br><span class="line"> <span class="keyword">int</span> to = toffset;</span><br><span class="line"> <span class="keyword">char</span> pa[] = prefix.value;</span><br><span class="line"> <span class="keyword">int</span> po = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> pc = prefix.value.length;</span><br><span class="line"> <span class="comment">// Note: toffset might be near -1>>>1.</span></span><br><span class="line"> <span class="keyword">if</span> ((toffset < <span class="number">0</span>) || (toffset > value.length - pc)) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;<span class="comment">//判断时候在范围内</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (--pc >= <span class="number">0</span>) {<span class="comment">//从所比较对象的末尾开始比较</span></span><br><span class="line"> <span class="keyword">if</span> (ta[to++] != pa[po++]) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">startsWith</span><span class="params">(String prefix)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> startsWith(prefix, <span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">endsWith</span><span class="params">(String suffix)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> startsWith(suffix, value.length - suffix.value.length);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这几个方法通常用于判断一个字符串的开头或者结尾是否是特定格式的,比如找到一个doc文件或者判断url的协议是不是http。</p><h3 id="String-concat-String-str"><a href="#String-concat-String-str" class="headerlink" title="String concat(String str)"></a>String concat(String str)</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">concat</span><span class="params">(String str)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> otherLen = str.length();</span><br><span class="line"> <span class="keyword">if</span> (otherLen == <span class="number">0</span>) {<span class="comment">//如果被添加的字符串为空,返回对象本身</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> len = value.length;</span><br><span class="line"> <span class="keyword">char</span> buf[] = Arrays.copyOf(value, len + otherLen);</span><br><span class="line"> str.getChars(buf, len);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> String(buf, <span class="keyword">true</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>将一个字符串添加到当前字符串后,通过判断str时候为空串来决定时候新建对象。</p><h3 id="String-replace-char-oldChar-char-newChar"><a href="#String-replace-char-oldChar-char-newChar" class="headerlink" title="String replace(char oldChar,char newChar)"></a>String replace(char oldChar,char newChar)</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">replace</span><span class="params">(<span class="keyword">char</span> oldChar, <span class="keyword">char</span> newChar)</span> </span>{</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (oldChar != newChar) {<span class="comment">//新旧值先对比,相等直接返回本身</span></span><br><span class="line"> <span class="keyword">int</span> len = value.length;</span><br><span class="line"> <span class="keyword">int</span> i = -<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">char</span>[] val = value; <span class="comment">/* avoid getfield opcode */</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (++i < len) {<span class="comment">//找到旧值最开始出现的位置</span></span><br><span class="line"> <span class="keyword">if</span> (val[i] == oldChar) {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (i < len) {<span class="comment">//从那个位置开始,直到末尾,用新值代替出现的旧值</span></span><br><span class="line"> <span class="keyword">char</span> buf[] = <span class="keyword">new</span> <span class="keyword">char</span>[len];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j < i; j++) {</span><br><span class="line"> buf[j] = val[j];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (i < len) {</span><br><span class="line"> <span class="keyword">char</span> c = val[i];</span><br><span class="line"> buf[i] = (c == oldChar) ? newChar : c;</span><br><span class="line"> i++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> String(buf, <span class="keyword">true</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这个replace是替换字符,replace(String oldStr,String newStr)方法采用的正则表达式。</p><h3 id="String-trim"><a href="#String-trim" class="headerlink" title="String trim()"></a>String trim()</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">trim</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> len = value.length;</span><br><span class="line"> <span class="keyword">int</span> st = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">char</span>[] val = value; <span class="comment">/* avoid getfield opcode */</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> ((st < len) && (val[st] <= <span class="string">' '</span>)) {<span class="comment">//找到字符串前段没有空格的位置</span></span><br><span class="line"> st++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> ((st < len) && (val[len - <span class="number">1</span>] <= <span class="string">' '</span>)) {<span class="comment">//找到字符串末尾没有空格的位置</span></span><br><span class="line"> len--;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//如果前后都没有出现空格,返回字符串本身</span></span><br><span class="line"> <span class="keyword">return</span> ((st > <span class="number">0</span>) || (len < value.length)) ? substring(st, len) : <span class="keyword">this</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>去掉字符串前后的空格。</p><h3 id="String-intern"><a href="#String-intern" class="headerlink" title="String intern()"></a>String intern()</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a canonical representation for the string object.</span></span><br><span class="line"><span class="comment"> * <p></span></span><br><span class="line"><span class="comment"> * A pool of strings, initially empty, is maintained privately by the</span></span><br><span class="line"><span class="comment"> * class {<span class="doctag">@code</span> String}.</span></span><br><span class="line"><span class="comment"> * <p></span></span><br><span class="line"><span class="comment"> * When the intern method is invoked, if the pool already contains a</span></span><br><span class="line"><span class="comment"> * string equal to this {<span class="doctag">@code</span> String} object as determined by</span></span><br><span class="line"><span class="comment"> * the {<span class="doctag">@link</span> #equals(Object)} method, then the string from the pool is</span></span><br><span class="line"><span class="comment"> * returned. Otherwise, this {<span class="doctag">@code</span> String} object is added to the</span></span><br><span class="line"><span class="comment"> * pool and a reference to this {<span class="doctag">@code</span> String} object is returned.</span></span><br><span class="line"><span class="comment"> * <p></span></span><br><span class="line"><span class="comment"> * It follows that for any two strings {<span class="doctag">@code</span> s} and {<span class="doctag">@code</span> t},</span></span><br><span class="line"><span class="comment"> * {<span class="doctag">@code</span> s.intern() == t.intern()} is {<span class="doctag">@code</span> true}</span></span><br><span class="line"><span class="comment"> * if and only if {<span class="doctag">@code</span> s.equals(t)} is {<span class="doctag">@code</span> true}.</span></span><br><span class="line"><span class="comment"> * <p></span></span><br><span class="line"><span class="comment"> * All literal strings and string-valued constant expressions are</span></span><br><span class="line"><span class="comment"> * interned. String literals are defined in section 3.10.5 of the</span></span><br><span class="line"><span class="comment"> * <cite>The Java&trade; Language Specification</cite>.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> a string that has the same contents as this string, but is</span></span><br><span class="line"><span class="comment"> * guaranteed to be from a pool of unique strings.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">native</span> String <span class="title">intern</span><span class="params">()</span></span>;</span><br></pre></td></tr></table></figure><p>intern()是一个native方法,上面给出了Jdk注释,大概意思就是如果常量池里面有当前字符串,返回该字符串的引用;没有的话就把当前字符串放进常量池,再返回该字符串的引用。关于intern()这个方法个人感觉用起来要慎重,因为一旦常量池里面的字符串达到一定规模之后性能会下降不少。由于没有接触过大规模数据的操作,等有机会接触了再详细说一说intern()。</p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p> 从上文我们可以看出,String对象是不可变的。String类中每一个看起来会修改String值发方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象则纹丝不动。</p>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>算法练习2</title>
<link href="/2017/04/15/suan-fa-lian-xi-2/"/>
<url>/2017/04/15/suan-fa-lian-xi-2/</url>
<content type="html"><![CDATA[<h1 id="算法练习2"><a href="#算法练习2" class="headerlink" title="算法练习2"></a>算法练习2</h1><h2 id="Median-of-Two-Sorted-Arrays"><a href="#Median-of-Two-Sorted-Arrays" class="headerlink" title="Median of Two Sorted Arrays"></a>Median of Two Sorted Arrays</h2><p>There are two sorted arrays <strong>nums1</strong> and <strong>nums2</strong> 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><p><strong>Example 1:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nums1 = [1, 3]</span><br><span class="line">nums2 = [2]</span><br><span class="line"></span><br><span class="line">The median is 2.0</span><br></pre></td></tr></table></figure><p><strong>Example 2:</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nums1 = [1, 2]</span><br><span class="line">nums2 = [3, 4]</span><br><span class="line"></span><br><span class="line">The median is (2 + 3)/2 = 2.5</span><br></pre></td></tr></table></figure><h3 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目大意是寻找两个有序数组的中位数。这是一个比较经典的算法题了,首先比较直观的解法就是合并数组然后求中位数。合并再排序可以优化以下,先计算长度,合并一半中位数就出来了。这样减少了一半的时间。</p><p>其实根据上面的思路我们不难看出,求中位数就是查找序列中第k大的数(第k-1和k大的数,k是len/2)。那么二分查找是一个很好的选择。这个思路有一个难点就是双数组的奇偶长度不好处理,我借鉴了Manacher算法的那个骚操作,无论数组长度奇偶,通过插入特殊字符统统转换成奇数长度。我们先定义以下,将一个数组切成两个,左边最大为L,右边最小为R。则当L1>R2时,L1减小,R2增大,当L2>R1时,L2减小,R1增大(这里面有个割的概念在此不赘述)。上面那个加特殊字符的操作还有一个奇妙的地方,每个位置除以2得到原来元素的位置,同时无论是切在特殊符号后面还是切在数字后面L=(k-1)/2;R=(k)/2; (k为切的位置)若L==R,则L是切的数字原来的位置,反之,L是特殊字符前的数字之前的位置,R是特殊字符后的数字之前的位置。</p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//合并再计算中位数</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span>[] nums2)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> l1 = nums1.length;</span><br><span class="line"> <span class="keyword">int</span> l2 = nums2.length;</span><br><span class="line"> <span class="keyword">int</span> l = l1 + l2;</span><br><span class="line"> <span class="keyword">int</span>[] res = <span class="keyword">new</span> <span class="keyword">int</span>[l/<span class="number">2</span> + <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">int</span> cur1 = <span class="number">0</span>, cur2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < l/<span class="number">2</span> + <span class="number">1</span>; i++) {</span><br><span class="line"> <span class="keyword">int</span> a = cur1 < l1 ? nums1[cur1] : Integer.MAX_VALUE;</span><br><span class="line"> <span class="keyword">int</span> b = cur2 < l2 ? nums2[cur2] : Integer.MAX_VALUE;</span><br><span class="line"> <span class="keyword">if</span> (a < b) {</span><br><span class="line"> res[i] = a;</span><br><span class="line"> cur1++;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> res[i] = b;</span><br><span class="line"> cur2++;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (l % <span class="number">2</span> != <span class="number">0</span>) <span class="keyword">return</span> res[l / <span class="number">2</span>];</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">return</span> (res[l / <span class="number">2</span> - <span class="number">1</span>] + res[l / <span class="number">2</span>]) / <span class="number">2.0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//分治法</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span>[] nums2)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(nums1.length == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> MedofArray(nums2);</span><br><span class="line"> <span class="keyword">if</span>(nums2.length == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> MedofArray(nums1);</span><br><span class="line"> <span class="keyword">int</span> n = nums1.length;</span><br><span class="line"> <span class="keyword">int</span> m = nums2.length;</span><br><span class="line"> <span class="keyword">if</span>(n > m) <span class="comment">//保证数组1一定最短</span></span><br><span class="line"> <span class="keyword">return</span> findMedianSortedArrays(nums2,nums1);</span><br><span class="line"> <span class="keyword">int</span> L1 = <span class="number">0</span>, L2 = <span class="number">0</span>, R1 = <span class="number">0</span>, R2 = <span class="number">0</span>, c1, c2, lo = <span class="number">0</span>, hi = <span class="number">2</span> * n; <span class="comment">//虚拟加了'#'所以数组1是2*n+1长度</span></span><br><span class="line"> <span class="keyword">while</span>(lo <= hi) {<span class="comment">//二分</span></span><br><span class="line"> c1 = (lo + hi) / <span class="number">2</span>; <span class="comment">//c1是二分的结果</span></span><br><span class="line"> c2 = m + n - c1;</span><br><span class="line"> <span class="comment">//判断越界</span></span><br><span class="line"> L1 = (c1 == <span class="number">0</span>) ? Integer.MIN_VALUE : nums1[(c1 - <span class="number">1</span>) / <span class="number">2</span>];<span class="comment">//中位数在数组1中</span></span><br><span class="line"> R1 = (c1 == <span class="number">2</span> * n) ? Integer.MAX_VALUE : nums1[c1 / <span class="number">2</span>];<span class="comment">//中位数在数组1中</span></span><br><span class="line"> L2 = (c2 == <span class="number">0</span>) ? Integer.MIN_VALUE : nums2[(c2 - <span class="number">1</span>) / <span class="number">2</span>];<span class="comment">//中位数在数组2中</span></span><br><span class="line"> R2 = (c2 == <span class="number">2</span> * m) ? Integer.MAX_VALUE : nums2[c2 / <span class="number">2</span>];<span class="comment">//中位数在数组1中</span></span><br><span class="line"> <span class="keyword">if</span>(L1 > R2) hi = c1 - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(L2 > R1) lo = c1 + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> (Math.max(L1,L2) + Math.min(R1,R2)) / <span class="number">2.0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">double</span> <span class="title">MedofArray</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(nums.length == <span class="number">0</span>) <span class="keyword">return</span> - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> (nums[nums.length / <span class="number">2</span>] + nums[(nums.length-<span class="number">1</span>) / <span class="number">2</span>]) / <span class="number">2.0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>Java数组</title>
<link href="/2017/04/09/java-shu-zu/"/>
<url>/2017/04/09/java-shu-zu/</url>
<content type="html"><![CDATA[<h1 id="Java数组"><a href="#Java数组" class="headerlink" title="Java数组"></a>Java数组</h1><p> 在Java中,有大量的方式可以持有对象。而数组是一种效率最高的存储和随机访问对象引用序列的方式。数组是一个简单的线性序列,这使得元素访问非常快速。但在其生命周期中数组对象的大小被固定且不可改变。</p><p> 数组有三种初始化方法,下面看代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span>[] i1 = {<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>};<span class="comment">//第一种</span></span><br><span class="line"> <span class="keyword">int</span>[] i2 = <span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>};<span class="comment">//第二种</span></span><br><span class="line"> <span class="keyword">int</span>[] i3 = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">5</span>];第三种</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < i3.length; i++) {</span><br><span class="line"> i3[i] = i + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> print(i1);</span><br><span class="line"> System.out.println();</span><br><span class="line"> print(i2);</span><br><span class="line"> System.out.println();</span><br><span class="line"> print(i3);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span>[] ii)</span> </span>{<span class="comment">//输出数组元素</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i : ii) {</span><br><span class="line"> System.out.printf(<span class="string">"%d "</span>, i);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>反编译之后发现编译器做了如下处理:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>[] i1 = <span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>};</span><br><span class="line"><span class="keyword">int</span>[] i2 = <span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>};</span><br><span class="line"><span class="keyword">int</span>[] i3 = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">5</span>];</span><br></pre></td></tr></table></figure><p>可以看到表面上我们用到了三种初始化方法,实际上Java编译器背地里将第一种方法转成了第二种方法。但是第一种方法只能用在定义数组的时候初始化,而第二种和第三种方法就没有这个限制了。</p><p> 数组可以分为基本类型数组和引用数组,他们的唯一区别就是基本类型数组开辟的内存空间是直接存的值,而引用数组存的是对象的引用。</p><p> 我们分析上面三种初始化方法,无论是静态指定数组长度的第三种方法,还是动态推测数组长度的一二种方法。都会显式或隐式的使用关键字new,我们都知道关键字new用于内存分配,也就是说数组的数据存在堆区,栈区存放的是数组的引用。</p><p> 下面我们来讲一下二维数组,理解了上面的话二维数组就是小意思了。二维数组可以理解成一维数组的每个元素都是数组。二维数组就相当于构建了一个一维数组,堆区的每个元素存放的是元素数组的引用,而数组数据则放在堆区的另外一块内存中。</p><p> 多维数组的情况跟二维数组就比较类似了,无非就是数组元素是数组引用,内层数组元素又是引用,等等等等,以此类推。</p><p> 在Java中,很多容器的底层都是用数组实现的,数组因为是长度不可改变的,所以在开发中需要写更多的代码来适应各种情况,那么各种容器就是对一些常用的操作进行封装,对开发速度有显著提升。</p>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>Java自动装箱/拆箱</title>
<link href="/2017/04/02/java-zi-dong-zhuang-xiang-chai-xiang/"/>
<url>/2017/04/02/java-zi-dong-zhuang-xiang-chai-xiang/</url>
<content type="html"><![CDATA[<h1 id="Java自动装箱-拆箱"><a href="#Java自动装箱-拆箱" class="headerlink" title="Java自动装箱/拆箱"></a>Java自动装箱/拆箱</h1><h2 id="什么是装箱-拆箱"><a href="#什么是装箱-拆箱" class="headerlink" title="什么是装箱/拆箱"></a>什么是装箱/拆箱</h2><p> 在Java中一共有四类八种基本数据类型,在JDK1.5中,给这四类八种基本数据类型加入了包装类,对应如下:</p><table><thead><tr><th>基本类型</th><th>包装类型</th></tr></thead><tbody><tr><td>byte</td><td>Byte</td></tr><tr><td>short</td><td>Short</td></tr><tr><td>int</td><td>Integer</td></tr><tr><td>long</td><td>Long</td></tr><tr><td>float</td><td>Float</td></tr><tr><td>double</td><td>Double</td></tr><tr><td>boolean</td><td>Boolean</td></tr><tr><td>char</td><td>Character</td></tr></tbody></table><p>在很多时候我们需要在基本数据类型和其对应的包装类之间相互转换,所以从JavaSE5开始引入了自动装箱/拆箱。将一个int变量转换成Integer对象,这个过程叫做装箱;反之将Integer对象转换成int类型值,这个过程叫拆箱。以上装箱/拆箱是在编译class文件的时候自动完成的,因此叫做自动装箱/拆箱。下面是一个小例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Integer i3 = <span class="number">100</span>;</span><br><span class="line"> <span class="keyword">int</span> i4 = i3;</span><br><span class="line"> System.out.println(i3 + <span class="string">" "</span> + i4);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>反编译之后的class文件如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Main</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Integer i3 = Integer.valueOf(<span class="number">100</span>);</span><br><span class="line"> <span class="keyword">int</span> i4 = i3.intValue();</span><br><span class="line"> System.out.println(i3 + <span class="string">" "</span> + i4);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>从上面的例子可以看到,当我们把一个值为100的int型变量赋给Integer对象时,Java编译器自动对int进行装箱,也就是加上了valueOf方法。而当我们把Integer对象赋给int变量时,Java编译器自动对Integer对象进行拆箱,也就是intValue方法。八个包装类装箱所用到的方法都是valueOf方法,拆箱方法都是形如“变量名+Value”,如intValue,longValue。</p><h2 id="什么时候触发装箱-拆箱"><a href="#什么时候触发装箱-拆箱" class="headerlink" title="什么时候触发装箱/拆箱"></a>什么时候触发装箱/拆箱</h2><ul><li>赋值。将包装类对象赋值给基本数据类型或者反之,都会触发自动装箱拆箱。</li><li>运算符。在表达式中含有运算符时会触发装箱拆箱操作。</li><li>方法参数传递。将基本数据类型作为形参,而方法需要相应的包装类型,这时会触发装箱,反之亦然。</li></ul><p>下面是一个小例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="comment">//赋值</span></span><br><span class="line"> Integer i1 = <span class="number">100</span>;</span><br><span class="line"> Integer ii = <span class="number">1</span>;</span><br><span class="line"> <span class="comment">//算数运算符</span></span><br><span class="line"> i1 += ii;</span><br><span class="line"> i1 += <span class="number">2</span>;</span><br><span class="line"> <span class="comment">//自增自减运算符</span></span><br><span class="line"> i1++;</span><br><span class="line"> i1--;</span><br><span class="line"> <span class="comment">//关系运算符</span></span><br><span class="line"> <span class="keyword">boolean</span> b = i1 > <span class="number">10</span>;</span><br><span class="line"> b = i1 == <span class="number">10</span>;</span><br><span class="line"> b = i1 > ii;</span><br><span class="line"> <span class="comment">//位运算符</span></span><br><span class="line"> <span class="keyword">int</span> i = i1 | ii;</span><br><span class="line"> i = i1 |<span class="number">10</span>;</span><br><span class="line"> i = i1 << ii;</span><br><span class="line"> i = i1 << <span class="number">2</span>;</span><br><span class="line"> <span class="comment">//方法参数传递</span></span><br><span class="line"> func(<span class="number">10</span>, i1);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">func</span><span class="params">(Integer i1, <span class="keyword">int</span> i2)</span> </span>{}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>反编译之后的代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Main</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Integer i1 = Integer.valueOf(<span class="number">100</span>);</span><br><span class="line"> Integer ii = Integer.valueOf(<span class="number">1</span>);</span><br><span class="line"> i1 = Integer.valueOf(i1.intValue() + ii.intValue());</span><br><span class="line"> i1 = Integer.valueOf(i1.intValue() + <span class="number">2</span>);</span><br><span class="line"> i1 = Integer.valueOf(i1.intValue() + <span class="number">1</span>);</span><br><span class="line"> i1 = Integer.valueOf(i1.intValue() - <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">boolean</span> b = i1.intValue() > <span class="number">10</span>;</span><br><span class="line"> b = i1.intValue() == <span class="number">10</span>;</span><br><span class="line"> b = i1.intValue() > ii.intValue();</span><br><span class="line"> <span class="keyword">int</span> i = i1.intValue() | ii.intValue();</span><br><span class="line"> i = i1.intValue() | <span class="number">10</span>;</span><br><span class="line"> i = i1.intValue() << ii.intValue();</span><br><span class="line"> i = i1.intValue() << <span class="number">2</span>;</span><br><span class="line"> func(Integer.valueOf(<span class="number">10</span>), i1.intValue());</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">func</span><span class="params">(Integer i1, <span class="keyword">int</span> i2)</span> </span>{}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>上面的例子很清晰的展示了Java编译器会在什么情况下进行自动装箱拆箱。在此就不赘述了。</p><h3 id="需要注意的点"><a href="#需要注意的点" class="headerlink" title="需要注意的点"></a>需要注意的点</h3><p> 在使用==操作符判断两个包装类对象的值是否相等的时候实际上是在比较两个对象是否是同一个对象,而不是两个对象的值是否相等。只有==操作符两边有一个基本类型变量时才会触发拆箱。</p><h2 id="装箱-拆箱方法实现"><a href="#装箱-拆箱方法实现" class="headerlink" title="装箱/拆箱方法实现"></a>装箱/拆箱方法实现</h2><p> 拆箱方法很简单,以Integer为例,下面是Integer类的intValue方法实现:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">intValue</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> value;<span class="comment">//value是Integer类的一个私有常量,存放Integer对象的值</span></span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>其他七个包装类同理。</p><p> 装箱方法同样以Integer为例:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Integer <span class="title">valueOf</span><span class="params">(<span class="keyword">int</span> i)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (i >= IntegerCache.low && i <= IntegerCache.high)</span><br><span class="line"> <span class="keyword">return</span> IntegerCache.cache[i + (-IntegerCache.low)];</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Integer(i);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>上面的IntegerCache类是Integer的私有静态内部类,里面维护了一个Integer对象数组来实现缓存支持。其中最小值low为-128,最大值high默认为127,可以通过JVM启动参数修改。也就是说int值在-128到127之间的会返回缓存数组里的Integer对象引用,超出缓存范围的新建Integer对象。</p><p> 在Java中,Integer、Short、Byte、Long、Character这几个类的valueOf方法的实现是类似的,只有Integer类可以通过参数改变缓存范围,Byte、Short、Long的固定范围是[-128, 127], Character的范围是[0, 127]。Double和Float的valueOf方法的实现是类似的,浮点型包装类没有缓存机制。而对于Boolean类,它的实现中定义了2个静态成员属性,所以不会新建Boolean对象。</p>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
<entry>
<title>算法练习1</title>
<link href="/2017/04/01/suan-fa-lian-xi-1/"/>
<url>/2017/04/01/suan-fa-lian-xi-1/</url>
<content type="html"><![CDATA[<h1 id="算法练习1"><a href="#算法练习1" class="headerlink" title="算法练习1"></a>算法练习1</h1><h2 id="Add-TwoNumbers"><a href="#Add-TwoNumbers" class="headerlink" title="Add TwoNumbers"></a>Add TwoNumbers</h2><p>You are given two <strong>non-empty</strong> linked lists representing two non-negative integers. 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><p>You may assume the two numbers do not contain any leading zero, except the number 0 itself.</p><p><strong>Input:</strong> (2 -> 4 -> 3) + (5 -> 6 -> 4)<br><strong>Output:</strong> 7 -> 0 -> 8</p><h3 id="解题思路"><a href="#解题思路" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目意思大概就是整数相加,输入是两个反向存储整数的链表,以链表的形式输出两数之和。其实反向存储整数更方便两数相加,进位直接加到下一个节点上。设输入链表为l1、l2,当l1或l2不为空时,进行循环相加对应的位,并作进位处理。循环结束后判断时候仍有进位,若有就加一个进位节点。</p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * public class ListNode {</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * ListNode next;</span></span><br><span class="line"><span class="comment"> * ListNode(int x) { val = x; }</span></span><br><span class="line"><span class="comment"> * }</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> ListNode <span class="title">addTwoNumbers</span><span class="params">(ListNode l1, ListNode l2)</span> </span>{</span><br><span class="line"> ListNode head = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line"> ListNode p = l1, q = l2, curr = head;</span><br><span class="line"> <span class="keyword">int</span> carry = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (p != <span class="keyword">null</span> || q != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">int</span> x = (p != <span class="keyword">null</span>) ? p.val : <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> y = (q != <span class="keyword">null</span>) ? q.val : <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> sum = carry + x + y;</span><br><span class="line"> carry = sum / <span class="number">10</span>;</span><br><span class="line"> curr.next = <span class="keyword">new</span> ListNode(sum % <span class="number">10</span>);</span><br><span class="line"> curr = curr.next;</span><br><span class="line"> <span class="keyword">if</span> (p != <span class="keyword">null</span>) p = p.next;</span><br><span class="line"> <span class="keyword">if</span> (q != <span class="keyword">null</span>) q = q.next;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (carry > <span class="number">0</span>) {</span><br><span class="line"> curr.next = <span class="keyword">new</span> ListNode(carry);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> head.next;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="Longest-Substring-Without-Repeating-Characters"><a href="#Longest-Substring-Without-Repeating-Characters" class="headerlink" title="Longest Substring Without Repeating Characters"></a>Longest Substring Without Repeating Characters</h2><p>Given a string, find the length of the <strong>longest substring</strong> without repeating characters.</p><p><strong>Examples:</strong></p><p>Given <code>"abcabcbb"</code>, the answer is <code>"abc"</code>, which the length is 3.</p><p>Given <code>"bbbbb"</code>, the answer is <code>"b"</code>, with the length of 1.</p><p>Given <code>"pwwkew"</code>, the answer is <code>"wke"</code>, with the length of 3. Note that the answer must be a <strong>substring</strong>, <code>"pwke"</code> is a <em>subsequence</em> and not a substring.</p><h3 id="解题思路-1"><a href="#解题思路-1" class="headerlink" title="解题思路"></a>解题思路</h3><p>题目意思是求最长不重复子串。我的思路是先求出字符串包含的字母个数num,最长不重复子串的长度必然小于等于num。接下来循环判断子串就好了。</p><h3 id="代码-1"><a href="#代码-1" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span>[] chars = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line"> <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">char</span> c : s.toCharArray()) {</span><br><span class="line"> chars[c] = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> num = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">256</span>; i++) {</span><br><span class="line"> <span class="keyword">if</span> (chars[i] != <span class="number">0</span>) num++;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++) {</span><br><span class="line"> String ss;</span><br><span class="line"> <span class="keyword">if</span> (i > s.length() - num) {<span class="comment">//不重复子串小于num且在s末尾</span></span><br><span class="line"> ss = s.substring(i);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> ss = s.substring(i, i + num);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> t = len(ss);</span><br><span class="line"> res = t > res ? t : res;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> res;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">len</span><span class="params">(String s)</span> </span>{<span class="comment">//从左开始判断最长不重复子串长度</span></span><br><span class="line"> <span class="keyword">int</span>[] cs = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line"> <span class="keyword">int</span> lens = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < s.length(); i++) {</span><br><span class="line"> <span class="keyword">char</span> c = s.charAt(i);</span><br><span class="line"> <span class="keyword">if</span> (cs[c] == <span class="number">1</span>) <span class="keyword">return</span> lens;</span><br><span class="line"> <span class="keyword">else</span> cs[c] = <span class="number">1</span>;</span><br><span class="line"> lens++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> lens;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法练习 </category>
</categories>
</entry>
<entry>
<title>Java基本类型</title>
<link href="/2017/03/27/java-ji-ben-lei-xing/"/>
<url>/2017/03/27/java-ji-ben-lei-xing/</url>
<content type="html"><![CDATA[<h1 id="Java基本类型"><a href="#Java基本类型" class="headerlink" title="Java基本类型"></a>Java基本类型</h1><p> Java中的变量分为基本类型和引用类型。基本类型是一些特别小的、简单的变量,对于这种变量,直接存储值并放在堆栈中会更高效;引用类型是和Java对象所关联的一个操纵对象的标识符,可以通过new操作符使引用和相应的对象相关联。</p><p> Java提供了八中基本类型,其中有六种数字类型(四个整数型、两个浮点型),一种字符类型,一种布尔类型。每种基本类型所占的存储空间的大小都是确定的,它们并不像其他大多数语言那样随机器硬件架构的变化而变化。这就是Java比其他大多数语言所编写的程序更具可移植性的原因之一。</p><h2 id="byte"><a href="#byte" class="headerlink" title="byte"></a>byte</h2><ul><li>byte数据类型是8位的、有符号的、以二进制补码表示的整数;</li><li>byte能表示的最大值为 +127(2^7-1), 最小值为 -128(-2^7);</li><li>byte数据类型多用于I/O流,因为8bits是数据存取的常用最小单位。</li></ul><h2 id="short"><a href="#short" class="headerlink" title="short"></a>short</h2><ul><li>short数据类型是16位的、有符号的、以二进制补码表示的整数;</li><li>short能表示的最大值为 32767(2^15-1),最小值是 -32768(-2^15);</li><li>short类型常用于存储一些比较小的整数。</li></ul><h2 id="int"><a href="#int" class="headerlink" title="int"></a>int</h2><ul><li>int 数据类型是32位的、有符号的、以二进制补码表示的整数;</li><li>int能表示的最大值是 2,147,483,647(2^31 - 1),最小值是 -2,147,483,648(-2^31);</li><li>一般的整型变量默认为int类型。</li></ul><h2 id="long"><a href="#long" class="headerlink" title="long"></a>long</h2><ul><li>long 数据类型是 64 位的、有符号的、以二进制补码表示的整数;</li><li>long能表示的最大值是 9,223,372,036,854,775,807(2^63 -1),最小值是 -9,223,372,036,854,775,808(-2^63);</li><li>long主要用于存储比较大的整数。</li><li>long类型初始化需要在整数后加L/l,否则这个整数将作为int型解析,可能会导致溢出。</li></ul><h2 id="float"><a href="#float" class="headerlink" title="float"></a>float</h2><ul><li>float 数据类型是单精度的、32位的、有符号的、符合IEEE 754标准的浮点数;</li><li>float用来表示精确度较低的浮点数,有效范围为7位。</li></ul><h2 id="double"><a href="#double" class="headerlink" title="double"></a>double</h2><ul><li>double 数据类型是双精度的、64 位的、有符号的、符合IEEE 754标准的浮点数;</li><li>double用来表示精确度较高的浮点数,有效范围为16位。</li></ul><h2 id="boolean"><a href="#boolean" class="headerlink" title="boolean"></a>boolean</h2><ul><li>boolean数据类型只有ture、false两种值;</li><li>boolean类型所占存储空间的大小没有明确指定。</li></ul><h2 id="char"><a href="#char" class="headerlink" title="char"></a>char</h2><ul><li>char数据类型是16位的、单一的Unicode字符。</li><li>char最大值是 \uffff(即为65,535),最小值是 \u0000(即为0);</li></ul><h2 id="自动类型转换"><a href="#自动类型转换" class="headerlink" title="自动类型转换"></a>自动类型转换</h2><p> 不同的数据类型之间可以混合运算,Java会将它们转换成同一类型,然后再进行运算,转换从低级转换到高级:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//低--------------------------------------------高</span></span><br><span class="line"><span class="comment">//byte,short,char -> int -> long -> float -> double</span></span><br></pre></td></tr></table></figure><p>自动类型转换只能从低级向高级转换,不能对boolean进行类型转换。</p><h2 id="强制类型转换"><a href="#强制类型转换" class="headerlink" title="强制类型转换"></a>强制类型转换</h2><p> 强制类型转换可以从高级转换到低级,但有可能会损失精度。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="keyword">double</span> d = <span class="number">1.234567890123456789</span>;</span><br><span class="line"> <span class="keyword">float</span> f = (<span class="keyword">float</span>) d;</span><br><span class="line"> <span class="keyword">long</span> l = <span class="number">0xFFFFFFFFFL</span>;</span><br><span class="line"> <span class="keyword">int</span> i = (<span class="keyword">int</span>) l;</span><br><span class="line"> <span class="keyword">char</span> c = (<span class="keyword">char</span>) <span class="number">100</span>;</span><br><span class="line"> <span class="keyword">byte</span> b = (<span class="keyword">byte</span>) <span class="number">200</span>;</span><br><span class="line"> System.out.println(d);</span><br><span class="line"> System.out.println(f);</span><br><span class="line"> System.out.println(l);</span><br><span class="line"> System.out.println(i);</span><br><span class="line"> System.out.println(c);</span><br><span class="line"> System.out.println(b);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 运行结果为:</span></span><br><span class="line"><span class="comment">// 1.2345678901234567double的精度为16位,最后的89损失掉了</span></span><br><span class="line"><span class="comment">// 1.2345679float的精度为7位,后面的损失掉了</span></span><br><span class="line"><span class="comment">// 68719476735</span></span><br><span class="line"><span class="comment">// -1l的大小超出int的表示范围,溢出,高位舍去。</span></span><br><span class="line"><span class="comment">// d'd'的ascii码值为100</span></span><br><span class="line"><span class="comment">// -56200超出byte的表示范围,溢出,高位舍去。</span></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Java基础 </category>
</categories>
</entry>
</search>