Пожалуйста, Baidu для некоторых основных концепций суффиксных массивов. Проще говоря, массив суффиксов представляет собой коллекцию всех размеров суффиксов строки. Тогда мы можем удовлетворить различные потребности в зависимости от некоторых свойств массива суффиксов.
Общедоступный класс mysuffixArrayTest {public char [] суффикс; // оригинальная строка public int n; // string public int [] Rank; // Рейтинг суффиксов [i] во всех суффиксах public int [] sa; // суффикс [sa [1]] <суффикс [sa [2]]… <суффикс [sa [len]], с достаточной работой, с достаточным я в суфлингах. Rank) public int [] height; // указывает суффикс [sa [i]] и суффикс [sa [i - 1]], то есть самый длинный публичный префикс двух смежных суффиксов, общественный инт [] h; // равен росте [i]], то есть самого длинного публичного префикса суффикса [i] и суффикса, сортируемого, сортировки, сортируемого, сортируемого [], сортировки, сортируемого [], сортировки [], сортировки, сортировки [], сортировки, сортируемого [], сортировки [], сортировки, сортировки [i] и сортировки, сортируемого [], сортировки [i] и сортировки, сортируемого [], сортировки [i] и сортировки, сортируемого [], сортировки [i] и суффикса. y; // Второе ключевое слово массив Public int [] x; // Ранг вспомогательный массив}В качестве примера следующие объяснения принимают строку «aabaaaab». Давайте сначала покажем результаты. Пожалуйста, обратитесь к этому результату для понимания и анализа (я скопировал чужую картину этого результата. Пожалуйста, подписайте 1 по умолчанию, потому что мой массив начинается с подписания 0)
Суффикс: оригинальный массив строк предполагает, что исходной строкой является «aabaaaab», затем соответствующее значение этого массива должно быть {'a', 'a', 'b', 'a', 'a', 'a', 'b'}
n: длина строки здесь n - 8
Ранг: рейтинговый массив массива суффиксов эквивалентен ранжированию, соответствующему суффиксу I-Th. Например, звание [0] относится к ранжированию суффикса «aabaaaab» [1] [1] относится к ранжированию суффикса "abaaaab"
SA: Это массив, который обратный для ряда. Узел X хранит суффикс? Или привести пример, чтобы проиллюстрировать, что SA [0] относится к массиву суффиксов с первым рейтингом, то есть 3. То есть соответствующий ранг [3] массива составляет 0. Пожалуйста, обязательно поймите формулу SA [rank [i]] = i. Если вы понимаете отношения между SA и рангом, вы также должны это понять.
Высота: высота [i] является длиной самого большого общего префикса массива суффиксов SA [i] и высоты суффиксов SA [I-1] [1] [1] относится ко второму и первым по величине обычным префиксам SA [1] и SA [0], то есть, самый большой общий префикс «AAAB» и «AAAAAB».
H: H [i] относится к суффиксу I-Th, и самый большой общественный префикс предыдущего H [0] относится к первым суффиксу, а именно: «aabaaaab» и самый большой общественный префикс предыдущего, а именно «aab», то есть рост [ранга [0]] = высота [3] = 3, это немного трудно понять. Вы не можете понять и продолжить чтение.
WS: Нечего сказать, считать сортировку вспомогательного массива
Y: Вторая сорта ключевых слов - это массив SA со вторым ключевым словом, сортированным эквивалентом второго ключевого слова
X: Вы можете понять это как резервное копирование ранга. Первоначально он использует резервную копию ранга, а затем записывает массив рангов после каждого цикла
Во -первых, давайте посмотрим на код для массива SA. Я объясню функцию кода один за другим и приложу общий код к следующему
rank = new int [n]; sa = new int [n]; ws = new int [255]; y = new int [n]; x = new int [n]; // Целью исходной строки для преобразования значения int в массив рангов для (int i = 0; i <n; i ++) {rank [i] = (int) суффикс [i]; }Функция приведенного выше кода заключается в инициализации массива и выполнении первого подсчета и сортировки. Первый цикл - назначить начальное значение массиву рангов. После выполнения соответствующее значение массива ранга составляет {97, 97, 98, 97, 97, 97, 97, 98}. Вы должны увидеть, что начальное значение массива ранга - это код ASCII, соответствующий букве.
Следующие три цикла являются первой сортировкой счета. Если вы не понимаете, что считает сортировку, пожалуйста, Baidu. Позвольте мне поговорить о процессе этих трех циклов
for (int i = 0; i <n; i ++) {ws [rank [i]] ++; x [i] = rank [i]; } for (int i = 1; i <ws.length; i ++) {ws [i]+= ws [i - 1]; }Что делают эти две петли, так это подсчитывают все значения возникновения и резервное копирование ранга до массива X. После запуска первого цикла WS [97] = 6, WS [98] = 2, а после запуска второго цикла WS [97] = 6, WS [98] = 8
for (int i = n-1; i> = 0; i--) {sa [-ws [rank [i]]] = i; }Приведенный выше абзац является конкретным кодом для подсчета и сортировки, чтобы найти массив SA. Все, должно быть, неправильно поняли в первый раз, когда они прочитали это. Почему они нашли SA? Я также был смущен впервые, но, пожалуйста, будьте терпеливы и внимательно понимайте этот код. Вы все еще помните формулу, упомянутую выше SA [rank [i]] = i, например, для суффикса «B», мы спрашиваем его SA, то есть SA [Rank [7]] = SA [98] = 7. Очевидно, что SA [98] не существует, но мы записали количество раз 98 появляется в массиве WS, поэтому WS [98] должен быть соответствующим рейтингом «B». Пожалуйста, не забудьте вычесть 1, чтобы стать SA [-ws [rank [i]]] = i. Что касается того, почему вам нужно пересечь сзади к фронту, вам нужно тщательно понять это, в противном случае вы определенно будете полностью ослеплены тем, как вы сортируете в соответствии со вторым ключевым словом. Как вы сортируете, если есть два значения ранга, которые одинаковы? Он должен появиться сначала перед массивом SA. Если вы подумаете об этом цикле и об изменениях в значении массива WS, вы поймете, что порядок цикла FO действительно представляет собой порядок расположения, когда значение ранга одинаково. Перенос сзади к фронту означает, что ранжирование суффиксов также ниже, когда значение ранга одинаково.
Выше приведено только первая сортировка счета, что эквивалентно сравнению только первой буквы каждого массива суффиксов, чтобы найти SA. Соответствующий результат, как показано на рисунке ниже.
// комбинация цикла сортировки для (int j = 1, p = 0; j <= n; j = j << 1) {// Если вам нужно заполнить его, добавьте массив сортировки сначала yp = 0; for (int i = n - j; i <n; i ++) {y [p ++] = i; } // диапазон второе ключевое слово в соответствии с первым ключевым словом SA для (int i = 0; i <n; i ++) {if (sa [i]> = j) {y [p ++] = sa [i] - j; }} // Сортировка двух ключевых слов для (int i = 0; i <ws.length; i ++) {ws [i] = 0; } for (int i: x) {ws [i] ++; } for (int i: x) {ws [i] ++; } for (int i = 1; i <ws.length; i ++) {ws [i]+= ws [i - 1]; } for (int i = n-1; i> = 0; i--) {sa [-ws [x [y [i]]] = y [i]; y [i] = 0; } // Рассчитайте массив ранга из SA int xb [] = new int [n]; // x массив резервного копирования для (int i = 0; i <n; i ++) {xb [i] = x [i]; } int number = 1; x [sa [0]] = 1; for (int i = 1; i <n; i ++) {if (xb [sa [i]]! = xb [sa [i - 1]]) {x [sa [i]] = ++ №; } else if (sa [i] + j> = n && sa [i - 1] + j> = n) {x [sa [i]] = number; } else if (sa [i] + j <n && sa [i - 1] + j> = n) {x [sa [i]] = ++ number; } else if (xb [sa [i] + j]! = xb [sa [i - 1] + j]) {x [sa [i]] = ++ №; } else {x [sa [i]] = number; } if (number> = n) break; }}Это самый сложный кусок кода, который можно понять при поиске массива SA. Прежде всего, вам нужно понять идею алгоритма умножения. После первого приказа подсчета мы уже знаем сортировку первой первоначальной буквы всех массивов суффиксов? Поскольку мы знаем, что сортировка первой первоначальной буквы эквивалентна порядку его второй буквы (обратите внимание на разницу между сортировкой и порядком. Сортировка заключается в том, что мы знаем, в какой из них он исправлен. Приказ заключается в том, что мы знаем только порядок, в котором он появляется, но мы не знаем, какой из них он специально оценивается). Это, конечно, потому что они родом из строки, и для каждого суффикса его также можно использовать в качестве суффикса для его предыдущего суффикса. Говоря об этом, например, для «Baaaab» порядок ее первой буквы соответствует второму порядку ключевого слова «abaaaab». Благодаря порядку первого ключевого слова и видом второго ключевого слова мы можем найти комбинированный вид двух ключевых слов. В соответствии с результатом комбинации, мы все еще можем использовать предыдущую идею. После первой комбинации «baaaab» мы разбираем порядок первых двух букв «Ba», чтобы он также мог использовать порядок второго ключевого слова «aabaaaab». Логика всего вида упоминается ниже
Затем мы проанализируем код в сегментах
for (int i = n - j; i <n; i ++) {y [p ++] = i; } // Выберите второе ключевое слово в соответствии с первым ключевым словом SA для (int i = 0; i <n; i ++) {if (sa [i]> = j) {y [p ++] = sa [i] - j; }}Приведенный выше код состоит в том, чтобы найти SA, то есть массив Y второго ключевого слова, причем первоначальное значение P было 0, а первым циклом является ранжирование суффикса, который необходимо заполнить в передней части массива.
Вы должны понять логику второго цикла в сочетании с предыдущей логической диаграммой. Мы пересекаем результат сортировки первого ключевого слова SA. If (sa [i]> = j) определяет, можно ли использовать суффикс в качестве второго ключевого слова для других суффиксов. Принимая первую петлю j = 1 в качестве примера, когда SA [i] = 0 представляет массив суффиксов «aabaaaab», очевидно, что его нельзя использовать в качестве второго ключевого слова для других суффиксов. Для второго ключевого слова, которое можно использовать в качестве других суффиксов, порядок его SA является соответствующим вторым ключевым словом. SA [i] - J находит суффикс его в качестве второго ключевого слова и помещает его в массив Y и P ++. Вы должны понимать здесь медленно.
// объединить два ключевых слова для (int i = 0; i <ws.length; i ++) {ws [i] = 0; } for (int i: x) {ws [i] ++; } for (int i = 1; i <ws.length; i ++) {ws [i]+= ws [i - 1]; } for (int i = n-1; i> = 0; i--) {sa [-ws [x [y [i]]]] = y [i]; y [i] = 0; }Выше приведено найти сортировку комбинации на основе первого ключевого слова сортировки SA и второго ключевого слова сортировка Y. Этот код довольно неясен. Сначала мы не можем понять код, но понять идею. Для сортировки двух ключевых слов фактические правила аналогичны сортировке двух чисел. Например, 11 и 12 сравнивают размер, 10 бит являются первым ключевым словом, а одиночные биты - второе ключевое слово. После сравнения 10 бит мы находим 11 = 12, а затем сравниваем единые биты, мы знаем, что 11 <12. Если 10 бит одинаковы, порядок отдельных битов - это порядок размера. Я сказал, что в первый раз, когда я считаю сортировкой выше, порядок сортировки счета для цикла фактически представляет собой порядок соглашения, когда значения ранга одинаковы. Итак, как мы находим заказ после того, как два ключевых слова объединены в одном счете сортировки? Позвольте мне сказать вам мое понимание. Одна сортировка подсчета на самом деле содержит два сорта, один из них - это тип численных значений, а другой - это тип порядка возникновения. Правила эквивалентны предыдущему примеру сравнения 11 и 12. Вид численных значений составляет 10 бит, а тип порядка возникновения - один бит. На данный момент у нас есть идея. Сортировка значений сортируется по первым ключевым словам, а сортировка случаев сортируется по второму ключевому слову, так что мы можем считать и сортировать одновременно, чтобы найти сортировку после объединения двух ключевых слов. Приведенный выше код является реализацией этой идеи. X массив - это рядовой массив первого ключевого слова, и мы считаем его.
for (int i = n-1; i> = 0; i--) {sa [-ws [x [y]]]] = y [i]; y [i] = 0; }Этот цикл является реализацией всех вышеперечисленных идей. Мы пересекаем второе массив ключевых слов Y со спины. Для y [i] мы рассчитываем рейтинг счета его первого ключевого слова. Этот рейтинг подсчета является рейтингом y [i], и окончательный счет уменьшается на 1. Объединенное сортирование ключевых слов была успешно найдена.
Я считаю, что если вы понимаете все вышеперечисленные коды, вы определенно будете поражены. Я также был взволнован, когда думал об этом коде снова и снова, и я был просто убежден. Это очарование алгоритмов.
С массивом SA мы можем найти рядовой массив. Это не сложно, поэтому мы не объясним это. Все коды для поиска SA прикреплены ниже.
public static void main (string [] args) {string str = "aabaaaab"; Mysuffixarraytest arraytest = new mysuffixarraytest (str.toString ()); arraytest.initsa (); // найти array sa} public void initsa () {rank = new int [n]; sa = new int [n]; ws = new int [255]; y = new int [n]; x = new int [n]; // Целью исходной строки для преобразования значения int в массив рангов для (int i = 0; i <n; i ++) {rank [i] = (int) суффикс [i]; } // Первый счет сортировки для (int i = 0; i <n; i ++) {ws [rank [i]] ++; x [i] = rank [i]; } for (int i = 1; i <ws.length; i ++) {ws [i]+= ws [i - 1]; } for (int i = n-1; i> = 0; i--) {sa [-ws [rank [i]]] = i; } // Сортировка комбинации цикла для (int j = 1, p = 0; j <= n; j = j << 1) {// Если вам нужно заполнить, добавьте отсортированный массив сначала yp = 0; for (int i = n - j; i <n; i ++) {y [p ++] = i; } // диапазон второе ключевое слово в соответствии с первым ключевым словом SA для (int i = 0; i <n; i ++) {if (sa [i]> = j) {y [p ++] = sa [i] - j; }} // Сортировка двух ключевых слов для (int i = 0; i <ws.length; i ++) {ws [i] = 0; } for (int i: x) {ws [i] ++; } for (int i = 1; i <ws.length; i ++) {ws [i]+= ws [i - 1]; } for (int i = n-1; i> = 0; i--) {sa [-ws [x [y [i]]] = y [i]; y [i] = 0; } // Рассчитайте массив ранга на основе SA int xb [] = new int [n]; // x резервное копирование массива для (int i = 0; i <n; i ++) {xb [i] = x [i]; } int number = 1; x [sa [0]] = 1; for (int i = 1; i <n; i ++) {if (xb [sa [i]]! = xb [sa [i - 1]]) {x [sa [i]] = ++ №; } else if (sa [i] + j> = n && sa [i - 1] + j> = n) {x [sa [i]] = number; } else if (sa [i] + j <n && sa [i - 1] + j> = n) {x [sa [i]] = ++ number; } else if (xb [sa [i] + j]! = xb [sa [i - 1] + j]) {x [sa [i]] = ++ №; } else {x [sa [i]] = number; } if (number> = n) break; }}}}Суммировать
Выше приведено пример кода для мешков массивов суффиксов Java, представленных вам. Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит вам вовремя. Большое спасибо за вашу поддержку сайту wulin.com!