CSC 153 | Grinnell College | Spring, 2005 |
Computer Science Fundamentals | ||
Laboratory Exercise | ||
This laboratory builds upon background material on character data and provides experience with string processing within Scheme. This includes:
This approach converts the string to a list of characters and then processes the list, yielding the following code (which uses vowel? from step 1 in this lab).
(define number-vowels (lambda (str) ;Pre-condition: str is a character string ;Post-condition: returns number of vowels in str (number-vowels-kernel (string->list str)) ) ) (define number-vowels-kernel (lambda (ls) ;Pre-condition: ls is a list of characters ;Post-condition: returns number of vowels in ls (cond ((null? ls) 0) ((vowel? (car ls)) (+ 1 (number-vowels-kernel (cdr ls)))) (else (number-vowels-kernel (cdr ls))) ) ) )
This approach examines each letter within the string itself, and increase a count (from 0) each time a vowel is encountered. This approach motivates the following code:
(define number-vowels (lambda (str) ;Pre-condition: str is a character string ;Post-condition: returns number of vowels in str (count-vowels-by-position str 0 0) ) ) (define count-vowels-by-position (lambda (str current-count current-position) ;Pre-condition: str is a character string; counts are 0 ;Post-condition: returns number of vowels in str (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))) ) ) )
Write a procedure which solves this problem 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.
The following procedures encodes a letter, based on a cipher alphabet:
(define encode-char (lambda (ch plain cipher) ;Pre-condition: ??? ;Post-condition: ??? (encode-char-kernel ch plain cipher 0) ) ) (define encode-char-kernel (lambda (ch plain cipher position) ;Pre-condition: ??? ;Post-condition: ??? (cond ((= position (string-length plain)) ch) ((char-ci=? ch (string-ref plain position)) (string-ref cipher position)) (else (encode-char-kernel ch plain cipher (+ position 1)))) ) )
Using these procedures, a message may be encoded as follows:
(define encode-message (lambda (str plain cipher) ;Pre-condition: str is a character string ; plain and cipher are as in encode-char ;Post-condition: returns transformation of str ; using monoalphabetic substitution (list->string (encode-message-kernel (string->list str) plain cipher)) ) ) (define encode-message-kernel (lambda (lst plain cipher) ;Pre-condition: lst is a character string ; plain and cipher are as in encode-char ;Post-condition: returns transformation of lst ; using monoalphabetic substitution (if (null? lst) '() (cons (encode-char (car lst) plain cipher) (encode-message-kernel (cdr lst) plain cipher)) ) ) )
Check that encode-message works correctly with the data from the above example:
(encode-message "THIS IS A MESSAGE TO ENCODE." "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "XDQTVBKRAUGMZHYWCJOSENILPF")
Add pre- and post-conditions to the above procedures. Be careful to specify all assumptions regarding the plain and cipher alphabets.
Write the corresponding procedure
(define dencode-message (lambda (str plain cipher) ;Pre-condition: str is a character string ; plain and cipher are as in encode-char ;Post-condition: returns a decoding of str ; using monoalphabetic substitution '(--- your part replaces this line ---) ) )
Note this is VERY EASY. In particular, your solution should fit easily on a single line.
Plain alphabet: abcdefghijklmnopqrstuvwxyz Cipher alphabet: rstlnejpaxkdzvqmhbyuofcgiw
Thus, an upper case T would be replaced by S as before, but a lower case t would be replaced by the letter t.
How would you change the code and/or the call to encode-message and decode-message to allow these different substitutions for upper and lower case letters? Be sure to run tests to check your conclusions!
In the above procedures, the user must supply the plain and cipher alphabets. However, in all cases, one would expect that the plain alphabet would be always be the same (i.e., the alphabet with both uppercase and lower case letters in their usual order). Revise encode-message and decode-message, so only a cipher alphabet must be supplied by the use. Again, be sure to test the resulting code.
Write a procedure that reverses the letters in a string. Thus, (string-reverse "this is a string") should return "gnirts a si siht"
A palindrome is a string which reads the same from front to back and from back to front. For example, "this is a palindromemordnilap a si siht" is a palindrome. Write a procedure palindrome that checks if a string is a palindrome.
This document is available on the World Wide Web as
http://www.walker.cs.grinnell.edu/courses/153.sp05/labs/lab-strings.shtml
created March 5, 1997 last revised February 2, 2005 |
![]() ![]() |
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |