-
C++で楕円の面積を求めるプログラムの作成方法
この記事では、C++を使って楕円(だえん)の面積を求める方法を解説します。楕円にはいくつかの重要な構成要素があり、それぞれの意味を理解しておくと計算の仕組みがより明確になります。楕円の主な構成要素要素説明中心楕円の中心点。2つの焦点を結ぶ線分の中点でもあります。長軸楕円における最も長い直径です。短軸楕円における最も短い直径です。弦楕円上の2点を結ぶ線分のことです。焦点楕円を定義する2つの特別な点。図中に示された2点が該当します。通径焦点を通り、長軸に対して垂直な直線(線分)のことです。楕円の面積の公式楕円の面積は、長半径 a と短半径 b を使って次の式で表されます。面積 = π × a ×
-
最近傍アルゴリズムをC++で実装!巡回セールスマン問題の最小コストを求める方法
概要本記事では、巡回セールスマン問題(TSP:Traveling Salesman Problem)を解くために用いられる最近傍アルゴリズムをC++で実装する方法を解説します。このプログラムは、すべてのノードを訪問するために必要な最小コストを、各辺を一度だけ通過するという条件のもとで計算します。必要な関数と擬似コードアルゴリズムの流れBegin Initialize c = 0, cost = 1000; Initialize g[][]. function swap() is used to swap two va
-
最近傍法(ニアレストネイバーアルゴリズム)で巡回セールスマン問題を解くC++プログラム
巡回セールスマン問題(TSP:Traveling Salesman Problem)は、「すべての都市をそれぞれ一度だけ訪れ、最後に出発地点へ戻る」という条件のもとで、移動コストの合計が最小となる経路を求める古典的な組合せ最適化問題です。本記事では、その代表的な近似解法である最近傍法(Nearest Neighbour Algorithm)を用いて、この問題をC++で実装する方法を解説します。 最近傍法のアルゴリズム 最近傍法は貪欲法(グリーディ法)に基づくシンプルな手法で、「現時点で最も良さそうな選択」を繰り返すことで、少ない計算コストで比較的良い解を得られるのが特徴です。 処理の手順
-
C++の純粋仮想関数と抽象クラスを徹底解説!基本概念から実装例まで
はじめにC++には、オブジェクト指向設計において重要な役割を果たす純粋仮想関数と抽象クラスという仕組みがあります。これらを理解することで、柔軟で拡張性の高いクラス設計が可能になります。本記事では、純粋仮想関数と抽象クラスの基本概念、特徴、そして実際のコード例を通じて、わかりやすく解説していきます。純粋仮想関数とは?純粋仮想関数とは、C++における仮想関数の一種で、関数の定義(処理内容)を持たず、宣言のみを行う特殊な関数です。宣言の末尾に = 0 を代入することで宣言されます。virtual void s() = 0; // 純粋仮想関数の宣言抽象クラスとは?抽象クラスとは、少なくとも1つの純粋
-
C++の仮想基底クラス(virtual base class)とは?多重継承の重複問題を解決する方法
C++における仮想基底クラス(virtual base class)は、派生クラスが同じ基底クラスのコピーを複数持ってしまう場合に使用される仕組みです。多重継承を行う際、同一の基底クラスが異なる経路から複数回継承されると、メンバへのアクセスが曖昧になりコンパイルエラーが発生します。この問題を解決するために、virtualキーワードを使った仮想継承が用いられます。 問題となるコード例 まず、仮想継承を使わない場合にどのような問題が起きるかを見てみましょう。 #include <iostream> using namespace std; class B { public:
-
C++の純粋仮想関数が「= 0」で宣言される理由を徹底解説
C++において、純粋仮想関数(Pure Virtual Function)が = 0 で初期化されるのは、特別な技術的な意味があるわけではなく、単に「この関数は純粋仮想である」ということをコンパイラに伝えるための構文にすぎません。 純粋仮想関数とは? 純粋仮想関数とは、C++における仮想関数の一種で、基底クラス側では関数の定義(実装)を書かず、宣言だけを行う関数のことです。宣言時に = 0 を代入することで、純粋仮想関数として宣言されます。 純粋仮想関数を1つ以上持つクラスは「抽象クラス」と呼ばれ、直接インスタンス化することはできません。派生クラスは、この純粋仮想関数を必ずオーバーライドして実
-
C++で純粋仮想デストラクタが必要な理由とは?
純粋仮想デストラクタの必要性C++プログラムにおいて、純粋仮想デストラクタを使用しても悪影響は一切ありません。むしろ、抽象クラスを作りたい場合に有効な手法の一つです。ただし、純粋仮想デストラクタには関数本体(定義)を必ず提供する必要があります。その理由は、オブジェクト破棄の際に派生クラスのデストラクタが基底クラスのデストラクタよりも先に呼び出されるためです。もし関数本体を提供しないと、オブジェクトの破棄処理の中で基底クラスのデストラクタを呼び出そうとしたときに実体が存在せず、リンクエラーが発生してしまいます。つまり、定義を持つ純粋仮想デストラクタを作成すれば、インスタンス化できない抽象クラスを
-
C++とJavaのデフォルトの仮想関数の動作の違い
はじめに オブジェクト指向プログラミングにおいて、仮想関数(virtual function)はポリモーフィズムを実現するための重要な仕組みです。基底クラスのポインタや参照を通じてメソッドを呼び出す際、実際にどのクラスのメソッドが実行されるかは、そのメソッドが仮想かどうかによって決まります。 C++とJavaでは、この「仮想」に関するデフォルトの挙動が正反対です。本記事では、両言語の違いをサンプルコードとともにわかりやすく解説します。 C++:デフォルトでは非仮想(non-virtual) C++では、メンバ関数はデフォルトで非仮想です。動的ディスパッチを行いたい場合は、virtualキーワ
-
C++の可変個引数関数テンプレート(Variadic Templates)の基本構文と実装例
C++の可変個引数関数テンプレートとはC++における可変個引数関数テンプレート(Variadic Function Templates)とは、引数の個数に制限がなく、任意の数の引数を受け取れる関数テンプレートのことです。C++11で導入されたこの機能を使うことで、型も個数も異なるさまざまな呼び出し方に対応できる、柔軟な汎用関数を作成できます。構文template(typename arg, typename... args) return_type function_name(arg var1, args... var2)ポイントは「typename...」のように続く省略記号「...」の部分
-
C++のテンプレートメタプログラミング入門:コンパイル時に計算を行う技法
テンプレートメタプログラミングとはテンプレートメタプログラミング(Template Metaprogramming)とは、C++のテンプレート機能を活用して、実行時ではなくコンパイル時に計算を行うプログラミング技法です。コンパイラがテンプレートのインスタンス化を通じて計算を処理するため、生成されるコードは高度に最適化され、実行時のオーバーヘッドを大幅に削減できます。サンプルコード以下は、4のn乗をコンパイル時に計算するシンプルな例です。#include <iostream> using namespace std; template<int n> struct pow
-
C++で直線に対する点の位置を判定!Above-Below-onテストの実装方法
この記事では、Above-Below-on テストを適用して、ある点が直線に対してどの位置(下側・上側・直線上)にあるのかを判定する C++ プログラムを紹介します。 平面上の任意の点 t(xt, yt) について、2点 m と n を結ぶ直線 L に対する位置関係は、次のスカラー値 s を計算することで求められます。 Y = A·xt + B·yt + C 計算結果の符号により、次のように判定できます。 s < 0 の場合:点 t は直線 L の時計回り側の半平面(下側・左側)にあります。 s > 0 の場合:点 t は直線 L の反時計回り側の半平面(上側・右側)にあります。
-
三角測量不要!C++で実装するSlickerアルゴリズムによる多角形の面積計算プログラム
本記事では、多角形を三角形に分割する三角測量(Triangulation)を行わずに面積を求められる「Slickerアルゴリズム」を実装したC++プログラムを紹介します。 Slickerアルゴリズムとは Slickerアルゴリズムは、隣り合う頂点の座標から外積に相当する値を順番に加算し、その合計を2で割ることで多角形の面積を直接求める手法です。この方式は「靴ひも公式(Shoelace Formula)」としても知られており、多角形を三角形に分割する前処理が不要なため、計算量はO(n)と非常に効率的です。凸多角形だけでなく凹多角形にもそのまま適用できます。 このアルゴリズムは、数学で一般的な「y
-
上下(above-below)プリミティブを使って2本の直線が交差するかどうかを判定するC++プログラム
ここでは、「上・下(above-below)」プリミティブを用いて、2本の直線が交差するかどうかを判定するC++プログラムを紹介します。この手法は、ある直線と線分の交差判定にも応用できます。線分が直線と交差するのは、線分の一方の端点が直線の左側にあり、もう一方の端点が右側にある場合、そのときに限られます。 交差判定の仕組み 直線の一般形 ax + by + c = 0 に、ある点の座標を代入すると、その結果の符号から点が直線のどちら側にあるかが分かります。結果が正なら一方の側、負なら反対側、0なら直線上に存在することを意味します。そこで、線分の両端点を同じ直線の方程式に代入し、得られる符号が
-
3点から定義される円の内側・外側に点があるか判定するC++プログラム
本記事では、平面上の3つの点 a、b、c によって定義される円に対して、ある点 d がその円の内側にあるのか、外側にあるのかを判定するC++プログラムを紹介します。判定には次の式を使用します。s = (x - xt)^2 + (y - yt)^2 − r * rここで、平面上の任意の点 t (xt, yt) の位置が、3点 (x1, y1)、(x2, y2)、(x3, y3) で定義される円とどのような関係にあるかは、s の値によって以下のように判別できます。s < 0 の場合:点 t は円の内側にあります。s > 0 の場合:点 t は円の外側にあります。s = 0 の場合:点
-
C++で実装する二次元ギフト包装アルゴリズム:凸包計算の基本とサンプルコード
二次元ギフト包装アルゴリズムとは本記事では、C++を用いて二次元平面におけるギフト包装アルゴリズム(Gift Wrapping Algorithm)を実装する方法を詳しく解説します。このアルゴリズムは「Jarvisの行進法」とも呼ばれ、与えられた点集合から凸包(Convex Hull)を求めるための代表的な手法の一つです。凸包とは、平面上に散らばるすべての点を内側に含む最小の凸多角形のことです。釘で打った点の周囲に輪ゴムを引っ掛けたとき、輪ゴムが描く形を思い浮かべると理解しやすいでしょう。外側の点を順に結んでいく様子がプレゼントを包む作業に似ていることから、「ギフト包装」という名前が付きました
-
C++における名前空間(namespace)とクラス(class)の違いを徹底解説
はじめに:名前空間とクラスはまったく別の概念C++において「名前空間(namespace)」と「クラス(class)」は、一見似たような役割を持つように見えますが、実際にはまったく異なる目的を持つ2つの概念です。クラスはデータ型であり、構造体(struct)を拡張したものと考えることができます。クラスにはデータメンバーやメンバ関数を定義でき、それらをひとつのまとまりとして扱います。一方、名前空間は変数や関数などをグループ化してまとめるための仕組みです。名前空間はオブジェクトとして生成することはできません。主な用途は、同名の関数・クラス・変数などを区別するための追加情報を与えることであり、同じ名
-
C++のstd::vectorとstd::arrayの違いとは?特徴と使い分けを徹底解説
C++には、複数の値をまとめて管理できるコンテナとして std::vector と std::array が用意されています。一見似ていますが、内部構造や動作には重要な違いがあり、それぞれ得意な場面が異なります。この記事では、両者の主な違い、宣言と初期化の基本構文、そして実際に動作するサンプルコードを交えながら、わかりやすく解説します。 std::vectorとstd::arrayの主な違い 比較項目std::vectorstd::array サイズ動的(要素の追加で自動拡張)固定(宣言時に決定) メモリ消費やや多い少ない(効率的) 要素アクセス高速だが僅かなオーバーヘッドあり常に一定
-
C++のstd::arrayクラスとは?主要メンバ関数をサンプルコード付きで解説
C++のstd::arrayクラスは、従来の生の配列と同等の高いパフォーマンスを持ちながら、自分自身のサイズ(要素数)を把握できるという大きな利点があります。C++11以降で利用できるこの固定長コンテナは、<array>ヘッダをインクルードすることで使用できます。配列に対する操作に使われる主なメンバ関数size():配列のサイズ、つまり配列に含まれる要素数を返します。max_size():配列が保持できる最大要素数を返します。get(), at(), operator[]:配列の各要素へアクセスするために使用します。front():配列の先頭(最初)の要素を返します。back():
-
C++で前置記法(プレフィックス記法)の式から式木を構築するプログラム
式木(Expression Tree)は、数式を表現するために用いられる二分木の一種です。式木では、内部ノードが演算子に対応し、葉ノードがオペランド(被演算子)に対応します。この記事では、前置記法(プレフィックス記法)で与えられた式から式木を構築し、中間順(インオーダー)、前置順(プレオーダー)、後置順(ポストオーダー)の3種類の走査で出力するC++プログラムを紹介します。 式木とは? 例えば、前置記法の式「++7*626」は、次のような二分木として表現できます。 + / \ + 6 / \ 7 *
-
C++でループ・再帰・gotoを使わずに文字をn回出力する方法
この記事では、C++においてループ(for文・while文)や再帰、goto文を一切使わずに、指定した文字をn回出力する方法を解説します。一見すると繰り返し処理にはループが必須に思えますが、実は std::string クラスのコンストラクタを活用することで、非常にシンプルにこの問題を解決できます。stringクラスのコンストラクタを利用するstd::string には、「文字」と「その繰り返し回数」を受け取るコンストラクタが用意されています。書式は以下のとおりです。string(繰り返し回数, 出力したい文字);例えば string(10, B) と書くと、「B」が10個並んだ文字列 BBB