リストに使われていない番号を取得するには


take  2014-07-02 18:49:41  No: 46418

Delphiというよりアルゴリズムの問題になってしまうのですが

TListから派生するクラスを使って、様々な要素を管理しています。
レコードの識別には重複しない「ID」が使われています。

新しいレコードが追加されると「リストに使われていないID」を
探し出して使うのですが、その部分に無駄がありそうです。

リストが追加されるだけなら問題は無いのですが
削除された場合には、未使用となったIDも再使用も考えています。

単純に考えると下記方法なのですが
件数が増えると時間がかかりそうです。

もっとよい方法があるのでしょうか?

var
  i,j : Integer;
  f : Boolean;
begin
  result := -1;
  j := 0;
  while j < 999999 do begin // 仕様状の最大件数を指定
    f := False;
    for i := 0 to Count-1 do begin
      if Items[i].ID = j then begin
        f := True;
        break;
      end;
    end;
    if not f then begin
      result := j;
      exit;
    end;
    j := j + 1;
  end;
end;


tor  2014-07-02 19:16:29  No: 46419

とりあえずリストの件数をホ件とした時、ループ回数がアーーーーー×ホと掛け算になってしまうのは効率が悪いですね。
何とか掛け算にならない方法を考えてみましょう。

ひとまず思いつくのは、ノトの出現を別のデータで記録しておく方法です。
アョヲサまだ使われていないノトのテーブルヲサテスローョョケケケケケケンヲサを用意する
イョヲサリストをスキャンして、使われているノトをテから取り除く(ループホ回)
ウョヲサ終わったらテに残っている最初の要素を取り出す(ループ最大アーーーーー回)
これならループ回数は最悪でもホォアーーーーーと足し算で済みます。

テには集合型を使いたいところですが、アーーーー要素も格納できないのでかわりにヤツあたりを使うことにして……
そうすると、ウのステップはヤツョマツを使えば自分でループしなくて済みますね。
(マツを使うため、上に書いたのとは論理を反転して「使われているノト」を記録することにします)

ヲサヲサテコヲサヤツサ
ヲサヲサコヲサノサ

ヲサヲサテヲサコスヲサヤツョテサ
ヲサヲサ
ヲサヲサヲサヲサテョモヲサコスヲサアーーーーーサヲサッッヲサこれで全要素がーで初期化される
ヲサヲサヲサヲサッッヲサ使われているノトをすべて調べてアに設定
ヲサヲサヲサヲサヲサヲサコスヲサーヲサョテュアヲサヲサテロョノロンョノトンヲサコスヲサアサ
ヲサヲサヲサヲサッッヲサ使われていない(ーになっている)ノトを探す
ヲサヲサヲサヲサメヲサコスヲサテョマツサ
ヲサヲサ
ヲサヲサヲサヲサテョニサ
ヲサヲササ

スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーイィ水ゥ アーコイエコウー シ  スュアセシ上級者セ シッニセシノヘヌ ス「コッッョョョッッウョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン

さん、ありがとうございます。
使われているノトに印を付けて置いて
あとから印の付いていないのを探し出す

いい方法ですね。

イ重ループから、イ回のループで済みそうです。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーイィ水ゥ アーコイカコウケ  書込者ノト:ロ 」 ァ」ハノ

 ン

補足、ノトがすべて使われている(ヤツの要素がすべてア)の場合に
マツの結果がどうなるかヘルプには書いてありません。困りますね……

おそらくュアとかを返してくれるのではないかと思いますが、そうでない場合例えば
ィアゥヲサテの要素を一つ余分にとっておく
ィイゥヲサマツの返り値がその最後の余分な要素だったら、全部埋まっていると判定する
といった手順が必要になると思います。

まあ、ノトの最大値が決まっていて重複がないわけですから
実用上は「リストの件数ヲサスノトの最大数」で判定して弾けば済みますが。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーイィ水ゥ アアコイイコイエ シ  スュアセシ上級者セ シッニセシノヘヌ ス「コッッョョョッッウョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン

補足ありがとうございます。

そもそもはチトマで様々なデータベースにアクセスしているのですが
オートナンバーを使おうとすると謎のエラーが出るので
代わりに用意しているのが今回のアルゴリズムです。

さんの方式の他に何とかできないか自分でも考えてみました。
1.リストを「ノト」でソートする。
2.件数−1ループさせる。
3.ループ中で現在のレコードのノトと次のレコードのノトを比較
    現在ノトと次ノトの差が「1」でなければ「空きがある」ことから
    現在のノトを1つ増加した値を  空きノトヲサとする。

ソートさせるのは仕様外なのですが
これも試してみます。
スススススススススススススススススススススススススススススススススススススススス
ニコ 通りすがり
トコ イーアエッーキッーイィ水ゥ アカコウイコーオ  書込者ノト:ロ 」。・。。  ン

