Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> प्रोग्रामिंग

कसाई का एल्गोरिथम


कसाई के एल्गोरिथम का उपयोग प्रत्यय सरणी से सबसे लंबी सामान्य उपसर्ग (LCP) सरणी प्राप्त करने के लिए किया जाता है। सबसे पहले प्रत्यय सरणियाँ पाई जाती हैं। उसके बाद कसाई का एल्गोरिदम एलसीपी खोजने के लिए प्रत्यय सरणी सूची लेता है।

एलसीपी सरणी के लिए, यह ओ (एम लॉग एन) लेता है, जहां एम पैटर्न की लंबाई है और एन टेक्स्ट की लंबाई है। कसाई का एल्गोरिदम, मुख्य स्ट्रिंग में पैटर्न खोजने के लिए ओ (एन) लेता है।

इनपुट और आउटपुट

Input:
Main String: “banana”
Output:
Suffix Array :
5 3 1 0 4 2
Common Prefix Array :
1 3 0 0 2 0

एल्गोरिदम

buildSuffixArray(text)

इनपुट: मुख्य स्ट्रिंग

आउटपुट: प्रत्यय सरणी, मुख्य पाठ से निर्मित

Begin
   n := size of text

   for i := 0 to n, do
      suffArray[i].index := i
      suffArray[i].rank[0] := text[i]
      if (i+1) < n, then
         suffArray[i].rank[1] := text[i+1]
      else
         suffArray[i].rank[1] := -1
   do

   sort the suffix array
   define index array to store indexes

   for k := 4 to (2*n)-1, increase k by k*2, do
      currRank := 0
      prevRank := suffArray[0].rank[0]
      suffArray[0].rank[0] := currRank
      index[suffArray[0].index] = 0

      for all character index i of text, do
         if suffArray[i].rank[0] = prevRank AND suffArray[i].rank[1] =
            suffArray[i-1].rank[1], then
            prevRank := suffArray[i].rank[0]
            suffArray[i].rank[0] := currRank
         else
            prevRank := suffArray[i].rank[0]
            suffArray[i].rank[0] := currRank + 1
            currRank := currRank + 1
            index[suffArray[i].index] := i
      done

      for all character index i of text, do
         nextIndex := suffArray[i].index + k/2
         if nextIndex< n, then
            suffArray[i].rank[1] := suffArray[index[nextIndex]].rank[0]
         else
            suffArray[i].rank[1] := -1
      done
      sort the suffArray
   done

   for all character index i of text, do
      insert suffArray[i].index into suffVector
   done
End

kasaiAlgorithm(text, suffVector)

इनपुट - प्रत्ययों की सूची के रूप में मुख्य पाठ और प्रत्यय सदिश

आउटपुट: वह स्थान जहाँ सबसे लंबा सामान्य उपसर्ग पाया जाता है

Begin
   n := size of suffVector
   define longPrefix list of size n and fill all entries with 0
   define suffInverse list of size n and fill all entries with 0

   for all index values ‘i’ of suffVector, do
      suffInverse[suffVector[i]] = i
   done

   k := 0
      for i := 0 to n-1, do
         if suffInverse[i] = n-1 then
            k :=0
            ignore the bottom part and go for next iteration.
         j := suffVector[suffInverse[i]+1]

         while (i+k)<n AND (j+k) < n and text[i+k] = text[j+k], do
            increase k by 1
         done
         longPrefix[suffInverse[i]] := k
         if k > 0 then
            decrease k by 1
   done
   return longPrefix
End

उदाहरण

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

struct suffix {
   int index;
   int rank[2];    // To store rank pair
};

bool compare(suffix s1, suffix s2) {    //compare suffixes for sort function
   if(s1.rank[0] == s2.rank[0]) {
      if(s1.rank[1] < s2.rank[1])
         return true;
      else
         return false;
   }else {
      if(s1.rank[0] < s2.rank[0])
         return true;
      else
         return false;
   }
}

