プロが教えるわが家の防犯対策術!

例えば、以下のように時間データがあるとします。データは、時系列順に並んでると限りません。
必ず、左がFrom時間、右がTo時間は成立します。
1 7:00~8:00
2 7:30~9:00
3 10:15~10:45
4 10:00~11:00
5 14:00~15:00
6 16:30~17:00
7 13:00~16:00

重複している時間を下記のように除去したいです。どのように時間を取得しても取得しても問題ありません。
ロジック的に可能でしょうか。

回答1例
1 7:00~9:00
2 10:00~11:00
3 13:00~17:00

回答2例
1 7:00~7:30
2 7:30~8:00
3 8:00~9:00
.
.
などなど

私が考えたロジックだと、下記のようにやってみましたがうまく動くと思いますか。
パターンの洗い出しができているかわからなくなってきました。
ほかに良い方法、スマートな方法などありますか。

1 7:00~8:00
2 7:30~9:00
3 10:15~10:45
4 10:00~11:00
5 14:00~15:00
6 16:30~17:00
7 13:00~16:00
8 6:00~7:30

①From時間を昇順に並べる
②先頭を基準とする。次のデータを対象データとする。
③対象のTo時間が基準データFrom時間より前の場合は変更しない。
④対象のFrom時間が基準データTo時間より後の場合は変更しない。
⓺対象のFrom時間が基準データFrom時間より後、かつ、
 対象のTo時間が基準データTo時間より後 の場合は、対象のFrom時間を基準のTo時間にする。
⑦対象のFrom時間が基準データFrom時間より後、かつ、
 対象のTo時間が基準データTo時間より前 の場合は、対象のデータを消す。
⑨対象のFrom時間が基準データFrom時間より前、かつ、
 対象のTo時間が基準データTo時間より後 の場合は、基準のデータを消し、対象のデータを基準とする。
⑧②~⑦の処理で下まで処理する。

(おそらく)処理結果

8 6:00~7:30
1 7:30~8:00
2 8:00~9:00
4 10:00~11:00
7 13:00~16:00
6 16:00~17:00

質問者からの補足コメント

  • from datetime import datetime as dt

    class TimeInfo:
    def __init__(self,From,To):
    self.From= From
    self.To = To

    dataInfos=[]

    dataInfos.append(TimeInfo(202201230700, 202201230800))
    dataInfos.append(TimeInfo(202201230730, 202201230900))
    dataInfos.append(TimeInfo(202201231015, 202201231045))
    dataInfos.append(TimeInfo(202201231000, 202201231100))

    No.3の回答に寄せられた補足コメントです。 補足日時:2022/01/23 14:03
  • dataInfos.append(TimeInfo(202201231400, 202201231500))
    dataInfos.append(TimeInfo(202201231630, 202201231700))
    dataInfos.append(TimeInfo(202201231300, 202201231600))
    dataInfos.append(TimeInfo(202201230600, 202201230730))

    dataInfos= sorted(dataInfos, key=lambda datetime: datetime.From) #①From時間で昇順に並べる。

    bx=0 #基準データの添え字をbxとする。最初はbx=0とする。
    kijunData=dataInfos[bx]

      補足日時:2022/01/23 14:03
  • for i in range(1,len(dataInfos)): #i = 1からN-1まで繰り返す。(④~⑥の繰り返し)
    if dataInfos[i].From > kijunData.To: #データ[i]のFrom時間>基準データのTo時間の場合、このデータをbx+1へ登録する。
    dataInfos[bx+1]=dataInfos[i]
    bx=bx+1 #bxに1加算。
    elif dataInfos[i].To>kijunData.To: #データ[i]のTo時間>基準データのTo時間の場合、
    #基準データのTo時間へデータ[i]のTo時間を設定  次の要素の繰り返しへ
    kijunData.To=dataInfos[i].To

      補足日時:2022/01/23 14:04
  • #データ[i]のFrom時間>基準データのTo時間の場合、このデータをbx+1へ登録する。
    こちらの意味を理解しきれずにサンプルを作ったのですが、どのデータに登録すればよいのでしょうか

      補足日時:2022/01/23 14:05

A 回答 (7件)

言語はなにを想定してますか。

    • good
    • 0
