dis4

dis4 - CS32
Discussion
 Sec.on
1B
 Week
5
...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: CS32
Discussion
 Sec.on
1B
 Week
5
 TA:
Brian
Choi
 Reminder
 •  Homework
3
 –  Due
Sunday
 •  Midterm
 –  5/5
Wednesday
 –  Open
book,
open
notes,
closed
friends.
 Recursion
 •  Func.on‐wri.ng
technique
where
the
func.on
refers
to
itself.
 •  Recall
the
following
func.on:
 int factorial(int n) { if (n == 0) return 1; return n * factorial(n – 1); } •  Let
us
talk
about
how
to
come
up
with
such
a
func.on.
 Decomposi.on
of
the
problem
 •  You’re
all
used
to
the
following
technique.
 int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n!
=
1
*
2
*
3
*
…
*
(n‐1)
*
n
 Decomposi.on
of
the
problem
 •  You’re
all
used
to
the
following
technique.
 int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n!
=
1
*
2
*
3
*
…
*
(n‐1)
*
n


 












=
(n‐1)!
 Decomposi.on
of
the
problem
 •  You’re
all
used
to
the
following
technique.
 int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n!
=
1
*
2
*
3
*
…
*
(n‐1)
*
n


 •  n!
=
factorial(n‐1)
*
n
 Decomposi.on
of
the
problem
 int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  n!
=
1
*
2
*
3
*
…
*
(n‐1)
*
n


 •  n!
=
factorial(n‐1)
*
n
 Power
of
Belief
 •  JUST
BELIEVE
factorial(n
‐
1)
will
do
the
right
thing.
 int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  •  •  •  factorial(n)
will
believe
that
factorial(n‐1)
will
return
the
right
value.
 factorial(n‐1)
will
believe
that
factorial(n‐2)
will
return
the
right
value.
 …
 factorial(1)
will
believe
that
factorial(0)
will
return
the
right
value.

 Power
of
Belief
 •  JUST
BELIEVE
factorial(n
‐
1)
will
do
the
right
thing.
 int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  •  •  •  •  factorial(n)
will
believe
that
factorial(n‐1)
will
return
the
right
value.
 factorial(n‐1)
will
believe
that
factorial(n‐2)
will
return
the
right
value.
 …
 factorial(1)
will
believe
that
factorial(0)
will
return
the
right
value.
 AND
MAKE
factorial(0)
return
the
right
value!

 Base
Case
 •  JUST
BELIEVE
factorial(n
‐
1)
will
do
the
right
thing.
 int factorial(int n) { if (n == 0) return 1; int temp = factorial(n - 1) * n; return temp; } •  •  •  •  •  factorial(n)
will
believe
that
factorial(n‐1)
will
return
the
right
value.
 factorial(n‐1)
will
believe
that
factorial(n‐2)
will
return
the
right
value.
 …
 factorial(1)
will
believe
that
factorial(0)
will
return
the
right
value.
 AND
MAKE
factorial(0)
return
the
right
value!

 Base
Case
 •  

 int factorial(int n) { if (n == 0) return 1; int temp = factorial(n - 1) * n; return temp; } Pa^ern
 •  How
to
Write
a
Recursive
Func.on
for
Dummies
(no
offense!)
 1.  Find
the
base
case.
 –  –  When
should
the
recursion
stop?
 What
is
the
last
brick?
 2.  Decompose
the
problem.
 –  The
simplest
case
 •  Run
the
same
func.on
on
n‐1
items.
 •  What
informa.on
do
I
get
out
of
it?
 •  How
do
I
use
this
informa.on
to
say
something
about
n
items?
 3.  Justsolve
this
subproblem!
 Pa^ern
 •  Once
you
have
answered
all
the
ques.ons.
Write
them
out
 this
way:
 •  func.on_header
 
{
 
 
take
care
of
the
base
cases
 
 
write
the
rela.onship
between
the
prev
step
and
the
curr
step
 
}
 •  Lastly,
look
back
and
make
sure
every
call
to
this
func.on
hits
 some
base
case
eventually.
 Prac.ce
