-
バイナリ文字列を並べ替えて、指定したインデックス範囲の値を最大化するには?(C/C++)
問題の概要0と1のみで構成される文字列が与えられ、さらに互いに重ならないM個の区間 [A1, B1], [A2, B2], …, [AM, BM](A ≤ B)が与えられます。どの2つの区間も交差しません。形式的には、任意の有効な i, j(i ≠ j)に対して、Ai < Bj または Bj < Ai が常に成り立ちます。この課題では、次の2つの条件を同時に満たすような妥当な並べ替え(順列)を見つけることが求められます。M個の与えられた区間に含まれる数値(1)の合計が最大になること。文字列全体が辞書順で最大になること。たとえば「1100」は「1001」よりも辞書順で大きな文字列です
-
C/C++で実装するBarabási-Albertグラフ(スケールフリーモデル向け)とは?
バラバーシ・アルバート(BA)モデルとは バラバーシ・アルバート(BA)モデルは、スケールフリーネットワークを生成するために提案された複数のモデルの一つとして扱われています。このモデルは、「成長(growth)」と「選択的接着(preferential attachment)」という2つの重要な概念を組み合わせたものです。どちらの概念も、現実のネットワークに広く見られる性質です。 成長(Growth) 「成長」とは、ネットワーク内のノード数が時間の経過とともに増加していくことを意味します。 選択的接着(Preferential Attachment) 「選択的接着」とは、すでに多くの接続を持つ
-
C/C++の算術加算でオーバーフローが起きる仕組み|2の補数による検出方法
2の補数とは2の補数(2s Complement)は、コンピュータアーキテクチャにおいて最も広く採用されている符号付き整数の表現方式です。Nビットの2の補数システムでは、-2n-1 ~ 2n-1-1 の範囲の整数を表現できます。具体例は以下の通りです。4ビットの場合: -8 ~ 75ビットの場合: -16 ~ 15オーバーフローが発生する仕組み2つのNビットの2の補数を加算した結果が、Nビットで表現できる範囲を超えると「オーバーフロー」が発生します。コンピュータ内部には固定長のNビットレジスタが搭載されており、2つのNビット数の加算結果は最大でもN+1ビットになります。この余分な1ビットはキャ
-
【C言語】UDPソケットを使ったファイル転送プログラムの実装方法
C言語によるソケットプログラミングを利用すると、2台のコンピュータ間でデータをやり取りできるようになります。中でもユーザーデータグラムプロトコル(UDP)とシンプルなクライアント/サーバー構成を組み合わせれば、ファイルの送受信も比較的簡単に実現できます。 本記事で紹介するプログラムの基本的な仕様は以下のとおりです。 セキュリティ:暗号化によってデータを保護します。 プロトコル:UDP(User Datagram Protocol) 暗号化方式:XOR暗号 アルゴリズムの流れ サーバーを起動し、クライアントからのファイル名を待ち受けます。 クライアントが取得したいファイル名を送信します。
-
C言語で整数をローマ数字に変換する方法
はじめに本記事では、C言語を用いて10進数の整数をローマ数字に変換するプログラムの作成方法を解説します。対象となる数値nは、1以上4000以下の範囲を想定しています。ローマ数字の一覧まず、基本となるローマ数字とその対応する数値を確認しておきましょう。数値ローマ数字1I4IV5V9IX10X40XL50L90XC100C400CD500D900CM1000M4000MMMM例えば、n = 859 の場合、そのローマ数字表現は DCCCLIX となります。変換アルゴリズムの考え方この問題は、「貪欲法(グリーディ法)」と呼ばれる手法と再帰処理を組み合わせることで効率的に解くことができます。具体的な手
-
C/C++で中括弧を使わずに2次元行列を整形して出力するテクニック
本記事では、C/C++プログラミングにおいて中括弧(波括弧)を使用せずに、2次元行列を整形して出力する方法を解説します。中括弧 { } は、プログラミング言語における区切り文字であり、コードブロックやスコープを定義するために使われます。C/C++では、中括弧がないとスコープの範囲を明確にすることが難しくなります。しかし、条件演算子や配列の添字を工夫することで、ループ本体を中括弧なしで記述し、すっきりとしたコードを実現できます。まずは、基本的な2次元行列の出力コードとその実行結果を見てみましょう。基本例:中括弧を使った通常の書き方#include <iostream> using n
-
C言語のスレッドを使って「1 2 3」を無限に出力する方法
Cプログラミング言語では、スレッド(thread)を活用することで、「1 2 3」という数列を無限に繰り返し出力することができます。本記事では、pthreadライブラリを使用した具体的な実装方法を解説します。まず、今回作成するコードの出力例を見てみましょう。1 2 3 1 2 3 1 2 3 1 2 3実装の考え方この出力を実現するには、C言語で並行して動作する3つのスレッドを使用します。各スレッドは共有変数の値を監視し、自分の番が回ってきたときだけ数字を出力する仕組みです。具体的な設計ポイントは以下のとおりです。1に初期化された共有変数を用意し、その値は直前の値に基づいて更新していく各スレッ
-
C言語でパスワードの文字を*(アスタリスク)に置き換えて表示する方法
この問題では、パスワードの文字列が与えられ、その各文字の代わりに *(アスタリスク)を表示することが求められます。これは、実際のログイン画面などでパスワード入力時に文字が見えないようにマスク処理する動作と同じ仕組みです。問題の例入力:password出力:********解決のアプローチこの問題を解くには、以下の手順に従います。まず、入力されたパスワードの長さを取得します。次に、パスワードの文字数だけループ処理を行い、各文字の代わりに * を1つずつ出力します。つまり、パスワード自体の内容をそのまま表示するのではなく、文字数と同じ数のアスタリスクを出力することで、元の文字列を隠しながら長さの情
-
C言語の事前定義識別子__func__とは?使い方とサンプルコードを解説
識別子とは識別子(identifier)とは、プログラム内の変数や関数などの実体を識別するために付ける名前のことです。通常、識別子はプログラマが作業効率を高めるために自分で定義しますが、言語にあらかじめ組み込まれている「事前定義識別子」も存在します。C++のcoutやcinなどがその代表例です。本記事では、C言語に用意されている事前定義識別子の一つである__func__について詳しく解説します。__func__の正式な定義C規格における__func__の正式な定義は次の通りです。「翻訳処理系は、各関数定義の開き波括弧の直後に、あたかも次の宣言が存在するかのように、識別子__func__を暗黙的
-
C/C++における配列の関数への渡し方を解説
このチュートリアルでは、配列が関数へどのように渡されるのかについて詳しく解説します。 C/C++において、配列を関数に渡す際には、配列そのものがコピーされるのではなく、ポインタとして渡されます。つまり、配列の先頭要素のアドレスが関数に引き渡されることになります。そのため、関数の内部で sizeof 演算子を使って配列のサイズを求めると、元の配列全体のサイズではなく、ポインタ自体のサイズが返される点に注意が必要です。 サンプルコード #include <stdio.h> // 配列をポインタとして渡す void fun(int arr[]){ unsigne
-
C/C++におけるベクトル(vector)の仕組みを徹底解説
本記事では、C/C++におけるベクトル(vector)データ構造の仕組みについて、サンプルコードを交えながら分かりやすく解説します。 ベクトルとは何か ベクトルは、標準的な配列を拡張したコンテナ型のデータ構造です。通常の配列は宣言時にサイズが固定されてしまうため、後から要素数を増減させることはできません。そのため、従来のプログラミングでは、容量が不足するたびにより大きな新しい配列を作成し、既存の要素をすべてコピーし直すという手間が発生していました。 一方、ベクトルは実行時にサイズを動的に変更できる点が大きな特徴です。ユーザーの要求に応じて柔軟に拡張・縮小が可能であり、この仕組みによって配列の再
-
LinuxのGCCコンパイラに「graphics.h」C/C++ライブラリを追加する方法
このチュートリアルでは、Linux環境のGCCコンパイラに「graphics.h」C/C++ライブラリを追加する方法を解説します。「graphics.h」はかつての教育用C言語環境で広く使われてきたグラフィックス描画用のヘッダファイルですが、LinuxのGCCには標準で含まれていません。これを使用するには、libgraphパッケージをコンパイルしてインストールする必要があります。 1. 必要なパッケージのインストール まず、ビルドツール一式のbuild-essentialと、libgraphが依存する外部ライブラリをインストールします。ターミナルを開いて、以下のコマンドを順に実行してください。
-
C/C++でセミコロン(;)を使わずにセミコロンを出力する方法
このチュートリアルでは、C/C++においてセミコロン(;)を一切記述せずにセミコロンを出力するプログラムについて解説します。一見不可能に思えますが、これを実現する方法は主に2つあります。ひとつはセミコロンのASCII値を利用する方法、もうひとつはユーザー定義マクロを利用する方法です。セミコロンのASCII値は「59」であることを利用すると、文字リテラル ; を直接書かなくても出力が可能になります。それぞれの方法を見ていきましょう。方法1:putchar() 関数を使うputchar() 関数は、指定したASCIIコードに対応する1文字を標準出力に書き出します。引数として 59 を渡すことで、セ
-
C/C++で算術演算子を使わずに2つの整数を加算する方法を解説
このチュートリアルでは、C/C++において算術演算子(+、-など)を使わずに2つの整数を加算する方法について詳しく解説します。算術演算子を使用せずに加算を実現するには、主に以下の2つのアプローチがあります。ポインタを利用する方法ビット演算子を利用する方法それぞれの仕組みと実装例を見ていきましょう。方法1:ポインタを使った加算C言語では、配列の添字アクセス p[b] は内部的に *(p + b) として解釈されます。つまり、ポインタに対する添字操作には暗黙的にアドレスの加算が含まれています。この性質を利用すると、明示的に + 演算子を書かなくても加算を実現できます。サンプルコード#include
-
C/C++のスレッド関数とは?pthreadによる並行処理の基本を解説
このチュートリアルでは、C/C++におけるスレッド関数の基本的な使い方を、実際のサンプルプログラムを通じて解説します。 スレッド関数を利用すると、複数の処理を同時(並行)に実行できます。これらの処理は互いに依存し合っていても、まったく独立していてもどちらでも構いません。POSIXスレッド(pthread)ライブラリを使えば、マルチスレッドプログラミングを手軽に実装できます。 サンプルコード #include <pthread.h> #include <stdio.h> #include <stdlib.h> void* func(void* arg){
-
C/C++プログラミングにおけるcontinue文の使い方を解説
このチュートリアルでは、C/C++におけるcontinue文の動作について詳しく解説します。 continue文はループ制御文の一つです。break文がループ自体を終了させるのに対し、continue文は現在の反復処理における残りのステートメントをスキップし、次の反復(イテレーション)へ処理を強制的に移す働きを持っています。 continue文とbreak文の違い break文:ループ全体を終了し、ループの外へ抜けます。 continue文:現在の回だけをスキップし、ループ処理は継続されます。 また、continue文の後の処理の流れは、ループの種類によって少し異なります。 for文の
-
C/C++で文字列を整数配列に変換する方法
本記事では、C/C++においてカンマ区切りの数値文字列(例:「2, 6, 3, 14」)を整数型の配列へ変換する方法を解説します。文字列操作と数値変換は、競技プログラミングや入力データの解析など、さまざまな場面で役立つ基本テクニックです。 基本的な考え方 変換の流れは以下のとおりです。 結果を格納するための新しい配列(ここではstd::vector)を用意する 与えられた文字列を先頭から1文字ずつ走査する 文字がカンマ「,」なら、それまでに組み立てた数値を配列へ追加し、次の要素へ移る 文字が数字なら「現在の値 × 10 + 新しい桁」で数値を組み立て続ける 空白などの区切り文字は読み飛ばす
-
C/C++で文字列を数値に変換する方法|sscanf()とstoi()の使い方を解説
この記事では、C/C++において文字列を数値へ変換する方法について詳しく解説します。文字列として入力された数字データを、計算や処理に使える数値型へ変換することは、プログラミングの基本操作の一つです。C/C++では主に以下の2つの方法で文字列から数値への変換が行えます。方法1:sscanf()を使う(C言語スタイル)sscanf()は、標準入力から読み込むscanf()と違い、指定した文字列からフォーマットに従って値を読み取る関数です。C言語から使える伝統的な手法で、C++でも引き続き利用できます。サンプルコード#include<stdio.h> int main(){
-
C/C++のセグメンテーションフォルト(コアダンプ)とは?主な原因と具体例を解説
本記事では、C/C++プログラミングにおける「コアダンプ(セグメンテーションフォルト)」について、その発生原因と具体的なコード例を交えてわかりやすく解説します。 セグメンテーションフォルトとは セグメンテーションフォルト(Segmentation Fault)とは、プログラムが許可されていないメモリ領域にアクセスしようとした際に、OSがプログラムを強制終了させる現象です。実行時エラーの中でも特によく発生するもので、「core dumped(コアダンプ)」というメッセージとともに表示されることから、この名前で広く知られています。 主な発生原因としては、次のようなケースが挙げられます。 読み取
-
C/C++プログラムでディレクトリ(フォルダ)を作成する方法
はじめに このチュートリアルでは、C/C++プログラムを使って新しいディレクトリ(フォルダ)を作成する方法について解説します。 ディレクトリの新規作成には、dir.h ヘッダーで定義されている mkdir() 関数を使用します。この関数は、引数に指定した名前のディレクトリを作成し、成功した場合は 0 を、失敗した場合は -1 を返します。 注意: 本記事で紹介するコードは、Windows 環境のコンパイラ(Turbo C++ など)向けです。Linux や macOS ではヘッダーファイルや関数の仕様が異なるため、そのままでは動作しない点にご留意ください。 サンプルコード #include