Используйте combn
(правда, не случайно).
n <- 5
out <- combn(n:1, n - 1)
out
# [,1] [,2] [,3] [,4] [,5]
#[1,] 5 5 5 5 4
#[2,] 4 4 4 3 3
#[3,] 3 3 2 2 2
#[4,] 2 1 1 1 1
Перетасуйте каждый столбец, если необходимо
set.seed(1)
apply(combn(n:1, n - 1), 2, sample)
Если вы ищете эффективность, используйте решение, которое я опубликовал;)
library(microbenchmark)
n <- 1000
set.seed(1)
benchmark <- microbenchmark(
akrun = vapply(seq_len(n), function(i) sample(setdiff(seq_len(n), i)), numeric(n-1)),
markus = apply(combn(n:1, n - 1), 2, sample),
A_Stam = create_matrix(n),
times = 30L
)
benchmark
#Unit: milliseconds
# expr min lq mean median uq max neval
# akrun 64.32350 66.99177 73.61685 71.15608 78.79612 104.99161 30
# markus 51.65092 53.01034 59.80802 58.48310 64.76143 78.35348 30
# A_Stam 1331.52882 1379.70371 1470.31044 1407.89861 1548.28011 1896.22913 30
Группа 3 определяется как являющийся 2 цифрами долго. Если Вы хотите соответствовать последним 4 цифрам, Вы хотите \(\d\d\d\d\)
без *
в конце. Если Вы просто хотите соответствовать всем цифрам, но первые 4, поместите Ваш *
в соответствии группы, а не снаружи.
Как записано, Ваш regex получает одну цифру, затем три цифры, затем любое количество групп из двух цифр каждый. Третье соответствие, поэтому, всегда будет двумя цифрами, если оно будет существовать. В Вашем конкретном тестовом сценарии, эти '89' находится в \4, не \3.
Изменение regex к
1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g
даст Вам '6789' как результат, так как он получит две или больше цифры (до столько, сколько там) в третьей группе.
Вы хотите использовать негруппу фиксации здесь, как так
1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g
который дает 6789
как результат здесь, и если введенный был изменен на
2345678
изменил бы строку на 278
Вы, вероятно, хотели бы (нуждайтесь в дополнительной группе обертывания):
%s/\(\d\)\(\d\d\d\)\(\(\d\d\)*\)\>/\3\g
Хотя я не уверен, почему Вы получаете первые 2 группы.
Я пробовал этот вариант в nvi и он не работает. В vim он работает, только вы должны исправить последнее инвертированное тире перед g на тире, вот так:
1,$s/\(\d\)\(\d\d\d\d\d\)\(\d\d\d\d\)*\>/\3/g
и оно заменяется на 89. Причина в том, что с помощью * вы говорите, что последнее \d\d может повторяться ноль, один или несколько раз, а с помощью > вы говорите о границе конечного слова. С группой 3 вы говорите, что вам нужна группа las, но из-за * последние две цифры (\d\d) равны 89. Убрав *>, вы можете получить 6789. Вот так:
1,$s/\(\d\)\(\d\d\d\d\)\(\d\d\d\)\(\d\d\d\)/\3/g
Следите за >, который играет хитрую роль, потому что с этим: :1,$s/\(\d\)\(\d\d\d\d\d\)\(\d\d\d\d\)\>/\3
вы получите 2389 LOL! Потому что с точки зрения конца слова-границы dddddd соответствует 456789 и заменяется двумя последними dd, а это 89. Таким образом, вы получаете 23+89
Потрясающе! LOL