Laboratory Exercises For Computer Science 153

Strings

Strings

Goals: This laboratory builds upon background material on character data and discusses string processing within Scheme. Such processing includes string literals, zero-based indexing, string procedures, and string predicates.

Review of Character Processing:

  1. Write a predicate vowel? which determines whether a given character is a vowel. Thus, (vowel? #\e) and (vowel? #\E) should both return true (#t), while (vowel? #\r), (vowel? #\R), and (vowel? #\?) should return false (#f).

Literal Strings: A string is a sequence of characters. The external form of a string is the characters enclosed in double-quotes:

   "This is a string!"
Special characters can be included in a string by escaping them with a back-slash:
   "Type \"stop\" to quit."
Zero-based Indexing: While much work with strings does not require access to individual characters within a string, some procedures reference positions in a string. In such cases, Scheme numbers character positions within strings starting at position 0. For example, consider the string:

   "I am very excited by the Scheme programming language!!!"
Scheme regards the first character (I) as being in position 0, followed by a blank or space character in position 1. The letters 'a' and 'm' follow in positions 2 and 3, respectively.

Some String Procedures: Some common string procedures are shown in the following table:

Procedure Sample Call Result of Example Comment
string? (string?
"sample string")
True (#t) is argument a string?
string-length (string-length
"sample string")
13 number of characters in string
string-append (string-append "Big" "Small") "BigSmall" concatenate two strings
substring (substring
"sample string" 3 10)
"ple str" extract characters from first to before second designated position from string
string-ref (string-ref
"sample string" 4)
#\l return character at given position
string->list(string->list "example") (#\e #\x #\a #\m #\p #\l #\e) makes a list of the characters in a string
list->string (list->string '(#\e #\x #\a #\m #\p #\l #\e)) "example" makes a string of the characters in a list
symbol->string (symbol->string 'example) "example" change a given symbol to a string
string->symbol (string->symbol "example") example convert a given string to a symbol

Some Comparisons of Strings: Scheme also provides various predicates to compare two strings are equal:

Procedure Comment
string=? Are two strings equal?
string Does first string come first?
string>? Does first string come after?
string<=? Is first string equal the second or does the first come before the second?
string>=? Are the strings equal or does the first come after the second?

Scheme also provides string predicates which are case-insensitive:

string-ci=? Same as string=?, but ignoring case
string-ci Same as string, but considering uppercase and lowercase letters to be equivalent
string-ci>? Same as string>?, but ignoring case
string-ci<=? Same as string<=?, but ignoring case
string-ci>=? Same as string>=?, but ignoring case

Additional Discussion: Reread Section 3.1 of the textbook.

Example: Consider the problem of counting the number of vowels within a string.

Approach 1: Convert the letters of the string to a list, and recursively count the vowels on the list. This might lead to the following code (which uses vowel? from earlier in this lab).


   (define number-vowels
       (lambda (str)
           (number-vowels-kernel (string->list str))
       )
   )

   (define number-vowels-kernel
       (lambda (ls)
           (cond ((null? ls) 0)
                 ((vowel? (car ls)) (+ 1 (number-vowels-kernel (cdr ls))))
                 (else (number-vowels-kernel (cdr ls)))
           )
        )
   )
  1. Why is the work divided into two procedures, number-vowels and number-vowels-kernel?

Approach 2: Examine each letter in the string, and increase your count (from 0) each time a vowel is encountered. This approach motivates the following code, which moves position by position from the start of the string to the end:

    (define number-vowels
       (lambda (str)
           (count-vowels-by-position str 0 0)
       )
    )

    (define count-vowels-by-position
       (lambda (str current-count current-position)
           (cond ((= current-position (string-length str))
                        current-count )
                 ((vowel? (string-ref str current-position))
                        (count-vowels-by-position str 
                                        (+ 1 current-count)
                                        (+ 1 current-position)))
                 (else (count-vowels-by-position str current-count
                                        (+ 1 current-position)))
           )
       )
   )
  1. Write a paragraph describing (in English) how this program works.
  2. In this code, characters are examined by moving from the beginning of the string to the end of the string. Rewrite this code, so processing proceeds from the end of the string to the start.

Approach 3: Proceed with recursion directly. The base case involves the empty string, which contains zero vowels. For other cases, examine the first letter and add one, if necessary, to the result of applying the procedure to the substring consisting of all letters except the first.

  1. Write a procedure which solves this problem using this third approach.

Encryption

Section 3.1.3 discusses how this approach can be applied to each character of a string in turn to encode the entire string.

  1. Write a paragraph describing the text's approach to encryption.

  2. A second approach to encryption uses the procedures encrypt-chars and decrypt-chars procedures from the previous lab on characters. Specifically, encryption could utilize the following outline:

    1. Convert a string to a list of characters.
    2. Apply encrypt-chars to the character list to produce a list of encoded values.
    3. Use the modified decrypt-chars to produce a string from the resulting list.

    Implement this alternative approach of encryption.

  3. Implement a corresponding procedure for decryption.

  4. After trying this alternative approach on a variety of strings, comment upon the relative merits of the text's approach to encryption and this alternative approach.

Further String Processing

  1. Solve exercises 3-7 and 3-9 in the text.

This document is available on the World Wide Web as

http://www.math.grin.edu/~walker/courses/153/lab-strings.html

created March 5, 1997
last revised January 13, 1998