RAPTOR - Working with Strings


Strings in Raptor are nothing more than one-dimensional arrays in which each element is one character in the string:


Because characters within a string can be accessed individually, they can also be manipulated individually:

Notice that we can use characters in much the same way that we use literal numbers. We simply surround the character with apostrophes (single quote marks). In fact, each character is associated with a specific number and all the apostrophes do is tell Raptor to look up the number associated with that character and use that number.

Let's write an algorithm that asks the user for a string, converts the string to all uppercase, and then outputs the converted string.

Since we are always stressing good problem decomposition, let's break our problem up as follows:

The MAIN algorithm

  1. Get a string from the User

  2. Output the original string

  3. Modify the string

  4. Output the modified string

Since all but the 3rd task can be handled by single Raptor symbols, there is no point is creating subcharts for them. The third one, however, lends itself nicely to a couple of levels of decomposition.

The MODIFY_STRING algorithm

  1. Walk through the string character by character and for each character in turn:

    1. Extract the character from the string.

    2. Modify the character.

    3. Re-insert the character back into the string.

This naturally suggests a simple count controlled loop where we first find out how many characters are in the string, and then execute a loop that looks at each character in turn and then calling a subchart that modifies that character. Notice that the Modify_String subchart doesn't concern itself with the details of the modification to be performed, it's task is simply to walk through the string character by character and call the Modify_Character subchart on each one.

The MODIFY_CHARACTER algorithm

The Modify_Character subchart takes the character stored in a particular variable (namely 'char') and performs some modification on it - it never deals with the details of working with a string, in fact it doesn't even know that there is a string at all.

  1. IF the character is lower case

    1. Convert the character to upper case

Notice that we, the algorithm writer, never needed to know the specific numbers that are associated with any of the characters. We let Raptor look those up when needed. What we did rely on was the following piece of rather intuitive information: The numbers associated with the characters in the alphabet are sequential. All this means is that whatever number is associated with an uppercase 'A', the number associated with an uppercase 'B' is one more and so on until we reach the number associated with an uppercase 'Z'. The same is true for lowercase characters.

One thing that we don't know - and don't need to know, although it would be trivial to find out - is what the relationship is between the number associated with an uppercase character and the corresponding lowercase character. Why not? How can we convert from lowercase to uppercase with that knowledge? The answer lies in the assignment statement above - the fragment (char - 'a') results in a value that represents the offset of the lowercase character we are working with from the lowercase 'a'. For instance, if the character is 'b' then the offset is 1. We then add this offset to an uppercase 'A' and the result will be the value associated with the uppercase equivalent to our original character - namely 'B' in our example.


If you run this algorithm and use "Bob" as your input, then you should get the following result:


Now let's increase the complexity of how we want to modify our string as follows:

  1. Ask the User to input a string.

  2. Ask the User for an uppercase shift amount.

  3. Ask the User for a lowercase shift amount.

  4. Output the original string.

  5. For each character in the string, shift it by the appropriate amount.

    1. Positive shifts are to the right (the new letter is later in the alphabet)

    2. Shifts "wrap-around" so that 'Y' with a shift of 3 becomes 'B' while 'c' with a shift of -5 becomes 'x'.

    3. Non-characters (spaces, numbers, punctuation marks, etc.) are not changed.

  6. Output the modified string.

Sounds pretty complex, doesn't it? Let's break it down and see if we can't greatly simplify it:

Under these constraints, we have a very simple problem:

  1. Ask the User to input a string (uppercase only).

  2. Output the original string.

  3. For each character in the string, shift it by +3 (three characters later with wraparound).

  4. Output the modified string.

Since we are assuming that the User is only entering uppercase characters, we will forego doing any checking on that. With this in mind, our Modify_Character subchart is quite straightforward:

To test our algorithm, we want to use a string that has characters at both ends of the alphabet and is long enough to see both wraparound and no wraparound at the end:

Our next step is to get our program working with negative shifts, although we will still restrict ourselves to uppercase characters. The needed modification should be pretty obvious. Since we will eventually get the shift amount from the User, we replace our hard-coded value of 3 with a variable (named "shift") whose value is assigned at the beginning of the Main subchart (although eventually, of course, it will be derived from values entered by the User). The resulting Modify_Character subchart and output from an example run are as follows:

At this point we can make note of the fact that our Modify_Character subchart is a self-contained subchart that performs a positive or negative shift on an uppercase characters including any necessary wraparound. So lets copy this subchart and rename it Shift_Uppercase:

With this subchart at a building block, we are now in a position to solve the rest of the problem. Consider the following new algorithm for our Modify_Character subchart:

  1. IF the character is uppercase:

    1. Set shift to Upper_Shift

    2. CALL Shift_Uppercase

  2. IF the character is lowercase:

    1. Set shift to Lower_Shift

    2. Convert char to uppercase

    3. CALL Shift_Uppercase

    4. Convert char to lowercase

The values "Upper_Shift" and "Lower_Shift" are the shift values entered by the User. We've already seen how to convert a lowercase character to an uppercase one.

Notice that by only modifying the character if we sense it as uppercase or lowercase explicitly, we automatically take care of all of the non-alphabetic characters by simply doing nothing.

The end result for our Modify_Character subchart is therefore:

The final version of our Main chart along with some sample output when the uppercase characters are shifted by 5 and the lowercase characters are shifted by -3 is as follows: