C++で長さkのすべての部分文字列を基数bから10進数に変換する方法
このチュートリアルでは、文字列から取り出した長さ「k」のすべての部分文字列を、基数「b」の数値として10進数に変換するC++プログラムについて解説します。
ここでは、ある長さを持つ文字列が与えられます。私たちのタスクは、その文字列からサイズ「k」の部分文字列を順番に取り出し、それぞれを基数「b」の表現から10進数へと変換することです。
アルゴリズムの流れ
- 元の文字列
str、部分文字列の長さk、基数bを受け取ります。 - 先頭から順に
substr(i, k)を使って長さkの部分文字列を1つずつ取得します。 - 各部分文字列の右端の桁から順に、「桁の値 × bの累乗」を計算して合計します。
- 変換結果をスペース区切りで出力します。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
// 部分文字列を10進数に変換する関数
int convert_substrings(string str, int k, int b){
for (int i = 0; i + k <= str.size(); i++){
// 長さkの部分文字列を取得
string sub = str.substr(i, k);
// 10進数への変換値を計算
int sum = 0, counter = 0;
for (int j = sub.size() - 1; j >= 0; j--){
sum = sum + ((sub.at(j) - '0') * (int)pow(b, counter));
counter++;
}
cout << sum << " ";
}
}
int main(){
string str = "12212";
int b = 3, k = 3;
convert_substrings(str, k, b);
return 0;
}出力
17 25 23
処理の解説
この例では、文字列「12212」を基数3・長さ3として処理しています。各部分文字列は次のように変換されます。
- 「122」 → 1×3² + 2×3¹ + 2×3⁰ = 17
- 「221」 → 2×3² + 2×3¹ + 1×3⁰ = 25
- 「212」 → 2×3² + 1×3¹ + 2×3⁰ = 23
内側のループでは、部分文字列の末尾(最下位桁)から先頭に向かって走査し、counter を使って対応するべき乗(b⁰、b¹、b²…)を計算しています。また、pow() は浮動小数点数を返すため、(int) で明示的にキャストして精度の誤差を防いでいます。このように、時間計算量は O(n×k) となり、シンプルかつ効率的にすべての部分文字列を変換できます。
-
C++でグラフに長さkを超える単純パスが存在するか判定するアルゴリズム
概念 重み付きグラフ、グラフ内の始点となる頂点、そして数値k(kは始点から終点までのパスの長さを表します)が与えられたとき、与えられた始点から始まり、任意の他の頂点(終点)で終わる単純パス(閉路を含まないパス)が存在するかどうかを判定することが課題です。以下のグラフを使って説明します。 入力例1 始点 s = 0, k = 64 出力 True この場合、0 -> 7 -> 1 -> 2 -> 8 -> 6 -> 5 -> 3 -> 4 という合計距離68の単純パスが存在し、64を超えているためtrueとなります。 入力例2 始点 s = 0
-
C++で始点から終点までのすべての経路を出力する方法|深さ優先探索(DFS)による実装
この記事では、有向グラフが与えられたときに、始点(ソース)から終点(デスティネーション)までのすべての経路を出力する問題を、C++で解く方法を解説します。有向グラフとは?有向グラフとは、各辺に向きが定められており、頂点Aから頂点Bへと一方向に進むことができるグラフのことです。逆向き(BからA)には、対応する逆向きの辺が存在しない限り移動できません。問題の例具体例を使って問題を理解しましょう。下図のようなグラフを考えます。始点を「K」、終点を「P」とした場合の出力は次のようになります。出力:K -> T -> Y -> A -> P K -> T -> Y -