学習内容について

 どうも、花粉症で鼻がヤバいことになっているしがないITエンジニアです。
連日雨が降っているにもかかわらず花粉が飛んでいるというのは何とも恐ろしいことだ。
病院嫌いなのだが、さすがに耳鼻科に行くべきか。。。

 導入はここまでにして問題を見ていこう。
なお、前の問題が見たい方は下記のリンクに移動してほしい。

与えられた正の整数より小さい最大の素数

 与えられた正の整数より小さい最大の素数を計算して出力するプログラムを書きなさい。

ヒント

ヒント

 単純に考えるなら2から与えられた正の整数まで順番に素数を求めていき、
一番大きい素数を記述すればいいということになる。

 素数の求め方としてはまず偶数は2以外はすべて素数ではないため除外してよい。
そのため、調査対象は主に奇数となる。
また、奇数の求め方は今まで求めてきた素数で割り切れるかどうかで判別可能だ。

 ちなみにその値が素数かどうかを求める場合は、
その値の平方根までをループ範囲に指定することで演算回数を減らせるが、
今回はその手法を使用できないかもしれない。

素数を求めるコード(ほぼ一つの解になるためできれば見ないように)

#include <vector>
#include <iostream>

using namespace std;

int main()
{

    unsigned int num = 0;
    cout << "正の整数を入力してください:";
    cin >> num;

    // 素数格納用
    vector<unsigned int> arr;

    // 予め2は入れておく
    arr.push_back(2);

    // 3から順番に素数を検索していく
    for (unsigned int i = 3; i < num; i += 2)
    {
        // i が素数の場合正
        bool prime_flag = true;

        // 今までに見つけた素数を基に素数を求める
        for (const auto& a : arr)
        {
            // i を a で割り切れる場合素数ではない
            if (i % a == 0)
            {
                prime_flag = false;
                break;
            }
        }

        // 素数だった場合は配列の末尾に登録
        if (prime_flag)
            arr.push_back(i);
    }
    // あとは一番最後に登録した素数を出力するだけ

    return 0;
}

解答

スポイラーのタイトル

bool is_prime(int const num)
{
	if (num <= 3)
	{
		return num > 1;
	}
	else if (num % 2 == 0 || num % 3 == 0)
	{
		return false;
	}
	else
	{
		for (int i = 5; i * i <= num; i += 6)
		{
			if (num % i == 0 || num % (i + 2) == 0)
			{
				return false;
			}
		}
	}

	return true;
}

int main()
{
	int limit = 0;
	std::cout << "Upper limit:";
	std::cin >> limit;

	for (int i = limit; i > 1; i--)
	{
		if (is_prime2(i))
		{
			std::cout << "Largest prime:" << i << std::endl;
			return 0;
		}
	}
}

解説

スポイラーのタイトル

 素数とは制の約数が1とそれ自身のみである正の整数です。
与えられた数より小さい最大の素数を求めるには、まず春日素数かどうかを判定する関数を書きます。その関数を使って、与えられた数より1だけ小さい数から始めて、数を減らしながら素数かどうか調べます。
最初の素数が最大の素数です。

最後に

 ヒントがただの別解になってしまった点に関しては申し訳なく思う。。。
筆者も解答を見ずに書いており、完全に意図していなかったので勘弁してほしい。

ただ、これに関しては解答がクレバー過ぎると思う。
あの無駄が無さすぎる素数の求める関数は知識が無いと作れる代物ではない。
筆者はその知識と技術力に嫉妬を覚えるより先に脱帽した。

By ta-boss

One thought on “[C++]Modern C++チャレンジの問題を解く~4問目~”

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です