この回答へのお礼

あえて、言語は書きませんでしたがC#で書く予定です

お礼日時:2022/01/23 11:27

C#の環境がないので、コメントだけになります。



③このケースはあり得ないので考慮不要です。
(From時間で昇順に並んでいることが前提なので。)
FromがToより大きいケースはないものとします。

④これでOKですが、これは、そのまま、登録されるので、次のデータを
処理するときは、このデータが、基準データになります。

⑥対象のFrom時間は考量不要です。(From時間で昇順に並んでいることが前提なので。)
この場合、基準と対象を1つにまとめるので、
⑥-1 基準のTo時間へ対象のTo時間を設定する。
⑥-2 対象を削除する。
になります。

⑦OKですが、対象のFrom時間は考量不要です。(⑥と同様)

⑨このケースはあり得ません。(③と同様)

⑧次のデータを処理するときは、常に、登録済みの最後のデータを基準データとして扱うようにしてください。
データを登録する場合は、前詰で登録するようにしてください。
    • good
    • 0

コーディングイメージとしては、以下のようになります。


N件のデータがあるとします。(N>1)
①From時間で昇順に並べる。
②基準データの添え字をbxとする。
 最初はbx=0とする。
③i = 1からN-1まで繰り返す。(④~⑥の繰り返し)
④データ[i]のFrom時間>基準データのTo時間の場合、
 このデータをbx+1へ登録する。(bx+1==iの場合は同じ位置になるので登録不要)
 bxに1加算。
 次の要素の繰り返しへ(continue)
⑤データ[i]のTo時間>基準データのTo時間の場合、
 基準データのTo時間へデータ[i]のTo時間を設定
 次の要素の繰り返しへ
⑥残ったケースは削除対象のデータなので処理不要(次の要素の繰り返しへ)
⑦0~bxまでのデータを印字する。(求める結果)
この回答への補足あり
    • good
    • 0
この回答へのお礼

詳しく説明いただきありがとうございます。
正直、落とし込めれていないので、いったんtatsumaru77様が、
回答していただいたプログラムをpythonでサンプルに落とし込んでみます。

お礼日時:2022/01/23 13:31

そもそもデータはどういう状態なの?



CSVなどのファイル?
DataTable等の変数内?
データグリッドビュー?

とは言え初心者だけどね。
    • good
    • 0
この回答へのお礼

もともとは、CSVなどのファイルのイメージです。
それをプログラム上で取得して加工します。

お礼日時:2022/01/23 13:32

>#データ[i]のFrom時間>基準データのTo時間の場合、このデータをbx+1へ登録する。

こちらの意味を理解しきれずにサンプルを作ったのですが、どのデータに登録すればよいのでしょうか

下記の意味であっています。
dataInfos[bx+1]=dataInfos[i]

なにか、C#でなくpythonのような気がするのですが、気のせいでしょうか。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
スクリプトはpythonで記述しています。
C#でこちらのコードは実装予定ですが、tatsumaru77さんが回答いただいたロジックをいったんpythonで作成してみました。
こちらのコードを実行すると下記のようになり、思ったような値を取得できないのですが、処理が抜けてしまっているのでしょうか。
実行結果
From:202201230600 To:202201230900
From:202201231000 To:202201231100
From:202201231015 To:202201231045
From:202201231300 To:202201231600
From:202201231400 To:202201231500
From:202201231630 To:202201231700
From:202201231400 To:202201231500
From:202201231630 To:202201231700

お礼日時:2022/01/23 14:45

確かにコードはPythonですね。

    • good
    • 0

python3のコーディング例を下記にアップしました。


このサイトは投稿時インデントが崩れるので、下記にアップしてます。
https://ideone.com/3J1xJC

実行結果
202201230600 ~ 202201230900
202201231000 ~ 202201231100
202201231300 ~ 202201231600
202201231630 ~ 202201231700
    • good
    • 0
この回答へのお礼

コーディング方法まで修正いただきありがとうございます。
すごくシンプルで、問題解決できそうですね。
0~bxまでが取得したい値ということを理解しきれていませんでしたが、サンプルコードを見てわかりました。
ありがとうございます

お礼日時:2022/01/23 15:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!