001 /* 002 * www.ti.bfh.ch 003 * 004 * Copyright 2007, Berne University of Applied Sciences, 005 * School of Engineering and Information Technology 006 * and individual contributors as indicated by the @authors tag. 007 * 008 * This is free software; you can redistribute it and/or modify it under the terms of the 009 * GNU Lesser General Public License as published by the Free Software Foundation; 010 * either version 3 of the License, or (at your option) any later version. 011 * 012 * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 013 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 014 * See the GNU Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License along with this software; 017 * if not, see <http://www.gnu.org/licenses/>. 018 * 019 */ 020 package ch.bfh.algo.example; 021 import java.util.List; 022 023 import ch.bfh.algo.Position; 024 import ch.bfh.algo.Sequence; 025 import ch.bfh.algo.sequence.ArraySequence; 026 import ch.bfh.algo.sequence.LinkedSequence; 027 028 /** 029 * The class <code>SequencesSortExamples</code> contains samples of 030 * the use of a <code>Sequence</code>. 031 * 032 * This class has no mean of being used, it is only a sample of 033 * possible applications of the <code>ch.bfh.algo</code> algorithmic 034 * framework. 035 * 036 * @author <a href="mailto:">Emmanuel Benoist</a> 037 * @version 1.0 038 */ 039 public class SequencesSortExamples{ 040 041 private class MyString{ 042 Position<MyString> positionInList1; 043 Position<MyString> positionInList2; 044 045 String str; 046 047 MyString(String s){ 048 str=s; 049 050 } 051 052 053 /** 054 * Get the PositionInList1 value. 055 * @return the PositionInList1 value. 056 */ 057 public Position<MyString> getPositionInList1() { 058 return positionInList1; 059 } 060 061 /** 062 * Set the PositionInList1 value. 063 * @param newPositionInList1 The new PositionInList1 value. 064 */ 065 public void setPositionInList1(Position<MyString> newPositionInList1) { 066 this.positionInList1 = newPositionInList1; 067 } 068 069 070 /** 071 * Get the PositionInList2 value. 072 * @return the PositionInList2 value. 073 */ 074 public Position<MyString> getPositionInList2() { 075 return positionInList2; 076 } 077 078 /** 079 * Set the PositionInList2 value. 080 * @param newPositionInList2 The new PositionInList2 value. 081 */ 082 public void setPositionInList2(Position<MyString> newPositionInList2) { 083 this.positionInList2 = newPositionInList2; 084 } 085 086 public String toString(){ 087 return str; 088 } 089 } 090 091 092 /** 093 * The method <code>bubbleSortArrayLike</code> is a very simple 094 * Bubble Sort written for the Java Collection Framework. 095 * 096 * This method does not include any reference to the 097 * *<code>ch.bfh.algo</code> framework. However, this works fine 098 * *with an <code>ArraySequence</code> since it is fully Java 099 * *Collection Framework compatible. 100 * 101 */ 102 public static void bubbleSortArrayLike(List<Integer> list){ 103 int size = list.size(); 104 for (int pass=0; pass < size ; pass++){ 105 for(int index = 0; index< size-(pass+1);index++){ 106 if(list.get(index)>list.get(index+1)){ 107 Integer tmp = list.get(index); 108 list.set(index,list.get(index+1)); 109 list.set(index+1,tmp); 110 } 111 } 112 } 113 114 } 115 116 117 /** 118 * This Bubble sort algorithm has been implemented using a 119 * <code>Sequence</code>. 120 * 121 * It is using also the <code>Position</code>s that are the 122 * place-holders of a <code>Sequence</code> 123 * 124 */ 125 public static void bubbleSortSequence(Sequence<Integer> seq){ 126 Position<Integer> pos1,pos2; 127 boolean unsorted=false; 128 while(unsorted){ 129 unsorted=true; 130 pos1 = seq.first(); 131 while(pos1!=seq.last()){ 132 pos2=seq.after(pos1); 133 if( pos1.element()> pos2.element()){ 134 Integer tmp = pos1.element(); 135 seq.replace(pos1,pos2.element()); 136 seq.replace(pos2,tmp); 137 } 138 } 139 } 140 } 141 142 143 /** 144 * This method <code>bubbleSortExamples</code> is used to run the 145 * two other methods: <code>bubbleSortArrayLike</code> and 146 * <code>bubbleSortSequence</code>. 147 * 148 * The first method is using only the standard Collection 149 * Framework syntax and interfaces. Whereas the second is using a 150 * syntax typical for the <code>ch.bfh.algo</code> framework. 151 */ 152 public static void bubbleSortExamples(){ 153 System.out.println("Example Using Bubble Sort: O(n^2)"); 154 System.out.println("Creation of an Integer ArraySequence:"); 155 List<Integer> seq1 = new ArraySequence<Integer>(); 156 seq1.add(10); 157 seq1.add(20); 158 seq1.add(30); 159 seq1.add(40); 160 seq1.add(1); 161 System.out.println(seq1); 162 System.out.println("we use a standard (Java Collection Framework) algorithm"); 163 bubbleSortArrayLike(seq1); 164 System.out.println("After Sort:"); 165 System.out.println(seq1); 166 System.out.println(""); 167 168 } 169 170 /** 171 * The method <code>removeFirstThreeOfL1FromL2</code> removes the 172 * tree first elements of the sequence1 from the sequence2. 173 * 174 * This is can not be done efficiently using classes of the java 175 * collection framework and is very efficient in our case 176 * (regardless of the number of elements in sequence1 or 177 * sequence2, this operation is O(1)). 178 * 179 */ 180 public static void removeFirstThreeOfL1FromL2(Sequence<MyString> sequence1, 181 Sequence<MyString> sequence2){ 182 Position<MyString> pos=sequence1.first(); 183 for(int i=0;i<3;i++){ 184 MyString s=sequence1.element(pos); 185 sequence2.delete(s.getPositionInList2()); 186 pos=sequence1.after(pos); 187 } 188 189 } 190 191 192 /** 193 * The method <code>positionEfficiencyExample</code> shows the 194 * advantage of the <code>Sequence</code> compared to standard 195 * structures such as <code>java.util.List</code>. 196 * 197 * We create two lists containing the same items. In each Item we 198 * save its <code>Position</code> in both of the lists. Afterwhat, 199 * it is possible to remove an item from a list in time 200 * O(1). Doing the same with <code>java.util.LinkedList</code> 201 * requires O(n), since it can not use a way to refere to an item 202 * inside a list (there is no place-holder like the 203 * <code>Position</code>). 204 * 205 */ 206 public void positionEfficiencyExample(){ 207 MyString s1=new MyString("1"); 208 MyString s2=new MyString("2"); 209 MyString s3=new MyString("3"); 210 MyString s4=new MyString("4"); 211 MyString s5=new MyString("5"); 212 MyString s6=new MyString("6"); 213 Sequence<MyString> seq1 = new ArraySequence<MyString>(); 214 s1.setPositionInList1(seq1.insert(s1)); 215 s2.setPositionInList1(seq1.insert(s2)); 216 s3.setPositionInList1(seq1.insert(s3)); 217 s4.setPositionInList1(seq1.insert(s4)); 218 s5.setPositionInList1(seq1.insert(s5)); 219 s6.setPositionInList1(seq1.insert(s6)); 220 221 Sequence<MyString> seq2 = new LinkedSequence<MyString>(); 222 s1.setPositionInList2(seq2.insert(s1)); 223 s6.setPositionInList2(seq2.insert(s6)); 224 s5.setPositionInList2(seq2.insert(s5)); 225 s4.setPositionInList2(seq2.insert(s4)); 226 s2.setPositionInList2(seq2.insert(s2)); 227 s3.setPositionInList2(seq2.insert(s3)); 228 229 System.out.println("----------------"); 230 System.out.println("Example for comparing two sequences: Remove elements from L1 in L2"); 231 System.out.println("Each removal is done in time O(1), which can not be done with other data structures in Java."); 232 System.out.println("Start"); 233 System.out.println("L1="+seq1); 234 System.out.println("L2="+seq2); 235 removeFirstThreeOfL1FromL2(seq1,seq2); 236 System.out.println("Result:"); 237 System.out.println("L1="+seq1); 238 System.out.println("L2="+seq2); 239 System.out.println("----------------"); 240 241 } 242 243 244 public static Sequence<Integer> mergeUsingPositions(Sequence<Integer> seq1, 245 Sequence<Integer> seq2, 246 Sequence<Integer> result){ 247 // We first expurgate the content of the result sequence 248 /*if(!result.isEmpty()){ 249 Position<Integer> pos = result.first(); 250 while (pos!=null){ 251 if(pos == result.last()){ 252 result.delete(pos); 253 pos = null; 254 } 255 else{ 256 Position<Integer> after = result.after(pos); 257 result.delete(pos); 258 pos=after; 259 } 260 } 261 }*/ 262 result.clear(); 263 Position<Integer> posSeq1,posSeq2; 264 posSeq1=seq1.first(); 265 posSeq2=seq2.first(); 266 while(posSeq1!=null && posSeq2!=null){ 267 if(posSeq1.element() < posSeq2.element()){ 268 result.add(posSeq1.element()); 269 if(posSeq1 != seq1.last()){ 270 posSeq1 = seq1.after(posSeq1); 271 } 272 else{ 273 posSeq1 = null; 274 } 275 } 276 else{ 277 result.add(posSeq2.element()); 278 if(posSeq2 != seq2.last()){ 279 posSeq2 = seq2.after(posSeq2); 280 } 281 else{ 282 posSeq2 = null; 283 } 284 } 285 286 } 287 288 if(posSeq2==null){ 289 while(posSeq1!=null){ 290 result.add(posSeq1.element()); 291 if(posSeq1 != seq1.last()){ 292 posSeq1 = seq1.after(posSeq1); 293 } 294 else{ 295 posSeq1 = null; 296 } 297 } 298 } 299 else{ 300 while(posSeq2!=null){ 301 result.add(posSeq2.element()); 302 if(posSeq2 != seq2.last()){ 303 posSeq2 = seq2.after(posSeq2); 304 } 305 else{ 306 posSeq2 = null; 307 } 308 } 309 } 310 return result; 311 } 312 313 public static void splitUsingIterator(List<Integer> seq, 314 List<Integer> res1, 315 List<Integer> res2){ 316 int i=0; 317 for (Integer item : seq){ 318 if(i++%2==0){ 319 res1.add(item); 320 } 321 else{ 322 res2.add(item); 323 } 324 325 } 326 327 } 328 329 330 /** 331 * The method <code>mergeSort</code> implements the merge sort 332 * algorithm using the <code>Sequence</code> interface. 333 * 334 * It uses on one side the compatibility with the java collection 335 * framework in the function <code>splitUsingIterator</code>. 336 * 337 *The second part, merging is done using <code>Position</code>s 338 */ 339 public static void mergeSort(Sequence<Integer> seq){ 340 if(seq.size()< 2){ 341 return; 342 } 343 Sequence<Integer> seq1 = new LinkedSequence<Integer>(); 344 Sequence<Integer> seq2 = new LinkedSequence<Integer>(); 345 splitUsingIterator(seq,seq1,seq2); 346 mergeSort(seq1); 347 mergeSort(seq2); 348 mergeUsingPositions(seq1,seq2,seq); 349 350 } 351 352 public static void testMerge(){ 353 ArraySequence<Integer> seq1 = new ArraySequence<Integer>(); 354 seq1.add(10); 355 seq1.add(20); 356 seq1.add(30); 357 seq1.add(40); 358 seq1.add(100); 359 LinkedSequence<Integer> seq2 = new LinkedSequence<Integer>(); 360 seq2.add(1); 361 seq2.add(2); 362 seq2.add(3); 363 seq2.add(43); 364 seq2.add(130); 365 seq2.add(132); 366 seq2.add(133); 367 368 Sequence<Integer> seq = new LinkedSequence<Integer>(); 369 mergeUsingPositions(seq1,seq2,seq); 370 System.out.println("----------------"); 371 System.out.println("Start Merge Test"); 372 System.out.println("L1="+seq1); 373 System.out.println("L2="+seq2); 374 System.out.println("Result="+seq); 375 System.out.println("----------------"); 376 System.out.println(" "); 377 378 } 379 380 /** 381 * This method tests if the method split 382 * (<code>splitUsingIterator()</code>) works as expected 383 * 384 * 385 */ 386 public static void testSplit(){ 387 388 LinkedSequence<Integer> seq = new LinkedSequence<Integer>(); 389 seq.add(10); 390 seq.add(20); 391 seq.add(30); 392 seq.add(40); 393 seq.add(100); 394 seq.add(1); 395 seq.add(2); 396 seq.add(3); 397 seq.add(43); 398 seq.add(130); 399 seq.add(132); 400 seq.add(133); 401 402 LinkedSequence<Integer> seqRes1 = new LinkedSequence<Integer>(); 403 404 LinkedSequence<Integer> seqRes2 = new LinkedSequence<Integer>(); 405 406 splitUsingIterator(seq,seqRes1,seqRes2); 407 408 System.out.println("----------------"); 409 System.out.println("Start Split Test"); 410 System.out.println("L="+seq); 411 System.out.println("Result1="+seqRes1); 412 System.out.println("Result2="+seqRes2); 413 System.out.println("----------------"); 414 System.out.println(" "); 415 416 417 } 418 419 420 /** 421 * This method tests if the merge sort algorithm 422 * (<code>mergeSort()</code>) works as expected 423 * 424 * 425 */ 426 public static void testMergeSort(){ 427 LinkedSequence<Integer> seq = new LinkedSequence<Integer>(); 428 seq.add(10); 429 seq.add(20); 430 seq.add(30); 431 seq.add(40); 432 seq.add(100); 433 seq.add(1); 434 seq.add(2); 435 seq.add(3); 436 seq.add(43); 437 seq.add(130); 438 seq.add(132); 439 seq.add(133); 440 441 442 System.out.println("----------------"); 443 System.out.println("Start MergeSort"); 444 System.out.println("L_Init="+seq); 445 mergeSort(seq); 446 System.out.println("L_Result="+seq); 447 System.out.println("----------------"); 448 System.out.println(" "); 449 450 451 } 452 453 454 public void run(){ 455 bubbleSortExamples(); 456 positionEfficiencyExample(); 457 testMerge(); 458 testSplit(); 459 testMergeSort(); 460 } 461 462 public static void main(String[] args){ 463 System.out.println("Start of the Examples"); 464 new SequencesSortExamples().run(); 465 } 466 467 }