-
【C++】指定された確率に従って3つの数値のいずれかを生成する関数の実装方法
この記事では、与えられた確率に従って3つの数値(A・B・C)のいずれかを返す関数を、C++で実装する方法を解説します。 問題の概要 ここでは、標準ライブラリの乱数生成関数 rand() を利用します。この関数は一定範囲内の数値を等しい確率(一様分布)で生成するという特徴を持っています。 私たちのタスクは、この一様な乱数を元に、出現確率がそれぞれ P(A)、P(B)、P(C) となる3つの数値 A・B・C のみを返す関数を作成することです。確率の定義より、次の式が成り立ちます。 P(A) + P(B) + P(C) = 1 アルゴリズムの考え方 rand() を使って目的の関数を作るには、
-
【C++】連結リスト内の特定の整数(int)の出現回数をカウントする関数の作成方法
問題の概要 この記事では、C++の連結リスト(リンクリスト)を扱います。与えられた連結リストの中に、特定の整数(int型)が出現する回数を数える関数を作成するのが課題です。 まずは具体例で問題を確認してみましょう。 入力 連結リスト: 10 → 50 → 10 → 20 → 100 → 10 / 探す値: 10 出力 3 説明:数値「10」は連結リスト内に合計3回出現しています。 解法の考え方 この問題の解法はとてもシンプルです。連結リストを先頭から順番に走査し、現在のノードの値が探している数値と一致したらカウンターを+1するだけでOKです。 連結リストのノードをたどる方法には「反復(イテレー
-
C++でコンパイルできないCプログラムの作成方法
C++はC言語の後継言語とされ、Cの機能をすべて備え、Cコードとの互換性があると考えられています。しかし実際には、C++コンパイラでコンパイルするとエラーが発生する、つまりコンパイルできないCプログラムが存在します。本記事では、C++ではコンパイルできないCプログラムの代表例を、具体的なコードとともに紹介します。1. 宣言前の関数呼び出しC++では、関数を宣言する前に呼び出すとコンパイルエラーになります。一方、C言語では暗黙的な関数宣言が行われるため、このコードは問題なく動作します。サンプルコード#include <stdio.h> int main(){ printHel
-
Linuxの「more」コマンドのようにファイル内容をページごとに表示するCプログラムの作成方法
この記事では、Linuxのmoreコマンドと同様に、ファイルの内容をページごとに表示するCプログラムの作成方法を解説します。 moreコマンドは、テキストファイルを一度にすべて表示するのではなく、画面に収まる範囲の行数だけを表示し、ユーザーの操作を待ってから続きを表示するページャーです。本プログラムでも同じように、まず指定した行数を画面に表示し、ユーザーがEnterキーを押すのを待ってから、次のページ(次のn行分)を表示していきます。 プログラムの仕組み ファイルの内容をページごとに表示するため、プログラムは以下の手順で動作します。 fopen関数でファイルを読み込みモード(r)で開きます。
-
C++のSTLで配列とベクトルを操作する方法|合計・最大値・最小値・ソート
配列とベクトルは、競技プログラミングで問題を解くうえで非常に重要なデータ構造です。C++のSTL(Standard Template Library:標準テンプレートライブラリ)には、これらに対してさまざまな操作を簡単に行える便利な関数が多数用意されています。 この記事では、その中でも特によく使われる「合計・最大値・最小値を求める関数」と「ソート関数」の使い方を、サンプルコードと実行結果つきで解説します。 合計・最大値・最小値を求める STLには、配列やベクトルの合計・最大値・最小値を求めるための関数が用意されています。それぞれ以下のように使用します。 合計を求める:accumulate()
-
C++で解く「単語の梯子(ワードラダー)」問題:ターゲット単語に到達する最短チェーンの長さ
この問題では、辞書と2つの単語「スタート(start)」と「ターゲット(target)」が与えられます。目的は、スタート単語からターゲット単語へと到達する「単語の梯子(ワードラダー)」と呼ばれるチェーンを生成することです。チェーンを構成する各単語は、隣り合う単語とたった1文字だけ異なり、かつすべて辞書に存在しなければなりません。なお、ターゲット単語は辞書に含まれており、すべての単語の長さは同一であるとします。プログラムの出力として、スタートからターゲットまでの最短経路の長さを求めます。まずは具体例を見ながら、問題の内容を確認しましょう。入力例Dictionary = {HEAL, HATE,
-
C++で2つの辞書単語の連結による単語形成を判定する方法
問題概要この問題では、辞書(単語の集合)と1つの文字列が与えられます。与えられた文字列が、辞書内の2つの単語を連結することで作れるかどうかを判定するのがタスクです。なお、同じ単語を繰り返して使用することは許されません。具体例を見ながら理解していきましょう。入力例dictionary = {hello, tutorials, program, problem, coding, point} word = tutorialspoint出力例yes説明「tutorialspoint」は、「tutorials」と「point」という2つの辞書単語を連結することで作成できます。解法アプローチ:トライ(T
-
C++でウッダル数(Woodall Number)を判定する方法
この問題では、ある数値が与えられ、それがウッダル数(Woodall number)であるかどうかを判定します。ウッダル数とは、次の式で表される特殊な数のことです。Wn = n × 2n − 1最初の5つのウッダル数は 1、7、23、63、159 です。具体例を見て、問題を理解しましょう。入力X = 159出力Yes159 は 5 × 25 − 1 = 159 と表せるため、ウッダル数であると判定できます。解法のアプローチこの問題を解くには、まず数の性質を観察します。ウッダル数は n × 2n − 1 という形で表されるため、必ず奇数になります。したがって、与えられた数が偶数であれば、その時点で
-
C++でNを2つ以上の正の整数の和として表す方法の総数を求める
この記事では、「整数 N が与えられたとき、それを 2 つ以上の正の整数の和として表す方法が何通りあるか」を求める問題を取り上げます。 まず、具体例を使って問題を確認しましょう。 入力例 N = 4 出力例 5 説明 4 は次のように和で表せます。 4, 3+1, 2+2, 2+1+1, 1+1+1+1 ※上記の答えには「4」そのものも含まれています。これは整数を順序を問わない和に分解する「分割(パーティション)」の総数、いわゆる分割数 p(n) と一致します。 アプローチ:オイラーの漸化式(五角数定理) この問題は、整数 n の分割数 p(n) を求める問題に帰着できます。分割数を効率よく
-
C++で配列要素の重複使用を許可して合計がNになる組み合わせの総数を求める方法
問題概要この問題では、整数の配列と数値Nが与えられます。配列の要素を足し合わせてNを作る方法が全部で何通りあるかを数えるのが課題です。同じ要素の繰り返し使用は許可されており、さらに要素の並び順が異なる組み合わせはそれぞれ別の方法としてカウントします。具体的な例を見てみましょう。入力例arr = {1, 3, 5}、N = 6出力例8解説N = 6 を作る8通りの方法は以下の通りです。5+1、1+5、3+3、3+1+1+1、1+3+1+1、1+1+3+1、1+1+1+3、1+1+1+1+1+1このように「5+1」と「1+5」のように順序だけが異なる組み合わせも、別々の方法として数える点がポイント
-
C++で2つの異なる集合から1つ以上のペアを選択する方法
この問題では、それぞれの集合の要素数を表す2つの正整数 n と m(n ≤ m)が与えられます。求めたいのは、これら2つの集合の要素から1つ以上のペアを選択する方法の総数です。まず、具体例で問題を確認しましょう。入力例2 2出力例6解説2つの集合 A と B は、どちらも2つの要素を持っています。Set A = {1, 2} Set B = {3, 4}ペアを1つだけ選ぶ場合は、(1, 3)、(1, 4)、(2, 3)、(2, 4) の 4通り。ペアを2つ同時に選ぶ場合は、「(1, 3) と (2, 4)」「(1, 4) と (2, 3)」の 2通りあります。したがって、答えは 4 + 2 =
-
C++でバイナリ文字列から1つの要素を削除してXORをゼロにする方法
問題の概要 この問題では、0と1だけで構成されたバイナリ文字列が与えられます。求めたいのは、1つの要素を削除したときに文字列全体のXORがゼロになるような削除方法の総数です。 まずは具体例で問題を確認してみましょう。 入力例 n = 11010 出力例 3 入力文字列「11010」には「1」が3つ含まれています。このうちどれか1つの「1」を削除すると、残る「1」は2個(偶数)となり、全体のXORが0になります。削除できるのは「1」の位置が3か所なので、答えは3通りです。 解法の考え方 この問題を解くカギは、XOR演算の基本的な性質にあります。 偶数個の「1」に対してXORを取ると、結果は必ず
-
C++で同じ行・列に重複しないようにn×n交点へ4つのアイテムを配置する組み合わせの求め方
この問題では、整数 n が与えられます。縦に n 本、横に n 本の直線が引かれており、これらの直線は合計 n2 個の交点を作ります。求めたいのは、どの行(横方向)にもどの列(縦方向)にも複数のアイテムが含まれないという条件のもとで、この交点のうち4か所にアイテムを配置する方法が全部で何通りあるのかということです。 具体例を見ながら問題を理解していきましょう。 入力 n=4 出力 24 解説 まず、n 本ある横線の中から、アイテムを置く対象となる4本を選びます。この選び方は nC4 通りです。 続いて、各横線には n 本の縦線が交差しているため、最初に選んだ横線上にはアイテムを置ける位置が n
-
【C++】隣り合う2段が同時に黄色にならないように階段を2色で塗る方法の総数を求める
n個の階段と、それらを塗るための2色(赤・黄)が与えられます。この記事では、「隣り合う2段がどちらも黄色にならない」という条件を満たしながら階段を塗る方法が何通りあるのかを数える問題を、C++で解いていきます。 まずは具体例で問題の内容を確認してみましょう。 入力例 3 出力例 5 説明 条件を満たす塗り方は「YRY」「RYR」「YRR」「RRY」「RRR」の5通りです。ここで R は赤色、Y は黄色を表します。 規則性を見つける この問題を解くために、段数が増えたときの塗り方の数を順番に観察してみましょう。 N = 1 のとき、ways(1) = 2:R、Y N = 2 のとき、ways(
-
隣り合う絵画が同じ色にならないようにC++でN枚の絵画を塗る方法の総数を求める
この記事では、整数 n と m が与えられたとき、n 枚の絵画を m 色の中から選んで塗り分ける方法が全部で何通りあるかを求める問題を扱います。ただし、隣り合う2枚の絵画に同じ色を使ってはいけないという制約があります。全探索ではなく、数学的な性質を活かした効率的な解法をC++で実装していきましょう。まず、具体例で問題を確認します。入力n = 3, m = 3出力12説明P1 P2 P3 C1 C2 C3 C1 C3 C2 C1 C2 C1 C1 C3 C1 C2 C1 C2 C2 C3 C2 C2 C1 C3 C2 C3 C1 C3 C1 C3 C3 C2 C3 C3 C1 C2 C3 C2
-
C++で結合演算を用いてn個の要素を掛け合わせる方法の総数を求める
問題概要この問題では、要素の個数を表す整数 n が与えられます。求めるのは、結合演算(associative operation)を用いて n 個の要素を掛け合わせる方法が何通りあるかを数えるプログラムです。結合演算とは、数値の並べ方や計算の順序がどうであっても、常に同じ結果を返す演算のことです。具体例で理解する入力3出力12解説(x*(y*z)), (x*(z*y)), (y*(x*z)), (y*(z*x)), (z*(x*y)), (z*(y*x)),((x*y)*z), ((y*x)*z), ((x*z)*y), ((z*x)*y), ((z*y)*x), ((y*z)*x).3つの要
-
C++の属性(アトリビュート)とは?主要な標準属性の使い方を徹底解説
属性(アトリビュート)とは属性(アトリビュート)は、同じコードを異なるコンパイラで動作させても一貫した挙動を実現するための、C++のモダンな仕組みです。属性を使うことでコンパイラに追加情報を与え、条件(制約)の強制、最適化、必要に応じた特定のコード生成を行わせることができます。属性はコンパイラにとっての一種の「情報マニュアル」のようなものであり、コードのパフォーマンス向上につながる各種の制御を行うために活用されます。属性はC++11で初めて導入され、それ以来C++の重要な要素となっています。さらに、バージョンが上がるごとに改訂が重ねられ、より強力で使いやすいものへと進化し続けています。C++に
-
C言語のファイル処理入門!fopenからfcloseまで基本を徹底解説
ファイル処理(File Handling)とは、プログラムを使ってデータをファイルに保存することです。C言語では、プログラムの実行結果やその他のデータをファイル処理の機能を使ってファイルに保存できます。また、逆にファイルからデータを読み出して、プログラム内で利用することも可能です。 C言語でファイルに対して実行できる主な操作は以下のとおりです。 新しいファイルを作成する 既存のファイルを開く 既存のファイルからデータを読み込む ファイルへデータを書き込む ファイル内の特定の位置へ移動する ファイルを閉じる fopen()関数でファイルを作成・開く C言語では、新しいファイルの作成や既存ファ
-
C/C++で理解する条件付き確率とベイズの定理の基本
条件付き確率とは、P(A|B) のように表記され、「事象Bがすでに起こった」という条件下で、事象Aが起こる確率のことを指します。 条件付き確率の公式は以下の通りです。 P(A|B) = P(A∩B) / P(B) ベイズの定理とは ベイズの定理は、相互に依存する事象同士の確率の関係を示す公式です。つまり、ある事象が起こったことを知ったとき、それがもう一方の事象の確率にどう影響するか(条件付き確率の関係)を表します。 事象Aと事象Bがあるとき、ベイズの定理によれば次の式が成り立ちます。 P(A|B) = {P(B|A) × P(A)} / P(B) ベイズの定理の導出 ここでは、条件付き確率の
-
C/C++で実装するバークレーアルゴリズム――分散システムの時刻同期を徹底解説
バークレーアルゴリズムとは バークレーアルゴリズム(Berkeleys Algorithm)は、分散システムにおいて各ノードの時計を同期させるために用いられるアルゴリズムです。特に、以下のような状況にあるシステムで有効とされています。 マシンに正確な時刻源が存在しない場合 ネットワークやマシンにUTCサーバーが用意されていない場合 分散システムとは、物理的に離れた場所に配置された複数のノードが、ネットワークを介して相互に接続されたシステムのことを指します。各ノードの時計は独立して動作しているため、誤差が生じやすく、何らかの同期機構が必要になります。 バークレーアルゴリズムの仕組み このア