Как укорачивать вектор?
Код:
? v=[1,2,3,4,5]; print(v[2..4])
[2, 3, 4]
В качестве последнего элемента можно указывать например его размер #v.
Можно конечно и переменные использовать вместо конкретных чисел.
Отбросить или начало или хвост.
Код:
? v=[1,2,3,4,5]; print(v[3..#v])
[3, 4, 5]
? v=[1,2,3,4,5]; print(v[1..3])
[1, 2, 3]
Как напечатать число 23454567654 в виде
23 454 567 654 с помощью printf?
Если речь про разделители групп разрядов, то никак.
Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
Код:
? x=1234567890123456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 123, 456]
1 234 567 890 123 456
Вообще связка strsplit/strjoin весьма мощная, хоть и медленная, можно делать много красивых вещей.
Теперь по сортировке.
Преобразование вектора чисел в одно число с последующей сортировкой и преобразованием обратно -- вполне нормальный подход. Тем более что можно выбрать в каком порядке преобразовывать числа для их правильной сортировки.
Преобразовать строку в длинное число можно так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); x=fromdigits(v,10^6)
34332000003000005000433000445000678
Преобразовать обратно уже показывал, но ещё раз:
Код:
? x=34332000003000005000433000445000678; d=digits(x,10^6); print(d); s=strjoin(d," "); print(s)
[34332, 3, 5, 433, 445, 678]
34332 3 5 433 445 678
Чтобы последующая сортировка была в порядке 2,3,4,5,6,1 столбцов, надо перед объединением вектора в одно число переставить его элементы желаемым образом, например так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); v=concat(v[2..6],v[1])
[3, 5, 433, 445, 678, 34332]
На самом деле для сортировки массива векторов вовсе не обязательно их преобразовывать в числа, можно и сразу vecsort натравить:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); print(vecsort(v))
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[[3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456], [3, 5, 433, 445, 678, 34332]]
Если бы у Вас был не вектор/массив векторов, а матрица, то подматрицы (в том числе отдельные строки или столбцы) из неё можно вытаскивать так:
Код:
? m=matrix(4,3,x,y,y*5+x)
[6 11 16]
[7 12 17]
[8 13 18]
[9 14 19]
? m[,2]
[11, 12, 13, 14]~
? m[,2..3]
[11 16]
[12 17]
[13 18]
[14 19]
? m[2..4,1]
[7, 8, 9]~
? m[2..4,1..2]
[7 12]
[8 13]
[9 14]
? m[2..4,]
[7 12 17]
[8 13 18]
[9 14 19]
А чтобы vecsort не хапала слишком много памяти под результат (если он большого размера, не просто вектор чисел), то можно вместо готовой перестановки получать лишь порядок индексов и потом идти в указанном им порядке по исходному вектору и сохранять данные куда и как надо:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); ind=Vec(vecsort(v,,1)); print(ind); foreach(ind,i, print(v[i]););
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[2, 3, 1]
[3, 5, 46, 33, 366, 5639]
[3, 5, 46, 55, 78, 456]
[3, 5, 433, 445, 678, 34332]
-- 21.05.2023, 18:09 --Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
К сожалению это часто работает некорректно:
Код:
? x=1234567890023456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 23, 456]
1 234 567 890 23 456
Ну тогда можно преобразовать каждую "цифру" в строку отдельно через strprintf, а потом уж объединить в единую строку:
Код:
? x=1234567890023456; d=digits(x,1000); for(i=2,#d, d[i]=strprintf("%03d",d[i]);); d[1]=Str(d[1]); print(strjoin(d," "));
1 234 567 890 023 456
Это правильно работает и для чисел до 1000 (и до 10 тоже).
-- 21.05.2023, 18:48 --Вашу задачу -- сортировку массива векторов чисел из текстовых строк по 2, 5, 1 элементу (ну для примера) -- можно решить в одну строчку:
Код:
? s=["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"] \\Реально заменимо на s=readstr(file); вообще без всяких циклов
["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"]
? vecextract(s,vecsort(eval(apply(t->vecextract(strsplit(t," "),[2,5,1]),s)),,1))
["5639 3 5 46 33 366", "456 3 5 46 55 78", "34332 3 5 433 445 678"]
Тут сначала делим строки на кусочки, выбираем только нужные столбцы (и в нужном для сортировки порядке), преобразуем строки в числа, получаем вектор перестановок для отсортированного результата, ну и переставляем
исходный массив строк в желаемом порядке.