C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でNより小さい「0と1のみで構成される数」を数える方法


問題概要

整数 N が入力として与えられたとき、N 未満の整数のうち、各桁が 0 と 1 のみで構成された数(いわゆる2進数のように見える数)がいくつあるかを求めるのが、この問題の目標です。
たとえば入力 N が 12 の場合、条件を満たすのは 1、10、11 の3つであるため、答えは 3 となります。

入出力例

例1

入力:

N=100

出力:

Nより小さい2進数字のみの数の個数 − 4

説明:

条件を満たす数は − 1, 10, 11, 100

例2

入力:

N=120

出力:

Nより小さい2進数字のみの数の個数: 7

説明:

条件を満たす数は: 1, 10, 11, 100, 101, 110, 111

プログラムのアプローチ

この手法では、整数型の vector「vec」を使用します。まず vec に 1 を push します。次の2進数的な数を生成するには、vec の末尾の数(temp、初期値は 1)を取り出し、temp×10temp×10+1 を新しい候補として追加していきます。これは、該当する数が必ず 1, 10, 11, 100, 110, 111 … という順序で並ぶためです。あとは vec から数を順に取り出し(pop)、その数が N 以下であればカウントを増やしていきます。

アルゴリズムの手順

  • 整数 N を入力として受け取ります。
  • 関数 Smaller_N(int N) が N を受け取り、条件を満たす数の個数を返します。
  • カウント変数を 0 で初期化します。
  • 0 と 1 のみを含む整数を格納するために、整数型の vector「vec」を用意します。
  • vec.push_back(1) によって 1 を vector に追加します。
  • while ループで vec を走査し、最後に push された要素を temp=vec.back() として取得し、vec から削除します。
  • temp<=N であればカウントを +1 し、次の2進数的な整数として temp*10 と temp*10+1 を生成して vec に追加します。
  • while ループが終了したら、カウントを結果として返します。

この方法は幅優先探索(BFS)のようなイメージで数を順次生成していくため、N を超えた候補はそれ以降展開されず、探索が自然に打ち切られる点がポイントです。

C++での実装例

#include <bits/stdc++.h>
using namespace std;
int Smaller_N(int N){
    int count = 0;
    vector<int> vec;
    vec.push_back(1);
    while (!vec.empty()){
        int temp = vec.back();
        vec.pop_back();
        if (temp <= N){
            count++;
            int temp_2 = temp * 10;
            vec.push_back(temp_2);
            vec.push_back(temp_2 + 1);
        }
    }
    return count;
}
int main(){
    int N = 1000;
    cout<<"Count of Binary Digit numbers smaller than N are: "<<Smaller_N(N);
    return 0;
}

出力

上記のコードを実行すると、次の出力が得られます。

Count of Binary Digit numbers smaller than N are: 8

まとめ

vector をキューのように使うことで、「0 と 1 のみで構成される数」を小さい順に効率よく生成し、N との比較だけで個数を求められます。桁が 0 と 1 しかないという性質を活かした、シンプルで分かりやすいアルゴリズムと言えるでしょう。

  1. C++で高さhの平衡二分木(バランス木)の総数を求める方法

    本記事では、二分木の高さHが与えられたとき、その高さを持つ平衡二分木(バランスの取れた二分木)が何通り存在するかをC++で求める方法を解説します。 二分木とは 二分木(バイナリツリー)とは、各ノードが最大2つの子ノード(左の子と右の子)を持つ木構造のデータ構造です。 高さ平衡二分木とは 高さ平衡二分木(height-balanced binary tree)とは、すべてのノードにおいて、左部分木と右部分木の深さの差が0または1しかない二分木として定義されます。つまり、どのノードを見ても、左部分木と右部分木の高さの差は最大で1である必要があります。 次の図は、高さh=3の場合に考えられる高さ平衡

  2. C++で1〜Nの数の合計がSになる最小個数を求める

    問題文1からNまでのN個の整数と、ある整数Sが与えられます。使用できる各数はN以下という制約のもとで、合計がSになるために必要な「数の個数」の最小値を求めて出力してください。例n = 7、s = 10 の場合、必要な数は最小で2個です。たとえば、次のような組み合わせが考えられます。(7, 3) (6, 4)アルゴリズム合計Sをできるだけ少ない個数で作るには、大きな数(最大でN)を優先的に使えばよいことが分かります。したがって、答えは次の式で計算できます。S % N > 0 のとき : (S / N) + 1 S % N == 0 のとき : S / Nつまり、これは「SをNで割った値の切