-
C++で16進数文字列をASCII文字列に変換する方法
このチュートリアルでは、C++を使って16進数の値を含む文字列をASCII文字列に変換するプログラムについて解説します。ここでは、16進数の値が並んだ文字列が与えられます。私たちのタスクは、その16進数の値を読み取り、対応するASCII文字列へと変換することです。アルゴリズムの流れ16進数文字列から先頭から2文字ずつ部分文字列として取り出します。取り出した2文字をstoul関数を使って基数16(16進数)として解釈し、整数値に変換します。変換した整数値をchar型にキャストし、ASCII文字列に連結します。この処理を文字列の末尾まで繰り返します。サンプルコード#include <bits
-
C++で最小ヒープを最大ヒープに変換する方法
このチュートリアルでは、最小ヒープ(min heap)を最大ヒープ(max heap)に変換するプログラムについて解説します。変換対象となる最小ヒープは、配列形式で与えられるものとします。課題は、与えられた最小ヒープをO(n)の時間計算量で最大ヒープへ変換することです。変換の考え方最小ヒープを最大ヒープに変換するには、配列の後半(葉に近い内部ノード)から順に「ヒープ化(heapify)」を行います。具体的には、最後の内部ノードであるインデックス(n-2)/2からインデックス0に向かって、各サブツリーが最大ヒープの条件(親が子以上の値を持つ)を満たすように要素を入れ替えていきます。アルゴリズムの
-
C++で片方向リンクリストを循環リンクリストに変換する方法
このチュートリアルでは、C++を使用して片方向リンクリスト(単方向連結リスト)を循環リンクリストに変換するプログラムの実装方法について詳しく解説します。 循環リンクリストとは、リストの末尾ノードのnextポインタが先頭ノードを指すようにしたデータ構造です。通常のリンクリストでは末尾ノードのnextがNULLを指しますが、この接続を先頭ノードへつなぎ替えることで、リスト全体を一周できるリング状の構造を作ることができます。 変換の考え方(アルゴリズム) 片方向リンクリストを循環リンクリストに変換する手順は非常にシンプルで、次の2ステップで実現できます。 先頭ノードからスタートし、nextがNU
-
C++で単方向リンクリストをXORリンクリストに変換する方法
はじめにこのチュートリアルでは、単方向リンクリスト(片方向連結リスト)をXORリンクリストに変換するプログラムについて解説します。単方向リンクリストが与えられたとき、その要素を保持したまま、各ノードのnextポインタを「前のノードのアドレスと次のノードのアドレスのXOR値」に書き換えることで、XORリンクリストへと変換するのが目的です。XORリンクリストとはXORリンクリストは、通常の双方向リンクリストで必要となるprevポインタとnextポインタを1つのポインタにまとめた、メモリ効率に優れたデータ構造です。各ノードには「前のノードのアドレス XOR 次のノードのアドレス」のみを格納し、走査時
-
C++で文字列をバイナリ(2進数)列に変換する方法
はじめに本記事では、C++を使って文字列をバイナリ(2進数)列に変換する方法を解説します。具体的には、文字列として与えられた各文字を、それぞれ対応する2進数表現に変換し、文字ごとに空白区切りで出力するプログラムを作成します。処理の流れ変換の手順は以下のとおりです。1. 文字列の各文字を取り出し、ASCIIコード(整数値)に変換する2. ASCIIコードを2進数の文字列に変換する3. 2進数の桁順を反転して正しい並びに整え、出力するサンプルコード#include <bits/stdc++.h>using namespace std;// バイナリ(2進数)表現への変換void con
-
C++で三項演算式を二分木に変換する方法
このチュートリアルでは、三項演算式を二分木に変換するプログラムについて詳しく解説します。ここでは「a?b:c」のような形式で書かれた三項演算式が入力として与えられます。私たちのタスクは、この式に含まれる条件分岐(選択肢)の構造をもとに、対応する二分木を構築することです。アプローチの考え方三項演算式は「条件 ? 真の場合の値 : 偽の場合の値」という構造を持っています。これを木として表現すると、次のように解釈できます。条件や値となる各文字がノードに対応します。「?」の直後に続く式は、現在のノードの左部分木になります。「:」の直後に続く式は、現在のノードの右部分木になります。この性質を利用すると、
-
C++で配列のGCD(最大公約数)を1にする変換アルゴリズム
このチュートリアルでは、配列全体のGCD(最大公約数)が1になるように配列を変換するプログラムをC++で解説します。問題の概要ここでは、配列と正整数 k が与えられます。許される操作は「配列の要素を k で割る」ことだけで、この操作は各要素が k 未満になるまで何度でも繰り返し行えます。この操作のみを使って、すべての要素のGCDを1にできるかどうかを判定するのが課題です。アプローチのポイント鍵となるのは「k の素因数はすべて k 以下である」という性質です。要素を k で割って取り除けるのは k の素因数だけなので、k より大きい素因数はどれだけ操作を繰り返しても消すことができません。したがっ
-
C++でASCII値の数列を対応する文字列に変換する方法
はじめに このチュートリアルでは、ASCII値が並んだ文字列を、それに対応する実際の文字列へと変換するC++プログラムについて解説します。 問題の概要 入力として、ASCIIコードが連なった数字の文字列が与えられます。課題は、この文字列を対応する文字に変換し、結果を出力することです。 たとえば「104101108108111」は、104が「h」、101が「e」、108が「l」、111が「o」に対応するため、「hello」と変換できます。 変換の考え方 ASCIIコードは2桁または3桁の数値で表されるため、単純に固定桁数で区切ることはできません。そこで、次のようなアルゴリズムを使用します。
-
【C++】1文字だけの変更で文字列を回文に変換できるか判定する方法
この記事では、与えられた文字列に対して「たった1文字を変更するだけで回文(前から読んでも後ろから読んでも同じになる文字列)にできるかどうか」を判定するC++プログラムを解説します。問題の概要入力として1つの文字列が与えられます。私たちのタスクは、その文字列の中から高々1文字を別の文字に置き換えることで、回文に変換できるかを判定することです。例えば「abccaa」という文字列の場合、末尾の「a」を「b」に変更すれば「abccba」となり回文になります。このように、不一致箇所が1か所以下であれば変換は可能と判断できます。アルゴリズムの考え方回文であるためには、文字列の先頭からi番目の文字と、末尾か
-
C++で無向グラフを「長さ2以上のパスが存在しない有向グラフ」に変換する方法
この記事では、無向グラフを「どの有向パスの長さも1を超えない有向グラフ」に変換するC++プログラムについて詳しく解説します。 問題の概要 入力として無向グラフが与えられます。私たちの課題は、このグラフを有向グラフへ変換することです。ただし、変換後のグラフには長さが1より大きい(=2以上の)パスが一切存在してはいけないという制約があります。この条件を満たす変換が不可能な場合は -1 を出力します。 解法のカギ:二部グラフとの関係 この問題は、グラフが二部グラフ(bipartite graph)であるかどうかと深い関係があります。 グラフの頂点を2つの集合に分割でき、すべての辺が一方の集合からもう
-
C++で24時間制の時刻を12時間制(AM/PM)に変換する方法
このチュートリアルでは、24時間制で表された時刻を、AM/PM付きの12時間制フォーマットへ変換するC++プログラムについて解説します。入力として「17:35:20」のような24時間形式の時刻文字列が与えられ、それを「5:35:20 PM」のような12時間形式へ変換するのが目的です。変換の基本的な考え方変換の手順はシンプルで、以下の3ステップで構成されます。時刻文字列の先頭2文字を数値として読み取り、「時」の値を求める時が12未満であれば「AM」、12以上であれば「PM」と判定する時を12で割った余りを新しい時刻とし、余りが0の場合は「12」と表示する(0時→12 AM、12時→12 PM)サ
-
C++で文字列配列内のアナグラムのペアをすべて検出・出力する方法
この記事では、文字列の配列が与えられたとき、その配列に含まれるアナグラム(アナグラム関係にある文字列のペア)をすべて見つけて出力する方法を、C++のサンプルコードとともに解説します。 アナグラムとは? アナグラムとは、ある文字列の文字を並べ替えることで作られる別の文字列のことです。たとえば「hello」と「lolhe」は、使用する文字とその個数が完全に一致しているため、互いにアナグラムの関係にあります。 問題の例 具体的な入力と出力の例を見てみましょう。 入力: array = {hello, hrdef, from, lohel, morf} 出力: [hello, lohel], [fro
-
C++で合計が等しいペアを未ソート配列からすべて出力する方法
問題の概要本記事では、ソートされていない配列の中から、合計値が等しくなるすべてのペアを見つけ出して出力する方法を、C++のコード例とともに解説します。具体例で理解するまず、簡単な例で問題を確認しましょう。入力: array = [12, 13, 20, 5] 出力: [12, 13] と [20, 5] ―― どちらも合計は 25このように、異なる要素同士の組み合わせであっても、合計値が一致するペアをすべて見つけるのが目的です。解決のアプローチこの問題を解くための基本的な流れは以下の通りです。配列内のすべてのペア (i, j) を二重ループで列挙し、それぞれの合計値を求めます。重複したペアの出
-
【C++】二分探索木から奇数の値を持つノードをすべて出力する方法
この記事では、二分探索木(BST)が与えられたときに、奇数の値を持つすべてのノードを出力する方法を解説します。二分探索木とは二分探索木は、以下の性質を持つ特殊な木構造です。左部分木には、必ずルートノードより小さい値が格納される右部分木には、必ずルートノードより大きい値が格納される左右どちらの部分木も、上記の2つの性質を満たす必要がある具体例を見て、問題を確認してみましょう。入力となる二分探索木:出力: 1 3 9解法のアプローチこの問題を解く最もシンプルな方法は、木全体を走査することです。走査の過程で各ノードの値をチェックし、その値が奇数であれば出力し、偶数であれば何もせず次のノードへ進みます
-
【C++】素因数の集合がXの素因数の集合の部分集合となる数をすべて出力する方法
本記事では、N個の整数からなる配列と整数Xが与えられたとき、素因数の集合がXの素因数の集合の部分集合となっている要素をすべて出力するアルゴリズムを、C++のコード例とともに解説します。 問題の概要 配列内の各数値について、その数を構成する素因数がすべてXの素因数に含まれる場合にのみ、その数値を出力対象とします。それ以外の数値は除外されます。 入力例・出力例 入力: X = 30、配列 = {2, 3, 6, 11, 14} 出力: 2 3 6 X = 30 = 2 × 3 × 5 なので、Xの素因数の集合は {2, 3, 5} です。 2: 素因数は {2} → 部分集合なので出力 3: 素
-
C++でN未満のすべての数を最大2種類の一意な数字で出力する方法
この問題では、整数Nが与えられ、N未満のすべての数のうち、最大2種類の異なる数字(ユニークな数字)のみを使用して構成される数を出力します。つまり、1つの数を作るために使える数字の種類は最大2つまでという制限があります。問題を理解するために、具体例を見てみましょう。入力: N = 17 出力: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16この例では、17未満の数はすべて1種類または2種類の数字で構成されているため、すべてが出力対象となります。解法のアプローチこの問題を解くには、2種類のユニークな数字のみで構成されるすべての数を生成します。数の生成プロセスは0から始
-
C++で葉ノードから距離kにあるすべてのノードを出力する方法
問題概要この問題では、二分木と数値Kが与えられ、葉ノードから距離Kにあるすべてのノードを出力することが求められます。二分木(Binary Tree)とは、各ノードが最大2つの子ノード(1つ・2つ・または0個)を持つ特別な木構造のことです。葉ノード(Leaf Node)とは、二分木の末端に位置するノードを指します。この問題における「葉ノードからの距離」とは、葉ノードよりも上位のレベルに位置するノードを意味します。たとえば、レベル4にある葉ノードから距離2のノードは、レベル2に存在することになります。具体例で理解しよう次の図のような二分木を例に考えてみましょう。K = 2 の場合、出力:6 9解法
-
C++で最小ヒープから値x未満のすべてのノードを出力する方法
この問題では、最小ヒープ(Min Heap)と値xが与えられ、xより小さい値を持つすべてのノードを出力することが求められます。最小ヒープとは、すべての親ノードがその子ノードの値以下となる特殊な二分木です。この性質により、根(ルート)には常にヒープ内の最小値が格納されます。具体例を使って問題を理解しましょう。X = 45出力 − 2 4 7 10 17 22 33 34この問題を解くには、最小ヒープ全体を先行順トラバーサル(前順走査)で探索し、与えられた値xより小さい値を持つノードのみを出力します。アルゴリズムのポイント最小ヒープでは親ノードの値が必ず子ノード以下であるため、あるノードの値がx以
-
【C++】部分木にK個の葉を持つ二分木のノードをすべて出力するアルゴリズム
問題概要 この問題では、二分木と整数Kが与えられ、「自分の部分木(子孫ノード)の中にちょうどK個の葉を持つ」ノードをすべて見つけて出力することが求められます。 二分木とは、各ノードが持てる子ノードの数が最大2個(0個・1個・2個)である特別な木構造のことです。 葉ノードとは、二分木において子を一切持たない、木の末端に位置するノードのことです。 具体例で理解する 次のような二分木を考えてみましょう。 A / \ B K / \ / \ N S T E / \ /
-
C++で二分木の指定した2つのレベル間にあるすべてのノードを出力する方法
この問題では、二分木と、木の中の2つのレベル(上位レベルと下位レベル)が与えられ、その2つのレベル間に存在するすべてのノードを出力することが求められます。二分木とは、各ノードが最大2つの子ノード(0個・1個・2個)を持つ特殊な木構造のことです。問題の例具体例を使って問題を理解しましょう。上位レベル(upper):3下位レベル(lower):1出力結果:6 3 9 7 4 8 10解決アプローチ方法1:再帰関数を使う方法この問題を解くには、指定されたレベルのノードを出力する必要があります。upperからlowerまでのレベルをループで回しながら、再帰関数を呼び出すことで実現できます。このアルゴリ