Для семи чисел наиболее эффективным алгоритмом, который существует в отношении числа сравнений, является алгоритм Форда-Джонсона. На самом деле, Википедия ссылается на статью, которую легко найти в Google, в которой говорится, что Ford-Johnson - лучший на 47 номеров. К сожалению, ссылки на Форд-Джонсона не так просто найти, и алгоритм использует некоторые сложные структуры данных.
Он появляется в книге «Искусство компьютерного программирования», том 3, Дональда Кнута, если у вас есть доступ к этой книге.
Есть статья, в которой описывается FJ и более эффективная версия памяти здесь .
В любом случае, из-за нехватки памяти в этом алгоритме, я сомневаюсь, что оно будет стоить вашего времени для целых чисел, так как стоимость сравнения двух целых чисел довольно низкая по сравнению со стоимостью выделения памяти и манипулирования указателями.
Теперь вы упомянули, что 5 карт уже отсортированы, и вам просто нужно вставить две. Вы можете сделать это с помощью сортировки вставкой наиболее эффективно, как это:
Order the two cards so that P1 > P2
Insert P1 going from the high end to the low end
(list) Insert P2 going from after P1 to the low end
(array) Insert P2 going from the low end to the high end
То, как вы это сделаете, будет зависеть от структуры данных. С массивом вы поменяете местами каждый элемент, поэтому поместите P1 на 1-е, P2 и 7-е (упорядоченные по максимуму), а затем поменяйте местами P1 вверх, а затем P2 вниз. Со списком вам просто нужно исправить указатели соответствующим образом.
Однако еще раз, из-за специфики вашего кода, действительно лучше, если вы последуете совету nikie и просто сгенерируете циклы for для каждого варианта, в котором P1 и P2 могут появиться в списке .
Например, отсортировать P1 и P2 так, чтобы P1
Loop Po1 from 0 to 5
Loop Po2 from Po1 + 1 to 6
If (Po2 == 1) C1start := P2 + 1; C1end := 51 - 4
If (Po1 == 0 && Po2 == 2) C1start := P1+1; C1end := P2 - 1
If (Po1 == 0 && Po2 > 2) C1start := P1+1; C1end := 51 - 5
If (Po1 > 0) C1start := 0; C1end := 51 - 6
for C1 := C1start to C1end
// Repeat logic to compute C2start and C2end
// C2 can begin at C1+1, P1+1 or P2+1
// C2 can finish at P1-1, P2-1, 51 - 3, 51 - 4 or 51 -5
etc
Затем вы вызываете функцию, передающую Po1, Po2, P1, P2, C1, C2, C3, C4, C5, и эта функция возвращает все возможные перестановки, основанные на Po1 и Po2 (это 36 комбинаций).
Лично я думаю, что это самое быстрое, что вы можете получить. Вы полностью избегаете необходимости что-либо заказывать, потому что данные будут предварительно заказаны. В любом случае, вы берете на себя некоторые сравнения, чтобы вычислить начало и конец, но их стоимость сведена к минимуму, так как большинство из них будет на самых внешних циклах, поэтому они не будут повторяться много. И они могут быть даже более оптимизированы за счет большего дублирования кода.