在 LaTeX3 中对列表进行排序

在 LaTeX3 中对列表进行排序

我有一个clist想进行冒泡排序的程序。我确信这是一件简单的事情,比如\clist_bubblesort:N或类似的事情,但我不知道合适的咒语是什么。快速谷歌搜索没有发现任何明显的信息...

答案1

l3sort包可以做到这一点(但目前使用合并排序,我希望你不介意加速),只要 clist 最多有 20000 个项目左右(我不记得确切的限制)。

\documentclass{article}
\usepackage{expl3, xparse}
\ExplSyntaxOn
\clist_new:N \l_my_clist
\NewDocumentCommand{\sorted}{m}
  {
    \clist_set:Nn \l_my_clist {#1}
    \clist_sort:Nn \l_my_clist
      { \int_compare:nTF { ##1 > ##2 } { \sort_return_swapped: } { \sort_return_same: } }
    \clist_use:Nnnn \l_my_clist { ~ and ~ } { , ~ } { , ~ and ~ }
  }
\ExplSyntaxOff
\begin{document}
  The sorted numbers are \sorted{3, 4, 123, -1, 2, -01}.
\end{document}

该命令将给定的列表存储在 clist 变量中,\l_my_clist然后使用以下标准对其进行排序:将两个项目作为整数进行比较;如果第一个大于第二个,则它们必须交换;否则将它们保留在相同的顺序。然后使用该 clist,并加上适当的分隔符:~and~对于包含两个项目的列表,,~大多数项目之间以 结尾,~and~~实际上是空格标记,因为空格会被忽略。

请注意,排序是稳定的,因为比较相等的数字被认为是有序的(当然,这依赖于适当地选择测试,\sort_return_same:当数字相等时调用,就像这里所做的那样)。

我有一个长期计划,提供类似的东西\sort_keep_one:n {##1},允许只保留两个术语中的一个,这对于删除重复项很有用。我可以想象这在构建索引时也很有用,只保留每部作品的一个副本,但跟踪页码列表:\sort_keep_one:n { ##1 ~ <pages> }

相关内容