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

C++で文字列内のすべての「面白い単語(ファニーワード)」を出力する方法

この記事では、与えられた文の中から「面白い単語(ファニーワード)」に該当するすべての文字列を検出し、出力するC++プログラムを解説します。

面白い単語とは?

「面白い単語」とは、次の条件を満たす単語のことです。つまり、元の文字列の隣接する文字同士の絶対差が、逆順にした文字列の隣接する文字同士の絶対差と等しいという条件です。

|string[0] - string[1]| = |revstring[0] - revstring[1]|

具体例で理解しよう

実際の例を見てみましょう。

入力: string = 'ABRS'
出力: Yes
解説:
逆順の文字列 = SRBA
|A-B| = 1 = |S-R|
|B-R| = 16 = |R-B|
|B-A| = 1 = |R-S|

この例では、元の文字列「ABRS」と逆順の文字列「SRBA」の隣接文字間の絶対差がすべて一致しているため、「ABRS」は面白い単語であると判定されます。

解決のアプローチ

この問題を解くための手順は以下の通りです。

まず、与えられた文から単語を1つずつ抽出します。次に、抽出した各単語が面白い単語かどうかを判定し、該当するものだけを出力します。

面白い文字列の判定方法

判定には、文字列を先頭と末尾の両端から同時に走査する手法を使います。具体的には、先頭側の隣接文字間の絶対差と、末尾側の隣接文字間の絶対差を比較していき、一度でも差が一致しなければ false を返します。最後まで走査できれば、その単語は面白い単語です。

なお、大文字・小文字の違いによる誤判定を防ぐため、あらかじめすべての文字を小文字に変換してから比較を行います。

C++での実装例

以下のコードは、上記のロジックを実装したものです。

サンプルコード

#include <iostream>
#include<string.h>
using namespace std;
bool isFunny(string word){
    int i = 1;
    int j = word.length() - 2;
    for (int i = 0; i < word.length(); i++)
        word[i] = tolower(word[i]);
    while (i <= j){
        if (abs(word[i] -
            word[i - 1]) != abs(word[j] -
            word[j + 1]))
            return false;
        i++;
        j--;
    }
    return true;
}
void printFunnyWords(string str){
    str +=" ";
    string word = "";
    for (int i = 0; i < str.length(); i++){
        char ch = str[i];
        if (ch!=' ')
            word += ch;
        else{
            if (isFunny(word))
                cout<<word<<"\t";
            word = "";
        }
    }
}
int main(){
    string sentence = "hello, i love malayalam langauge";
    cout<<"All funny words of the string '"<<sentence<<"' are :\n";
    printFunnyWords(sentence);
    return 0;
}

実行結果

All funny words of the string 'hello, i love malayalam langauge' are :
i malayalam

コードのポイント

printFunnyWords 関数では、文をスペースで区切りながら単語を組み立てています。isFunny 関数は、単語を小文字化した上で、両端から中央に向かって隣接文字の絶対差を比較します。この計算量は O(n) であり、非常に効率的です。

実行結果からわかるように、「i」と「malayalam」だけが条件を満たす面白い単語として出力されました。回文的な性質を持つ単語や短い単語は、この条件を満たしやすい傾向があります。

  1. C++でキャメルケース表記の辞書からパターンに一致するすべての単語を出力する方法

    この問題では、キャメルケース(CamelCase)で記述された文字列の配列とパターンが与えられ、そのパターンに一致する配列内のすべての文字列を出力することが求められます。 用語の説明 文字列の配列とは、要素がすべて文字列型である配列のことです。 キャメルケース(camelCase)は、プログラミングで広く使われている命名規則の一つです。複合語を表記する際に、2語目以降の先頭文字を大文字にし、残りの文字を小文字で記述します。 例:iLoveProgramming 問題の定義 課題:指定されたパターンに一致するすべての文字列を見つけ出すことです。 入出力例 入力: TutorialsPoint,

  2. C++で文字列のすべての部分文字列を出力するプログラムの解説

    はじめにこの記事では、与えられた文字列からすべての部分文字列を取り出して出力するC++プログラムについて解説します。文字列(char型配列)が1つ与えられ、その文字列から生成できるすべての部分文字列を順番に画面へ表示するのが本プログラムの目的です。部分文字列とは部分文字列とは、元の文字列から連続する文字を取り出して作られる文字列のことです。例えば「abca」という文字列の場合、「a」「b」「ab」「bca」「abca」などがすべて部分文字列に該当します。長さnの文字列からは、長さ1の部分文字列がn個、長さ2のものがn-1個、長さ3のものがn-2個…と続くため、部分文字列の総数は n×(n+1)