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

C言語で文章から最長の回文(パリンドローム)を見つけて出力する方法

この記事では、C言語を使って与えられた文章の中から最も長い回文(パリンドローム)を見つけ出し、画面に出力するプログラムを解説します。回文の基本的な定義から、具体的なアルゴリズム、実際のコード例、そして実行結果まで順を追って見ていきましょう。

回文(パリンドローム)とは?

回文とは、文字列を逆順に並べ替えても意味や読み方が変わらない単語・語句のことを指します。

:「Nitin」は文字列を逆から読んでも「Nitin」のままなので、回文です。

今回の課題は、与えられた文章の中に含まれる複数の単語から、最も長い回文を特定することです。

たとえば、次のような文章が与えられたとします。

malayalam liemadameil iji

この文章には「malayalam」「liemadameil」「iji」という3つの回文が含まれていますが、その中で最も長いのは liemadameil です。

アルゴリズム

この問題は、各単語に対して先頭と末尾から同時に文字を比較していく「両端ポインタ方式」で効率よく判定できます。処理の流れは以下の通りです。

開始
ステップ1 → 変数 i, j, k, l, max を 0 で初期化し、index を -1、check を 0、count を 0 として宣言する
ステップ2 → i = 0 から strlen(str) 未満の間、i++ しながら繰り返す
  max = 0、k = i、j = i + 1 とする
  str[j] が空白 ' ' でも NULL '\0' でもない間、j を 1 ずつ増やす
  l = j - 1 とする
  もし str[k] が空白でも NULL でもない場合
    k <= l の間、以下を繰り返す
      もし str[k] == str[l] ならば
        max を 1 増やす
        もし count <= max ならば
          index = i、count = max とする
      それ以外の場合
        max = 0、count = -1 とする
        ループを抜ける
      k を 1 増やし、l を 1 減らす
  i = j とする
ステップ3 → 繰り返し終了
ステップ4 → i = index から、i != -1 かつ str[i] != ' ' かつ str[i] != '\0' の間、i++ しながら繰り返す
  str[i] を表示する
ステップ5 → 繰り返し終了
停止

C言語による実装例

上記のアルゴリズムを実際のC言語コードにすると、次のようになります。

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[]) {
    char str[] = {"malayalam liemadameil iji"};
    int i, k, l, j, max =0, index = -1, check = 0, count = 0;
    for(i=0; i<strlen(str); i++) {
        max = 0;
        k = i;
        j = i+1;
        while(str[j]!=' ' && str[j]!='\0'){
            j++;
        }
        l = j-1;
        if(str[k]!=' ' && str[k]!='\0') {
            while(k<=l) {
                if (str[k]==str[l]) {
                    max++;
                    if(count<=max) {
                        index = i;
                        count = max;
                    }
                } else {
                    max = 0;
                    count = -1;
                    break;
                }
                k++;
                l--;
            }
        }
        i = j;
    }
    for (i = index; i!=-1 && str[i]!=' ' && str[i]!='\0'; i++) {
        printf("%c", str[i]);
    }
    return 0;
}

コードのポイント

  • 外側の for ループで各単語の先頭位置を順番に調べます。
  • 内側の while ループで単語の終わり(空白またはNULL文字)を検出します。
  • 変数 k を先頭から、l を末尾から移動させながら文字を比較し、すべて一致すればその単語は回文です。
  • 一致した文字数を max として記録し、これまでの最大値 count より大きければ、開始位置 index と長さを更新します。

出力結果

上記のプログラムをコンパイルして実行すると、次の出力が得られます。

liemadameil

このように、文章中に含まれる複数の回文の中から、自動的に最も長いものだけが出力されます。文字列操作とポインタ的なインデックス管理の練習として、非常に良い題材と言えるでしょう。

  1. C言語で自然数を列方向に出力するプログラムの作り方

    プログラムの概要 本記事では、C言語を使って自然数を列方向(縦方向)に並べたパターンを出力する方法を解説します。完成イメージは以下のとおりです。 1 2 6 3 7 10 4 8 11 13 5 9 12 14 15 一見複雑に見えるこの数列も、行と列の関係さえ理解できれば、シンプルなループ処理だけで実現できます。 アルゴリズムの考え方 変数 i は行番号、j は列番号を表し、ここでは5行分のパターンを作成します。 外側のループで各行(i = 1〜5)を順に処理する 内側のループに入る前に、k を i の値で初期化する 内側のループで各列(j = 1〜i)を処理する 現在の k の値を表示

  2. 【C言語】数字パターンを出力するプログラムの作り方

    プログラムの概要 数値パターンとは、「パターンルール」と呼ばれる規則に基づいて生成された数列のことです。パターンルールでは、1つまたは複数の数学的操作を用いて、数列内の連続する数値同士の関係を表現します。 C言語では、for文による繰り返し処理を組み合わせることで、このような規則性のある数字パターンを簡単に出力できます。本記事では、代表的な2種類のパターン(三角形型とひし形型)を出力するプログラムを紹介します。 パターンの例 パターン1(三角形型) 1 2 6 3 7 10 4 8 11 13 5 9 12 14 15 パターン1では、各行の先頭の数字が行番号と一致し、隣の要素は直前の値に「