元々の要件がはっきりしないのであてずっぽうですが、
アョなんらかのハッシュアルゴリズムを使う
イョ管理対象の「レコード「のアドレスを使う
ウョ再利用しない仕様にして現在の要素数を新しい要素のノトとする
エョヌユノトをィそのままではないにしてもゥ使う
オョ現在日時のような重複する可能性の低い値を使う
カョちゃんとしたデータベースエンジンを使うィニツヲサナとかゥ
思いつくのはこれくらいか…
スススススススススススススススススススススススススススススススススススススススス
ニコ ム
トコ イーアエッーキッーイィ水ゥ アカコエーコウク  書込者ノト:ロ 「「 。 ン

基本的にノトがアから順に使用され、無意味に飛び飛びになる事がないのであれば
さんの方法にちょっと手を加え、使用中のノトの最大値と
最大値以下で使用されていないノトのリストを作っておけば
初期設定を除けば、ループする必要は無くなり
未使用リストに何もない時はノトの最大値まで連番になっているので
追加するノトは単純に最大値の次にすることができます。

例えば、目的のデータが
  アャイャウャオャカャキャクャアーャアアャアイャアエャアオ
だとしたら、未使用リストを
  エャケャアウ
としておき
最大ノトは15になります。
データを追加するときは、未使用リストの先頭の4を使用し
未使用リストから4を削除します。
未使用リストが空の状態ならば、最大ノトの次の16を使用し
最大ノトを16に更新します。
既存データを削除するときは、削除したノトを未使用リストに追加します。
未使用リストの管理工数が増えますが、未使用ノトを捜す時間は小さくなるでしょう。

もっとも、このノトに特別重要な意味がないのであれば
多少飛び飛びになっていても無視して構わないのではとも思いますが。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーイィ水ゥ アキコークコーク シ  スュアセシ上級者セ シッニセシノヘヌ ス「コッッョョョッッウョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン

通りすがりさん、どうもです。
ウョオョカはこちらでも考えてみました。
番号を日付や時間+シリアル番号みたいなのにするのは
やりやすくていいですね。

ムさん
未使用リスト、いいですね。
それも候補にしたいと思います。

それぞれ比較してどうなるかやってみたいと思います。
ありがとうございました。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーイィ水ゥ アキコークコエー シ  スュアセシ上級者セ シッニセシノヘヌ ス「コッッョョョッッウョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン
モコ 

解決し忘れました
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーキッーウィ木ゥ ーケコイクコエキ  書込者ノト:ロ 」。ィ ン

上のほうの数行しか読んでないので勘違いかもしれませんが、
配列を使ったら簡単にいきそうな気がします。

ヲサヲサヲサヲサヲサミヲサ宣言ヲサ
ヲサヲサヲサヲサトコヲサヲサローョョケンヲサヲササ

ヲサヤニアョニティモコヲサヤマゥサ

ヲサヲサコヲサラサ

ヲサヲサッッ初期化
ヲサヲサヲサヲサコスヲサーヲサヲサケヲサヲサ
ヲサヲサヲサヲサトロンヲサコスヲサァァサ
ヲサヲササ

ヲサヲサッッ適当に新規追加
ヲサヲサトローンヲサコスヲサァァサ
ヲサヲサトロインヲサコスヲサァァサ
ヲサヲサトロエンヲサコスヲサァァサ
ヲサヲサトロカンヲサコスヲサァァサ
ヲサヲサトロクンヲサコスヲサァァサ

ヲサヤニアョツアティモコヲサヤマゥサ

ヲサヲサコヲサラサ

ヲサヲサッッ追加
ヲサヲサヲサヲサコスヲサーヲサヲサケヲサヲサ
ヲサヲサヲサヲサヲサトロンヲサスヲサァァヲサヲサ
ヲサヲサヲサヲサヲサヲサトロンヲサコスヲサァァサ
ヲサヲサヲサヲサヲサヲサツサ
ヲサヲサヲサヲササ
ヲサヲササ

ヲサヲサッッリスト確認
ヲサヲサフツアョノョテサ
ヲサヲサヲサヲサコスヲサーヲサヲサケヲサ
ヲサヲサヲサヲサフツアョノョチィトロンゥサ

ヲサヤニアョツイティモコヲサヤマゥサ

ヲサヲサコヲサラサ

ヲサヲサッッ削除
ヲサヲサトロメィアーゥンヲサコスヲサァァサ

ヲサヲサッッリスト確認
ヲサヲサフツアョノョテサ
ヲサヲサヲサヲサコスヲサーヲサヲサケヲサ
ヲサヲサヲサヲサフツアョノョチィトロンゥサ


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加