Если бы ваш «Список 2» был кратчайшим, результат предпосчета был бы таким:
{ /* Список 2: {1,2,3}; {1,2,5}; {1,3,4}; {4,5,6} */
{1,2,3,...}, /* '1' есть в 1, 2 и 3-м массивах */
{1,2,0,...},
{1,3,0,...},
{3,4,0,...},
{2,4,0,...},
{4,0,...},
{0,...},
...
{0,...} /* 50-й массив */
}
Тогда расчет для каждого массива из длинного списка был бы таким:
int[][] pred;
...
for (int i = 0; i < 10; i++) {
for (int si = 0; ; si++) {
int from_short_list = pred[from_long_list[i] - 1][si];
if (!from_short_list) break;
<ячейка для from_long_list, from_short_list> ++;
}
}
Проще не счетчики добавлять, а по построенному дереву в глубину пройтись 1 раз.
И это точно верный путь:
«Functionality:… Find the most frequently occurring substrings of a minimum length (ex. 1) in O(n) time.» — со странички в английской википедии.
Damaskus, имеете ввиду все равно не получается доступа к внутреннему состоянию? Во-первых, можно будет сделать интерфейс вложенным в BASE, ведь интерфейсы с extension methods очень похожи на абстрактные классы, а их делать вложенными можно. Во-вторых, чем тогда поможет миксин в Си++ (или что вы имеете ввиду под «прививанием» нужных методов)?
По ощущениям, рука уставала в основном от «подкрючивания» пальцев для кликов и скролла. Вес роли не играет — не такой он большой, да и двигается мышь всего на пару сантиметров туда-сюда.
Тогда расчет для каждого массива из длинного списка был бы таким: