2017-03-11 1 views
1

私は15,000のポインタを持っています。文字のマージソート

私はそのようなループ内でのソートマージ置く理由はアルファベット順ではなく、配列内の文字列内の各インデックス内の文字を並べ替えることで、コード

for (int x = 0; x < n;x++) 
{ 
    mergeSort(array[x],0,strlen(array[x]-1); 
} 

の小さなビットを持っています。

forループでマージソートを行うと効率が低下しますか?それは私にn log nの実行時間を失わせるだろうか?

+0

[X Y問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)のように聞こえます。文字列の配列内の各文字列の文字を並べ替える場合は、これで問題ありません。たとえば、 "apple"、 "hello"は "aelpp"、 "ehllo"に変わります。しかし、私はあなたの究極の目標ではないと思う。 – janos

+0

@janosと同じと思っています。おそらく、15,000の文字列をソートするのではなく、15,000個のポインターの配列をソートするためにmergesortを使用することが目標です。あなたはmergesort()のコードを投稿していないので、それがマージソートの最適な実装かどうかはわかりません。 – rcgldr

答えて

0

kを文字の総数とすると、時刻はn*k/n*log(k/n) = k*log(k/n)になります。 1つの配列内のすべての文字を持っていて、それらをすべて並べ替える場合(それはk*log(k))よりも速くなります。それを漸近的に良くする方法はありません。

実用的な観点から、あなたは別のソート方法を使用して

  • を考慮することができます。漸近的には同等ですが、一部のメソッドは短い配列ではパフォーマンスが向上する可能性があります(メモリのローカリティが向上しているなどの理由から、ここにはhttps://www.youtube.com/watch?v=fHNmRkzxHWs&t=52m36sがあります)。
  • マルチスレッドの使用。
0

マージソートは常にO(n * log_2(n))です。ここで、nはソートされている配列の長さです。この場合、それは文字列の長さです。それぞれの種類はO(n * log_2(n))になります。

しかし、あなたは、このように合計時間は、各弦のための時間の和である、文字列ごとに一回の並べ替えを繰り返している:

O(n1 * log_2(n1)) + O(n2 * log_2(n2)) + ... + O(nk * log_2(nk)) 

N1、N2、...、NKソートされているすべての文字列の長さです。

すべてのk文字列の長さがnであると仮定すると、このアルゴリズム全体がk * O(n * log_2(n))であると仮定します。

+0

ありがとうございました。私は言葉を比較している最速の実行時間は、並べ替えて比較することです。なぜ私のコードが凶悪な力よりも遅いのかまだ分かりません。ブルートフォースでは、k * O(n^2)があります。ここで、nは単語のサイズです。私は1,000,000の入力サイズを試しましたが、依然としてO(n^2)の時間が短くなっています。 – PaperCode46

+0

これらの複雑さはすべて漸近的である、つまりnが無限に近づくにつれて行動を表していることに注意してください。小さな値のnに対して 'O(n * log_2(n)) 'より速く実行する' O(n^2) 'アルゴリズムを持つことはかなり一般的です。 – Alexander

0

この場合、ある種の基数ソートを使ってO(n log n)を上回ることができます。例えば

、(文字列は本当に短い場合を除き)すべての文字を使用すると、次の操作を行うことができます1つのバイトであれば:

create an array of 256 ints 
for each string: 
    memset array to 0 (*) 
    loop through the bytes until zero is reached 
     for each byte increment the corresponding value in the array 
    loop through the array and write n characters with the value of current pos 
    (*) instead of memset, you could reset the values to zero in this loop 

これはまたに完全な文字列をスキャンしていstrlen()への呼び出しを排除長さを取得します。だからあなたはあなたの文字列を一回通過するような並べ替えをしています。

文字列には通常の文字と数字しか含まれていない場合は、より短い配列を使用できます。

文字列が実際には短い場合、上記と他のソートアルゴリズムにはオーバーヘッドがあります。代わりに、bubblesortでテストを行うことができます(はい) - 私はどこかで項目の数が少ない場合、バーストートを高速化することができます(数は6程度だと思います)。

もちろん、文字列がUnicodeの場合は、もう少し作業をする必要があります(ただし、例のコードを見るとそうは見えません)。

+0

「プレーンテキスト=アスキー=文字は8ビットです」ということは間違っているだけでなく、間違っています。あなたがまだその方法をプログラミングしているならば、信じていない医師病原菌でhttps://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ –

+0

@AntonínLejsekまあ実際に私はユニコードに関するいくつかのテキストを入力していましたが、回答を単純にするためにポストする前にもう一度削除しました。質問/回答はユニコードに関するアルゴリズムの詳細なので、質問のコードはシングルバイトも同様です。とにかく、標準ソートアルゴリズムを使用してUnicode文字(またはutf-8文字列)の配列をソートすることは常に問題になります。なぜなら、文字は異なるバイト数(UTF-16)でエンコードすることができ、 。 Btw、興味深いリンク、私はその記事を過去に何度も読んだ。 –

+0

私はあなたに絶対に同意する、私はちょうど元の答えでこの部分が不足していた。ローカライズされた文字列を扱うことができない非常に多くのソフトウェアがありますが、この悪は根絶されなければなりません。人々は、すべてのコードでchar-> 8bitを見ると、後でそれをプロダクションコードで使用するのは不思議ではありません。 –