現在高速検索のアルゴリズムを考えておりますが、
そこにデータの追加・削除が絡むと、
どのようにデータをまとめればいいのでしょうか?
例えば
------------ ------------ -------------
|data1|DATA1| |data2|DATA2| |data3|DATA3| ・・・
------------ ------------ -------------
と要素を2つ持ったデータが複数存在した場合、
dataの昇順リスト
----------------------------
|Index|各データの先頭アドレス|
----------------------------
|・
|・
|・
DATAの昇順リスト
----------------------------
|Index|各データの先頭アドレス|
----------------------------
|・
|・
|・
というそれぞれのリストを持たせれば、
dataで検索したい場合、DATAで検索したい場合、
各リストのIndex値を用いて2分探索すれば高速だと考えました。
しかしデータの追加・削除があればそれぞれのリストを
その度にソートし直さなければなりません。
もちろん追加・削除の度にデータ1つ分ずつずらしてやればいいだけですが、
基本的に使わない領域は解放したいですから、データ数の上限値が決まってない以上は
領域も確保されているとは限らないですから安易にデータをずらすことも出来ません。
データのずらしかたもどうでしょう?
リストに加えるor削除する箇所からその時の最大値までをコピーして
データ1つ分のサイズをずらして貼り付けるといった動作は、
連続した処理や排他的処理を考えると好ましくないのでしょうか?
もし根本的に高速検索と追加・削除の相性が良い手法があればご教授願います。
No.1ベストアンサー
- 回答日時:
Baranced-Tree (平衡木)を使えば良いのではないでしょうか?
平衡木 - Security Akademeia
http://akademeia.info/index.php?%CA%BF%B9%D5%CC%DA
No.8
- 回答日時:
>現在高速検索のアルゴリズムを考えておりますが、
何と比べて「高速」なアルゴリズムを考えておられる
のでしょうか?
目標をはっきりさせておかないと、既存の物より遅い
のか速いのかさえ判別できないと思いますが?
#高速検索にアセンブラを使用するという方法も一応
#ありますが....
No.7
- 回答日時:
蛇足ですけど^^
uya_15 さんは何度か質問を投げていらっしゃいますが、仕事としてプログラミングされているのなら、一度、アルゴリズム・データ構造の良書で勉強なさるのが、結局、早道で今後のためにもなるように思います^^
わたしは、古いテキストしか知りませんが、
・A.V.エイホ 他 著、大野義夫 訳『データ構造とアルゴリズム』培風館
・石畑清 著『アルゴリズムとデータ構造 (岩波講座 ソフトウェア科学)』岩波書店
などはいかがでしょう。A.V.エイホの『アルゴリズムの設計と解析』などもいいですが多少難しいですし、D.E.クヌースの『The Art of Computer Programming』はさらに難しいので、わたしはお薦めしません^^
いくつかの高速検索のためのアルゴリズムには目を通しまして、
ただしっかり勉強だけを出来る時間の余裕もなかったので、しっかり理解できたのは2分木探索くらいでした。
またこのアルゴリズムはこういう時に最適だ!というところまで読みきれなかったので、
調べながらその傍らで質問させてもらいました。
No.6
- 回答日時:
すみません。
参考にあげた URL では、<クローズドハッシュ>と呼んでいます^^;>『オープンハッシュ表(呼び方はいろいろ錯綜してるようですが)で持ってもいいと思います。』
No.5
- 回答日時:
あと、「基本的に使わない領域は解放したいですから…」とありますが、ちなみに、標準的な Unix 系のOSの malloc・free・realloc を使った実装は、free しても、システム自体に不要なメモリを返すわけではなく(プロセス自体の大きさは減少しない)、malloc・realloc で不要メモリの再利用ができるようにしているだけだと思います。
brk・sbrk などを使えば、システムにメモリを返す(プロセス自体の大きさが減少する)ことができると思いますが、そうするとたぶん、malloc・free・realloc (これらが内部で sbrk を使っていると思うので)は使えなくなるのでやめたほうがいいと思います。windows は知りませんけど^^;No.4
- 回答日時:
ご参考:
0. レコードを配列の要素として持つ必要がない。
1. レコードの記憶管理は別にする。
2. key、KEY 毎に一意にレコードが決まる。
3. key、KEY 毎に、ソート順に表示できたほうがいい。
とすると、以下のサンプルコードのようなやり方もあると思います。
1 で記憶管理も一緒にするとすれば insert・erase で new・delete するとか、2 でレコードが複数ある可能性があれば multimap にするとか、3 でソート順に表示しなくてもいい(ほとんど表示処理しないなら表示の際にソートして表示もいいですが)ならハッシュ表で実装してもいいですし。。まぁいろいろあると思いますけど^^
また、ソートされている必要がなく、レコードを配列要素として持つ必要がある(ただし、管理のためのメンバをレコードに追加できる場合)のなら、オープンハッシュ表(呼び方はいろいろ錯綜してるようですが)で持ってもいいと思います。
http://www-ui.is.s.u-tokyo.ac.jp/~takeo/course/2 …
ただ、すべて、主記憶に格納できる場合の話で、レコード・レコード数が巨大で外部記憶に格納しないとならない場合はまた別の方法によるのがいいと思います^^
===(key==data、KEY==DATA なら map でなくて set でいい)
#include <iostream>
#include <string>
#include <map>
#include <utility>
struct Record
{
std::string key;
double data;
int KEY;
std::string DATA;
};
std::map<std::string, Record *> map1;
std::map<int, Record *> map2;
Record *find(const std::string &k)
{
std::map<std::string, Record *>::iterator i = map1.find(k);
if (i == map1.end()) return 0;
return i->second;
}
Record *find(int k)
{
std::map<int, Record *>::iterator i = map2.find(k);
if (i == map2.end()) return 0;
return i->second;
}
bool insert(Record *r)
{
if (find(r->key) || find(r->KEY)) return false;
map1.insert(std::make_pair(r->key, r));
map2.insert(std::make_pair(r->KEY, r));
return true;
}
template<typename T> bool erase(const T &k)
{
Record *r = find(k);
if (!r) return false;
map1.erase(r->key);
map2.erase(r->KEY);
return true;
}
void print(const Record *r)
{
std::cout << r->key << '\t' <<
r->data << '\t' << r->KEY << '\t' << r->DATA << '\n';
}
void print1()
{
std::map<std::string, Record *>::iterator i = map1.begin();
while (i != map1.end()) {
print(i->second);
++i;
}
std::cout << '\n';
}
void print2()
{
std::map<int, Record *>::iterator i = map2.begin();
while (i != map2.end()) {
print(i->second);
++i;
}
std::cout << '\n';
}
#include <iostream>
int main()
{
Record recs[] = {
{ "yamada", 0.0, 0, "taro" },
{ "tanaka", 1.0, 1, "jiro" },
{ "sato", 2.0, 2, "saburo" },
{ "fujita", 3.0, 3, "taira" },
{ "suzuki", 4.0, 4, "muneo" },
};
std::size_t nrec = sizeof recs / sizeof recs[0];
for (int i = 0; i < nrec; ++i) insert(recs + i);
print1();
erase("fujita"); erase(1);
print2();
}
===
% ./a.out
fujita 3 3 taira
sato 2 2 saburo
suzuki 4 4 muneo
tanaka 1 1 jiro
yamada 0 0 taro
yamada 0 0 taro
sato 2 2 saburo
suzuki 4 4 muneo
No.3
- 回答日時:
ソートしている目的が単に検索のためだけであれば、検索項目毎のハッシュ表を持つのもいいと思いますよ。
ほかの用途に必要なのでソートされている必要があるのなら、検索項目毎にバランス木にするのがいいんじゃないでしょうか。お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- Excel(エクセル) Excel 値を返す数式についてです 3 2022/11/21 20:08
- その他(データベース) c言語の問題です。これを踏まえてコーディングしたいのでおしえていただきたいです。 3 2023/08/03 09:27
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Java 動かなくなったのでJavaソースを手直しお願いします。 2 2022/04/30 05:35
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 3 2023/02/28 01:13
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Excel(エクセル) VBAのoffsetの動き方について教えてください 3 2022/11/25 23:36
- その他(プログラミング・Web制作) pandasでまとめてインデックスを削除するにはどうすればいいですか? たとえば、以下のプログラムで 1 2022/07/31 23:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
多次元配列のソート方法
-
VB.NETでファイル名順にファイ...
-
あるディレクトリ内のファイル...
-
C# DataGridView のヘッダーセ...
-
線形リストのソートについて
-
プログラミングについて 配列を...
-
リスト構造のソートで悩んでま...
-
n個の要素で出来る順列組み合...
-
Excel VBA テキストボックス内...
-
Fortran77で多次元配列を並び替...
-
System.IO.Directory.GetFiles...
-
構造体配列の並べ替え
-
アルゴリズム
-
C++ 入力した3つのint型の整数...
-
DataGridViewでのソート制御
-
VB.NETでソートされたデータセ...
-
VBScriptで重複レコードを削除...
-
部分和問題がわかりません。
-
構造体配列のソート
-
2次元配列を複数項目でソートし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
VB.NETでファイル名順にファイ...
-
ファイル名「1.jpg ~10.jpg~...
-
excel VBA の条件をつけての列...
-
リスト構造のソートで悩んでま...
-
C# DataGridView のヘッダーセ...
-
DataGridViewの複数列を連動し...
-
文字列をソートする方法
-
C# DataTableの行をソートしてD...
-
C言語・要素除去
-
Excelですべての組合せ(重複組...
-
VBA基本構文の作り方 2列の...
-
列のどこをクリックしてもソー...
-
excel VBA リストビューの行...
-
あるディレクトリ内のファイル...
-
コレクションの数値をSortで並...
-
数字文字列のソート方法
-
VBScriptで重複レコードを削除...
-
2次元配列を複数項目でソートし...
-
10個の整数を入力して小さい順...
おすすめ情報