Professional Documents
Culture Documents
04 Journey of 1000miles
04 Journey of 1000miles
Scalability!
Explorations in Computing!
2012 John S. Conery !
Search!
the program shows tunes that have that string in the song title, album title, artist name, or
other fields!
Defining Search!
The examples on the previous slides were similar to searches in everyday life!
we need to search the collection to find a single item that matches a certain condition (e.g.
name of book, name of a person)!
Not all searches fit this paradigm of looking for a specified item!
files may be organized by student name, but we need to search by file contents, e.g. find
students whose advisor is Prof. X!
select all customer records where the customer s name starts with A !
Search Algorithms!
As in real life, there are many variations and many different types of search
algorithms!
solarsystem.nasa.gov
Sorting!
Iterative Algorithms!
The goal for this chapter: study two new algorithms based on iteration!
repeating (iterating) a series of small steps can lead to the solution of important problems!
Search algorithm:!
! !linear search!
Sort algorithm:!
! !insertion sort!
Linear Search!
As the name implies, the idea is to start at the beginning of a collection and
compare items one after another!
Some terminology:!
Array Indices!
Index Expressions!
if a is an array the expression a[i] means the item at location i in the array !
=> "orange"!
>> a[3] = "tangerine"!
=> "tangerine"!
>> a!
=> ["apple", "lime", "kiwi", "tangerine", "ugli"]!
>> a[5]!
=> nil!
A Project!
return
false if x is not in a!
search(a,x)!
return
return
nil if x is not in a!
Conditional Expressions!
To implement our contains? method we can use each to iterate over the
array!
def contains?(a,k)!
Optional project:!
Use a while loop to compare a[i] with the item we re looking for!
return i if a[i] == k
i += 1end!
>> Source.listing("search")
1:
def search(a, k)
2:
i =
Performance!
another way to phrase it: how many iterations will our Ruby method make?!
search may get lucky and find the item in the first location!
We can attach a probe to one of the lines in the method to show the state
of the search at each step!
>> a!
=> ["tan", "mint", "salmon", "chocolate", "wheat"]!
>> puts brackets(a, 2)!
tan
mint [salmon
chocolate
wheat]!
return i if a[i] == k!
Attach a probe to line 4, telling Ruby to print brackets around the region
that has not been searched yet:!
>> Source.probe( "search", 4, "puts brackets(a,i)" )!
=> true!
>> trace { search(a, "chocolate") }!
[tan
mint
salmon
chocolate
wheat]!
tan [mint
salmon
chocolate
wheat]!
tan
mint [salmon
chocolate
wheat]!
tan
mint
salmon [chocolate
wheat]!
=> 3!
mint
salmon
chocolate
wheat]!
tan [mint
salmon
chocolate
wheat]!
tan
mint [salmon
chocolate
wheat]!
tan
mint
salmon [chocolate
wheat]!
tan
mint
salmon
chocolate [wheat]!
=> nil!
Optional project:!
attach
make
how
how
Write a method named max that will find the largest item in an array!
here is an outline to get you started -- fill in the parts indicated by question marks!
there will be more than one line in the body of the loop!
def max(a)!
x = a[0]!
i = 1!
while ??!
??!
end!
return x!
end!
Variations:!
Sorting!
The search algorithms shown on the previous slides are examples of linear
algorithms!
systematically progress through the collection, all the way to the end if necessary!
The next set of slides will introduce a very simple sorting algorithm known
as insertion sort!
Insertion Sort!
when it is time to find a place for the J in this hand the portion to the left is sorted!
Insertion Sort!
This new version is precise enough that we can organize a Ruby method
that will implement this algorithm!
Example:
when i = 3 key will be J
end!
return a!
end!
A description like this that is part Ruby and
part English is known as pseudocode
When algorithms require more than a few lines of Ruby we will use
pseudocode in the lecture slides!
you can call Source.listing or Source.checkout if you want to see the gory
details !
>> Source.listing("isort") 1:
def isort(array) 2:
a = array.clone
# make a copy of the input 3:
i
= 1 4:
while i < a.length 5:
...
!
!
!
!
!
# see slides below
6:
i += 1 7:
end 8:
return a 9:
end=> true!
The following pictures show an example of how insertion sort works (using
a list of numbers instead of cards)!
Helper Method!
Nested Loops!
An algorithm with one loop inside another is said to have nested loops!
5:
insert_left(a, i)
6:
i += 1!
7:
end!
Attach a probe on line 5, to tell Ruby to print brackets around part of a just
before calling insert_left:!
>> Source.probe("isort", 5, "puts brackets(a,i)")!
=> true!
Using trace to call isort to sort the array shown on the previous slides: !
>> a!
=> [0, 8, 9, 5, 7, 2, 3]!
>> trace { isort(a) }!
0 [8
3]!
8 [9
3]!
9 [5
3]!
9 [7
3]!
9 [2
3]!
9 [3]!
acura
rolls-royce
opel]!
infiniti [acura
rolls-royce
opel]!
opel]!
acura
citroen
infiniti [rolls-royce
acura
citroen
infiniti
rolls-royce [opel]!
Counting Comparisons!
2:
return x < y!
3:
end!
=> true!
Count the comparisons made when sorting the array of car names:!
>> count { isort(a) }!
=> 6!
>> trace
citroen
{ isort(a) }!
[infiniti
acura
rolls-royce
opel] citroen
infiniti [acura
ro
Challenge!
Explain how many comparisons will be made in the general case (for any
arbitrary size array) when isort is passed an array that is already sorted:!
>> a = TestArray.new(100)!
=> [142, 617, 826, ... 949, 550]!
>> count { isort(a.sort) }!
=> ??!
For large arrays the n doesn t add very much, and we can get a good
estimate by just computing !
Big-Oh Notation!
Because the
term in the equation is the dominant term when n is large,
we can use it to estimate the number of comparisons!
pronounced oh of n-squared !
comparisons !
Scalability!
The fact that the number of comparisons grows as the square of the array
size may not seem important!
The outer loop has the same structure as the iteration in linear search!
the inner loop moves a[i] to its proper location in the sorted region!
Summary!
the inner loop scans back from right to left to find the place for an item!
array index!
pseudocode!