Добавить открывающую фигурную скобку в начало списка в tcl

Я пытаюсь найти декартово произведение двух множеств в tcl. Моя логика готова, но мне нужно украсить вывод и поставить открывающую скобку в начале списка. Я могу добавить в конец с помощью команды append, но при этом возникает ошибка для начала списка. Ниже приведен код:

set a {0 1}
set b {1 2 3}
set s {}
append s "\{"                                              ### this is where the problem is
for {set i 0} { $i < 2 } {incr i} {
         for {set j $i} { $j < 2 } {incr j} {
                  set x "([lindex $a $i],[lindex $b $j])"
                  lappend s "$x,"
                  
         }
         if {$j == 2} {
                  set x "([lindex $a $i],[lindex $b $j])"
                  lappend s "$x"
               }
      }
      append s }
      puts $s

Теперь используя

append s "\{" 

дает

unmatched open brace in list

С другой стороны, используя

append s "\\{"

дает следующий вывод:

\{ (0,1), (0,2), (0,3) (1,2), (1,3)}

Есть ли способ удалить первую косую черту и пробел между открывающей фигурной скобкой и первой скобкой?


person Saransh Choudhary    schedule 16.03.2021    source источник
comment
Вы пытаетесь построить строку, а не список. Так что лучше используйте строковые команды, такие как append, а не команду списка, такую ​​как lappend. Это позволяет избежать волшебного цитирования при печати результата.   -  person Schelte Bron    schedule 16.03.2021
comment
В качестве альтернативы создайте список и поместите его в фигурные скобки в конце: puts "{[join $s]}"   -  person Schelte Bron    schedule 16.03.2021
comment
Вам может быть интересно это: wiki.tcl-lang.org/page/Cartesian+product   -  person Shawn    schedule 16.03.2021
comment
Ха! Два очень похожих ответа…   -  person Donal Fellows    schedule 16.03.2021


Ответы (2)


Преимущество использования списка заключается в том, что вы можете легко соединить его с запятыми между ними, поэтому вам не нужно прибегать к особой обработке последнего элемента, как вы это делаете. Заключить все это в фигурные скобки проще всего в конце, после присоединения к списку:

set a {0 1}
set b {1 2 3}
set s {}
for {set i 0} {$i < 2} {incr i} {
    for {set j $i} {$j < 3} {incr j} {
        set x "([lindex $a $i],[lindex $b $j])"
        lappend s $x
    }
}
puts "{[join $s ", "]}"
person Schelte Bron    schedule 16.03.2021

Вам, вероятно, лучше построить вывод в виде списка, который затем преобразуется в строку:

set a {0 1}
set b {1 2 3}

# The list of cells to appear in the output
set cells {}
# [foreach] is nicer than [for]/[lindex]
foreach i $a {
    foreach j $b {
        # Format a single cell
        lappend cells "($i,$j)"
    }
}
# Produce the result string with [string cat] and [join]
set result [string cat "{" [join $cells ", "] "}"]
puts $result
person Donal Fellows    schedule 16.03.2021
comment
Он говорит: unknown or ambiguous subcommand "cat": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart while executing "string cat "{" [join $cells ", "] "}"" invoked from within "set result [string cat "{" [join $cells ", "] "}"]" (file "tt.tcl" line 14) Я пропустил какой-либо пакет или это проблема версии? - person Saransh Choudhary; 16.03.2021
comment
Я думал об использовании foreach в своем ответе, пока не заметил, что внутренний цикл должен начинаться с элемента $i вместо 0. Тогда я решил оставаться ближе к исходному коду. - person Schelte Bron; 16.03.2021
comment
@SaranshChoudhary Какую версию tcl вы используете? - person Shawn; 16.03.2021
comment
Для string cat вам нужен Tcl 8.6.3 или новее. (Я не совсем уверен насчет .3. Он был добавлен в каком-то патче поверх 8.6) - person Schelte Bron; 16.03.2021
comment
@Шон, я использую 8.5 - person Saransh Choudhary; 16.03.2021
comment
Просматривая примечания к выпуску, я обнаружил, что string cat впервые появился в Tcl 8.6.2. - person Schelte Bron; 16.03.2021
comment
Используете 8.5? Возможно, стоит попытаться перейти на использование текущих производственных версий; Версия 8.6 находится на стадии расширенной поддержки, а это означает, что она своевременно получает только исправления безопасности (и, к счастью, их не слишком много). - person Donal Fellows; 16.03.2021
comment
В более старых версиях Tcl [string cat "{" [join $cells ", "] "}"] также может быть записано как "{[join $cells {, }]}", но я не думаю, что это так же ясно, как и то, что происходит. - person Donal Fellows; 17.03.2021