プログラミング
 Computer >> コンピューター >  >> プログラミング >> プログラミング

接尾辞配列


指定された文字列から、可能なすべてのサフィックスを取得できます。辞書式順序で接尾辞を並べ替えると、接尾辞配列を取得できます。接尾辞配列は、接尾辞木を使用して形成することもできます。接尾辞木のDFSトラバーサルを使用することにより、接尾辞配列を取得できます。接尾辞配列は、線形時間で接尾辞を見つけるのに役立ちます。二分探索タイプの手順を使用して、接尾辞配列を使用して部分文字列を検索することもできます。

時間計算量はO(m log n)

入力と出力

Input:
Main String: “BANANA”, Pattern: “NAN”
Output:
Pattern found at position: 2

アルゴリズム

fillSuffixArray(text、suffArray)

入力: メインストリング

出力: 接尾辞の配列

Begin
   n := text Length
   define suffix array as allSuffix of size n

   for i := 0 to n-1, do
      allSuffix[i].index := i
      allSuffix[i].suff := substring of text from (i to end)
   done

   sort the allSuffix array
   store indexes of all suffix array in suffArray.
End

suffixArraySearch(テキスト、パターン、suffArray)

入力: メインの文字列、パターン、接尾辞配列

出力- パターンが見つかった場所

Begin
   patLen := size of pattern
   strLen := size of text
   left := 0
   right := strLen -1

   while left <= right, do
      mid := left + (right - left)/2
      tempStr := substring of text from suffArray[mid] to end
      result := compare tempStr and pattern upto pattern length.

      if result = 0, then
         print the location
      if res < 0, then
         right := mid – 1
      else
         left := mid +1
   done
End

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

struct suffix {
   int index;
   string suff;
};

int strCompare(string st1, string st2, int n) {
   int i = 0;
   while(n--) {
      if(st1[i] != st2[i])
         return st1[i] - st2[i];
      i++;
   }
   return 0;
}

bool comp(suffix suff1, suffix suff2) {     //compare two strings for sorting
   if(suff1.suff<suff2.suff)
      return true;
   return false;
}

void fillSuffixArray(string mainString, int suffArr[]) {
   int n = mainString.size();
   suffix allSuffix[n];    //array to hold all suffixes

   for(int i = 0; i<n; i++) {
      allSuffix[i].index = i;
      allSuffix[i].suff = mainString.substr(i);    //from ith position to end
   }

   sort(allSuffix, allSuffix+n, comp);
   for(int i = 0; i<n; i++)
      suffArr[i] = allSuffix[i].index;    //indexes of all sorted suffix
}

void suffixArraySearch(string mainString, string pattern, int suffArr[], int array[], int *index) {
   int patLen = pattern.size();
   int strLen = mainString.size();
   int left = 0, right = strLen - 1;    //left and right for binary search

   while(left <= right) {
      int mid = left + (right - left)/2;
      string tempStr = mainString.substr(suffArr[mid]);
      int result = strCompare(pattern,tempStr, patLen);
   
      if(result == 0) {    //the pattern is found
        (*index)++;
        array[(*index)] = suffArr[mid];
      }

      if(result < 0)
         right = mid -1;
      else
         left = mid +1;
   }
}

int main() {
   string mainString = "BANANA";
   string pattern = "NAN";
   int locArray[mainString.size()];
   int index = -1;

   int suffArr[mainString.size()];
   fillSuffixArray(mainString,  suffArr);
   
   suffixArraySearch(mainString, pattern, suffArr, locArray, &index);
   for(int i = 0; i <= index; i++) {
      cout << "Pattern found at position: " << locArray[i]<<endl;
   }
}

出力

Pattern found at position: 2

  1. アレイが回文であるかどうかをチェックするCプログラム

    任意のサイズnの配列arr[]が与えられた場合、私たちのタスクは、配列が回文であるかどうかを確認することです。回文は、MADAM、NAMANなどのように、同じように前後に読み取ることができるシーケンスです。 したがって、配列が回文であるかどうかを確認するために、-のように配列を前後にトラバースできます。 例 Input: arr[] = {1, 0, 0, 1} Output: Array is palindrome Input: arr[] = {1, 2, 3, 4, 5} Output: Array is not palindrome 以下で使用されるアプローチは次のとおりです

  2. Cの配列内の範囲の積

    配列、L、R、Pを入力として指定し、タスクは、モジュロの下の積を出力としてLとRの間の範囲を見つけ、それを表示することです。 図に示されているように、要素の配列と、2としての左の値であるLと2としての右の値であるRがあります。ここで、プログラムはそれらの間の範囲の積を見つける必要があります。 例 Input-:  A[] = { 1, 2, 3, 4, 5, 6 }    P = 29  L = 2 R = 6 Output-: 24 Input-: A[] = {1, 2, 3, 4, 5, 6},    L =