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

C++での回文部分文字列クエリ


このチュートリアルでは、指定された文字列の回文部分文字列クエリを解決する必要があります。回文の部分文字列クエリの解決は、C++での通常のクエリの解決よりもはるかに複雑です。はるかに複雑なコードとロジックが必要です。

このチュートリアルでは、文字列strとQ個のsubstring [L ... R]クエリが提供され、それぞれに2つの値LとRがあります。クエリを解決してsubstring[L。 ..R]は回文です。 LからRの範囲内に形成された部分文字列が回文であるかどうかを判断して、各クエリを解決する必要があります。例-

Let's input "abbbabaaaba" as our input string.
The queries were [3, 13], [3, 11], [5, 8], [8, 12]
It is necessary to determine whether the substring is a plaindrome
A palindrome is "abaaabaaaba" (3, 13) .
It is not possible to write "baaa" as a palindrome [3, 11].
As in [5, 8]: "aaab" cannot be a palindrome.
There is a palindrome in "baaab" ([3, 12]).

解決策を見つけるためのアプローチ

ナイーブな方法

ここでは、部分文字列がインデックス範囲LからRであるかどうかを確認して回文を見つける必要があります。したがって、すべての部分文字列クエリを1つずつ確認し、それらが回文であるかどうかを判断する必要があります。 Qクエリがあり、各クエリが応答するのに0(N)時間かかるため。最悪の場合、0(Q.N)の時間がかかります。

#include <bits/stdc++.h>
using namespace std;
int isPallindrome(string str){
   int i, length;
   int flag = 0;
   length = str.length();
   for(i=0;i < length ;i++){
      if(str[i] != str[length-i-1]) {
         flag = 1; break;
      }
   }
   if (flag==1)
      return 1;
   return 0;
}
void solveAllQueries(string str, int Q, int query[][2]){
   for(int i = 0; i < Q; i++){
      isPallindrome(str.substr(query[i][0] - 1, query[i][1] - 1))?                  cout<<"Palindrome\n":cout<<"Not palindrome!\n";
   }
}
int main() {
   string str = "abccbeba"; int Q = 3;
   int query[Q][2] = {{3, 5}, {5, 7}, {2, 1}};
   solveAllQueries(str, Q, query);
   return 0;
}

出力

Palindrome
Palindrome
Not palindrome!

動的計画法

問題を解決するために動的計画法アプローチを使用することは効率的なオプションです。解決するには、DP配列を作成する必要があります。これは、部分文字列[i...j]がDP[i][j]の回文であるかどうかを示すブール値を含む2次元配列です。

このDPマトリックスが作成され、各クエリのすべてのL-R値がチェックされます。

#include <bits/stdc++.h>
using namespace std;
void computeDP(int DP[][50], string str){
   int length = str.size();
   int i, j;
   for (i = 0; i < length; i++) {
      for (j = 0; j < length; j++)
         DP[i][j] = 0;
   }
   for (j = 1; j <= length; j++) {
      for (i = 0; i <= length - j; i++) {
         if (j <= 2) {
            if (str[i] == str[i + j - 1])
               DP[i][i + j - 1] = 1;
         }
         else if (str[i] == str[i + j - 1])
            DP[i][i + j - 1] = DP[i + 1][i + j - 2];
      }
   }
}
void solveAllQueries(string str, int Q, int query[][2]){
   int DP[50][50];
   computeDP(DP, str);
   for(int i = 0; i < Q; i++){
      DP[query[i][0] - 1][query[i][1] - 1]?cout
      <<"not palindrome!\n":cout<<"palindrome!\n";
   }
}
int main() {
   string str = "abccbeba"; int Q = 3;
   int query[Q][2] = {{3, 5}, {5, 7}, {2, 1}};
   solveAllQueries(str, Q, query);
   return 0;
}

出力

palindrome!
not palindrome!
palindrome!

結論

このチュートリアルでは、c++コードとともにパリンドロームの部分文字列クエリを解決する方法を学びました。このコードは、Java、Python、およびその他の言語で作成することもできます。このコードは、最も複雑で長いコードの1つでした。回文クエリは通常のサブストリングクエリよりも難しく、非常に正確なロジックが必要です。このチュートリアルがお役に立てば幸いです。


  1. 数値がC++の回文であるかどうかを確認します

    ここでは、番号が回文であるかどうかを確認する方法を説明します。回文数は両方向で同じです。たとえば、番号12321は回文ですが、12345は回文ではありません。 ロジックは非常に単純です。数を逆にする必要があります。逆の数が実際の数と同じである場合、それは回文です。そうでない場合はそうではありません。より良いアイデアを得るためのアルゴリズムを見てみましょう。 アルゴリズム isPalindrome(n)- 入力 −数n 出力 −数値が回文の場合はtrue、それ以外の場合はfalse begin    temp := n    rev :=

  2. C++の部分文字列

    部分文字列は文字列の一部です。 C ++で部分文字列を取得する関数はsubstr()です。この関数には、posとlenの2つのパラメーターが含まれています。 posパラメータは部分文字列の開始位置を指定し、lenは部分文字列の文字数を示します。 C++で部分文字列を取得するプログラムは次のとおりです- 例 #include <iostream> #include <string.h> using namespace std; int main() {    string str1 = "Apples are red"; &nb