Сделайте один проход по всем строкам и создайте HashMap, который отображает каждый биграмм на набор индексов строк, содержащих этот биграмм. (В настоящее время вы создаете биграмный набор 900 000 раз для каждой строки.)
Затем выполните обход всех наборов и постройте HashMap из пар [index, index] для общего числа биграмм. (Последняя карта не должна содержать избыточных пар ключей, таких как [1,2] и [2,1] - просто храните одну или другую.)
Оба эти этапа можно легко распараллелить. Если вам нужен пример кода, пожалуйста, дайте мне знать.
ПРИМЕЧАНИЕ одна вещь, хотя: из 26 букв английского алфавита можно получить в общей сложности 26x26 = 676 биграмм. Многие из них никогда не будут или почти никогда не будут найдены, потому что они не соответствуют правилам английского правописания. Поскольку вы создаете наборов биграмм для каждой строки, а строки такие длинные, вы, вероятно, найдете почти одинаковые биграммы в каждой строке. Если бы вы собирали списки биграмм для каждой строки (другими словами, если бы частота каждой биграммы считалась), более вероятно, что вы действительно сможете измерить степень схожести между строками, но тогда вычисление коэффициента Дайса, приведенное в статье в Википедии, не сработает; вам нужно будет найти новую формулу.
Я предлагаю вам продолжить исследование алгоритмов определения сходства между строками, попробовать реализовать несколько из них и запустить их на меньшем наборе строк, чтобы увидеть, насколько хорошо они работают.