1 CSC 427: Data Structures and Algorithm Analysis Fall 2010 Brute force approach  KISS vs. generality  HW2 examples: League Standings, Enigma, Musical.

Slides:



Advertisements
Similar presentations
Recursion Chapter 14. Overview Base case and general case of recursion. A recursion is a method that calls itself. That simplifies the problem. The simpler.
Advertisements

1 CSC 427: Data Structures and Algorithm Analysis Fall 2008 Inheritance and efficiency  ArrayList  SortedArrayList  tradeoffs with adding/searching.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with Java From Control Structures through Data Structures by.
1 CSC 427: Data Structures and Algorithm Analysis Fall 2006 Inheritance and efficiency  ArrayList  SortedArrayList  tradeoffs with adding/searching.
CHAPTER 13 Recursion. Recursive Solution A recursive solution  solves a problem by solving a smaller instance of the problem. Example  How do we go.
Backtracking.
1 CSC 222: Computer Programming II Spring 2005 Searching and efficiency  sequential search  big-Oh, rate-of-growth  binary search  example: spell checker.
Data Structures Introduction Phil Tayco Slide version 1.0 Jan 26, 2015.
Chapter 14: Sorting and searching. Chapter Goals To study several sorting and searching algorithms To appreciate that algorithms for the same task can.
1 CSC 222: Computer Programming II Spring 2004 Searching and efficiency  sequential search  big-Oh, rate-of-growth  binary search Class design  templated.
1 CSC 222: Computer Programming II Spring 2005 Stacks and recursion  stack ADT  push, pop, peek, empty, size  ArrayList-based implementation, java.util.Stack.
1 CSC 222: Object-Oriented Programming Spring 2012 Lists, data storage & access  ArrayList class  methods: add, get, size, remove, contains, set, indexOf,
1 CSC 222: Object-Oriented Programming Spring 2013 Java interfaces & polymorphism  Comparable interface  defining an interface  implementing an interface.
Recitation 1 CS0445 Data Structures Mehmud Abliz.
1 CSC 222: Object-Oriented Programming Spring 2012 Searching and sorting  sequential search  algorithm analysis: big-Oh, rate-of-growth  binary search.
1 CSC 321: Data Structures Fall 2013 HW1 autopsy 1.parallel lists 2.Comparable Word objects 3.Comparators 4.MVC pattern.
1 CSC 222: Object-Oriented Programming Spring 2012 recursion & sorting  recursive algorithms  base case, recursive case  silly examples: fibonacci,
1 CSC 222: Object-Oriented Programming Spring 2012 Object-oriented design  example: word frequencies w/ parallel lists  exception handling  System.out.format.
1 CSC 221: Computer Programming I Spring 2008 ArrayLists and arrays  example: letter frequencies  autoboxing/unboxing  ArrayLists vs. arrays  example:
CIS 068 Welcome to CIS 068 ! Stacks and Recursion.
Passing Other Objects Strings are called immutable which means that once a String object stores a value, it never changes –recall when we passed a message.
CSE 143 Lecture 11 Maps Grammars slides created by Alyssa Harding
The while Loop Syntax while (condition) { statements } As long condition is true, the statements in the while loop execute.
Data Design and Implementation. Definitions of Java TYPES Atomic or primitive type A data type whose elements are single, non-decomposable data items.
1 CSC 221: Computer Programming I Fall 2004 Lists, data access, and searching  ArrayList class  ArrayList methods: add, get, size, remove  example:
1 CSC 222: Object-Oriented Programming Spring 2013 Lists, data storage & access  ArrayList class  methods: add, get, size, remove, contains, set, indexOf,
1 CSC 221: Computer Programming I Spring 2008 Lists, data storage & access  ArrayList class  methods: add, get, size, remove, contains, set, indexOf,
Honors Track: Competitive Programming & Problem Solving Optimization Problems Kevin Verbeek.
ArrayList Class An ArrayList is an object that contains a sequence of elements that are ordered by position. An ArrayList is an object that contains a.
1 CSC 222: Object-Oriented Programming Spring 2013 Searching and sorting  sequential search vs. binary search  algorithm analysis: big-Oh, rate-of-growth.
(c) University of Washington15-1 CSC 143 Java List Implementation via Arrays Reading: 13.
1 CSC 427: Data Structures and Algorithm Analysis Fall 2011 Decrease & conquer  previous examples  search spaces examples: travel, word ladder  depth.
1 CSC 427: Data Structures and Algorithm Analysis Fall 2011 Space vs. time  space/time tradeoffs  hashing  hash table, hash function  linear probing.
(c) University of Washington16-1 CSC 143 Java Linked Lists Reading: Ch. 20.
(c) University of Washington16-1 CSC 143 Java Lists via Links Reading: Ch. 23.
1 CSC 427: Data Structures and Algorithm Analysis Fall 2010 Java Collections & List implementations  Collection classes: ─List (ArrayList, LinkedList),
Searching and Sorting Searching: Sequential, Binary Sorting: Selection, Insertion, Shell.
COMP108 Algorithmic Foundations Polynomial & Exponential Algorithms
Week 15 – Wednesday.  What did we talk about last time?  Review up to Exam 1.
1 CSC 421: Algorithm Design and Analysis Spring 2014 Brute force approach & efficiency  league standings example  KISS vs. generality  exhaustive search:
1 CSC 221: Computer Programming I Fall 2005 simple conditionals and expressions  if statements, if-else  increment/decrement, arithmetic assignments.
Computer Science 1620 Sorting. cases exist where we would like our data to be in ascending (descending order) binary searching printing purposes selection.
Sorting & Searching Geletaw S (MSC, MCITP). Objectives At the end of this session the students should be able to: – Design and implement the following.
COMP 110: Spring Announcements Program 5 Milestone 1 was due today Program 4 has been graded.
19-Mar-16 Collections and ArrayLists.. 2 Collections Why use Collections. Collections and Object-Orientation. ArrayLists. Special Features. Creating ArrayLists.
CSC 427: Data Structures and Algorithm Analysis
CSC 421: Algorithm Design and Analysis
CSC 222: Object-Oriented Programming Spring 2017
CSC 222: Object-Oriented Programming
CSC 222: Object-Oriented Programming Spring 2015
CSC 421: Algorithm Design and Analysis
CSC 321: Data Structures Fall 2016 Balanced and other trees
CS1020 – Data Structures And Algorithms 1 AY Semester 2
CSC 222: Object-Oriented Programming
CSC 421: Algorithm Design and Analysis
COMP108 Algorithmic Foundations Polynomial & Exponential Algorithms
CSC 222: Object-Oriented Programming
CSC 222: Object-Oriented Programming
CSC 222: Object-Oriented Programming Fall 2017
CSCI 104 Backtracking Search
CSC 421: Algorithm Design and Analysis
CSE 373 Data Structures and Algorithms
CSC 221: Computer Programming I Fall 2009
CSC 421: Algorithm Design and Analysis
CSC 222: Object-Oriented Programming Spring 2013
CSC 421: Algorithm Design and Analysis
Data Structures & Algorithms
CSC 222: Object-Oriented Programming
CSC 222: Object-Oriented Programming Spring 2012
CSC 321: Data Structures Fall 2018 Balanced and other trees
Presentation transcript:

1 CSC 427: Data Structures and Algorithm Analysis Fall 2010 Brute force approach  KISS vs. generality  HW2 examples: League Standings, Enigma, Musical Themes  exhaustive search: string matching  generate & test: N-queens, TSP, Knapsack  inheritance & efficiency ArrayList  SortedArrayList

2 Brute force many problems do not require complex, clever algorithms  a brute force (i.e., straightforward) approach may suffice  consider the exponentiation application simple, iterative version: a b = a * a * a * … * b recursive version: a b = a b/2 * a b/2 while the recursive version is more efficient, O(log N) vs. O(N), is it really worth it? brute force works fine when  the problem size is small  only a few instances of the problem need to be solved  need to build a prototype to study the problem

League Standings consider the league standings problem from HW2  a Map is a natural structure for keeping team-record pairs  biggest problem was displaying team records in decreasing order (by wins) o TreeMap makes it easy to get the teams in alphabetical order o to order by score, need to sort the teams by number of wins 3 elegant, generalizable, efficient solution:  create a Record class that encapsulates the team name and win/loss record  make this class Comparable, so that a team with more wins is >  can then put Records in a list and sort

Record class 4 class Record implements Comparable { private String teamName; private int numWins; private int numLosses; public Record(String name) { this.teamName = name; this.numWins = 0; this.numLosses = 0; } public void addWin() { this.numWins++; } public void addLoss() { this.numLosses++; } public int compareTo(Record other) { if (other.numWins == this.numWins) { return this.teamName.compareTo(other.teamName); } else { return other.numWins - this.numWins; } public String toString() { return this.teamName + " " + this.numWins + "-" + this.numLosses; } Record class provides methods for adding wins & losses the compareTo method looks first at number of wins if same number of wins, looks next at team name the toString method makes it easy to display a Record

Standings class 5 public class Standings { public static void main(String[] args) { TreeMap teams = new TreeMap (); Scanner input = new Scanner(System.in); String team1 = input.next(); int score1 = input.nextInt(); String team2 = input.next(); int score2 = input.nextInt(); while (score1 >= 0 || score2 >= 0) { if (!teams.containsKey(team1)) { teams.put(team1, new Record(team1)); } if (!teams.containsKey(team2)) { teams.put(team2, new Record(team2)); } if (score1 > score2) { teams.get(team1).addWin(); teams.get(team2).addLoss(); } else { teams.get(team1).addLoss(); teams.get(team2).addWin(); } team1 = input.next(); score1 = input.nextInt(); team2 = input.next(); score2 = input.nextInt(); } main method for solving the problem is fairly simple since Record s are Comparable, can use Collections.sort to order them ArrayList standings = new ArrayList (); for (String teamName : teams.keySet()) { standings.add(teams.get(teamName)); } Collections.sort(standings); for (Record t : standings) { System.out.println(t); } System.out.println("DONE"); }

How efficient is this solution? let G = the number of games and T = the number of teams while loop executes G times, each time through must read in teams & scores check to see if teams already storedin Map add record to Map if not already stored determine which team won/lost update records of both teams in Map sorting the records requires constructing an empty ArrayList getting the keySet for the Map getting each record and storing in the Arraylist sorting the ArrayList displaying the sorted records 6

Simpler version? is the development of a new Record class really necessary? is there a (reasonable) upper limit on the number of games?  e.g., suppose we knew/guessed there were at most 100 games  we could avoid code complexity by making ~100 passes through the teams traverse teams, displaying all teams with 100 wins, then… traverse teams, displaying all teams with 99 wins, then… traverse teams, displaying all teams with 98 wins, then … … traverse teams, displaying all teams with 0 wins  how inefficient is this? 7

StandingsBrute class 8 public class StandingsBrute { public static void main(String[] args) { TreeMap wins = new TreeMap (); TreeMap losses = new TreeMap (); Scanner input = new Scanner(System.in); String team1 = input.next(); int score1 = input.nextInt(); String team2 = input.next(); int score2 = input.nextInt(); int numGames = 0; while (score1 >= 0 || score2 >= 0) { if (!wins.containsKey(team1)) { wins.put(team1, 0); losses.put(team1, 0); } if (!wins.containsKey(team2)) { wins.put(team2, 0); losses.put(team2, 0); } if (score1 > score2) { wins.put(team1, wins.get(team1)+1); losses.put(team2, losses.get(team2)+1); } else { wins.put(team2, wins.get(team2)+1); losses.put(team1, losses.get(team1)+1); } numGames++; team1 = input.next(); score1 = input.nextInt(); team2 = input.next(); score2 = input.nextInt(); } simpler version one maps for wins, another for losses must keep track of num games for (int i = numGames; i >= 0; i--) { for (String s : wins.keySet()) { int numWins = wins.get(s); if (numWins == i) { System.out.println(s + " " + wins.get(s) + "-" + losses.get(s)); } System.out.println("DONE"); }

Incremental improvements? remove a record from the Map after displaying  impact on efficiency? 9 before traversing the keySet to display all teams with W wins, call containsValue(W) to make sure some exist  impact on efficiency? make a pass throught the keySet and store win totals in an ArrayList then sort the win totals and traverse looking only for those totals  impact on efficiency?

Enigma problem if we really wanted to model an Enigma machine, would want to define classes that model the components  Rotor, Backplate, … that way, could easily generalize to interchangeable rotors, variable numbers of rotors, etc. if the goal is to just solve this problem, can go much simpler  represent each rotor and backplate as a String  connect letters using indexOf and charAt methods  rotate rotors using substring and concatenation 10

Enigma class 11 public class Enigma { private String innerRotor; private String middleRotor; private String backplate; public Enigma(String inner, String middle, String back){ this.middleRotor = middle; this.innerRotor = inner; this.backplate = back; } public String encode(String message){ String middleCopy = this.middleRotor; String innerCopy = this.innerRotor; String encMessage = ""; for(int i = 0; i < message.length(); i++){ String temp = message.substring(i,i + 1); int tempPos = innerCopy.indexOf(temp); String buffer = backplate.substring(tempPos, tempPos + 1); tempPos = middleCopy.indexOf(buffer); encMessage += backplate.substring(tempPos, tempPos+1); innerCopy = rotate(innerCopy); if (innerCopy.equals(this.innerRotor)) { middleCopy = rotate(middleCopy); } return encMessage; } private String rotate(String rotor){ return rotor.substring(rotor.length()-1,rotor.length()) + rotor.substring(0,rotor.length()-1); }... here, chose to have some generality  rotors and backplate are fields, initialized by a constructor  encode and rotate are methods as a result, would be easy to add additional functionality  encode multiple messages  add a decode method  create a GUI

Enigma class (cont.) public static void main(String[] args) { Scanner input = new Scanner(System.in); String inner = input.nextLine(); String middle = input.nextLine(); String back = input.nextLine(); String message = input.nextLine(); Enigma coder = new Enigma(inner, middle, back); String coded = coder.encode(message.substring(0, message.length()-1)); System.out.println(coded + "."); } what is the purpose of the substring? why is "." added to the end of the coded message? by designing the solution with fields and methods, can easily add a GUI

Musical Themes problem this was by far the trickiest solution to code, but also most concise checking to see whether two sequences of notes are similar is fairly straightforward  can make use of char substraction'B' – 'A' = 1 need to systematically try subsequences of the score for matches  could start with the longest possible match, shorten until find a match  could start with shortest possible match, lengthen until no more matches ABCEGDEFACABCEGDEFACABCEGDEFACABCEGDEFACABCEGDEFAC ABCEGDEFAC 13

Themes class 14 public class Themes { private static boolean matches(String seq1, String seq2) { for (int i = 0; i < seq1.length() - 1; i++) { int diff1 = (7 + seq1.charAt(i + 1) - seq1.charAt(i)) % 7; int diff2 = (7 + seq2.charAt(i + 1) - seq2.charAt(i)) % 7; if (diff1 != diff2) { return false; } return true; } private static String findMatch(String seq) { for (int matchSize = seq.length() / 2; matchSize > 1; matchSize--) { int stop1 = seq.length() - (2 * matchSize); for (int start1 = 0; start1 <= stop1; start1++) { int stop2 = seq.length() - matchSize; for (int start2 = start1 + matchSize; start2 <= stop2; start2++) { String sub1 = seq.substring(start1, start1 + matchSize); String sub2 = seq.substring(start2, start2 + matchSize); if (Themes.matches(sub1, sub2)) { return sub1; } return seq.substring(0, 1); } public static void main(String[] args) { Scanner input = new Scanner(System.in); int numThemes = input.nextInt(); for (int i = 0; i < numThemes; i++) { System.out.println(Themes.findMatch(input.next())); } matches:  determines whether two sequences of same length are similar  uses % op findMatch:  tries every possible pair of themes  starts with longest, goes left-to-right  TRICKY, but concise

Exhaustive search in the worst case, the themes program must try (almost) every possible pair of subsequences for a match  for long  short approach, if no matches of size >= 2, can simply return first char  for short->long approach, can stop each pass as soon as a match is found 15 related example: string matching  consider the task of the String indexOf method find the first occurrence of a desired substring in a string  this problem occurs in many application areas, e.g., DNA sequencing CGGTAGCTTGCCTAGGAGGCTTCTCATAGAGCTCGATCGGTACG… TAGAG

Exhaustive string matching the brute force/exhaustive approach is to sequentially search CGGTAGCTTGCCTAGGAGGCTTCTCATAGAGCTCGATCGGTACG… … CGGTAGCTTGCCTAGGAGGCTTCTCATAGAGCTCGATCGGTACG… 16 public static int match(String seq, String desired) { for (int start = 0; start <= seq.length() – desired.length(); start++) { String sub = seq.substring(start, start+desired.length()); if (sub.equals(desired)) { return start; } return -1; } efficiency of search?we can do better (more later)

Generate & test sometimes exhaustive algorithms are referred to as "generate & test"  can express algorithm as generating each candidate solution systematically, testing each to see if the candidate is actually a solution musical themes: try seq.substring(0, seq.length()/2) if no match, try seq.substring(0, seq.length()/2 – 1) if no match, try seq.substring(1, seq.length()/2) if no match, try seq.substring(2, seq.length()/2+1) … string matching: try seq.substring(0, desired.length()) if no match, try seq.substring(1, desired.length()+1) if no match, try seq.substring(2, desired.length()+2) … 17

18 Generate & test: N-queens given an NxN chess board, place a queen on each row so that no queen is in jeopardy generate & test approach  systematically generate every possible arrangement  test each one to see if it is a valid solution this will work (in theory), but the size of the search space may be prohibitive 4x4 board  8x8 board  = 1,820 arrangements = 131,198,072 arrangements 4! = 24 arrangements 8! = 40,320 arrangements again, we can do better (more later)

nP-hard problems: traveling salesman there are some problems for which there is no known "efficient" algorithm (i.e., nothing polynomial)  known as nP-hard problems generate & test may be the only option 19 Traveling Salesman Problem: A salesman must make a complete tour of a given set of cities (no city visited twice except start/end city) such that the total distance traveled is minimized. example: find the shortest tour given this map generate & test  try every possible route efficiency?

xkcd: Traveling Salesman Problem comic 20 a dynamic programming approach (more later) can improve performance slightly, but still intractable for reasonably large N

nP-hard problems: knapsack problem another nP-hard problem: Knapsack Problem: Given N items of known weights w 1,…,w N and values v 1,…,v N and a knapsack of capacity W, find the most value subset of items that fit in the knapsack. example: suppose a knapsack with capacity of 50 lb. Which items do you take? tiara$ lbs coin collection$ lbs HDTV$ lbs laptop$ lbs silverware$ lbs stereo $80025 lbs PDA $600 1 lb clock $300 4 lbs generate & test solution:  try every subset & select the one with greatest value 21

22 Dictionary revisited recall the Dictionary class earlier  the ArrayList add method simply appends the item at the end  O(1)  the ArrayList contains method performs sequential search  O(N) this is OK if we are doing lots of adds and few searches import java.util.List; import java.util.ArrayList; import java.util.Scanner; import java.io.File; public class Dictionary { private List words; public Dictionary() { this.words = new ArrayList (); } public Dictionary(String filename) { this(); try { Scanner infile = new Scanner(new File(filename)); while (infile.hasNext()) { String nextWord = infile.next(); this.words.add(nextWord.toLowerCase()); } catch (java.io.FileNotFoundException e) { System.out.println("FILE NOT FOUND"); } public void add(String newWord) { this.words.add(newWord.toLowerCase()); } public void remove(String oldWord) { this.words.remove(oldWord.toLowerCase()); } public boolean contains(String testWord) { return this.words.contains(testWord.toLowerCase()); }

23 Timing dictionary searches we can use our StopWatch class to verify the O(N) efficiency dict. sizeinsert time 38, msec 77, msec 144, msec dict. sizesearch time 38, msec 77, msec 144, msec execution time roughly doubles as dictionary size doubles import java.util.Scanner; import java.io.File; public class DictionaryTimer { public static void main(String[] args) { System.out.println("Enter name of dictionary file:"); Scanner input = new Scanner(System.in); String dictFile = input.next(); StopWatch timer = new StopWatch(); timer.start(); Dictionary dict = new Dictionary(dictFile); timer.stop(); System.out.println(timer.getElapsedTime()); timer.start(); for (int i = 0; i < 100; i++) { dict.contains("zzyzyba"); } timer.stop(); System.out.println(timer.getElapsedTime()/100.0); }

24 Sorting the list if searches were common, then we might want to make use of binary search  this requires sorting the words first, however we could change the Dictionary class to do the sorting and searching  a more general solution would be to extend the ArrayList class to SortedArrayList  could then be used in any application that called for a sorted list recall: public class java.util.ArrayList implements List { public ArrayList() { … } public boolean add(E item) { … } public void add(int index, E item) { … } public E get(int index) { … } public E set(int index, E item) { … } public int indexOf(Object item) { … } public boolean contains(Object item) { … } public boolean remove(Object item) { … } public E remove(int index) { … } … }

25 SortedArrayList (v.1) using inheritance, we only need to redefine what is new  add method sorts after adding; indexOf uses binary search  no additional fields required  big-Oh for add ? big-Oh for indexOf ? import java.util.ArrayList; import java.util.Collections; public class SortedArrayList > extends ArrayList { public SortedArrayList() { super(); } public boolean add(E item) { super.add(item); Collections.sort(this); return true; } public int indexOf(Object item) { return Collections.binarySearch(this, (E)item); }

26 SortedArrayList (v.2) is this version any better? when?  big-Oh for add ?  big-Oh for indexOf ? import java.util.ArrayList; import java.util.Collections; public class SortedArrayList > extends ArrayList { public SortedArrayList() { super(); } public boolean add(E item) {// NOTE: COULD REMOVE THIS METHOD AND super.add(item);// JUST INHERIT THE ADD METHOD FROM return true;// ARRAYLIST AS IS } public int indexOf(Object item) { Collections.sort(this); return Collections.binarySearch(this, (E)item); }

27 SortedArrayList (v.3) if insertions and searches are mixed, sorting for each insertion/search is extremely inefficient  instead, could take the time to insert each item into its correct position  big-Oh for add ? big-Oh for indexOf ? import java.util.ArrayList; import java.util.Collections; public class SortedArrayList > extends ArrayList { public SortedArrayList() { super(); } public boolean add(E item) { int i; for (i = 0; i < this.size(); i++) { if (item.compareTo(this.get(i)) < 0) { break; } super.add(i, item); return true; } public int indexOf(Object item) { return Collections.binarySearch(this, (E)item); } search from the start vs. from the end?

28 Dictionary using SortedArrayList note that repeated calls to add serve as insertion sort dict. sizeinsert time 38, sec 77, sec 144, sec dict. sizesearch time 38, msec 77, msec 144, msec insertion time roughly quadruples as dictionary size doubles; search time is trivial import java.util.Scanner; import java.io.File; import java.util.Date; public class DictionaryTimer { public static void main(String[] args) { System.out.println("Enter name of dictionary file:"); Scanner input = new Scanner(System.in); String dictFile = input.next(); StopWatch timer = new StopWatch(); timer.start(); Dictionary dict = new Dictionary(dictFile); timer.stop(); System.out.println(timer.getElapsedTime()); timer.start(); for (int i = 0; i < 100; i++) { dict.contains("zzyzyba"); } timer.stop(); System.out.println(timer.getElapsedTime()/100.0); }

29 SortedArrayList (v.4) if adds tend to be done in groups (as in loading the dictionary)  it might pay to perform lazy insertions & keep track of whether sorted  big-Oh for add? big-Oh for indexOf?  if desired, could still provide addInOrder method (as before) import java.util.ArrayList; import java.util.Collections; public class SortedArrayList > extends ArrayList { private boolean isSorted; public SortedArrayList() { super(); this.isSorted = true; } public boolean add(E item) { this.isSorted = false; return super.add(item); } public int indexOf(Object item) { if (!this.isSorted) { Collections.sort(this); this.isSorted = true; } return Collections.binarySearch(this, (E)item); }

30 Timing the lazy dictionary on searches modify the Dictionary class to use the lazy SortedArrayList dict. sizeinsert time 38, msec 77, msec 144, msec dict. size1 st search 38, msec 77, msec 144, msec dict. sizesearch time 38, msec 77, msec 144, msec import java.util.Scanner; import java.io.File; import java.util.Date; public class DictionaryTimer { public static void main(String[] args) { System.out.println("Enter name of dictionary file:"); Scanner input = new Scanner(System.in); String dictFile = input.next(); StopWatch timer = new StopWatch() timer.start(); Dictionary dict = new Dictionary(dictFile); timer.stop(); System.out.println(timer.getElapsedTime()); timer.start(); dict.contains("zzyzyba"); timer.stop(); System.out.println(timer.getElapsedTime()); timer.start(); for (int i = 0; i < 100; i++) { dict.contains("zzyzyba"); } timer.stop(); System.out.println(timer.getElapsedTime()/100.0); }