Word Cleaning Code
Author |
Message |
uberwalla
|
Posted: Mon Nov 27, 2006 6:53 pm Post subject: Word Cleaning Code |
|
|
ok so for class i got to do this assignment where u input a word and it cleans it for u. by clean it means that if u have anything other then letters then it removes it. Example: u enter u%tr9e. then it outputs utre.
i have the program done in a way and it works except for ONE thing it seems.
I get this msg: Quote: Substring Index Is Greater Than Length Of String
it happens when i actually input the word to clean
and it high lights this line:
Quote: if x (letterNum) >= chr (97) and x (letterNum) <= chr (122) then
All works fine when u look back at the output window; the word cleans, but i get that error any suggestions//help? plz
here is my code:
code: |
%The "Clean" Program
%By: Mike Lanthier
%Monday, November 27, 2006
var word : string
var letterNum : int := 1
function clean (x : string) : string
for i : 1 .. length (word)
if x (letterNum) >= chr (97) and x (letterNum) <= chr (122) then
put x (letterNum) ..
else
put "" ..
end if
letterNum := letterNum + 1
end for
result clean (word)
end clean
get word
put clean (word)
|
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
Cervantes
|
Posted: Tue Nov 28, 2006 9:44 am Post subject: (No subject) |
|
|
Your code doesn't work because it's creating an infinite recursive loop. See your function? What is the value that it returns? It returns 'clean (word)'. So now we've got to call the clean function on word again, and return whatever that returns. But then that will once again return clean (word).
So you've got an infinite loop. That doesn't explain why things crash, though. The reason things crash is because you are using global variables and not reseting their state when you recall your function. See, letterNum starts at 1, but then when you call your function again (done by the function itself), letterNum starts at some number greater than one, and quickly becomes larger than the length of word.
Now, we need to clean this up, a lot. First, we need to get rid of these global variables. We should be using local variables: variables whose scope is contained to the function -- they don't exist outside the function. And indeed, why should they? They're only used in processing of our word. Next, we need to get rid of the use of put. If at all possible, functions should not have side effects. That means that they shouldn't change the state of your program. Outputting something does change the state of something: the run window. Instead, have the function return the cleaned version of the word. That makes a lot more sense, right? Here's one version of your code:
code: |
function clean (x : string) : string
var cleaned_word := ""
for i : 1 .. length (x)
if x (i) >= chr (97) and x (i) <= chr (122) then
cleaned_word += x (i)
end if
end for
result cleaned_word
end clean
var word : string
get word
put clean (word)
|
That's one way to do it. But now I'm going to show you another way. It doesn't use loops. It uses recursion (check the Turing Walkthrough for a link to the tutorial, if you're interested). In many ways, this is more natural. Here's how it works. We give our word, "u%tr9e" to our function, and it returns "u" + the result of calling clean on "%tr9e". Calling clean on "%tr9e" simply calls clean on "tr9e". That is, it returns the result of calling clean on "tr9e". Calling clean on "tr9e" returns "t" plus the result of calling clean on "r9e", which returns "r" + the result of calling clean on "9e", which returns the result of calling clean on "e", which returns "e" plus the result of calling clean on "", which returns "". You can see that this will build our cleaned word. Here's the code:
code: |
function clean (x : string) : string
if x = "" then
result ""
elsif x (1) >= chr (97) and x (1) <= chr (122) then
result x (1) + clean (x (2 .. *))
else
result clean (x (2 .. *))
end if
end clean
var word : string
get word
put clean (word)
|
Questions? |
|
|
|
|
|
uberwalla
|
Posted: Tue Nov 28, 2006 10:56 am Post subject: (No subject) |
|
|
ok first of all id like to say tyvm that answers my question completely
but i do have a few questions about the second one.
Quote:
code: |
if x = "" then
result ""
elsif x (1) >= chr (97) and x (1) <= chr (122) then
result x (1) + clean (x (2 .. *))
else
result clean (x (2 .. *))
end if
end clean
|
i understand the rest of what u had put and i understand the if x ... to the line elsif etc.
what i dont understand is where the clean (x(2..*) comes into play
i undestand that * is the last letter of the word or somthing right?
if u dont understand my question plz ask and ill try to make it better |
|
|
|
|
|
zylum
|
Posted: Tue Nov 28, 2006 3:41 pm Post subject: (No subject) |
|
|
'*' refers to the length of the word. this way you dont have to do
code: | result x (1) + clean (x (2 .. length(x))) |
so the first if checks if the recursion is complete, the second checks if the first letter is usable. if so return it plus the cleaned version of the rest of the string. if not, then that letter is useless and you only return the clean version of the rest of the string. |
|
|
|
|
|
Cervantes
|
Posted: Tue Nov 28, 2006 3:41 pm Post subject: (No subject) |
|
|
means the string of characters in x starting from the second character and ending with the last character.
code: |
"hello world" (2 .. *) % gives "ello world"
|
So in our recursive analysis, we wanted to call clean on everything but the first character (the "rest" of the string, if you will). That's how it's done. |
|
|
|
|
|
uberwalla
|
Posted: Tue Nov 28, 2006 3:56 pm Post subject: (No subject) |
|
|
ahh ok tyvm guys |
|
|
|
|
|
|
|