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

C++で指定インデックス範囲内の回文部分文字列の個数を求める方法


文字列と、startからendまでの範囲が与えられたとき、その範囲内に存在する回文(パリンドローム)部分文字列の個数を計算するのが本記事のテーマです。回文とは、「nitin」や「aba」のように、前から読んでも後ろから読んでも同じになる文字列のことを指します。

入力 − InputString = "cccaabbbdee"、start = 2、end = 6

出力 − 指定インデックス範囲内の回文部分文字列の個数:7

説明 − 文字列と範囲が与えられているため、startポインタの位置2('c')からendポインタの位置6('b')まで文字列を走査します。対象となる部分文字列は「caabb」です。この中に含まれる回文部分文字列は、'c'、'a'、'a'、'b'、'b'、'aa'、'bb' の7つとなります。

入力 − InputString = "lioaabbbdee"、start = 0、end = 2

出力 − 指定インデックス範囲内の回文部分文字列の個数:3

説明 − startポインタの位置0('l')からendポインタの位置2('o')まで走査すると、対象となる部分文字列は「lio」です。この中の回文部分文字列は 'l'、'i'、'o' の3つとなります。

プログラムで採用しているアプローチ

  • 任意のサイズの文字列と、変数startからendまでの範囲を宣言します。
  • データを関数 palindrome_index(arr, InputString) に渡し、以降の処理を行います。
  • 関数内で、文字列の長さに対応するサイズの2次元配列 check を宣言します。
  • i を0から配列の長さまでループさせます。
  • その内部で、j を0から配列の長さまでさらにループさせます。
  • ループ内では check[i][j] = 0 および arr[i][j] = 0 を設定します。
  • i を length - 1 から0以上となる間、逆順にループさせます。
  • ループ内で check[i][i] と arr[i][i] を1に設定した後、j を i + 1 から配列の長さまでループさせます。
  • ループ内で、i 番目の文字と j 番目の文字が一致し、かつ (i + 1 > j - 1 または check[i + 1][j - 1] != 0) が成り立つ場合は check[i][j] を1に、そうでなければ0に設定します。続いて arr[i][j] = arr[i][j - 1] + arr[i + 1][j] - arr[i + 1][j - 1] + check[i][j] を計算します。
  • 最後に、start と end をインデックスとして2次元配列の値を出力します。

import java.io.*;
class testqwe {
    static void palindrome_index(int arr[][], String s) {
        int length = s.length();
        int[][] check = new int[length + 1][length + 1];
        for (int i = 0; i <= length; i++) {
            for (int j = 0; j <= length; j++) {
                check[i][j] = 0;
                arr[i][j] = 0;
            }
        }

        for (int i = length - 1; i >= 0; i--) {
            check[i][i] = arr[i][i] = 1;
            for (int j = i + 1; j < length; j++) {
                if(s.charAt(i) == s.charAt(j) && (i + 1 > j - 1 || (check[i + 1][j - 1]) != 0)) {
                    check[i][j] = 1;
                } else {
                    check[i][j] = 0;
                }
                arr[i][j] = arr[i][j - 1] + arr[i + 1][j] - arr[i + 1][j - 1] + check[i][j];
            }
        }
    }
    public static void main(String args[]) {
        String InputString = "cccaabbbdee";
        int[][] arr;
        arr = new int[50][50];
        palindrome_index(arr, InputString);
        int start = 2;
        int end = 6;
        System.out.println("Count of Palindromic substrings in an Index range " + arr[start][end]);
    }
}

上記のコードを実行すると、以下のような出力が得られます −

出力

Count of Palindromic substrings in an Index range 7

  1. C++で解く「最小範囲 II」:±K の加算で最大値と最小値の差を最小化するアルゴリズム

    問題の概要整数の配列 A が与えられます。各要素 A[i] に対して、x = -K または x = K のどちらか一方を選び、その値を A[i] に加算します(各要素につき1回のみ)。この操作をすべての要素に適用すると、新しい配列 B が得られます。求めるのは、B の最大値と最小値の差として実現できる最小値です。例として、入力が A = [0, 10]、K = 2 の場合を考えてみましょう。このとき B = [2, 8] となるため、出力は 6 になります。解法のアプローチこの問題は、以下の手順で解くことができます。ret := 0、n := 配列 A のサイズ と初期化する配列 A を昇順に

  2. C++で素数の長さを持つ回文部分文字列を数える方法

    このチュートリアルでは、素数の長さを持つ回文部分文字列の個数を求めるプログラムについて解説します。文字列が1つ与えられ、その中から「回文になっている」かつ「長さが素数である」すべての部分文字列を数えるのが課題です。解決のアプローチこの問題は、次の2つの処理を組み合わせることで効率よく解決できます。素数判定: エラトステネスの篩(ふるい)を使い、文字列の長さ以下の素数をあらかじめすべて求めておきます。回文判定: 各素数の長さ j について、すべての開始位置 i から長さ j の部分文字列を取り出し、両端から中央に向かって文字を比較して回文かどうかを確認します。C++での実装例#include &