Finding the greater word

Hello,
I have a file with the following contents:

>>>Goodness ^ Of ^ Grace: Come :;You broken! > Heavy laden.. ..
<<<+Come! You helpless!?.() come You in despair:-(..

I wrote the following code to find the greater word:

function extractor()
    inn = open("input.txt","r")
    temp1 = ""
    temp2 = ""
    while !eof(inn)
        ch = read(inn, Char)
        if isletter(ch)
            temp1 *= ch
        elseif isspace(ch) && (cmp(temp1,temp2) == 1)
            temp2 = temp1
            temp1 = ""
        end        
    end
    println(temp2)
end

extractor()

The result is:

Of

What is wrong?

Thank you.

Define what you mean by “greater” for us. What word did you want to find and why?

1 Like

Hi,
Thank you so much for your reply.
For example, You is smaller than you.

Why is You smaller than you?

Hi,
Because:

julia> Int('Y')
89

julia> Int('y')
121

How do you compare an empty string “” with the string “abc”?

1 Like

With the cmp function:

julia> temp1 = "Goodness"
"Goodness"

julia> temp2 = ""
""

julia> cmp(temp1,temp2)
1
julia> a="Of"
"Of"

julia> b="Goodness"
"Goodness"

julia> if cmp(a,b) == 1
       println("a is greater than b")
       else println("b is greater than a") end
a is greater than b

So “Of” is the greatest word of them all. Problem solved.

2 Likes

Hi,
But, You is greater than Of:

julia> cmp("Of","You")
-1

julia> Int('O')
79

julia> Int('Y')
89
julia> "You" < "you"
true

It’s lexical ordering.

Use temp1 > temp2 instead. It does the same thing, but is clearer. I actually didn’t know about the cmp function until now.

The easiest approach here would be to leverage the fact that you can already compare strings directly:

julia> "You" < "you"
true

julia> "You" < "Of"
false

In Julia, comparing strings will treat them as bytearrays and compare each byte in the string. If all the bytes are the same, the larger string is greater. Not only is this efficient (it calls into Libc’s memcmp), it is generally also what you want when comparing strings.
Therefore, you can find the largest word using maximum:

julia> largest_word(s::Union{String, SubString{String}}) = maximum(eachsplit(s); init="");

julia> largest_word(""">>>Goodness ^ Of ^ Grace: Come :;You broken! > Heavy laden.. ..
       <<<+Come! You helpless!?.() come You in despair:-(..""")
"laden.."

If you only want to compare words, you can use strip to remove non-letters:

function largest_word(s::Union{String, SubString{String}})
      words = Iterators.map(w -> strip(!isletter, w), eachsplit(s))
      maximum(words ;init="")
 end
1 Like

Hello,
Thank you, but I’m a beginner and I don’t want to use the maximum function. Which part of my code is wrong? I expect this code to print in!

The issue with your code is that you don’t reset temp1 on every word. That is:

  1. You read the word Goodness: temp2 is now Goodness
  2. You read the word Of. This is larger than Goodness, so temp2 is now Of
  3. You read the word Grace. This is smaller than Of, so temp2 stays Of
  4. You read the word Come. However, you did not clear temp1 after reading Grace. So, temp1 is now GraceCome. Since temp1 is never cleared, but more letters is added to its end, it will keep being smaller than Of.

So, you need to make temp1 = "" unconditional on wheter temp1 < temp2:

        if isletter(ch)
            temp1 *= ch
        elseif isspace(ch)
            if temp1 < temp2
                temp2 = temp1
            end
            temp1 = ""
        end    
2 Likes

Hi,
Not really, I cleared temp1 variable:

while !eof(inn)
        ch = read(inn, Char)
        if isletter(ch)
            temp1 *= ch
        elseif isspace(ch) && (cmp(temp1,temp2) == 1)
            temp2 = temp1
            temp1 = ""
        end        
    end

Please read carefully.
You only clear temp1 if it becomes greater than temp2.
You need to clear it after any word regardless of it being the current greatest or not.

There is also a question how you treat a sequence like aaa!!bb which is not a continuous letter sequence but also not a space-separated sequence.

And, whenever you open a file, you must close it. It’s best to write:

open("input.txt", "r") do inn
   # do your stuff
end

which is a shorthand for

inn = open("input.txt", "r")
try
    # do your stuff
finally
    close(inn)
end

The try ... finally construct is crucial because finally block will run even if there is an error in the try block. Without that, the file will certainly be closed only if there were no errors thrown from the function.

5 Likes

Hi,
Thank you so much for your reply.
I guess the code is correct. I removed the comparison operation from the code:

function extractor()
    inn = open("input.txt","r")
    temp1 = ""
    while !eof(inn)
        ch = read(inn, Char)
        if isletter(ch)
            temp1 *= ch
        elseif isspace(ch)
            println(temp1)
            temp1 = ""
        end
    end
end

extractor()

The output is:

Goodness

Of

Grace
Come
You
broken

Heavy
laden
Come
You
helpless
come
You
in
despair

So I have emptied the temp1 variable in the right place.
What is your opinion?

Thank you.

Hi,
Thank you @jakobnissen. You were right. I should have used two if statements and cleared the temp1 variable somewhere else. The correct code is as follows:

function extractor()
    inn = open("input.txt","r")
    temp1 = ""
    temp2 = ""
    n = 0
    while !eof(inn)
        ch = read(inn, Char)
        if isletter(ch)
            temp1 *= ch
        elseif isspace(ch)
            if (cmp(temp1,temp2) == 1)
            temp2 = temp1
            end
            temp1 = "" 
        end         
    end
    println(temp2)
end

extractor()

If I understand the problem correctly, I believe this would serve as a “Julionic” way to do it

julia> input = """">>>Goodness ^ Of ^ Grace: Come :;You broken! > Heavy laden.. ..\n<<<+Come! You helpless!?.() come You in despair:-(..""";

julia> getproperty.(eachmatch(r"\w+", input), :match) |> findmax
("laden", 8)
2 Likes

Hi,
Thank you so much for your solution, but I’m a newbie.

It much nicer and easier to understand if you write temp1 > temp2 instead, as suggested before.

2 Likes