0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

リストが連番かどうか判定する(C#)

Last updated at Posted at 2022-10-08

はじめに

 本記事はリストが連番かどうかを判定するC#のコードを考えたので私が備忘録的に残した記事です。もしよろしければお読みになった方のお役に立てたら嬉しいです。また、連番の中に欠番がある状態かどうかを判定するコードも書いてみたのでこちらもご参考ください。

追記:
 当初リストがソートされていないと連番だとは言えないという前提で記事を書いていたのですが、いただいたコメントから下記2ケースに分けて書きかえることにしました。ケースに合わせて需要のある方のコードをご参考いただければうれしいです

  • Listがソートされている状態で判定したい場合
  • Listが未ソートの状態でも判定したい場合

 またリストのサイズが0の時の判定結果はどうするのかという定義が曖昧でしたので、今回は「リストのサイズが0ならば連番だと判定しない」ということにしました。

Listがソートされている状態で判定したい場合

処理内容とソースコード

処理内容

 どんな処理手順で判定を行うかというアイデアについて書きます。

  1. 判定対象のリストが昇順にソートされているか調べる
  2. リスト内で重複した要素を削除したリストの長さと元のリストの長さが等しいか調べる
  3. 判定対象のリストの最大値と最小値の差が、判定対象のリストの長さ - 1と等しいか調べる
  4. 1. と2. と3. の真偽値がいずれも真であれば連番だと判定する
  5. 上記以外の場合に連番でないと判定する

 下記の方法でも良いかなと思っていたのですが、こちらの記事で書いたコードへの拡張性を持たせたかったので上記のアルゴリズムにしてみました。

  1. 判定対象の最小値と長さを取得
  2. この長さで最小値始まりのリストを新たに生成
  3. 新たに生成されたリストと判定対象のリストが等しいか判定する

ソースコード

Main.cs
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Main {
    /// <summary>
    /// 指定されたリストが連番かどうかを判定します。
    /// リストのサイズが0だとFalseと判定します。
    /// </summary>
    /// <param name="intList">判定対象のリスト</param>
    /// <returns>連番かどうかの真偽値</returns>
    public bool isSequence (List<int> intList) {
        return intList.Count() > 0
            && intList.OrderBy(element => element).SequenceEqual(intList)
            && intList.Distinct().Count() == intList.Count()
            && intList.Max() == intList.Min() + intList.Count() - 1
        ;
    }
}

Listが未ソートの状態でも判定したい場合

処理内容とソースコード

処理内容

 よろしければこちらのコメントをご参照いただければと思いますが、改めてこの節で想定している処理内容を整理しておきます。

  1. 判定対象のリストをHashSet化する(重複要素を省く)
  2. 上記のHashSetの最小値から最大値までの要素が、HashSet内が含まれているか逐次確認する
  3. 全要素が含まれていれば連番だと判定する
  4. 上記以外だと連番だと判定しない

ソースコード

Main.cs
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Main {
    /// <summary>
    /// 指定されたリストが連番かどうかを判定します。
    /// リストのサイズが0だとFalseと判定します。
    /// </summary>
    /// <param name="intList">判定対象のリスト</param>
    /// <returns>連番かどうかの真偽値</returns>
    public bool isSequence (List<int> intList) {
        var uniqueList = new HashSet<int>(intList);
        return uniqueList.Count() > 0
            && Enumerable.Range(uniqueList.Min(), uniqueList.Count).All(i => uniqueList.Contains(i));
    }
}

おわりに

 もっとうまい書き方あるかもですがもしよろしかったら何かのお役に立てていただければと思います。ちなみに当方ポーカーのゲームを作っておりましてその運びで連番かどうかを判定するアルゴリズムを考えておりました。
 またコメントくださった@shiracamusさんと@albireoさんほんとにありがとうございました!とても勉強になりました。

0
1
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?