0

I have string output:

1 4 2 1 4

I want to get each character in string to compare. I did it to want to know whether the list is sorted yet.

DONG DAO
  • 19
  • 3
  • You can just loop through the elements and check if the previous element is smaller/greater than the current element, right? – Jerry Apr 19 '21 at 06:43
  • yes. the first, i will compare the first element with the rest. then to 2nd element .... – DONG DAO Apr 19 '21 at 06:52

2 Answers2

1

It's not exactly clear to me what you are trying to achieve. Going by "to know whether the list is sorted", and assuming a list of integers, you can use tcl::mathop::< or tcl::mathop::<=, depending on whether you want to allow duplicate values:

if {[tcl::mathop::<= {*}$list]} {
    puts "List is sorted"
} else {
    puts "List is mixed up"
}

This will also work for ASCII comparison of strings. For more complex comparisons, like using dictionary rules or case insensitive, it's probably easiest to combine that with lsort along with the -indices option:

tcl::mathop::< {*}[lsort -indices -dictionary $list]

The -indices option returns the original index of each list element in sorted order. By checking if those indices are in incremental order, you know if the original list was already sorted.

Of course, if the point of the exercise was to avoid unnecessary sorting, then this is no use. But then again, bubble sort of an already sorted list is very fast and will basically do exactly the comparisons you described. So just sorting will probably be faster than first checking for a sorted list via a scripted loop.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Schelte Bron
  • 4,113
  • 1
  • 7
  • 13
  • Upon examining the source code, it looks like Tcl doesn't use the bubble sort algorithm for sorting a list. I would nonetheless be surprised if just sorting an already sorted list would be slower than first checking using a scripted loop. In case of an unsorted list, the impact will even be worse. – Schelte Bron Apr 19 '21 at 09:38
  • Tcl uses mergesort, as that's both fast and stable. – Donal Fellows Apr 20 '21 at 08:18
0

To get each character in the string, do split $the_string "" (yes, on the empty string). That gives you a list of all the characters in the string; you can use foreach to iterate over them. Remember, you can iterate over two (or more) lists at once:

foreach c1 [split $the_string ""] c2 $target_comparison_list {
    if {$c1 ne $c2} {
        puts "The first not equal character is “$c1” when “$c2” was expected"
        break
    }
}

Note that it's rarely useful to continue comparison after a difference is found as the most common differences are (relative to the target string) insertions and deletions; almost everything after either of those will differ.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215