vector<int> buildSuffixArray(string mainString) {
   int n = mainString.size();
   suffix suffixArray[n];

   for (int i = 0; i < n; i++) {
      suffixArray[i].index = i;
      suffixArray[i].rank[0] = mainString[i] - 'a';     //store old rank
      suffixArray[i].rank[1] = ((i+1)<n)?(mainString[i+1]-'a'):-1; //rank after alphabetical ordering
   }

   sort(suffixArray, suffixArray+n, compare);    //sort suffix array upto first 2 characters
   int index[n];  //index in suffixArray

   for (int k = 4; k < 2*n; k = k*2) {    //increase k as power of 2
      int currRank = 0;
      int prevRank = suffixArray[0].rank[0];
      suffixArray[0].rank[0] = currRank;
      index[suffixArray[0].index] = 0;

      for (int i = 1; i < n; i++) {    // Assigning rank to all suffix
         if (suffixArray[i].rank[0] == prevRank && suffixArray[i].rank[1] == suffixArray[i-1].rank[1]) {
            prevRank = suffixArray[i].rank[0];
            suffixArray[i].rank[0] = currRank;
         } else{    //increment rank and assign
            prevRank = suffixArray[i].rank[0];
            suffixArray[i].rank[0] = ++currRank;
         }
         index[suffixArray[i].index] = i;
      }

      for (int i = 0; i < n; i++) {    // Assign next rank to every suffix
         int nextIndex = suffixArray[i].index + k/2;
         suffixArray[i].rank[1] = (nextIndex < n)? suffixArray[index[nextIndex]].rank[0]: -1;
      }
      sort(suffixArray, suffixArray+n, compare); //sort upto first k characters
   }

   vector<int>suffixVector;
   for (int i = 0; i < n; i++)
      suffixVector.push_back(suffixArray[i].index);    //index of all suffix to suffix vector
      return  suffixVector;
}

vector<int> kasaiAlgorithm(string mainString, vector<int> suffixVector) {
   int n = suffixVector.size();
   vector<int> longPrefix(n, 0);    //size n and initialize with 0
   vector<int> suffixInverse(n, 0);

   for (int i=0; i < n; i++)
      suffixInverse[suffixVector[i]] = i;    //fill values of inverse Suffix list
   int k = 0;
   for (int i=0; i<n; i++) {     //for all suffix in main string
      if (suffixInverse[i] == n-1) {    //when suffix at position (n-1)
         k = 0;
         continue;
      }

      int j = suffixVector[suffixInverse[i]+1];    //nest string of suffix list
      while (i+k<n && j+k<n && mainString[i+k]==mainString[j+k]) //start from kth index
         k++;
      longPrefix[suffixInverse[i]] = k;    // prefix for the current suffix.
      if (k>0)
         k--;    //remofe first character of string
   }
   return longPrefix;
}

void showArray(vector<int> vec) {
   vector<int>::iterator it;

   for (it = vec.begin(); it < vec.end() ; it++)
      cout << *it << " ";
   cout << endl;
}

int main() {
   string mainString = "banana";
   vector<int>suffixArray = buildSuffixArray(mainString);
   int n = suffixArray.size();

   cout<< "Suffix Array : "<<endl;
   showArray(suffixArray);

   vector<int>commonPrefix = kasaiAlgorithm(mainString, suffixArray);

   cout<< "\nCommon Prefix Array : "<<endl;
   showArray(commonPrefix);
}

आउटपुट

Suffix Array :
5 3 1 0 4 2
Common Prefix Array :
1 3 0 0 2 0

  1. फोर्ड फुलकर्सन एल्गोरिथम

    फोर्ड-फुलकर्सन एल्गोरिथम का उपयोग किसी दिए गए ग्राफ में प्रारंभ शीर्ष से सिंक शीर्ष तक अधिकतम प्रवाह का पता लगाने के लिए किया जाता है। इस ग्राफ में हर किनारे की क्षमता है। स्रोत और सिंक नाम के दो शीर्ष दिए गए हैं। स्रोत शीर्ष में सभी बाहरी किनारे हैं, कोई अंदरूनी किनारा नहीं है, और सिंक में सभी अंदर

  1. फ्लोयड वारशाल एल्गोरिथम

    Floyd-Warshall एल्गोरिदम का उपयोग किसी दिए गए भारित ग्राफ से सभी जोड़ी सबसे छोटी पथ समस्या को खोजने के लिए किया जाता है। इस एल्गोरिथम के परिणामस्वरूप, यह एक मैट्रिक्स उत्पन्न करेगा, जो ग्राफ़ में किसी भी नोड से अन्य सभी नोड्स के लिए न्यूनतम दूरी का प्रतिनिधित्व करेगा। सबसे पहले, आउटपुट मैट्रिक्स

  1. एल्गोरिथम में चरण गणना विधि

    चरण गणना विधि एल्गोरिदम का विश्लेषण करने की विधि में से एक है। इस पद्धति में, हम गिनते हैं कि एक निर्देश कितनी बार क्रियान्वित हो रहा है। इससे हम एल्गोरिथम की जटिलता का पता लगाने की कोशिश करेंगे। मान लीजिए कि अनुक्रमिक खोज करने के लिए हमारे पास एक एल्गोरिदम है। मान लीजिए प्रत्येक निर्देश c1, c2,… ल