| | 22 | |
| | 23 | 05-31日,我们按照陈小虎的建议与方法,继续完成上周的CodeKata活动的题目,本周末下午,由于平台组部分同事负责的项目有较紧急的事情[[BR]] |
| | 24 | 需要处理,所以没有参加,最后,由陈阳与邝巨恒来完成CodeKata活动。由李峰全程协调,指导。尽管这次CodeKata活动的人气少了许多,[[BR]] |
| | 25 | 但丝毫不影响陈阳与邝巨桓的信心与积极性,两位开发人员,结对编程,以轮流编写代码,另一位协助的方式,各个击破,完成了活动。[[BR]] |
| | 26 | 按照陈小虎给出的建议的,我们准备了生产环境的数据,用来测试 |
| | 27 | data.txt |
| | 28 | [[BR]]1 0 |
| | 29 | [[BR]]2 16428 |
| | 30 | [[BR]]7 15670 |
| | 31 | [[BR]]9 16427 |
| | 32 | [[BR]]19 1 |
| | 33 | [[BR]]22 16427 |
| | 34 | [[BR]]292 3 |
| | 35 | [[BR]]293 19 |
| | 36 | [[BR]]294 3 |
| | 37 | [[BR]]295 19 |
| | 38 | [[BR]]297 17136 |
| | 39 | [[BR]]298 19 |
| | 40 | [[BR]]301 19 |
| | 41 | [[BR]]304 19 |
| | 42 | [[BR]]305 19 |
| | 43 | [[BR]]306 19 |
| | 44 | [[BR]]307 19 |
| | 45 | [[BR]]308 19 |
| | 46 | [[BR]]312 17125 |
| | 47 | [[BR]]318 16420 |
| | 48 | [[BR]]322 9999 |
| | 49 | [[BR]]327 16428 |
| | 50 | [[BR]]388 16031 |
| | 51 | [[BR]]393 18975 |
| | 52 | [[BR]]715 9999 |
| | 53 | [[BR]]1307 19 |
| | 54 | [[BR]]2427 16427 |
| | 55 | [[BR]]2429 16428 |
| | 56 | [[BR]]8005 17148 |
| | 57 | [[BR]]9999 1 |
| | 58 | [[BR]]13351 17146 |
| | 59 | [[BR]]13352 1 |
| | 60 | [[BR]]13372 19 |
| | 61 | [[BR]]13373 19 |
| | 62 | [[BR]]13374 16428 |
| | 63 | [[BR]]13402 1 |
| | 64 | [[BR]]14033 19 |
| | 65 | [[BR]]14034 19 |
| | 66 | [[BR]]14077 19 |
| | 67 | [[BR]]14087 19 |
| | 68 | [[BR]]14093 19 |
| | 69 | [[BR]]14112 19 |
| | 70 | [[BR]]14119 19 |
| | 71 | [[BR]]14140 14034 |
| | 72 | [[BR]]14141 16425 |
| | 73 | [[BR]]14142 16425 |
| | 74 | [[BR]]14143 16411 |
| | 75 | [[BR]]14144 16411 |
| | 76 | [[BR]]14149 16425 |
| | 77 | [[BR]]14150 16425 |
| | 78 | [[BR]]14152 306 |
| | 79 | [[BR]]14153 306 |
| | 80 | [[BR]]14221 17133 |
| | 81 | [[BR]]14250 14077 |
| | 82 | [[BR]]14306 3 |
| | 83 | [[BR]]14359 14034 |
| | 84 | [[BR]]14360 293 |
| | 85 | [[BR]]14483 305 |
| | 86 | [[BR]]14493 14093 |
| | 87 | [[BR]]14505 295 |
| | 88 | [[BR]]............ |
| | 89 | [[BR]]19275 19 |
| | 90 | [[BR]]19276 16072 |
| | 91 | [[BR]]19285 16072 |
| | 92 | [[BR]]19287 16072 |
| | 93 | [[BR]]19295 16072 |
| | 94 | [[BR]]19305 16072 |
| | 95 | [[BR]]19315 16072 |
| | 96 | [[BR]]19335 15961 |
| | 97 | |
| | 98 | |
| | 99 | 下面帖出题目的解决方案的单元测试代码与实现代码[[BR]] |
| | 100 | 单元测试代码如下[[BR]] |
| | 101 | NodeContainerTest.java |
| | 102 | {{{ |
| | 103 | /* |
| | 104 | * To change this template, choose Tools | Templates |
| | 105 | * and open the template in the editor. |
| | 106 | */ |
| | 107 | package findex; |
| | 108 | |
| | 109 | import java.io.BufferedReader; |
| | 110 | import java.io.IOException; |
| | 111 | import java.io.InputStream; |
| | 112 | import java.io.InputStreamReader; |
| | 113 | import java.util.ArrayList; |
| | 114 | import java.util.List; |
| | 115 | import java.util.logging.Level; |
| | 116 | import java.util.logging.Logger; |
| | 117 | import org.junit.After; |
| | 118 | import org.junit.AfterClass; |
| | 119 | import org.junit.Assert; |
| | 120 | import org.junit.Before; |
| | 121 | import org.junit.BeforeClass; |
| | 122 | import org.junit.Test; |
| | 123 | import static org.junit.Assert.*; |
| | 124 | |
| | 125 | /** |
| | 126 | * |
| | 127 | * @author pc |
| | 128 | */ |
| | 129 | public class NodeContainerTest { |
| | 130 | @Before |
| | 131 | public void setUp() { |
| | 132 | //getTestData(); |
| | 133 | } |
| | 134 | |
| | 135 | @After |
| | 136 | public void tearDown() { |
| | 137 | } |
| | 138 | |
| | 139 | |
| | 140 | /** |
| | 141 | * Test of getRoute method, of class NodeContainer. |
| | 142 | */ |
| | 143 | @Test |
| | 144 | public void testGetRoute() { |
| | 145 | |
| | 146 | NodeContainer nContain = new NodeContainer(16); |
| | 147 | |
| | 148 | Node[] nodes = getTestData(); |
| | 149 | |
| | 150 | nContain.setContainer(nodes); |
| | 151 | |
| | 152 | int[] result = nContain.getRoute(2); |
| | 153 | |
| | 154 | Assert.assertEquals(0, result[0]); |
| | 155 | Assert.assertEquals(1, result[1]); |
| | 156 | Assert.assertEquals(16428, result[2]); |
| | 157 | Assert.assertEquals(2, result[3]); |
| | 158 | |
| | 159 | result = nContain.getRoute(8888); |
| | 160 | Assert.assertEquals(0,result.length); |
| | 161 | |
| | 162 | result = nContain.getRoute(0); |
| | 163 | Assert.assertEquals(0,result.length); |
| | 164 | |
| | 165 | result = nContain.getRoute(-99); |
| | 166 | Assert.assertEquals(0,result.length); |
| | 167 | |
| | 168 | } |
| | 169 | |
| | 170 | @Test |
| | 171 | public void testGetDirectChildren() { |
| | 172 | NodeContainer nContain = new NodeContainer(16); |
| | 173 | |
| | 174 | Node[] nodes = getTestData(); |
| | 175 | |
| | 176 | nContain.setContainer(nodes); |
| | 177 | |
| | 178 | //普通节点(正常情况) |
| | 179 | int[] result = nContain.getDirectChildren(9999); |
| | 180 | Assert.assertEquals(5, result.length); |
| | 181 | for (int id : result) { |
| | 182 | Assert.assertTrue(id == 322 || id == 715 || id == 15252 || id == 15253 || id == 15530); |
| | 183 | } |
| | 184 | |
| | 185 | //最根节点 |
| | 186 | result = nContain.getDirectChildren(0); |
| | 187 | Assert.assertEquals(1, result.length); |
| | 188 | Assert.assertEquals(1, result[0]); |
| | 189 | |
| | 190 | //不存在节点 |
| | 191 | result = nContain.getDirectChildren(-100); |
| | 192 | Assert.assertEquals(0, result.length); |
| | 193 | |
| | 194 | //末节点 |
| | 195 | result = nContain.getDirectChildren(18505); |
| | 196 | Assert.assertEquals(0, result.length); |
| | 197 | } |
| | 198 | |
| | 199 | @Test |
| | 200 | public void testGetChildren() { |
| | 201 | NodeContainer nContain = new NodeContainer(16); |
| | 202 | |
| | 203 | Node[] nodes = getTestData(); |
| | 204 | |
| | 205 | nContain.setContainer(nodes); |
| | 206 | |
| | 207 | //普通节点(正常情况) |
| | 208 | |
| | 209 | int[] result = nContain.getChildren(16428); |
| | 210 | for(int i=0; i<result.length; i++){ |
| | 211 | System.out.println(result[i]); |
| | 212 | } |
| | 213 | |
| | 214 | for (int id : result) { |
| | 215 | Assert.assertTrue(id == 16816 || id == 16031 || id == 15402 |
| | 216 | || id == 15051 || id == 13374 || id == 2429 |
| | 217 | || id == 327 || id == 27 || id == 388 || id == 15244 |
| | 218 | || id == 15834 || id == 2); |
| | 219 | } |
| | 220 | |
| | 221 | //子只有一级 |
| | 222 | result = nContain.getChildren(18975); |
| | 223 | for (int id : result) { |
| | 224 | Assert.assertTrue(id == 393 || id == 18976 || id == 18985); |
| | 225 | } |
| | 226 | |
| | 227 | //最根节点 |
| | 228 | result = nContain.getChildren(1); |
| | 229 | //Assert.assertEquals(nodes.length - 1, result.length); |
| | 230 | |
| | 231 | //不存在节点 |
| | 232 | result = nContain.getDirectChildren(-100); |
| | 233 | Assert.assertEquals(0, result.length); |
| | 234 | |
| | 235 | //末节点 |
| | 236 | result = nContain.getDirectChildren(18505); |
| | 237 | Assert.assertEquals(0, result.length); |
| | 238 | } |
| | 239 | |
| | 240 | public Node[] getTestData() { |
| | 241 | |
| | 242 | List<String> lines = new ArrayList<String>(1500); |
| | 243 | InputStream in = this.getClass().getResourceAsStream("/data.txt"); |
| | 244 | BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| | 245 | String line = null; |
| | 246 | try{ |
| | 247 | while((line = reader.readLine()) != null){ |
| | 248 | lines.add(line); |
| | 249 | } |
| | 250 | }catch(Exception ex){ |
| | 251 | |
| | 252 | }finally{ |
| | 253 | if(reader != null){ |
| | 254 | try { |
| | 255 | reader.close(); |
| | 256 | } catch (IOException ex) { |
| | 257 | Logger.getLogger(NodeContainerTest.class.getName()).log(Level.SEVERE, null, ex); |
| | 258 | } |
| | 259 | } |
| | 260 | } |
| | 261 | Node[] nodes = new Node[lines.size()]; |
| | 262 | for(int i=0, len = lines.size(); i < len; i++){ |
| | 263 | String[] data_line = lines.get(i).split("\\s"); |
| | 264 | Node node = new Node(Integer.valueOf(data_line[0]),Integer.valueOf(data_line[1])); |
| | 265 | nodes[i] = node; |
| | 266 | } |
| | 267 | |
| | 268 | return nodes; |
| | 269 | |
| | 270 | } |
| | 271 | |
| | 272 | |
| | 273 | |
| | 274 | } |
| | 275 | |
| | 276 | }}} |
| | 277 | |
| | 278 | 实现代码如下[[BR]] |
| | 279 | Node.java |
| | 280 | {{{ |
| | 281 | |
| | 282 | /* |
| | 283 | * To change this template, choose Tools | Templates |
| | 284 | * and open the template in the editor. |
| | 285 | */ |
| | 286 | package findex; |
| | 287 | |
| | 288 | /** |
| | 289 | * |
| | 290 | * @author pc |
| | 291 | */ |
| | 292 | public class Node { |
| | 293 | private int id; |
| | 294 | private int pid; |
| | 295 | |
| | 296 | public Node(int id, int pid) { |
| | 297 | this.id = id; |
| | 298 | this.pid = pid; |
| | 299 | } |
| | 300 | |
| | 301 | public int getId() { |
| | 302 | return id; |
| | 303 | } |
| | 304 | |
| | 305 | public void setId(int id) { |
| | 306 | this.id = id; |
| | 307 | } |
| | 308 | |
| | 309 | public int getPid() { |
| | 310 | return pid; |
| | 311 | } |
| | 312 | |
| | 313 | public void setPid(int pid) { |
| | 314 | this.pid = pid; |
| | 315 | } |
| | 316 | |
| | 317 | } |
| | 318 | |
| | 319 | }}} |
| | 320 | NodeContainer.java |
| | 321 | {{{ |
| | 322 | package findex; |
| | 323 | |
| | 324 | /** |
| | 325 | * |
| | 326 | * @author pc |
| | 327 | */ |
| | 328 | public class NodeContainer { |
| | 329 | |
| | 330 | private int limit; |
| | 331 | private Node[] nodes; |
| | 332 | private static final int ROOT_ID = 0; |
| | 333 | |
| | 334 | public int getLimit() { |
| | 335 | return limit; |
| | 336 | } |
| | 337 | |
| | 338 | public void setLimit(int limit) { |
| | 339 | this.limit = limit; |
| | 340 | } |
| | 341 | |
| | 342 | public Node[] getContainer() { |
| | 343 | return nodes; |
| | 344 | } |
| | 345 | |
| | 346 | public void setContainer(Node[] container) { |
| | 347 | this.nodes = container; |
| | 348 | } |
| | 349 | |
| | 350 | public NodeContainer(int limit) { |
| | 351 | this.limit = limit; |
| | 352 | this.nodes = new Node[this.limit]; |
| | 353 | } |
| | 354 | |
| | 355 | public int getParentId(Node[] nodes,int id){ |
| | 356 | for(int i=0, len = nodes.length; i< len; i++){ |
| | 357 | Node current = nodes[i]; |
| | 358 | if(id == current.getId()){ |
| | 359 | return current.getPid(); |
| | 360 | } |
| | 361 | } |
| | 362 | return -1; |
| | 363 | } |
| | 364 | |
| | 365 | /** |
| | 366 | * 获取根版到子版的路径 |
| | 367 | * |
| | 368 | * @param id 子版ID |
| | 369 | * @return |
| | 370 | */ |
| | 371 | public int[] getRoute(int id) { |
| | 372 | int[] result = new int[limit]; |
| | 373 | int index = 0; |
| | 374 | if (nodes == null) { |
| | 375 | throw new RuntimeException("没数据"); |
| | 376 | } |
| | 377 | |
| | 378 | if(getParentId(nodes,id) == -1){ |
| | 379 | return new int[0]; |
| | 380 | } |
| | 381 | |
| | 382 | int count = 0; |
| | 383 | |
| | 384 | int tmpId = id; |
| | 385 | while(tmpId != -1) { |
| | 386 | result[index] = tmpId; |
| | 387 | index++; |
| | 388 | tmpId = getParentId(this.nodes, tmpId); |
| | 389 | count++; |
| | 390 | } |
| | 391 | int[] result2 = new int[count]; |
| | 392 | for(int i = count -1, j=0; i>=0 ; i--,j++){ |
| | 393 | result2[j] = result[i]; |
| | 394 | |
| | 395 | } |
| | 396 | return result2; |
| | 397 | } |
| | 398 | |
| | 399 | // 根据fid,获取直接子版 |
| | 400 | public int[] getDirectChildren(int id) { |
| | 401 | int[] result = new int[nodes.length]; |
| | 402 | int index = 0; |
| | 403 | for (Node node : nodes) { |
| | 404 | if (node.getPid() == id) { |
| | 405 | result[index] = node.getId(); |
| | 406 | index++; |
| | 407 | } |
| | 408 | } |
| | 409 | int[] tmp = new int[index]; |
| | 410 | System.arraycopy(result, 0, tmp, 0, index); |
| | 411 | return tmp; |
| | 412 | } |
| | 413 | |
| | 414 | //根据fid,获取所有子版 |
| | 415 | public int[] getChildren(int id){ |
| | 416 | int[] result = new int[nodes.length]; |
| | 417 | |
| | 418 | //递归将子版添加到result中 |
| | 419 | recuri(result,id); |
| | 420 | int len = 0; |
| | 421 | for(int i=0; i<result.length; i++){ |
| | 422 | if(result[i] == 0){ |
| | 423 | break; |
| | 424 | } |
| | 425 | len++; |
| | 426 | } |
| | 427 | int[] tmp = new int[len]; |
| | 428 | System.arraycopy(result, 0, tmp, 0, len); |
| | 429 | return tmp; |
| | 430 | } |
| | 431 | |
| | 432 | public void recuri(int[] childs,int id) { |
| | 433 | |
| | 434 | int[] directChildren = getDirectChildren(id); |
| | 435 | for(int i=0; i<directChildren.length; i++){ |
| | 436 | if(hasChild(directChildren[i])){ |
| | 437 | recuri(childs,directChildren[i]); |
| | 438 | } |
| | 439 | |
| | 440 | } |
| | 441 | int posi = 0;// 记录childs的长度 |
| | 442 | for(int j=0; j<childs.length; j++){ |
| | 443 | if(childs[j] == 0){ |
| | 444 | posi = j; |
| | 445 | break; |
| | 446 | } |
| | 447 | } |
| | 448 | System.arraycopy(directChildren, 0, childs, posi, directChildren.length); |
| | 449 | |
| | 450 | } |
| | 451 | |
| | 452 | private boolean hasChild(int id) { |
| | 453 | for (Node node : nodes) { |
| | 454 | if (node.getPid() == id) { |
| | 455 | return true; |
| | 456 | } |
| | 457 | } |
| | 458 | return false; |
| | 459 | } |
| | 460 | } |
| | 461 | |
| | 462 | }}} |