C++で文字列内の重複文字とその出現回数を出力する方法
この問題では、与えられた文字列の中から重複しているすべての文字を検出し、それぞれの出現回数とともに出力する必要があります。
問題の理解
まず、具体例を使って問題を確認してみましょう。
入力:TutorialsPoint 出力: t (3) o (2) i (2)
解説:各文字の出現回数を数えると、以下のようになります。
- t → 3回
- u → 1回
- o → 2回
- r → 1回
- i → 2回
- a → 1回
- s → 1回
- n → 1回
この結果から、出現回数が2回以上の文字(t、o、i)だけが出力対象となります。
解決のアプローチ
この問題を解くための手順は以下の通りです。
- 文字列を先頭から走査し、各文字の出現回数をカウントします。
- カウント結果を、ASCIIコードに対応したサイズ256の整数型配列に格納します。
- 配列を走査し、出現回数が1より大きい文字とその回数を出力します。
ASCII文字は最大256種類あるため、サイズ256の配列を用意することで、あらゆる半角英数字・記号に対応できます。
C++による実装例
#include <iostream>
using namespace std;
#define NO_OF_CHARS 256
class duplicate_char {
public:
// 各文字の出現回数をカウントする関数
void charCounter(char *str, int *count) {
int i;
for (i = 0; *(str + i); i++)
count[*(str + i)]++;
}
// 重複文字を出力する関数
void printDuplicateCharacters(char *str) {
int *count = (int *)calloc(NO_OF_CHARS, sizeof(int));
charCounter(str, count);
int i;
for (i = 0; i < NO_OF_CHARS; i++)
if (count[i] > 1)
printf("%c\t\t %d \n", i, count[i]);
free(count);
}
};
int main() {
duplicate_char dupchar;
char str[] = "tutorialspoint";
cout << "The duplicate characters in the string\n";
cout << "character\tcount\n";
dupchar.printDuplicateCharacters(str);
return 0;
}実行結果
The duplicate characters in the string
character count
i 2 o 2 t 3
コードのポイント
- charCounter関数:文字列を1文字ずつ読み込み、その文字のASCIIコードをインデックスとして配列
countの値を増やしていきます。 - calloc関数:メモリを確保すると同時に0で初期化するため、カウント用配列の初期化が不要になります。
- free関数:動的に確保したメモリを解放し、メモリリークを防ぎます。
このアルゴリズムの計算量は、文字列の長さをNとすると O(N + 256)、つまり実質 O(N) となり、非常に効率的です。大文字と小文字を区別せずにカウントしたい場合は、toupper() や tolower() を使って文字を正規化してからカウントするとよいでしょう。
-
C++で無向グラフ内のすべてのサイクル(閉路)を検出して出力する方法
問題の概要 この記事では、無向グラフが与えられたときに、そのグラフ内に形成されるすべてのサイクル(閉路)を検出して出力する方法を解説します。 無向グラフとは、頂点同士が双方向で接続されているグラフのことです。すべての辺に方向がなく自由に行き来できるため、「無向ネットワーク」とも呼ばれます。 サイクル(閉路)とは、グラフデータ構造において、頂点の並びが一周して出発点に戻るような閉じた経路を形成しているものを指します。 まず、具体例を見て理解を深めましょう。 入力グラフ: 出力: Cycle 1: 2 3 4 5 Cycle 2: 6 7 8 この例では、頂点2〜5で構成されるサイクルと、頂点6
-
【C++】文字列内の「1(0+)1」パターンをすべて検出する方法
文字列の中に「1(0+)1」という形式のパターンが含まれていると仮定します。ここで「(0+)」は、1個以上の「0」が連続して現れることを意味します。この記事では、文字列からこのパターンをすべて検出する方法を解説します。パターン同士が重なり合う場合もカウントの対象とします。なお、対象の文字列はバイナリ文字列であるとは限らず、数字と小文字の英字のみで構成された文字列を扱います。例として、文字列が「1101001」の場合を考えてみましょう。この場合、「101」と「1001」の2つのパターンが見つかります。解決のためのアプローチこの問題は、以下の手順に従って解くことができます。文字列内のすべての文字c