C#でシーケンス(連番)から欠落している数字を検索する方法
C#で数値のリストから欠落している数字(連番の抜け)を見つける方法を解説します。LINQのEnumerable.RangeとExceptメソッドを組み合わせることで、シンプルかつ効率的に実装できます。
手順1:リストを作成する
まず、対象となる整数のリストを用意します。
List<int> myList = new List<int>(){1, 2, 3, 5, 8, 9};
手順2:最小値と最大値を取得する
次に、OrderByでリストを並べ替え、最初(最小値)と最後(最大値)の要素を取得します。
int a = myList.OrderBy(x => x).First(); int b = myList.OrderBy(x => x).Last();
手順3:完全な連番リストを生成し、差分から欠落した数字を抽出する
Enumerable.Rangeを使って最小値から最大値までの完全な連番リストを作成し、Exceptメソッドで元のリストとの差分を求めることで、欠落している数字だけを取り出せます。
List<int> myList2 = Enumerable.Range(a, b - a + 1).ToList(); List<int> remaining = myList2.Except(myList).ToList();
サンプルコード全体
using System.Collections.Generic;
using System;
using System.Linq;
public class Program {
public static void Main() {
List<int> myList = new List<int>(){1, 2, 3, 5, 8, 9};
Console.WriteLine("Numbers... ");
foreach(int val in myList) {
Console.WriteLine(val);
}
int a = myList.OrderBy(x => x).First();
int b = myList.OrderBy(x => x).Last();
List<int> myList2 = Enumerable.Range(a, b - a + 1).ToList();
List<int> remaining = myList2.Except(myList).ToList();
Console.WriteLine("Remaining numbers... ");
foreach (int res in remaining) {
Console.WriteLine(res);
}
}
}
出力結果
Numbers... 1 2 3 5 8 9 Remaining numbers... 4 6 7
ポイント
この手法では、最小値と最大値を取得する前にOrderByで並べ替えているため、元のリストがソートされていない場合でも正しく動作します。また、Exceptは集合演算を行うため、リスト内に重複する値が存在しても問題なく欠落分のみを抽出できます。
-
【C++】ソート済み配列から目標値に最も近い要素を検索する方法
n個の要素を持つソート済み配列Aがあるとします。この中から、指定された整数に最も近い値を見つけたいと思います。配列には重複した値や負の数が含まれている場合もあります。例えば、配列が [2, 5, 6, 7, 8, 8, 9] で目標値が 4 の場合、最も近い要素は 5 となります。解決のアプローチ配列を先頭から順に走査し、各要素と目標値の絶対差を記録しておき、最後に差が最小となる要素を返すという線形探索の方法もあります。しかし、配列がすでにソートされているため、二分探索(バイナリサーチ)を使えば O(log n) の時間計算量でより効率的に解くことができます。二分探索を用いた手順は以下の通りで
-
C++で有理数の最小公倍数(LCM)を求める方法
本記事では、有理数(分数)の最小公倍数(LCM)を求める方法を解説します。例えば、{2/7, 3/14, 5/3} という有理数のリストが与えられた場合、そのLCMは 30/1 となります。 有理数のLCMを求める公式 この問題を解くには、まずすべての分子のLCM(最小公倍数)を計算し、次にすべての分母のGCD(最大公約数)を計算します。有理数のLCMは、次の式で表されます。 $$LCM = \frac{すべての分子のLCM}{すべての分母のGCD}$$ 各分数の倍数となる有理数は、分子がすべての分子の公倍数であり、かつ分母がすべての分母の公約数である必要があります。その中で最小のものが「分子