C++で数値文字列が指定された基数として有効かどうかを判定する方法
数値を表す文字列が与えられたとき、その数値が指定された基数 B で有効に表現できるかどうかを判定することを考えます。例えば、文字列が「101110」で b = 2(2進数)の場合、プログラムは true を返します。同様に、文字列が「A8F」で基数が16(16進数)の場合も true となります。
判定方法は非常にシンプルです。文字列内のすべての文字が、指定された基数で使用される記号(数字または英字)の範囲内に含まれていれば true を返し、1つでも範囲外の文字が存在すれば false を返します。
このプログラムは基数16までに対応しています。基数が10以下の場合は「0」~「9」の数字のみをチェックし、基数が11以上の場合は数字に加えて「A」以降の英字もチェック対象になります。例えば基数16では、0~9 および A~F が有効な文字となります。
サンプルコード
#include <iostream>
using namespace std;
bool inGivenBase(string s, int base) {
if (base > 16) // このプログラムは基数16まで対応
return false;
else if (base <= 10) { // 0~9 の数字のみの場合
for (int i = 0; i < s.length(); i++)
if (!(s[i] >= '0' && s[i] < ('0' + base)))
return false;
} else {
for (int i = 0; i < s.length(); i++)
if (! ((s[i] >= '0' && s[i] < ('0' + base)) || (s[i] >= 'A' && s[i] < ('A' + base - 10))))
return false;
}
return true;
}
int main() {
string str = "A87F";
int base = 16;
if(inGivenBase(str, base)){
cout << str << " is in base " << base;
} else {
cout << str << " is not in base " << base;
}
}
出力結果
A87F is in base 16
この例では、文字列「A87F」の各文字(A、8、7、F)がすべて16進数で使用可能な記号の範囲内にあるため、「A87F is in base 16」と出力されます。もし範囲外の文字(例えば基数16では無効な「G」など)が1つでも含まれていれば、関数は false を返し、「is not in base」というメッセージが表示されます。
このように、文字を1つずつ走査して有効な記号の範囲と比較するだけのシンプルな線形探索(計算量 O(n))で、任意の基数に対する数値文字列の妥当性を効率的に判定できます。
-
C++で巨大な数値が75で割り切れるかどうかを判定する方法
本記事では、非常に大きな数値が75で割り切れるかどうかを判定する方法を解説します。扱う数値が大きすぎるため、通常の整数型では表現できない場合があり、そのような数値は文字列として受け取って処理を行います。 75で割り切れるための条件 75 = 3 × 25 であり、3と25は互いに素です。したがって、次の性質が成り立ちます。 ある数が75で割り切れる ⇔ その数が3と25の両方で割り切れる 3で割り切れる条件 各桁の数字の合計が3で割り切れる場合、その数は3で割り切れます。 25で割り切れる条件 下2桁の値が25で割り切れる(つまり「00」「25」「50」「75」のいずれかで終わる)場合、
-
C++で巨大な数値が5で割り切れるかどうかを判定する方法
この記事では、ある数値が5で割り切れるかどうかを判定する方法を解説します。ここで扱うのは非常に大きな数値であるため、通常の整数型(int や long long)では表現しきれません。そこで、数値を文字列として受け取って処理します。 5の倍数の判定ルール 5で割り切れるかどうかは、実はとても簡単に判定できます。数値の最後の桁(1の位)が「0」または「5」であれば、その数は必ず5で割り切れるというのが割り算の基本ルールです。 例えば、「154484585745184258458158245285265」のような桁数の多い数値でも、末尾が「5」になっているため、実際に割り算を行わなくても即座に5