C++でASCII値が指定範囲[l、r]外のアルファベットをカウントして出力する方法
任意の長さの文字列が与えられたとき、その中に含まれるアルファベットのうち、ASCII値が指定範囲 [l, r] に含まれない文字をカウントして出力するのが本記事のテーマです。まず、判定の基準となる英字のASCII値を確認しておきましょう。
大文字アルファベット(A〜Z)のASCII値一覧
| A | B | C | D | E | F | G | H | I | J | K | L | M |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
小文字アルファベット(a〜z)のASCII値一覧
| a | b | c | d | e | f | g | h | i | j | k | l | m |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
| n | o | p | q | r | s | t | u | v | w | x | y | z |
| 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
具体例
入力: str = "point"、First = 111、Last = 117 出力: 範囲外の文字: i, n / カウント: 2
解説: 'i'(105) と 'n'(110) は範囲 [111, 117] に含まれないため、カウントの対象となります。
入力: str = "ABCZXY"、First = 65、Last = 70 出力: 範囲外の文字: Z, X, Y / カウント: 3
解説: 'Z'(90)、'X'(88)、'Y'(89) は範囲 [65, 70] に含まれないため、カウントの対象となります。
解法のアプローチ
- 文字列と、範囲の開始値・終了値を入力として受け取り、それぞれ変数に格納します。
- length() 関数を使って文字列の長さを取得します(スペースも文字数に含まれます)。
- カウントを保存する変数と、一度出力した文字を記録するための unordered_map を用意します。
- i を 0 から文字列の長さ未満までループさせます。
- ループ内で、left ≤ str[i] ≤ right が成立しない場合(範囲外の文字の場合)にカウントを +1 します。
- マップを利用することで、同一の文字が複数回出力されるのを防ぎます。
- 最後にカウントを返し、結果を出力します。
C++による実装例
#include <iostream>
#include <unordered_map>
using namespace std;
// ASCII値が範囲 [l, r] 外である文字の数をカウントする関数
int count_non_char(string str, int left, int right){
int count = 0;
// 同じ文字を一度しか出力しないためにマップを使用
unordered_map<char, int> m;
int len = str.length();
for (int i = 0; i < len; i++) {
if (!(left <= str[i] and str[i] <= right)){
count++;
if (m[str[i]] != 1){
cout << str[i] << " ";
m[str[i]]++;
}
}
}
// カウントを返す
return count;
}
// メイン関数
int main(){
string str = "tutorialspoint";
int left = 102, right = 111;
cout << "Characters and ";
cout << "\nand count in the given range is: " << count_non_char(str, left, right);
return 0;
}
実行結果
上記のコードを実行すると、次の出力が得られます。
Characters and and count in the given range is: t u r a s p 8
"tutorialspoint" のうち、't'(116)、'u'(117)、'r'(114)、'a'(97)、's'(115)、'p'(112) の6種類の文字が範囲 [102, 111] の外側にあり、重複を除いて出力されています。重複を含めた出現回数の合計は8回です。
計算量
- 時間計算量: O(n) ― 文字列を一度だけ走査すればよいため高速です(n は文字列の長さ)。
- 空間計算量: O(k) ― 出力済みの文字を管理するマップが必要とする領域です(k は異なる文字の種類数、英字のみなら最大52種類)。
-
sin(x)とcos(x)の値を計算するC++プログラムの解説
sin(x)とcos(x)の値を計算するC++プログラム 本記事では、角度を入力として受け取り、その角度に対応するsin(x)(正弦)とcos(x)(余弦)の値を計算して結果を表示するC++プログラムを解説します。ライブラリ関数に頼らず、テイラー展開(マクローリン展開)を用いて数値を近似する手法を紹介します。 sin(x)とは sin(x)は三角関数の一つで、角度xに対する正弦の値を求めるために使用されます。直角三角形では、斜辺に対する対辺の比として定義されます。 $$\sin (x) = \displaystyle\sum\limits_{k=0}^\infty \frac{(-1)^{k
-
【C++】Cで割り切れ、範囲[A, B]に含まれない最小の正の整数を求める方法
問題の概要今回は興味深いプログラミング問題を取り上げます。3つの整数 A、B、C が与えられたとき、「X mod C = 0」を満たし、かつ X が範囲 [A, B] に含まれない最小の正の整数 X を求めることを考えます。例えば、A = 5、B = 10、C = 4 の場合、答えとなる X の値は 4 です。これは、4 が C で割り切れ(4 ÷ 4 = 1)、かつ範囲 [5, 10] の外側に存在するためです。解法のアプローチこの問題は、以下のシンプルな手順で解くことができます。C が範囲 [A, B] に含まれない場合: C をそのまま結果として返します。C 自身が「C で割り切れ、範囲