1:
Average
 double average(const double arr, int n) { // assume n > 0 } Prac.ce
1:
Average
 •  What
is
the
base
case?
 •  What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?
 That
is,
how
do
I
get
the
average
of
n
items,
knowing
the
 average
of
n‐1
of
them?
 Prac.ce
1:
Average
 •  •  What
is
the
base
case?
 n
=
1,
where
the
average
is
just
the
value
of
the
only
item.
 What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?
 That
is,
how
do
I
get
the
average
of
n
items,
knowing
the
 average
of
n‐1
of
them?
 •  average(arr,
n)
 
=
total(all
n
items)
/
n
 


 
=
{total(first
n‐1
items)
+
n‐th
item}
/
n
 

 
 
 
 
=
average(arr,
n‐1)
*
(n‐1)
+
n‐th
item
 


 
 
 








n
 •  Prac.ce
1:
Average
 double average(const double arr, int n) { if (n == 1) return arr[0]; double prevTotal = (n – 1) * average(arr, n – 1); return (arr[n – 1] + prevTotal) / n; } Prac.ce
2:
Summing
Digits
 int sumOfDigits(const int n) { // assume n >= 0 } Prac.ce
2:
Summing
Digits
 •  What
is
the
base
case?
 •  What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?
 That
is,
how
do
I
get
the
sum
of
n
digits,
knowing
the
sum
of
 digits
of
(n‐1)
digits?
 Prac.ce
2:
Summing
Digits
 •  •  What
is
the
base
case?
 n
<
10
(i.e.,
n
is
a
single
digit
number),
where
the
sum
of
 digits
is
simply
n
 •  What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?
 That
is,
how
do
I
get
the
sum
of
n
digits,
knowing
the
sum
of
 digits
of
(n‐1)
digits?
 Just
add
the
last
digit
to
the
sum!
 •  Prac.ce
2:
Summing
Digits
 int sumOfDigits(const int n) { if (n < 10) return n; return n % 10 + sumOfDigits(n / 10); } Prac.ce
3:
Dele.ng
characters
 string deleteChar(const string s, const char c) { } Prac.ce
3:
Dele.ng
characters
 •  What
is
the
base
case?
 •  What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?

 Prac.ce
3:
Dele.ng
characters
 •  •  What
is
the
base
case?
 s
==
“”:
There
is
no
character
to
delete!
Just
return
“”.
 •  •  What
is
the
rela.onship
between
(n)‐step
and
(n‐1)‐step?

 Suppose
the
string
is
of
length
n,
and
I
make
a
recursive
call
 on
s.substr(1).
(e.g.
If
the
string
is
“hello”,
the
recursive
call
 will
be
made
on
“ello”.)
 What’s
returned
by
deleteChar
must
not
contain
any
c.
You
 only
need
to
append
s[0]
to
it
if
s[0]
!=
c.
If
s[0]
==
c,
just
 return
it.
 •  Prac.ce
3:
Dele.ng
characters
 string deleteChar(const string s, const char c) { if (s == “”) return “”; if (s[0] == c) return deleteChar(s.substr(1), c); else return s[0] + deleteChar(s.substr(1), c); } Prac.ce
4:
Fibonacci
numbers
 •  Fibonacci
numbers
refer
to
the
sequence
of
numbers
of
the
 following
form:
 0,
1,
1,
2,
3,
5,
8,
13,
21,
34,
55,
…
 –  –  –  F(0)
=
0
 F(1)
=
1
 F(n)
=
F(n‐1)
+
F(n‐2),
n
>=
2
 Prac.ce
4:
Fibonacci
numbers
 // A little too obvious now, isn’t it? int fibo(const int n) { if (n == 0) return 0; if (n == 1) return 1; return fibo(n – 1) + fibo(n – 2); } Prac.ce
4:
Fibonacci
numbers
 •  Note
that
fibo()
makes
two
recursive
calls.



 fibo(4)
 fibo(3)
 fibo(2)
 fibo(1)
 •  fibo(1)
 fibo(0)
 Look
at
all
this
redundancy!!!!
 fibo(2)
 fibo(1)
 fibo(0)
 Trick:
Memoiza.on
 int fibMem[100]; // global for (int i = 2; i < 100; ++i) fibMem[i] = -1; fibMem[0] = 0; fibMem[1] = 1; if (fibMem[n-2] != -1) fib2 = fibMem[n-2]; else fib2 = fibo(n-2); fibMem[n] = fib1 + fib2; int fibo(const int n) { int fib1, fib2; if (fibMem[n-1] != -1) fib1 = fibMem[n-1]; else fib1 = fibo(n-1); return fib1 + fib2; } Memoiza.on
is
an
op.miza.on
technique
that
 basically
helps
avoid
compu.ng
the
same
value
 over
and
over
by
remembering
it.
 We
like
this
since
memory
is
cheap,
but
 compu.ng
.me
is
not!
 Prac.ce
5:
Palindrome
 •  Examples:
“eye”,
“racecar”,
“deed”
 bool palindrome(const string s) { } •  •  Base
case?
(Hint:
An
empty
string
is
a
palindrome.)
 General
case?
 Prac.ce
5:
Palindrome
 •  Examples:
“eye”,
“racecar”,
“deed”
 bool palindrome(const string s) { }
 •  Cases:
(1)
size
=
0,
(2)
size
=
1,
(3)
the
first
char
differs
from
 the
last
one,
(4)
first
char
=
last
char
 Prac.ce
5:
Palindrome
 •  Examples:
“eye”,
“racecar”,
“deed”
 bool palindrome(const string s) { if (s.size() == 0 || s.size() == 1) return true; if (s[0] != s[s.size() - 1]) return false; return palindrome(s.substr(1, s.size() - 2)); }
 •  Cases:
(1)
size
=
0,
(2)
size
=
1,
(3)
the
first
char
differs
from
 the
last
one,
(4)
first
char
=
last
char
 Prac.ce
6:
targetSum
 •  Given
a
set
of
integers,
can
we
find
a
combina.on
that
sums
 up
to
exactly
targetSum?
 bool targetSum(int a, int n, int targetSum) { } •  •  Base
case?
 General
case?
 Prac.ce
6:
targetSum
 •  Given
a
set
of
integers
{1,
2,
3},
can
we
find
a
combina.on
 that
sums
up
to
exactly
targetSum?
 bool targetSum(int a, int n, int targetSum) { } •  •  Base
case?
If
n
==
0,
no
such
sum
exists.
If
the
current
 number
is
exactly
targetSum,
then
that’s
it.

 General
case?
Either
the
current
number
is
part
of
the
 targetSum,
or
is
not
included
in
the
targetSum.
 Prac.ce
6:
targetSum
 •  Given
a
set
of
integers
{1,
2,
3},
can
we
find
a
combina.on
 that
sums
up
to
exactly
targetSum?
 bool targetSum(int a, int n, int targetSum) { if (n == 0) return false; if (*a == targetSum) return true; return exactSum(a + 1, n – 1, targetSum - *a) || exactSum(a + 1, n – 1, targetSum); } Prac.ce
helps
 •  •  •  Recursion
is
somewhat
counter‐intui.ve
when
confronted
for
 the
first
.me.
 Just
do
a
lot
of
prac.ce
and
you
will
see
the
pa^ern.
 Again,
the
key
to
recursion
is
to
“believe”!
Do
not
try
to
track
 the
call
stack
down
and
see
what
happens
un.l
you
really
 have
to.
 Test
Taking
Tips
 •  •  •  •  I
know
it’s
open
book,
but
osen
it
helps
to
create
cheat
 sheets
anyways.
 Have
some
“representa.ve”
example
codes
available
in
your
 notes.
 But
do
not
try
to
copy
from
hw/proj
solu.ons!
We
have
seen
 so
many
people
using
variable
names
and
func.on
calls
from
 projects,
when
they
don’t
even
exist
in
the
exam
ques.ons!
 (e.g.,
using
Animal
class’s
name()
func.on
when
the
problem
 asks
you
to
build
a
class
called
Tank.)
 Get
a
lot
of
sleep
before
coming
into
the
exam
site.

 ...
View Full Document

This note was uploaded on 02/09/2012 for the course CS 32 taught by Professor Davidsmallberg during the Spring '08 term at UCLA.

Ask a homework question - tutors are online