-
C++で連結リストのピーク要素を見つけるアルゴリズムを解説
このチュートリアルでは、C++を使って与えられた連結リスト(リンクリスト)からピーク要素を見つけるプログラムを作成します。 ピーク要素とは、両隣の要素(前後の要素)よりも大きい値を持つ要素のことです。それでは、問題を解くための手順を順番に見ていきましょう。 アルゴリズムの手順 連結リスト用のノード構造体(struct Node)を定義します。 ダミーデータを使って連結リストを構築します。 連結リストが空、または要素数が1の場合など、ベースケース(境界条件)を先にチェックします。 最初の要素の値を変数 prev(前の要素)として保存しておきます。 連結リストを先頭から走査します。 現在の要素
-
C++で配列のピーク要素を見つける方法
このチュートリアルでは、与えられた配列の中からピーク要素を見つけるプログラムをC++で作成します。 ピーク要素とは、その両隣にある要素よりも大きい(または等しい)値を持つ要素のことです。それでは、問題を解くための手順を順番に見ていきましょう。 解決手順 ダミーデータで配列を初期化します。 最初の要素と最後の要素がピーク要素の条件を満たしているかどうかをチェックします。配列の端は隣接要素が1つしかないため、特別な扱いが必要です。 2番目の要素から配列を走査します。 現在の要素が、直前の要素と直後の要素の両方以上であるかを確認します。 上記の条件を満たした場合、その要素をピーク要素として返し
-
C++で3つの連結リストから合計が指定値と一致するトリプレットを見つける方法
このチュートリアルでは、C++を使って、3つの連結リスト(リンクリスト)から、それぞれ1要素ずつ選んだ3つの値の合計が指定された数と一致する組み合わせ(トリプレット)を見つけるプログラムを作成します。解決のアプローチ最もシンプルな方法は、ブルートフォース(総当たり)です。各リストの全要素を順番に組み合わせて、合計が目標値と一致するかどうかを確認します。手順は以下の通りです。連結リスト用のノード構造体(struct)を定義します。ダミーデータを使って3つの連結リストを作成します。3重のネストしたループを書き、各リストの先頭から末尾まで要素を走査します。現在走査中の3つの要素の合計を計算します。合
-
C++で配列内から指定した合計値になるトリプレット(3つの要素)を見つける方法
このチュートリアルでは、配列の中から合計が指定された値と一致する3つの要素(トリプレット)を見つけるプログラムをC++で作成します。 解き方の手順 以下のステップで問題を解いていきます。 テスト用のダミーデータを含む配列を作成します。 3つの要素を走査するため、三重のネストされたループを記述します。各ループは配列の末尾まで繰り返します。 選んだ3つの要素を加算します。 その合計を指定された値と比較します。 両者が一致した場合、該当する要素を出力してループを抜けます。 実装例 それでは、実際のコードを見てみましょう。 #include <bits/stdc++.h> usi
-
C++で指定した数値とのXORが最大になる数を求める方法
このチュートリアルでは、指定した数値とのXOR(排他的論理和)演算の結果が最大になる数を求めるプログラムをC++で作成します。ここでは、扱う数値は8ビットであると仮定します。XOR演算の基本XOR演算では、異なるビット同士を演算すると「1」になり、同じビット同士を演算すると「0」になります。この性質を利用すると、ある数値XとのXORが最大になるのは、Xの各ビットをすべて反転させた値、つまり1の補数であることがわかります。8ビットの場合、すべてのビットが1の値は (1 << 8) - 1、すなわち255です。この値とXのXORを取ることで、Xの各ビットが反転され、XORが最大になる数
-
C++で配列内の合計がゼロになるすべてのトリプレットを見つける方法
はじめにこのチュートリアルでは、配列の中から合計がゼロになる3つの要素(トリプレット)をすべて見つけるC++プログラムを作成します。まずは、問題を解決するための手順を確認しましょう。ダミーデータを含む配列を作成します。3つの要素を選ぶために、三重のネストしたループを記述し、配列の末尾まで反復処理を行います。選んだ3つの要素を加算します。その合計が0と等しいかどうかを比較します。等しい場合は、該当する3つの要素を出力します。コード例それでは、実際のコードを見てみましょう。#include<bits/stdc++.h>using namespace std;void findTripl
-
自然数の約数をすべて求める方法【C++で解説】
はじめにこのチュートリアルでは、自然数の約数をすべて見つけるプログラムをC++で作成します。約数とは、その数を余りなしで割り切ることができる整数のことです。これは非常にシンプルな問題なので、基本的なアルゴリズムの練習に最適です。それでは、解決の手順を見ていきましょう。アルゴリズムの手順調べたい自然数を初期化します。1からその数まで順番にループ処理を行います。現在の数で対象の数が割り切れるかどうかを判定します(剰余演算 % を使用)。割り切れる場合は、その数は約数なので出力します。この方法の計算量は O(n) であり、n が大きくなると処理時間が増加しますが、まずは最も分かりやすい素直な実装を紹
-
C++で自然数の約数をすべて効率的に求める方法
このチュートリアルでは、自然数の約数をすべて求めるプログラムをC++で作成します。一見単純な問題ですが、効率的なアルゴリズムを知っておくと、大きな数を扱う際に大きく役立ちます。それでは、解決の手順を見ていきましょう。 アルゴリズムの流れ 対象となる数値を初期化します。 1から与えられた数の平方根(√n)まで繰り返すループを作成します。 与えられた数が現在の数で割り切れるかどうかを判定します。 割り切れる場合は、現在の数と「与えられた数 ÷ 現在の数」の2つを出力します。 なぜ平方根までのループでよいのか? 約数は必ずペアで存在します。例えば n = 65 の場合、「1 × 65」「5
-
C++で二分探索木(BST)から指定した合計値になるペアをすべて検索する方法
このチュートリアルでは、二分探索木(BST)の中から、合計が指定された数値と等しくなるすべてのペアを見つけるプログラムを作成します。ペアを効率よく探すために、木のノードの値を2つの異なるリストに格納しながら処理を進めます。これは、ソート済み配列で使われる「Two Pointer(双方向ポインタ)」のテクニックを、BSTに対して左右両方向から中順走査を行うことで実現するアプローチです。それでは、問題を解くための手順を順番に見ていきましょう。アルゴリズムの手順二分木用の構造体(struct Node)を作成します。新しいノードを二分探索木に挿入する関数を用意します。※二分探索木では、根(ルート)よ
-
C++でタンク満杯時に無駄になる水の量を計算する方法
はじめにこのチュートリアルでは、次の問題をC++で解く方法を解説します。容量がNリットルのタンクがあり、ポンプを使って毎分Sリットルの速度で水を注入します。ところが、タンクには穴が空いていて、水を入れている間、毎分WSリットルの速度で水が漏れ出てしまいます。このとき、タンクを満杯にするまでに無駄になる水の総量を求めるのが今回のゴールです。計算の考え方この問題は、次の3つのステップで解くことができます。まず、タンクに実際に溜まっていく水の量は、「注水速度から漏水速度を引いた差」に等しくなります。次に、タンクの容量を毎分の実質注水量で割ることで、タンクが満杯になるまでにかかる時間を求められます。最
-
【C++入門】配列内の重複(繰り返し)要素を検索する方法
このチュートリアルでは、与えられた配列の中から繰り返し(重複)要素を見つけ出すプログラムをC++で作成します。 まずは、問題を解決するための基本的な手順を確認しましょう。 アルゴリズムの手順 配列を初期化します。 配列内の各要素の出現回数を記録するためのカウンタ用マップ(map)を初期化します。 配列を先頭から順に走査します。 各要素の出現回数をカウントしていきます。 出現回数が1より大きい(2回以上現れる)要素を出力します。 サンプルコード それでは、実際のコードを見てみましょう。 #include <bits/stdc++.h> using namespace std
-
C++で解く誕生日のパラドックス(誕生日問題)|確率の仕組みと実装例
誕生日のパラドックスとは 誕生日のパラドックス(Birthday Paradox)は、確率論において非常に有名な問題の一つです。この問題は次のように定式化されます。 「ある誕生日パーティーに複数の人が集まっている。この中に同じ誕生日の人同士が存在するとして、その確率をもとに、必要な人数のおおよその値を求めよ」 直感的には「365日もあるのだから、同じ誕生日の人がいるのは珍しい」と感じるかもしれません。しかし実際には、驚くほど少ない人数でも高い確率で誕生日が重なることが数学的に証明されています。これが「パラドックス」と呼ばれる所以です。 コイン投げとの類似点 確率論では、コインを1回投げて表が出
-
C++で単方向リンクリストの先頭ノードを削除する方法を解説
リンクリスト(連結リスト)とは、複数のノードが相互に接続された線形データ構造のことです。各ノードは「データフィールド」と「次のノードのアドレス」という2つのフィールドで構成されています。 ここでは、単方向リンクリストから先頭ノードを削除する方法について考えてみましょう。まずは具体例を見ていきます。 入力1 − 4 → 3 → 2 → 1 出力 − 3 → 2 → 1 → 説明 − 「4」は与えられた単方向リンクリストの先頭ノードです。このノードを削除すると、リンクリストは 3 → 2 → 1 となります。 入力2 − 1 → 2 → 3 → 出力 − 2 → 3 → 説明 − 先頭ノード「1」
-
【C++】文字列を2文字回転させて別の文字列を取得できるか判定するプログラムの作成方法
問題の概要2つの文字列「a」と「b」が与えられたとき、文字列「a」を反時計回りまたは時計回りにちょうど2文字分回転させることで、文字列「b」を得られるかどうかを判定します。入力例1a = google b = legoog出力:True解説: 文字列「google」を反時計回りに2文字分回転すると「legoog」になります。したがって、True を返します。入力例2a = tuorialst b = tutorials出力:False解説: 文字列「tuorialst」は、どちらの方向に2文字分回転しても「tutorials」にはなりません。したがって、False を返します。この問題を解くた
-
【C++入門】バイナリ文字列内の「1」で始まり「1」で終わる部分文字列を数える方法
長さ N のバイナリ文字列 str が与えられたとき、その中に含まれる「1」で始まり「1」で終わる部分文字列の個数を求める問題を考えてみましょう。ここでいうバイナリ文字列とは、「0」と「1」のみで構成された文字列のことです。具体例入力例1:N = 5 str = 11101出力:6解説:このバイナリ文字列には、「1」で始まり「1」で終わる部分文字列が6つ存在します。具体的には、{11, 111, 1110, 11101, 1101, 101} の6つです。入力例2:N = 4 str = 0011出力:1解説:この場合、条件を満たす部分文字列は {11} のみで、合計1つとなります。解き方のア
-
C++で2つの配列の要素を比較してカウントする方法:二分探索による効率的なアプローチ
ここでは、ソートされていない2つの配列 arr1[] と arr2[] が与えられた場合を考えます。目的は、arr1[] の各要素について、「その要素以下の値が arr2[] 内にいくつ存在するか」を数えることです。なお、両方の配列には重複した要素が含まれている可能性がある点に注意してください。 入出力例 入力: N = 6 M = 7 arr1[N] = {1, 2, 5, 0, 6, 3} arr2[M] = {0,0,1,2,1,3,4,6,8} 出力: 4 5 7 2 8 6 この問題を解くためのアプローチ arr1[] の各要素について、それ以下の要素が arr2[] にいくつある
-
C++で単一連結リストから末尾ノード(テールノード)を削除する方法
連結リスト(リンクリスト)とは、線形データ構造の一種であり、複数の「ノード」で構成されます。各ノードには2つのフィールドがあり、1つは格納する値(データ)、もう1つは次のノードのアドレスを保持するためのポインタです。本記事の課題は、連結リストの末尾からノードを削除することです。連結リストの最後にあるノードは「テールノード(末尾ノード)」と呼ばれます。なお、連結リストが空の場合はNULLを返します。入出力例入力1: 1 → 2 → 3 → 4 → 5出力: 1 → 2 → 3 → 4 →説明: 与えられた単一連結リストの末尾にあるノードは「5」です。最後のノードを削除すると、出力は 1 → 2
-
C++で文字列がすべて大文字かどうかを判定する方法を解説
文字列 str に何らかの文字が含まれているとします。ここでの課題は、与えられた文字列のすべての文字が大文字であるかどうかを判定し、結果に応じて True または False を返すことです。具体的な例を見てみましょう。 入力例1: str = INDIA 出力: True 説明: 入力文字列のすべての文字が大文字であるため、この場合は true を返します。 入力例2: str = Programmer 出力: False 説明: 先頭の1文字以外は大文字ではないため、この場合は false を返します。 問題を解くためのアプローチ この問題では、与えられた文字列のすべての文字が大文字かど
-
C++で文字列内の最初の一意の文字のインデックスを検索する方法
問題の概要文字列 s が与えられたとき、その中で繰り返し現れない最初の一意の文字を見つけ、そのインデックスを返すことが課題です。該当する文字が文字列中に存在しない場合は、-1 を返します。入出力例1入力:s = tutorialspoint出力:1説明: 文字列「tutorialspoint」の中で、繰り返されない最初の一意の文字は「u」であり、そのインデックスは「1」です。したがって、出力として「1」を返します。入出力例2入力:s = aaasttarrs出力:-1説明: 文字列「aaasttarrs」には一意の文字(1回しか現れない文字)が存在しないため、出力として「-1」を返します。解法
-
C++で単方向連結リストの末尾からK番目のノードを効率的に検索する方法
連結リスト(リンクリスト)とは、複数のノードが互いに接続された線形データ構造です。各ノードは「データフィールド」と「次のノードへのアドレス」という2つの要素で構成されています。ここでは、与えられた単方向連結リストの中から末尾からK番目のノードを見つける方法を解説します。問題の例入力:1→2→3→4→7→8→9 K = 4出力:末尾から4番目のノード:4説明:この単方向連結リストにおいて、末尾から4番目に位置するノードは「4」であるため、出力として「4」を返します。解決のためのアプローチ連結リストの各ノードにはデータと次のノードへのアドレスが格納されています。末尾からK番目のノードを求めるには、