arrays and strings - phillip compeau, carnegie mellon...

68
Arrays and Strings 02-201

Upload: others

Post on 16-Feb-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

  • Arrays and Strings 02-201

  • Arrays

  • Recall: Fibonacci() and Arrays

    1 1 2 3 5 8 13 21 34 55

    Fibonacci(n)aßarrayoflengthna[1]ß1a[2]ß1foriß3tona[i]ßa[i-1]+a[i-2]returna

    a

  • var a [10]intvar b [100]stringvar c [20]float64

    Declare arrays of the given type and length.

    13 18 -2 10 11 10 -22 8 8 7 -30 -33 -22

    0 1 2 3 4 5 6 7 8 9 10 11 12 index of array:!array elements:!

    Declaring Arrays

  • fmt.Println(a[7],a[8])a[0] = 10b[30] = “hi there”i := 12 + 2c[i] = 3.1c[2*i] = c[i]

    Array elements can be accessed by putting their index between [ ] following the array name:

    x[i] can appear on left side of assignment to set a value.

    Accessing/Changing Array Elements in Go

  • • The length of an array can be found with len(x), where x is an array.

    • Array indices start at 0. The first element is x[0]; last element is x[len(x) - 1].

    • It’s an error to try to access elements past the end (or before the beginning) of the array:

    var d [100]intd[len(d)-1] = 3 // OKd[len(d)] = 3 // ERROR!d[-60] = 7 // ERROR!

    Accessing/Changing Array Elements in Go

  • Command Line Arguments with os.Args

    HW2: enter command line information that is input as parameters into a function directly.

    Package “os” provides access to these parameters:

    • os.Args[1] is “a”• os.Args[2] is “3”• os.Args[3] is “77”• os.Args[4] is “another param”• os.Args[0] is “myProgram”

    go run myProgram.go a 3 77 “another param”

    os.Args is an array of strings.

  • Exiting a Program with os.Exit()

    func RandomWalk(n, s int) { if n

  • Multidimensional Arrays as 2-D Tables

    0 1 2

    3 4 5 6

    0 1 2 3 var a [7][4]inta[1][2] = 19y := a[3][0] // gives 0x := len(a) // gives 7

    7 rows

    4 columns

    Think of as “an array of length 7, where each element contains an array of length 4”

  • Multidimensional Arrays as 2-D Tables

    0 1 2

    3 4 5 6

    0 1 2 3 var a [7][4]inta[1][2] = 19y := a[3][0] // gives 0x := len(a) // gives 7

    7 rows

    4 columns

    Think of as “an array of length 7, where each element contains an array of length 4”

    Think: How can we determine the number of columns?

  • Multidimensional Arrays as 2-D Tables

    0 1 2

    3 4 5 6

    0 1 2 3 var a [7][4]inta[1][2] = 19y := a[3][0] // gives 0x := len(a) // gives 7

    7 rows

    4 columns

    Think of as “an array of length 7, where each element contains an array of length 4”

    z := len(a[0]) // gives 4

  • Strings

  • String Conversion Pain

    Exercise: What should be the value of MJordan?

    MJordan := string(45)

  • String Conversion Pain

    Exercise: What should be the value of MJordan?

    Answer: It seems like it should be “45”.

    But the answer is “-”.

    MJordan := string(45)

  • How Strings are Represented Internally

    H e l l o , W o r l d !

    72 101 108 108 111 44 32 87 111 114 108 100 33

    Logical interpretation

    Internal representation

    Each item in a string is called a character.

    A character in Go is represented using a “byte” variable type that is a number.

  • ASCII Chart (You don’t need to know these numbers)

    Binary Dec Glyph010 0000 32 (space)010 0001 33 !010 0010 34 "010 0011 35 #010 0100 36 $010 0101 37 %010 0110 38 &010 0111 39 '010 1000 40 (010 1001 41 )010 1010 42 *010 1011 43 +010 1100 44 ,010 1101 45 -010 1110 46 .010 1111 47 /011 0000 48 0011 0001 49 1011 0010 50 2011 0011 51 3011 0100 52 4011 0101 53 5011 0110 54 6011 0111 55 7011 1000 56 8011 1001 57 9011 1010 58 :011 1011 59 ;011 1100 60 <011 1101 61 =011 1110 62 >011 1111 63 ?

    Binary Dec Glyph100 0000 64 @100 0001 65 A100 0010 66 B100 0011 67 C100 0100 68 D100 0101 69 E100 0110 70 F100 0111 71 G100 1000 72 H100 1001 73 I100 1010 74 J100 1011 75 K100 1100 76 L100 1101 77 M100 1110 78 N100 1111 79 O101 0000 80 P101 0001 81 Q101 0010 82 R101 0011 83 S101 0100 84 T101 0101 85 U101 0110 86 V101 0111 87 W101 1000 88 X101 1001 89 Y101 1010 90 Z101 1011 91 [101 1100 92 \101 1101 93 ]101 1110 94 ^101 1111 95 _

    Binary Dec Glyph110 0000 96 `110 0001 97 a110 0010 98 b110 0011 99 c110 0100 100 d110 0101 101 e110 0110 102 f110 0111 103 g110 1000 104 h110 1001 105 i110 1010 106 j110 1011 107 k110 1100 108 l110 1101 109 m110 1110 110 n110 1111 111 o111 0000 112 p111 0001 113 q111 0010 114 r111 0011 115 s111 0100 116 t111 0101 117 u111 0110 118 v111 0111 119 w111 1000 120 x111 1001 121 y111 1010 122 z111 1011 123 {111 1100 124 |111 1101 125 }111 1110 126 ~

  • Restoring Sanity: strconv Package

  • x, err := strconv.Atoi(”107") //gives 107if err != nil {

    os.Exit(1)}

    Restoring Sanity: strconv Package

    MJordan := strconv.Itoa(45) // gives “45”

    y, err := strconv.ParseFloat(“3.1”, 64)if err != nil {

    os.Exit(1)}

    Check out FormatFloat() for float to string conversion.

  • •  Contains many built-in string algorithms.

    •  Example: testing whether a string contains another:

    var a = “hi, there”var b = “the”if strings.Contains(a, b) {

    fmt.Println(“String a contains string b!”)}

    strings Package

  • s1 + s2 “concatenate” strings s1 and s2!

    “hi” + “there” == “hithere”“what’s “ + “up” + “ doc?” == “what’s up doc?”

    Recall: String + Operator

  • Indexing Strings

    Strings work like arrays in some ways: •  Strings have fixed length. •  You can find the length of string s with len(s). •  You can access elements of string s with s[i].

    s := “Hi There!”fmt.Println(s[0]) // prints Hfmt.Println(s[len(s)-1]) // prints !if s[0] == ‘H’ // “single quotes” for single symbols

    H i T h e r e !0 1 2 3 4 5 6 7 8

  • Substrings in Go

    s := “Hi There!”fmt.Println(s[3:5]) // prints Thfmt.Println(s[1:]) // prints i There!fmt.Println(s[:4]) // prints Hi T

    var str string = s[3:6]fmt.Println(str) // prints Thefmt.Println(str[0]) // prints T

    H i T h e r e !0 1 2 3 4 5 6 7 8

  • Recall: Counting Pattern in Text

    1.  Start from the first position of Text and check whether Pattern appears in Text starting at its first position.

    2.  If yes, draw a dot on a piece of paper. 3.  Move to the second position of Text and check

    whether Pattern appears in Text starting at its second position.

    4.  If yes, draw another dot on the same piece of paper. 5.  Continue until you reach the end of Text. 6.  Count the number of dots on the piece of paper.

  • Example: Implement PatternCount()

    Pattern Counting Problem: Count the number of times that a pattern appears in a longer string. •  Input: Strings Text and Pattern. •  Output: The number of times that Pattern appears

    in Text.

    Exercise: Write a PatternCount() function handling overlapping instances of Pattern solving this problem.

    fmt.Println(strings.Count(“ATATA”, “ATA”))// prints 1, not 2.

  • Example: Implement PatternCount()

    func PatternCount(Pattern, Text string) int {//fill in details here

    }

  • Example: Reverse Complementing a String

    Reverse Complement Problem: •  Input: A DNA string Text. •  Output: The reverse complement of Text.

    T C A G C G T A T C A

    A G T C G C A T A G T

    3

    3

    5

    5

    Think: How could we solve this problem top-down?

  • Example: Reverse Complementing a String

    ReverseComplement()

    Complement() Reverse()

  • (Unlike Arrays) Strings are Not Editable!

    func Complement(s string) string {for i:=0; i

  • Reverse Complementing a String

    func Complement(s string) string {s2 := ""for i:=0; i

  • Reverse Complementing a String

    func Complement(s string) string {s2 := ""for i:=0; i

  • Reverse Complementing a String

    func Reverse(s string) string {s2 := ””n := len(s)for i:=0; i

  • Slices

  • Last Time: Random Walk

    Input: Integers n and s. Output: Print each step of a random walk with s steps in an n x n chessboard.

  • Self-Avoiding Random Walks

    Exercise: Write pseudocode for a function that prints a random self-avoiding walk.

    Self-avoiding walk: that never visits the same square of the checkerboard twice.

    •  Input: Integers n and s. •  Output: Print each step of

    a random self-avoiding walk with s steps in an n x n chessboard (start in the middle).

  • Pseudocode for Random Self-Avoiding Walk

    SelfAvoidingRandomWalk(n,s)fieldßnxnbooleanarrayholdingallfalse(x,y)ß(n/2,n/2)field[x][y]ßtruePrint(x,y)foriß0to(steps–1) (xNext,yNext)=(x,y) whilefield[xNext][yNext] (xNext,yNext)=RandomStep(x,y,10) (x,y)=(xNext,yNext) field[x][y]=true Print(x,y)

    Note the code reuse of RandomStep() ...

  • Just Two Little Problems

    func SelfAvoidingRandomWalk(n, s int) {var field [n][n]bool //throws error!// ... blah

    }

    1. Corner case: If the path works itself into a corner with nowhere to go, the algorithm will have an infinite loop!

    2. In Go, arrays cannot have length equal to a variable.

  • Who First Computed Earth’s Circumference?

  • Eratosthenes of Cyrene (276 – 195 BC)

    Also: first algorithm for identifying prime numbers

  • Finding Primes

    Prime Number Problem: •  Input: An integer n. •  Output: All integers p < n such that p is prime.

  • Sieve of Eratosthenes

    https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#/media/File:Sieve_of_Eratosthenes_animation.gif!

  • Sieve of Eratosthenes

    Exercise: Write a program in pseudocode that takes n as input and returns an array isComposite such that:

    •  isComposite[i] = true if i is composite

    •  isComposite[i] = false if i is prime

    Prime Number Problem: •  Input: An integer n. •  Output: All integers p < n such that p is prime.

  • Fill in Details Later

    func primeSieve(isComposite []bool) { var biggestPrime = 2 for biggestPrime < len(isComposite) { for i := 2*biggestPrime; i < len(isComposite); i += biggestPrime { isComposite[i] = true } biggestPrime++ for biggestPrime < len(isComposite) && isComposite[biggestPrime] { biggestPrime++ } }}

    PrimeSieve(n)isCompositeßarrayofnfalsebooleanvaluesbiggestPrimeß2whilebiggestPrime<n

  • Strings

  • Need to Implement: Substring() and Count()

    FrequentWords(Text,k)FrequentPatternsßanemptylistcßemptyarrayoflength|Text|-kforiß0to|Text|-kPatternßSubstring(Text,i,k)c[i]ßCount(Text,Pattern)maxCountßMax(a)foriß0to|Text|-kifa[i]=maxCountaddSubstring(Text,i,k)toFrequentPatternsFrequentPatternsßRemoveDuplicates(FrequentPatterns)returnFrequentPatterns

  • s1 + s2 “concatenate” strings s1 and s2!

    “hi” + “there” == “hithere”“what’s “ + “up” + “ doc?” == “what’s up doc?”

    String + Operator

  • Indexing Strings

    Strings work like arrays in some ways: •  Strings have fixed length. •  You can find the length of string s with len(s). •  You can access elements of string s with s[i]. •  You cannot modify a string once it has been created.

    s := “Hi There!”fmt.Println(s[0]) // prints Hfmt.Println(s[len(s)-1]) // prints !s[3] = “t” // ERROR! Can’t assign to stringsif s[0] == ‘H’

    //note the “single quotes” for individual symbols.

  • Substrings in Go

    s := “Hi There!”fmt.Println(s[3:5]) // prints Thfmt.Println(s[1:]) // prints i There!fmt.Println(s[:4]) // prints Hi T

    var str string = s[3:6]fmt.Println(str) // prints Thefmt.Println(str[0]) // prints T

    H i T h e r e !0 1 2 3 4 5 6 7 8

  • Recall: Counting Pattern in Text

    1.  Start from the first position of Text and check whether Pattern appears in Text starting at its first position.

    2.  If yes, draw a dot on a piece of paper. 3.  Move to the second position of Text and check

    whether Pattern appears in Text starting at its second position.

    4.  If yes, draw another dot on the same piece of paper. 5.  Continue until you reach the end of Text. 6.  Count the number of dots on the piece of paper.

  • Example: Implement Count()

    Pattern Counting Problem: Count the number of times that a pattern appears in a longer string. •  Input: Strings Text and Pattern. •  Output: The number of times that Pattern appears

    in Text.

    Note: our Count() function should handle overlaps (unlike strings.Count()).

    Think: do you see why “strings” is before “Count()”?

    Exercise: Write a Count() function in Go solving this problem.

  • Example: Reverse Complementing a String

    Reverse Complement Problem: •  Input: A DNA string Text. •  Output: The reverse complement of Text.

    T C A G C G T A T C A

    A G T C G C A T A G T

    3

    3

    5

    5

    Exercise: How could we solve this? What are the barriers?

  • Strings are Not Editable!

    func Complement(s string) string {for i:=0; i

  • Self-Avoiding Random Walks

    Self-avoiding walk: a walk that never visits the same square of the checkerboard twice.

    Input: Integers n and s. Output: Print each step of a random self-avoiding walk with s steps in an n x n chessboard (start in the middle).

  • Pseudocode for Random Self-Avoiding Walk

    SelfAvoidingRandomWalk(n,s)fieldßnxnbooleanarrayholdingallfalse(x,y)ß(n/2,n/2)field[x][y]ßtruePrint(x,y)foriß0to(steps–1) (xNext,yNext)=(x,y) whilefield[xNext][yNext] (xNext,yNext)=RandomStep(x,y,10) (x,y)=(xNext,yNext) field[x][y]=true Print(x,y)

    Note the code reuse of RandomStep() ...

  • Just Two Little Problems

    func SelfAvoidingRandomWalk(n, s int) {var field [n][n]bool //throws error!// ... blah

    }

    1. Corner case: If the path works itself into a corner with nowhere to go, the algorithm will have an infinite loop!

    2. In Go, arrays cannot have length equal to a variable.

  • Let’s Next Look at Max()

    FrequentWords(Text,k)FrequentPatternsßanemptylistcßemptyarrayoflength|Text|-kforiß0to|Text|-kPatternßSubstring(Text,i,k)c[i]ßCount(Text,Pattern)maxCountßMax(a)foriß0to|Text|-kifa[i]=maxCountaddSubstring(Text,i,k)toFrequentPatternsFrequentPatternsßRemoveDuplicates(FrequentPatterns)returnFrequentPatterns

  • func Max(A [10000000]int) int { m := 0 for i := range A { if A[i] > m { m = A[i] } } return m}

    func main() { var numbers [10000000]int

    // fill numbers with random integers for i := range numbers { numbers[i] = rand.Int() }

    fmt.Println(Max(numbers))}

    A new array A is created and the contents from numbers is copied over (wasteful of memory).

    Issue #2: Arrays Copied in Function Calls

  • (See Burrows-Wheeler Transform Slides)

  • Slices

  • var a []int// at this point a has the special value nil// and can’t be used as an arraya = make([]int, 10, 20)

    0 ! 0! 0 ! 0 ! 0 ! 0! 0 ! 0! 0! 0! 0! 0! 0! 0! 0! 0! 0! 0! 0! 0!0 ! 1! 2 ! 3 ! 4 ! 5! 6 ! 7! 8! 9! 10! 11! 12! 13! 14! 15! 16! 17! 18! 19!

    Underlying array has size 20!

    Length of this slice is 10 !

    A slice variable is declared by not specifying a size in []

    Creates an array of size 20 with a slice of size 10 inside it.

    Slices: Everything Arrays in Go Should Be

  • Omitting the Third Parameter

    var a []inta = make([]int, 10)// this is the same as make([]int, 10, 10)

  • We Can Still Change Items

    var a []inta = make([]int, 10)a[3] = -18

  • Passing a Variable as Slice Length

    var n int = 5050var a []stringa = make([]string, n) // this is OK!

  • Defining a Slice in One Line

    var n int = 100b := make([]string, n) // this is OK!

  • String literals: a sequence of characters between “”

    “Hi there”“!”“1+㆔=4”“3.14159”

    Integer literals: a sequence of digits 0…9

    726402000734

    bool (Boolean) literals: either true or false

    truefalse

    Unicode strings are supported.

    Recall: Literals ... The Other Side of “=”

  • Can also write slice literals (useful if you have a short list of data that may change):!

    Array and Slice Literals

    var a = []float64{3.2, -30, 84, 62}var prime = []int{2,3,5,7,11}

  • Can also write slice literals (useful if you have a short list of data that may change):!

    We can also use array literals (useful for a short list of data that is fixed):!

    Array and Slice Literals

    var a = []float64{3.2, -30, 84, 62}var prime = []int{2,3,5,7,11}

    var a = [3]float64{3.2, -30.0, 84.134}var prime = [5]int{2,3,5,7,11}

  • The append() Operation

    If we want to make a slice bigger by adding something to the end of it...

    s := make([]int, 10)

    0! 0 ! 0 ! 0! 0 0! 0! 0! 0 0!0! 1 ! 2 ! 3! 4! 5! 6! 7! 8! 9!

  • The append() Operation

    If we want to make a slice bigger by adding something to the end of it...

    s := make([]int, 10)s = append(s, 5)

    0! 0 ! 0 ! 0! 0 0! 0! 0! 0 0! 50! 1 ! 2 ! 3! 4! 5! 6! 7! 8! 9! 10