Dhenn
Dhenn

Reputation: 295

TCL Program that Compare String

I'm trying to create a program that the First and last characters are compared, Second and second to the last are compared, Third and third to the last are compared, and so on, and if any of these characters match, the two will be converted to the uppercase of that character.

Example:

Please enter a text: Hello Philippines finals: HEllo PhIlippinEs

I can't create any piece of code, I'm stuck with

puts "Please enter text:"
set myText [gets stdin]

string index $myText 4 

Can someone help me please?

Upvotes: 1

Views: 4342

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137567

The simplest way to code this is to use foreach over the split-up characters. (It's formally not the most efficient, but it's very easy to code correctly.)

puts "Please enter text:"
set myText [gets stdin]

set chars [split $myText ""]
set idx 0
foreach a $chars b [lreverse $chars] {
    if {[string equals -nocase $a $b]} {
        lset chars $idx [string toupper $a]
    }
    incr idx
}
set output [join $chars ""]

puts $output

Note that the foreach is iterating over a copy of the list; there are no problems with concurrent modification. In fact, the only vaguely-tricky part from a coding perspective is actually that we need to keep track of the index to modify, in the idx variable above.


With Tcl 8.6 you could write:

set chars [split $myText ""]
set output [join [lmap a $chars b [lreverse $chars] {
    expr {[string equals -nocase $a $b] ? [string toupper $a] : $a}
}] ""]

That does depend on having the new lmap command though.


If you're really stuck with 8.3 (it's unsupported and has been so for years, so you should be prioritizing upgrading to something more recent) then try this:

set chars [split $myText ""]
set idx [llength $chars]
set output {}
foreach ch $chars {
    if {[string equals -nocase $ch [lindex $chars [incr idx -1]]]} {
        append output [string toupper $ch]
    } else {
        append output [string tolower $ch]
    }
}

All the features this uses were present in 8.3 (though some were considerably slower than in later versions).

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 246754

This procedure will also capitalize the first i in Phillipines because it's equidistant from the start and the end of the string.

proc compare_chars {str} {
    set letters [split $str ""]
    for {set i [expr {[llength $letters] / 2}]} {$i >= 0} {incr i -1} {
        set a [lindex $letters $i]
        set b [lindex $letters end-$i]
        if {$a eq $b} {
            lset letters $i [set L [string toupper $a]]
            lset letters end-$i $L
        }
    }
    join $letters ""
}
puts [compare_chars "Hello Phillipines"]
# outputs =>  HEllo PhIllipinEs

Upvotes: 3

Related Questions