web-dev-qa-db-ja.com

名前で「認識」して知っておくべきアルゴリズム/データ構造はどれですか。

自分はかなり経験豊富なプログラマだと思っています。私は5年以上プログラミングをしています。私の弱点は用語ですが。私は独学で学んでいるので、プログラミングの方法は知っていますが、コンピュータサイエンスのより正式な側面のいくつかは知りません。それで、名前で認識して知ることができる実用的なアルゴリズム/データ構造は何ですか?

注、アルゴリズムの実装に関する本の推奨を求めているのではありません。私はそれらを実装することは気にせず、アルゴリズム/データ構造が問題の良い解決策になる時期を認識できるようにしたいだけです。私が「認識」すべきアルゴリズム/データ構造のリストをもっと求めています。たとえば、私はこのような問題の解決策を知っています:

0〜999のラベルが付いたロッカーのセットを管理します。人々はロッカーを借りるためにあなたのところに来て、それからロッカーの鍵を返すために戻ってきます。どのロッカーが無料で、どのロッカーが使用されているかを管理するソフトウェアをどのように構築しますか?

解決策は、キューまたはスタックです。

私が探しているのは、「どのような状況でBツリーを使用する必要があるか-ここではどの検索アルゴリズムを使用する必要があるか」などです。アルゴリズムが機能します。

ウィキペディアの データ構造 および アルゴリズム のリストを見てみましたが、少々やり過ぎだと思います。それで、私が認識する必要がある本質的なことは何ですか?

69
Earlz

客観的な対応:

