C++

 Computer >> コンピューター >  >> プログラミング >> C++
  1. 【C++】ビンパッキングアルゴリズムの実装方法とサンプルプログラム

    ビンパッキング問題とはビンパッキング問題(Bin Packing Problem)は、切断在庫問題(カッティングストック問題)の一種です。異なる体積を持つ複数の物体を、それぞれ体積Vの容器(ビン)に収めるとき、使用するビンの本数が最小になるように詰め込むことを目指します。計算複雑性理論の観点では、ビンパッキング問題はNP困難(NP-hard)な組合せ最適化問題に分類されます。そのため、大規模なインスタンスに対して厳密な最適解を効率的に求めることは困難で、実際には貪欲法などの近似解法が広く利用されています。なお、ビンの数を1つに制限し、各アイテムが「体積」と「価値」の両方の属性を持つ場合、ビンに

  2. DFT(離散フーリエ変換)係数を直接計算するC++プログラムの実装方法

    離散フーリエ変換(DFT)とは、関数を等間隔でサンプリングして得られた有限個のデータ列を、複素正弦波の有限線形結合における係数のリストへ変換する手法です。係数は周波数順に並べられ、元のサンプル値と同じ値を持つように構成されます。これにより、サンプリングされた関数を元の領域(多くの場合、時間や直線上の位置)から周波数領域へと変換することができます。本記事では、一次関数 ax + by = c のサンプル列に対してDFT係数を実装で直接計算するC++プログラムを紹介します。アルゴリズム処理の流れは以下の擬似コードの通りです。まず入力された係数からサンプル列を生成し、次に各周波数kに対応する余弦・正

  3. 素朴なアルゴリズムで離散フーリエ変換(DFT)を計算するC++プログラム

    離散フーリエ変換(DFT:Discrete Fourier Transform)とは、関数を等間隔でサンプリングして得られた有限個の標本列を、複素正弦波の有限な線形結合における係数列へと変換する手法です。求められた係数は周波数の順に並べられ、元の標本値と同じ情報を持つため、サンプリングされた関数をその元の領域(多くの場合、時間や直線上の位置)から周波数領域へと変換できます。 DFTの基本式 N点の標本列 x(0), x(1), …, x(N−1) に対して、k番目のDFT係数は次のように定義されます。 X(k) = Σ x(i) × e−2πik/N(i = 0 ~ N−1) オイラーの公式に

  4. C++で複素数2次元配列に対して2D FFTをインプレースで実行する方法

    2D FFT(二次元高速フーリエ変換)とは高速フーリエ変換(FFT)は、離散フーリエ変換(DFT)およびその逆変換を効率的に計算するためのアルゴリズムです。フーリエ解析では、時間領域(または空間領域)の信号を周波数領域へ、あるいはその逆方向へと変換します。FFTは、DFT行列を疎行列(ほとんどの要素がゼロ)の積に因数分解することで、変換処理を大幅に高速化します。本記事では、複素数を含む2次元配列(画像データなど)を対象に、C++で2D FFTをインプレースで実行するプログラムを紹介します。出力として、各周波数成分の実部、虚部、そして振幅(amp)を求めます。アルゴリズムBegin 配列

  5. 行列累乗法を使ってフィボナッチ数を求めるC++プログラム

    フィボナッチ数は通常 Fn と表記され、フィボナッチ数列と呼ばれる数列を構成します。これは「各項が直前の2つの項の和になる」という性質を持つ数列で、0 と 1 から始まります。すなわち −F0 = 0、F1 = 1そしてFn = Fn-1 + Fn-2(n > 1 のとき)行列累乗法によるアプローチ単純な再帰や反復処理でもフィボナッチ数は求められますが、行列の累乗計算を利用すると O(log n) の時間計算量で n 番目のフィボナッチ数を高速に求めることができます。これは、次の恒等式に基づいています。{{1,1},{1,0}}n = {{Fn+1, Fn}, {Fn, Fn-1}}アル

  6. 【C++】ピボットをランダムに選択するランダム化クイックソートの実装方法

    クイックソートは、リストを2つの部分に分割することでソートを行う代表的なアルゴリズムです。まずパーティション(分割)処理によってピボット要素が選択され、ピボットより小さい値は左側へ、大きい値は右側へ配置されます。その後、分割された各部分リストに対して同じ手順を再帰的に適用していきます。本記事で取り上げるのは、ピボット要素をランダムに選択する「ランダム化クイックソート」です。固定ルールでピボットを選ぶ場合、整列済みやほぼ整列済みのデータを入力すると最悪計算量O(n2)に陥る可能性がありますが、ピボットをランダムに選ぶことでこのリスクを大幅に軽減できます。ピボット選択後は通常どおりパーティション分

  7. O(n)の計算量で100未満の数値をソートするC++プログラム:計数ソートの実装方法

    少数の小さな数値を線形時間 O(n) でソートしたい場合、「計数ソート(Counting Sort/カウントソート)」という手法が非常に有効です。計数ソートは安定なソートアルゴリズムの一つで、キーとなる値が小さな整数であるオブジェクトを整列するのに適しています。各キー値と同じ値を持つ要素の個数を数え上げ、その情報をもとに配列を再構築することでソートを実現します。キー同士の値の範囲(最大値との差)が小さい場合に高い効率を発揮しますが、範囲が大きすぎるとカウント用の配列が巨大化し、空間計算量が悪化する点には注意が必要です。計数ソートの計算量時間計算量:O(n + r) ※rはキー値の範囲(最大値)

  8. 100個の要素をクイックソートで並べ替えるC++プログラムの解説

    クイックソートは、リストを2つの部分に分割することで並べ替えを行うソート手法です。最初にパーティションアルゴリズムによってピボット要素を選択します。ピボットの左側にはピボットより小さい値が、右側にはピボットより大きい値が配置されます。パーティション分割が完了した後、分割されたそれぞれのリストに対して同じ手順を再帰的に適用していきます。本記事では、約100要素という比較的大きな配列をソートする例を扱います。まず連続した数値を用意し、それをランダムな順序にシャッフルして未ソート状態を作り出します。その後、クイックソートを使って配列を並べ替えます。クイックソートの計算量時間計算量 − 最良ケースおよ

  9. C++で連結リストをマージソートする方法|実装手順とサンプルコード

    マージソートは「分割統治法(divide and conquer)」に基づくソートアルゴリズムです。データセット全体を小さな部分に分割していき、それぞれを整列させながら大きな塊へと統合することで、最終的に完全にソートされたデータを得ます。最悪ケースでも時間計算量が O(n log n) と低く抑えられるため、入力データの初期状態に左右されず安定した性能を発揮できるのが大きな特徴です。 連結リスト(リンクリスト)は、マージソートとの相性が抜群です。配列のように要素を物理的に移動させる必要がなく、ノード間のリンク(ポインタ)を付け替えるだけでマージ処理が完結するため、非常に効率的にソートできます。

  10. 隣接行列を使ってグラフを表現するC++プログラムの解説

    グラフの隣接行列(Adjacency Matrix)とは、サイズが V × V の正方行列のことです。ここでの V はグラフ G の頂点数を表します。行列の行と列にはそれぞれ頂点が対応しており、頂点 i から頂点 j への辺が存在する場合は、i 行 j 列の要素に「1」(重み付きグラフの場合は非ゼロの値)を格納します。辺が存在しない場合は、その位置には「0」が入ります。 隣接行列表現の計算量 隣接行列は計算時に O(V2) の記憶領域を必要とします。グラフが最大数の辺を持つ場合でも最小数の辺しか持たない場合でも、必要なメモリ量は同じです。つまり、辺の数に依存せず常に V × V 分の領域を確

  11. 接続行列を使ってグラフを表現するC++プログラムの解説

    接続行列(インシデンス行列)とはグラフの接続行列(インシデンス行列)は、グラフをメモリ上に格納するためのもうひとつの表現方法です。隣接行列と異なり、接続行列は正方行列ではありません。そのサイズは V × E で表されます。ここで V はグラフの頂点数、E は辺の数です。この行列では、各行に頂点が配置され、各列に辺が配置されます。ある辺 e {u, v} に対しては、列 e のうち頂点 u と頂点 v に対応する位置に「1」がマークされます。これにより、「どの頂点がどの辺に接続しているか」という情報を直感的に把握できます。接続行列の計算量とメモリ使用量接続行列による表現では、構築時に O(V ×

  12. C++で隣接リストを使ってグラフを表現する方法と実装例

    グラフの隣接リスト(Adjacency List)表現とは、連結リスト(リンクリスト)を用いてグラフを表す手法のことです。この表現方式では、リストの配列を使用します。配列のサイズは V であり、ここでの V はグラフの頂点数を意味します。つまり、V 個の異なるリストを格納するための配列を用意するということです。あるリストの先頭が頂点 u である場合、そのリストには u のすべての隣接頂点が格納されることを示しています。隣接リスト表現の計算量この表現方式に必要な空間計算量は、無向グラフの場合 O(V+2E)、有向グラフの場合 O(V+E) となります。辺の数が増えるほど、必要な記憶領域も増加して

  13. リンクリスト(隣接リスト)を使ってグラフを表現するC++プログラム

    グラフをコンピュータのメモリ上に格納する方法はいくつかあります。そのひとつが接続行列(インシデンス行列)です。この行列は正方行列ではなく、そのサイズは V × E となります。ここで V はグラフの頂点数、E は辺の本数を表します。接続行列では、各行に頂点を、各列に辺を配置します。この表現では、辺 e = {u, v} に対して、列 e のうち頂点 u と頂点 v に対応する位置に 1 がマークされます。接続行列による表現の計算量接続行列による表現では、O(V × E) のメモリ領域が必要になります。完全グラフの場合、辺の本数は V(V−1)/2 となるため、接続行列はメモリを大きく消費します

  14. BFS(幅優先探索)で無向グラフの連結性を判定するC++プログラム

    グラフの連結性とは グラフが連結(接続)されているかどうかを調べるには、何らかのグラフ探索アルゴリズムを使って、すべてのノードを訪問できるかどうかを確認します。探索を完了した時点で未訪問のノードが1つでも残っていれば、そのグラフは連結していないことになります。 無向グラフの場合は、任意の1つのノードを選び、そこから探索を開始します。本記事では、探索アルゴリズムとして幅優先探索(BFS:Breadth-First Search)を採用しています。 入力と出力の例 入力 − グラフの隣接行列 0110010110110110110100110 出力 − 「グラフは連結しています。」 アルゴリズム

  15. BFSを用いて有向グラフの連結性を判定するC++プログラム

    グラフの連結性を調べるには、何らかの探索アルゴリズムを使ってすべてのノードを辿ってみます。探索が完了した時点で、まだ訪問していないノードが1つでも残っていれば、そのグラフは連結していないと判断できます。 有向グラフの場合は、すべてのノードを起点として探索を実行する必要があります。あるノードへの辺が外向きのみで内向きの辺を持たない場合、そのノードは他のどの起点から探索しても未訪問のままになる可能性があるためです。 この記事では、探索アルゴリズムとしてBFS(幅優先探索)を使用します。 入力 − グラフの隣接行列 01000 00100 00011 10000 01000 出力 − The

  16. DFS(深さ優先探索)を使って無向グラフの連結性を判定するC++プログラム

    グラフの連結性(接続性)を確認するには、何らかのグラフ探索アルゴリズムを使ってすべてのノードを訪問できるかどうかを試します。探索が完了した時点で、まだ訪問されていないノードが1つでも残っていれば、そのグラフは連結していないと判断できます。無向グラフの場合は、任意の1つのノードを選び、そこから探索を開始します。本記事では、探索アルゴリズムとして再帰的なDFS(深さ優先探索)を使用します。入力と出力入力 − グラフの隣接行列0110010110110110110100110出力 − 「The Graph is connected.」(グラフは連結している)アルゴリズムtraverse(u, vis

  17. 【C++】Wagner-Fischerアルゴリズムで文字列照合!レーベンシュタイン距離の求め方

    本記事では、Wagner-Fischer(ワグナー・フィッシャー)アルゴリズムを使って2つの文字列を比較する方法を解説します。このアルゴリズムを利用すると、片方の文字列をもう片方に一致させるために必要な最小の編集回数を求めることができます。 これは動的計画法(ダイナミックプログラミング)を用いた代表的な手法で、2つの文字列間のレーベンシュタイン距離(編集距離)を計算します。レーベンシュタイン距離とは、1文字の「挿入」「削除」「置換」を繰り返して一方の文字列を他方に変換するときの、最小の操作回数のことです。 入力:2つの文字列 Support と Suppose 出力:必要な最小変更回数:2 ア

  18. C++の文字列ライブラリを使って文字列照合を行うプログラムの実装方法

    この記事では、C++の文字列ライブラリ関数を活用して文字列照合(パターンマッチング)を行う方法を解説します。メイン文字列の中から部分文字列が出現する位置を取得するために、find()関数を使用します。find()メソッドは、指定した文字列が最初に見つかった位置を返すため、この関数を繰り返し呼び出すことで、すべての一致箇所を検出できます。なお、文字列が見つかった場合はその位置(インデックス)が返されますが、見つからなかった場合は string::npos が返されます。この仕組みを利用することで、検索の終了条件を簡単に判定できます。入力:メイン文字列 aabbabababbbaabb、部分文字列

  19. C++で大文字と小文字を区別せずに文字列を比較する方法

    C++の標準ライブラリには、文字列を扱うためのstringクラスが用意されています。この記事では、2つの文字列が同一であるかどうかを大文字と小文字を区別せずに判定する方法を解説します。ロジックは非常にシンプルです。まず、比較対象となる両方の文字列をすべて小文字(または大文字)に変換します。その後、変換済みの文字列同士を比較し、結果を返すだけです。文字列を小文字に変換する際には、<algorithm>ヘッダで提供されているstd::transform関数を使用します。これにより、文字列内の各文字に対して::tolowerを適用できます。入力と出力の例入力: 2つの文字列 Hello

  20. C++で文字列に部分文字列が含まれているか確認する方法|find()関数の使い方を解説

    ここでは、C++の標準文字列ライブラリ(std::string)を使って、メイン文字列の中に特定の部分文字列(サブストリング)が含まれているかどうかを確認する方法を解説します。検索には find() 関数を使用します。find() は、部分文字列が最初に出現する位置を返すため、この関数を繰り返し呼び出せば、メイン文字列内のすべての出現箇所を取得することができます。部分文字列が見つかった場合、find() はその位置(インデックス)を返します。一方、見つからなかった場合は特別な定数 string::npos を返します。したがって、「部分文字列がメイン文字列に存在するかどうか」を判定したい場合は

Total 5990 -コンピューター  FirstPage PreviousPage NextPage LastPage CurrentPage:31/300  20-コンピューター/Page Goto:1 25 26 27 28 29 30 31 32 33 34 35 36 37