如何对 pari/gp 中的混合整数/分数列表进行排序

How to sort a list of mixed integers / fractions in pari/gp

目前,我正在通过使用 FareySeries(n) 调用我的函数来实现 return n 阶 Farey 系列的算法。这很好用,例如调用 L = FareySeries(4) return秒 List([0, 1, 1/2, 1/3, 1/4, 2/3, 3/4]) 但我需要对列表进行排序。看了文档,我想

listsort(L)

会完成这项工作,但似乎这只适用于整数和浮点数(我手动测试过)。是否有一些内置函数(或参数)用于对包含混合整数和分数的列表进行排序,还是我必须手动对其进行排序? 我不需要代码自己整理,我只想使用,已经实现的;在这里坚持编码的基础知识。

最简单的解决方法是使用 vecsort。一般来说,我建议始终在列表上使用向量,除非在逐步构建列表时。构造一个列表后,return 将它作为向量从函数中更清晰。

L = List([0, 1, 1/2, 1/3, 1/4, 2/3, 3/4]);
listsort(L);
L

给出:List([0, 1, 1/2, 1/3, 1/4, 2/3, 3/4])(不正确)

L = List([0, 1, 1/2, 1/3, 1/4, 2/3, 3/4]);
vecsort(L)

给出:List([0, 1/4, 1/3, 1/2, 2/3, 3/4, 1])(正确)

请注意 vecsort 不会修改原始列表,因此如果您想更新列表,则需要将 vecsort 的输出分配回变量。

不过,我建议使用向量。

L = Vec(List([0, 1, 1/2, 1/3, 1/4, 2/3, 3/4]));
vecsort(L)

给出:[0, 1/4, 1/3, 1/2, 2/3, 3/4, 1](注意缺少 List)。

根本原因是vecsort使用了lex,而listsort使用了cmp。我不确定为什么 cmp 表现如此糟糕 - 可能是一个错误,但更有可能被设计破坏。

似乎 listsort 的排序顺序与集合使用的顺序相同,并且针对性能而非用户期望进行了优化。如果您希望在您的列表中使用 setsearch,那么您需要像集合一样对其进行排序。还有一个函数vecsearch,它使用lex作为比较函数。

也许还值得一提的是,vecsortvecsearch 都将用户提供的比较函数作为可选参数。