この質問に対する私の最初の回答は、CS学生の卒業生としての経験的経験と、CSの分野で一緒に働きたいと思っている人々のタイプについての私の予想した意見に基づいていました。実際には(ACM SIGCSEとIEEEコンピューティング学会の主観的な意見に関して)目的の答えがあります。 [〜#〜] acm [〜#〜][〜#〜] ieee [〜#〜] ボディは10年ごとに 学部のコンピュータサイエンスカリキュラムの提案を詳しく説明する共同出版物 コンピューティング業界の状態に関する専門知識に基づいています。詳細は cs2013.org にあります。委員会は カリキュラムの推奨事項をリストした最終レポート を発行します。

そうは言っても、私のリストはかなり良いと思います。

以下の元の回答


何を知っておくべきですか?

最小

熟練したプログラマーは、コンピューターサイエンスについて少なくとも学部レベルの知識を持っている必要があると思います。確かに、Computer Scienceの小さなサブセットのみで多くの仕事に効果を発揮できますほとんどの専門職。また、多くの人々は学部の研究の後にさらに専門化します。しかし、CSの基礎知識を知らないという言い訳にもなりません。

タイトルの質問に答えるために、学部のCS学生(熟練したプログラマーの基盤)が卒業時に知っておくべきことを次に示します。

データ構造

  • マシンデータ表現
    • 1、2の補数、および関連する演算
    • 単語、ポインタ、浮動小数点
    • ビットアクセス、シフト、および操作
  • リンクされたリスト
  • ハッシュテーブル(マップまたは辞書)
  • 配列
  • スタック
  • キュー
  • グラフ
  • データベース

アルゴリズム

  • 並べ替え:
    • バブルソート(それが悪い理由を知るため)
    • 挿入ソート
    • マージソート
    • クイックソート
    • 基数スタイルの並べ替え、カウントの並べ替え、バケットの並べ替え
    • ヒープソート
    • ボゴと量子ソート(=
  • 検索:
    • 線形検索
    • バイナリ検索
    • 深さ優先検索
    • 幅優先検索
  • 文字列操作
  • 反復
  • ツリートラバーサル
  • リストトラバーサル
  • ハッシュ関数
  • ハッシュテーブル、ツリー、リスト、スタック、キュー、配列、およびセットまたはコレクションの具体的な実装
  • スケジューリングアルゴリズム
  • ファイルシステムトラバーサルと操作(inodeまたは同等のレベル)。

デザインパターン

  • モジュール化
  • 工場
  • ビルダー
  • シングルトン
  • アダプタ
  • デコレータ
  • フライ級
  • 観察者
  • イテレータ
  • 州[マシン]
  • モデルビューコントローラー
  • スレッド化と並列プログラミングパターン

パラダイム

  • 命令的
  • オブジェクト指向
  • 機能的
  • 宣言的
  • 静的および動的プログラミング
  • データマークアップ

複雑さの理論

  • 複雑な空間
  • 計算能力
  • レギュラー、コンテキストフリー、ユニバーサルチューリングマシンの完全な言語
  • 正規表現
  • カウントと基本的な組み合わせ論

超えて

質問の後半で尋ねていることを理解するために、上記に精通している場合は、特定のシナリオに適したパターン、アルゴリズム、およびデータ構造を簡単に識別できるはずです。ただし、多くの場合、最善の解決策はないことを認識する必要があります。場合によっては、2つの悪の小さい方を選択するか、2つの同等に実行可能な解決策を単に選択する必要がある場合もあります。このため、あなたはあなたの選択をあなたの仲間から守るために一般的な知識が必要です。

アルゴリズムとデータ構造に関するいくつかのヒントを次に示します。

  • Binary Searchは、並べ替えられたデータに対してのみ使用できます(使用する必要があります)。
  • 基数スタイルの並べ替えは素晴らしいですが、並べ替えられる対象のクラスが有限である場合に限られます。
  • ツリーは、ハッシュテーブルと同様に、ほとんどすべてのものに適しています。ハッシュテーブルの機能を推定して使用すると、効率を犠牲にして多くの問題を解決できます。
  • 配列は、最も高いレベルのデータ構造をサポートするために使用できます。 「データ構造」は、配列内の場所にアクセスするための賢い計算に過ぎない場合があります。
  • 言語の選択は、髪の毛を引っ張ったり、問題を乗り越えたりすることの違いになる可能性があります。
  • ASCIIテーブルと128要素の配列は、暗黙のハッシュテーブル(=
  • 正規表現は多くの問題を解決できますが、それらは HTMLの解析には使用できません です。
  • 時々、データ構造はアルゴリズムと同じくらい重要です。

上記のいくつかは頭の悪い人のように見えないかもしれませんし、いくつかは曖昧に見えるかもしれません。もっと詳しくお聞きしたいのなら、できます。しかし、「文字列内のすべての文字の出現回数をカウントする関数を設計する」などのより具体的な質問に遭遇したときに、ASCIIテーブルと128個の要素の配列で、回答の適切な暗黙のハッシュテーブルを形成します。

これらのアイデアに基づいて、私はあなたの質問で概説されたロッカー問題の答えを提案します。


あなたの質問で提起された問題への回答。

これはあなたの質問への最良の答えではないかもしれませんが、あまり複雑なものを必要としない興味深い質問だと思います。そして、ロッカーが空いているかどうかを判断するために線形時間を必要とするキューまたはスタックを使用する時間の複雑さを確実に打ち破ります。

あなたは0-999のロッカーを持っています。これで、ロッカーの数が固定されているため、0〜999の範囲で衝突のないハッシュ関数を簡単に想像できます。この関数は単純にh(x) = x mod 1000です。今度は、[概念的に]整数キーと1000要素のchar配列の内容を値として使用してハッシュテーブルを作成します。顧客がロッカー78を使用するために予約し、78をハッシュ関数に入れて(78を返す)、その番号を配列のベースポインターに追加して、オフセット値が指す場所に真の値を格納します。同様に、 78が使用中かどうかを確認する必要がある場合は、その場所に格納されている値を読み取り、trueかどうかを確認します。

このソリューションは、バイナリツリーに基づく優先度キューの場合のlog(n)時間のストレージとルックアップとは対照的に、ルックアップとストレージの一定の時間で動作します。説明は意図的に冗長になっているので、より高い概念が効率的なアルゴリズムにまとめられているのがわかります。

さて、あなたが尋ねるかもしれません、もし私が利用可能なすべてのロッカーを知る必要があるなら、優先キューはもっと良いのではないでしょうか?優先度キューに利用可能なロッカーがk個ある場合、それらすべてを反復すると、kステップかかります。さらに、優先度キューの実装によっては、優先度キューをすべて再構築するときに再構築する必要がある場合があります。これにはk * log(k):(k <1000)ステップが必要です。配列ソリューションでは、1000要素の配列を反復処理して、開いている配列を確認するだけです。使用可能なリストまたは使用済みリストを実装に追加して、k回のみチェックインすることもできます。

78
David Cowden

スティーブン・S・スキエナによるアルゴリズム設計マニュアルは、あなたが探しているソースのようです。 2番目の部分は、関連するアルゴリズムのレビューに関する問題の分類されたリストです。 ウェブ版 があります。

6
AProgrammer

「すべき」はありません。 A.基本的な複雑さのクラス(線形、対数など)について理解します。B. Bツリーのような空想的なデータ構造でできるのと同じように、単純な配列でほとんど何でもできることを理解します。適切な構造/アルゴリズムを選択するコツは、パフォーマンス、予想される入力サイズ、実装の複雑さのバランスを取ることです。

次に、抽象的ですが非常に有用なものがあります(有用性はすぐにはわかりません)。状態マシン、グラフ理論、凸性理論(線形計画法など)です。

4
zvrba

MITは Introduction to Algorithms の講義ノート、ビデオ、課題、試験資料を無料で公開しています。 講義のタイトル は、対象となるアルゴリズム/データ構造のリストです。

これは、あなたが知っておくべきことについての peer-reviewed コンセンサスです。おそらく、これもすばらしい学習リソースです。

3
MarkJ