JavaのStringソートアルゴリズムのソースコード
I.はじめに
Q:選択肢は何ですか?
選択は、設定数Nが、Kの目によって最大値を決定することが想定されます。例えば、Aと大きいBのオブジェクトが必要ですか?別の例:配列から項目の最大数を見つけることを検討するには?
問題を解決する選択し、あなたが目標容量を持っている必要があり、それは、任意の2つのオブジェクトを比較し、小さいか等しいである大規模などの、決定することです。比較的長いオブジェクト(同等)容量、回覧オブジェクトリストに続いてアイテムの最大の問題は、解決策を見つけ、一つは解決することができます。
だから、JDKのソースコードは、それより多くの(同等の)能力を達成するためにどのように?
二、java.lang.Comparableとインタフェース
匹敵します
compareTo
自然の比較として知られている方法、。
インタフェースは唯一の方法であるpublic int compareTo(T o);
、それは見ることができます
- 基準T 0へ:比較する着信オブジェクトに対応するインタフェースクラスを実装
- 戻り値INT:未満と等しい、より大きいを表す、正、負、および0
セットリスト(コレクションリスト)またはオブジェクトの配列(配列)、だけでなく、簡単に使用することができ、対応するツール:
- java.util.Collections#ソート(リスト)リストの並べ替え
- java.util.Arrays#ソート(オブジェクト[])ソートされた配列
そのStringオブジェクトはどのように比較しますか?
三、文字列のアルゴリズムのソースコード
文字列のソース列JDK 1.0を見ることができます。1.2 JDKなければならないときに、StringクラスはComparableインタフェースを実装し、比較されているオブジェクトを渡す必要はStringです。図は、オブジェクト:
文字列は、最終的なクラスは、文字列から新しいクラスを拡張することはできませんです。ライン114から、ストレージ構造は、文字列(CHAR)アレイであることがわかります。まず、あなたは文字列の比較のケースを見ることができ、以下のように、コードは次のとおりです。
/**
* 字符串比较案例
*
* Created by bysocket on 19/5/10.
*/
public class StringComparisonDemo {
public static void main(String[] args) {
String foo = "ABC";
// 前面和后面每个字符完全一样,返回 0
String bar01 = "ABC";
System.out.println(foo.compareTo(bar01));
// 前面每个字符完全一样,返回:后面就是字符串长度差
String bar02 = "ABCD";
String bar03 = "ABCDE";
System.out.println(foo.compareTo(bar02)); // -1 (前面相等,foo 长度小 1)
System.out.println(foo.compareTo(bar03)); // -2 (前面相等,foo 长度小 2)
// 前面每个字符不完全一样,返回:出现不一样的字符 ASCII 差
String bar04 = "ABD";
String bar05 = "aABCD";
System.out.println(foo.compareTo(bar04)); // -1 (foo 的 'C' 字符 ASCII 码值为 67,bar04 的 'D' 字符 ASCII 码值为 68。返回 67 - 68 = -1)
System.out.println(foo.compareTo(bar05)); // -32 (foo 的 'A' 字符 ASCII 码值为 65,bar04 的 'a' 字符 ASCII 码值为 97。返回 65 - 97 = -32)
String bysocket01 = "泥瓦匠";
String bysocket02 = "瓦匠";
System.out.println(bysocket01.compareTo(bysocket02));// -2049 (泥 和 瓦的 Unicode 差值)
}
}
結果は以下の通りであります:
0
-1
-2
-1
-32
-2049
図から分かるように、compareTo
それは2つの文字列を辞書と比較することです。特定のルールの比較は、コードのコメントを見ることができます。次のルールを比較します。
- 各文字列は、0を返し、まったく同じです
- 文字列の各文字は、前のセクション、リターンとまったく同じである:長さの差は、二つの文字列の後ろにあります
- 各文字列は、フロント部分に存在する同じではありません、返す:ASCII文字が表示されるとの違いは、同じではありません
- リターンに対応する比較中国語Unicodeコード値(UnicodeはASCIIが含ま)
- 文字のASCIIコードでfoo「でC」は67です
- 文字のASCIIコードでbar04「D」は68です。
- foo.compareTo(bar04)は、67--68 = -1を返し
- 図に示すように、共通のASCII文字コード、
文字列を見てcompareTo
辞書順を達成するためにどのような方法。ソース・図:
次のようにソースに解釈しました:
- 行1156:現在の文字列と別の文字列、小さい方の長さの値LIMを取得
- 行1161:LIMは0(小さな非空の文字列)よりも大きければ、比較が開始されます
- 1164ライン:現在の文字列と文字とを比較することによって、その後別の文字列、。差が等しくない場合は、Unicodeエンコーディング値の2つの文字を返し
- 1169ライン:現在の文字列と文字とを比較することによって、その後別の文字列、。両者が等しい場合、二つの文字列の長さの差が返されます
だから、ソートするために、Comparableインタフェースを実装するより多くの機能を持っているようにしてください。このオブジェクトのリストを得る(及びアレイ)インターフェイスCollections.sort(とは、Arrays.sort)を介して注文することができます。
そこTreeSetのツリー構造(赤黒木)を使用して実装、コレクションの要素を並べ替えます。匹敵するこのインタフェースを実現するためにはどのようなものです
並べ替えを使用して、Comparableインタフェースを実装していない場合はまた、java.lang.ClassCastExceptionが、例外がスローされます。詳細はを見て、「Javaコレクション:三、HashSetの、TreeSetのと比較LinkedHashSetの」https://www.bysocket.com/archives/195
IVの概要
上記でも述べた、実際には、この比較は、いくつかの欠点があります:
- デフォルトの文字ケースを無視しないのcompareTo。あなたが無視したい場合は、compareToメソッドを再カスタマイズ
- 決定は二次元で比較することはできません。例えば、大きい2 * 3 * 3 1矩形と矩形を決定するために?
- 例えば、いくつかのクラスは、インターフェイスを実装することはできません。finalクラスは、新しいクラスを拡張することはできません。また、解決策があります:関数オブジェクト(関数オブジェクトを)
方法パラメータ:だけでなく、データを処理するクラスを定義し、クラスのインスタンスを渡します。転送するターゲットの内側にそれを置くことによって機能。多くの場合、関数オブジェクトと呼ばれるこのようなオブジェクト(目的球オブジェクト)
インターフェイスメソッドの設計では、
その挿入は、それを並べ替えますか?
記事のプロジェクト:
- JDK 1.8
- プロジェクト名:アルゴリズムコア学習
- プロジェクトアドレスします。https://github.com/JeffLi1993/algorithm-core-learning
I.はじめに
上記のソートアルゴリズムJavaのString源は、選択肢が何であるかに言えば、より多くの容量ものです。
選択は、設定数Nが、Kの目によって最大値を決定することが想定されます。この問題を解決するためのアルゴリズム。
アルゴリズムとは何ですか?
これは、いくつかのアルゴリズムのコレクション、命令の簡単なセット、指定された命令の簡単なセットです。重要な指標を決定するためのアルゴリズム:
- これで問題が解決するかどうか最初に。
- 結果が必要などのくらいの時間の問題を解決するために、つまり、時間を実行している第2のアルゴリズム。
- メモリなどがあり必要なスペース資源、。
作業プログラムを書くことは多くの場合、十分ではありません。大規模なデータが発生したので、実行時間が重要な課題です。
アルゴリズムの性能は、大きいO表記で表されます。Oマーク表記は精度が粗い、大きな相対成長率です。例えば2N及び3N + 2のために、O(N)です。それは、多くの場合、直線的な成長を言われて、指数関数的な成長、などということが多いが言われています
典型的な成長率
典型的なアプローチは、分割統治の性能を提供するために分割統治戦略の分岐です。
- 問題は、サブ部分である、再帰的にそれらを解決する2つのほぼ等しいサブ問題に分割されます。
- 治療一緒にパッチ適用の問題を解決し、再度実行する追加作業の少量の二つのサブステージは、最終的には全体の問題の解決策を得ました。
第二に、ソート
スケジューリング問題は、古いですが、人気のある質問となっています。暴露からACMは、今や各関わるアルゴリズム、いくつかのアルゴリズムまたはJDKのソースコードの読み物を動作させるには、多くの場合、ソートアルゴリズムが表示されています。
アレイ(または配列)のセットにアルゴリズムをソート降順(或いは昇順)順序に沿ってデータ配置を並び替えます。オーダーへの障害からこのようなデータを、どのようなメリット?
- アプリケーションレベル:問題を解決します。
- 最も簡単には最大または最小を見つけることです
- 一緒に「一緒に」問題の解決、すなわち、同じマーク要素
- プロジェクト内の2つの以上のファイルを一致させます
- キーコードによって情報を見つけます
- システムレベル:システムの昇順、システムのエントロピーを減らすために
(ドナルド・クヌースの古典的な「コンピュータプログラミングのアート」コンピュータプログラミングの(アート)ボリュームIII)
ウィキペディアで得られた情報へのアクセス:
メインメモリに完成し、配列決定、内部順序と呼ばれています。これは、ディスクや外部の仕分け外部ソートと呼ばれる他のストレージ並べ替えを完了する必要があります。プロフィール住所ます。https://en.wikipedia.org/wiki/External_sorting
前の「JavaのStringソートアルゴリズムのソースコードは」、java.lang.Comparableとインタフェースについて話しました。そうインターフェースは抽象型である、抽象メソッド(のcompareTo)の集合であり、インターフェイスで宣言。従ってタイプに属する同等のソートオブジェクトは、すなわち、同等のインタフェースを実現し、その後のcompareToソート比較達成オブジェクトのメソッドを呼び出します。
これらの条件下で呼ばれるソートは、比較(比較ベースのソート)に基づいてソート
第三に、挿入ソート
方言:ビッグベアーは、(a)は、ローからハイキュー(ソート)までの高さに合わせて2、3 ...クマを負担します。クマNはチームに参加し、この時間は、それが尾からチームを比較し始めました。それはフロントクマの高さ、交換位置との比較よりも低い場合、順次尾部から頭部に比べ&交換位置。Nが負担すべき場所への最終的な変更。これは、挿入ソートの原理です。
挿入ソート(挿入ソート)
- 最も簡単な種類の一つ。PS:バブルソートのように見えるが、学習のために推奨されていません
- N - 成る1回ソーティングプロセス。
- そのような要素がソートされている場合は、ソートは必要ありません。すなわち、N = 1(1 - 1 = 0)
- 現在の位置状態要素への最初の位置から各ソート保証は、ソートされます。
- 図:フォワード各要素を比較し、それらの位置で終端
/**
* 插入排序案例
* <p>
* Created by 泥瓦匠@bysocket.com on 19/5/15.
*/
public class InsertionSortingDemo {
/**
* 插入排序
*
* @param arr 能比较的对象数组
* @param <T> 已排序的对象数组
*/
public static <T extends Comparable> void insertionSort(T[] arr) {
int j;
// 从数组第二个元素开始,向前比较
for (int p = 1; p < arr.length; p++) {
T tmp = arr[p];
// 循环,向前依次比较
// 如果比前面元素小,交换位置
for (j = p; (j > 0) && (tmp.compareTo(arr[j - 1]) < 0); j--) {
arr[j] = arr[j - 1];
}
// 如果比前面元素大或者相等,那么这就是元素的位置,交换
arr[j] = tmp;
}
}
public static void main(String[] args) {
Integer[] intArr = new Integer[] {2, 3, 1, 4, 3};
System.out.println(Arrays.toString(intArr));
insertionSort(intArr);
System.out.println(Arrays.toString(intArr));
}
}
コード解析、次のように:
- 配列の2番目の要素からは、前方の比較を開始します。最初の要素よりも小さい、次にスイッチ位置
- 次いで、第三、第四など、比較の2番目の要素であれば...
- シーケンシングを完了するために、最後の要素を比較した場合
時間計算量は、最良のシナリオは、ソートが正しく配置されたことがO(N ^ 2)であることが条件決意サイクルを満たすことができないので、それは、O(N)であり、逆の順序で最も極端なアレイ、すなわち(OでありますN ^ 2)。したがって、アルゴリズムの時間複雑度は、O(N ^ 2)であります
、次のような結果をmainメソッドの実行:
[2, 3, 1, 4, 3]
[1, 2, 3, 3, 4]
そして、最適化について考え、それを最適化する方法でしょうか?
挿入ソートより前方より最適化バージョン。前半の比較、良くなる可能性が高い二点。特定のコード、自身が試すことができます
四の挿入ソート、ののArray.sortソース
達成するために自分自身をソートするために使用上の挿入アルゴリズムは、実際にはJDKのArray.sortは簡単にソートするための方法を提供します。次のようにケースのコードは次のとおりです。
/**
* Arrays.sort 排序案例
* <p>
* Created by 泥瓦匠@bysocket.com on 19/5/28.
*/
public class ArraysSortDemo {
public static void main(String[] args) {
Integer[] intArr = new Integer[] {2, 3, 1, 4, 3};
System.out.println(Arrays.toString(intArr));
Arrays.sort(intArr);
System.out.println(Arrays.toString(intArr));
}
}
、次のような結果をmainメソッドの実行:
[2, 3, 1, 4, 3]
[1, 2, 3, 3, 4]
それは、Arrays.sortは、それを達成する方法ですか?JDK 1.2ではアレイ、JDK 1.8バージョンソートアルゴリズムを最適化する際とき。次のように:
- 要素の数は、挿入ソートを使用して、47未満である場合
- 要素の数は、高速なソートを使用して、286未満の場合
- Timsort積分アルゴリズムのマージソートや挿入ソート
上記と同じ目的を達成するために挿入ソートアルゴリズムを統合し、我々はマージソートを参照してくださいソースコード。ここでは、ラインの説明で並ぶありません。
V.の概要
この問題を解決するためのアルゴリズム。必ずしも複数の問題を解決することがあり、問題を解決するためのアルゴリズムではありません。最適なソリューションを実現しています。挿入ソートは、それは簡単なことです
サンプルコード
読者は、以下の倉庫で、この記事の例を見ることができます:StringComparisonDemo文字列の比較ケースケース:
- Githubの:https://github.com/JeffLi1993/algorithm-core-learning
- Gitee:https://gitee.com/jeff1993/algorithm-core-learning
参考資料
- 「データ構造とアルゴリズム解析:(オリジナルブック第3版)を記述するためのJava言語」
- https://en.wikipedia.org/wiki/Unicode
- https://www.cnblogs.com/vamei/tag/%E7%AE%97%E6%B3%95/
- https://www.bysocket.com/archives/2314/algorithm