C++で文字列からk個の回文を作成できるか判定する方法
文字列 s と整数 k が与えられたとします。ここでの課題は、s に含まれるすべての文字を使って、k 個の空でない回文(パリンドローム)文字列を構築できるかどうかを判定することです。
例えば、入力が "true"、k = 4 の場合を考えてみましょう。この場合、各文字をそれぞれ別の文字列に割り当てるしか方法がないため、出力は True になります。
解決のアプローチ
この問題を解く鍵となるのは、回文の性質です。回文では、奇数回出現する文字は最大で 1 種類しか許されません。したがって、k 個の回文を構築できるかどうかは、「奇数回出現する文字の種類数」が k 以下であるかどうかで決まります。
以下の手順で解くことができます。
n:= 文字列sの長さn < kの場合 →falseを返す(文字数が足りず、k 個の空でない文字列を作れないため)n == kの場合 →trueを返す(各文字を 1 つずつ別々の文字列にすればよいため)- マップ(連想配列)を 1 つ定義する
sの各文字cについて、m[c]を 1 ずつ増やす(出現回数をカウント)odd:= 0 とする- マップ
mの各キー・値ペアitについて、oddに「値 AND 1」(出現回数が奇数なら 1)を加算する odd <= kならtrue、それ以外はfalseを返す
実装例
理解を深めるために、以下の C++ 実装例を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool canConstruct(string s, int k) {
int n = s.size();
if (n < k)
return false;
if (n == k)
return true;
map<char, int> m;
for (char c : s)
m[c]++;
int odd = 0;
for (auto& it : m) {
odd += (it.second & 1);
}
return odd <= k;
}
};
main(){
Solution ob;
cout << (ob.canConstruct("true",4));
}入力
"true"
出力
1
このアルゴリズムの計算量は、文字列の長さを n とすると O(n) であり、非常に効率的です。文字数の事前チェックと奇数回出現文字のカウントというシンプルな考え方だけで、問題を解決できる点がポイントです。
-
C++で文字列の配列を定義・操作する方法を解説
この記事では、C++において文字列の配列をどのように定義し、扱うのかを詳しく解説します。C言語との違い:文字列配列の基礎知識C言語には文字列型が存在しないため、文字列はchar型の配列(文字配列)として表現する必要がありました。そのため、複数の文字列をまとめて管理する「文字列の配列」を作るには、2次元のchar型配列を用意し、各行に異なる文字列を格納するという手法が取られていました。これは直感的ではなく、コードも冗長になりがちでした。一方、C++ではstd::stringクラスが標準ライブラリとして提供されています。このクラスのオブジェクトを使えば、文字列データを効率的かつ安全に格納・操作でき
-
C++で文字列の配列を作成する方法【サンプルコード付き】
はじめにC++では、stringキーワード(std::string)を使用することで、文字列の配列を簡単に作成できます。本記事では、この手法を用いたC++プログラムの具体的な例を、アルゴリズム・サンプルコード・実行結果とともにわかりやすく解説します。アルゴリズム処理の流れは以下の通りです。開始 stringキーワードを使用して配列の各要素を文字列で初期化する 配列の内容を出力する 終了サンプルコード#include<iostream> #include<bits/stdc++.h> using namespace std; int main() { &nbs