গ্যালাপ অনুসন্ধান মার্জ: ও (লগ (এন) * লগ (আই)) ও (এন) এর পরিবর্তে
আমি মন্তব্যগুলিতে গ্রেইয়ার্ডের পরামর্শটি এগিয়ে গিয়ে প্রয়োগ করেছি। বেশিরভাগ কারণেই আমার এই কোডটির একটি অত্যন্ত দক্ষ মিশনের সমালোচনামূলক সংস্করণ প্রয়োজন।
- কোডটি একটি গ্যালাপ অনুসন্ধান ব্যবহার করে যা হে (লগ (i)) যেখানে আমি বর্তমান সূচক থেকে দূরত্ব যেখানে প্রাসঙ্গিক সূচক বিদ্যমান।
- গ্যালপ অনুসন্ধান যথাযথ, ব্যাপ্তি সনাক্ত করার পরে কোডটি বাইনারি অনুসন্ধান ব্যবহার করে। যেহেতু গ্যালাপ এটিকে একটি ছোট পরিসীমাতে সীমাবদ্ধ করেছে ফলাফলযুক্ত বাইনারি অনুসন্ধানগুলি ও (লগ (i))
- গ্যালাপ এবং মার্জ পিছনের দিকে সঞ্চালিত হয়। এটি মিশনকে গুরুত্বপূর্ণ বলে মনে হচ্ছে না তবে এটি অ্যারেগুলিকে মার্জ করার অনুমতি দেয়। যদি আপনার অ্যারেগুলির একটিতে ফলাফলের মানগুলি সংরক্ষণ করার জন্য পর্যাপ্ত জায়গা থাকে তবে আপনি কেবল এটি মার্জ করা অ্যারে এবং হিসাবে ব্যবহার করতে পারেন ফলাফল অ্যারে । আপনার অবশ্যই এ জাতীয় ক্ষেত্রে অ্যারের মধ্যে বৈধ পরিসরটি নির্দিষ্ট করতে হবে।
- সেক্ষেত্রে এটির জন্য মেমরি বরাদ্দ প্রয়োজন হয় না (সমালোচনামূলক ক্রিয়াকলাপগুলিতে বড় সঞ্চয়)। এটি কেবল নিশ্চিত করে যে এটি কোনও অ-প্রক্রিয়াজাত মানগুলিকে ওভাররাইট করতে পারে না এবং (যা কেবল পিছনের দিকে করা যায়)। আসলে, আপনি ইনপুট এবং ফলাফল উভয়ের জন্য একই অ্যারে ব্যবহার করেন। এটি কোনও খারাপ প্রভাব ফেলবে না।
- আমি ধারাবাহিকভাবে Integer.compare ব্যবহার করেছি () যাতে এটি অন্য উদ্দেশ্যে স্যুইচ করা যায়।
- এর আগে এমন কিছু সুযোগ রয়েছে যা আমি পূর্বে প্রমাণিত তথ্যগুলি সামান্য প্রচার করতে এবং ব্যবহার না করে থাকতে পারি। যেমন দুটি মানের ব্যাপ্তিতে বাইনারি অনুসন্ধান করা, যার জন্য একটি মান ইতিমধ্যে পরীক্ষা করা হয়েছিল। মূল লুপটি বলার আরও ভাল উপায় থাকতে পারে, যদি ক্রমিকভাবে দুটি ক্রিয়াকলাপে একত্রিত করা হয় তবে ফ্লিপিং সি মানটির প্রয়োজন হবে না। যেহেতু আপনি জানেন যে আপনি একটি করতে হবে অন্য সময় প্রতি সময়। কিছু পালিশের জন্য জায়গা আছে।
ও (লগ (এন) * লগ (আই)) ও (এন) এর পরিবর্তে সময়ের জটিলতার সাথে এটি করার সবচেয়ে কার্যকরী উপায় হওয়া উচিত । এবং ও (এন) এর সবচেয়ে খারাপ ক্ষেত্রে সময়ের জটিলতা। যদি আপনার অ্যারেগুলি ঝাঁঝরা হয়ে থাকে এবং মানগুলির দীর্ঘ স্ট্রিং একসাথে থাকে তবে এটি এটি করার জন্য অন্য কোনও উপায়ে বামন হবে, অন্যথায় এটি তাদের চেয়ে ভাল হবে।
মার্জিং অ্যারের শেষে এটি দুটি পড়ার মান এবং ফলাফল অ্যারের মধ্যে লেখার মান রয়েছে। কোন শেষ মানটি কম তা সন্ধান করার পরে, এটি অ্যারেটিতে গ্যালাপ অনুসন্ধান করে। 1, 2, 4, 8, 16, 32, ইত্যাদি ইত্যাদি যখন এটির সীমাটি খুঁজে পায় যেখানে অন্য অ্যারের পড়ার মানটি আরও বড়। এটি বাইনারি সেই ব্যাপ্তিতে অনুসন্ধান করে (পরিধিকে অর্ধেক করে দেয়, সঠিক অর্ধে সন্ধান করে, একক মান পর্যন্ত পুনরাবৃত্তি করে)। তারপরে এটি অ্যারে সেই মানগুলি রাইটিং পজিশনে অনুলিপি করে। অনুলিপিটি প্রয়োজনীয়তার সাথে মনে রেখে, এমনভাবে সরানো হয়েছে যে এটি উভয় পাঠ্য অ্যারে থেকে একই মানগুলি ওভাররাইট করতে পারে না (যার অর্থ লেখার অ্যারে এবং পড়ার অ্যারে একই হতে পারে)। এরপরে এটি অন্যান্য অ্যারের জন্য একই ক্রিয়াকলাপ সম্পাদন করে যা এখন অন্য অ্যারের নতুন পঠিত মানের চেয়ে কম হিসাবে পরিচিত।
static public int gallopSearch(int current, int[] array, int v) {
int d = 1;
int seek = current - d;
int prevIteration = seek;
while (seek > 0) {
if (Integer.compare(array[seek], v) <= 0) {
break;
}
prevIteration = seek;
d <<= 1;
seek = current - d;
if (seek < 0) {
seek = 0;
}
}
if (prevIteration != seek) {
seek = binarySearch(array, seek, prevIteration, v);
seek = seek >= 0 ? seek : ~seek;
}
return seek;
}
static public int binarySearch(int[] list, int fromIndex, int toIndex, int v) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = list[mid];
int cmp = Integer.compare(midVal, v);
if (cmp < 0) {
low = mid + 1;
} else if (cmp > 0) {
high = mid - 1;
} else {
return mid;// key found
}
}
return -(low + 1);// key not found.
}
static public int[] sortedArrayMerge(int[] a, int[] b) {
return sortedArrayMerge(null, a, a.length, b, b.length);
}
static public int[] sortedArrayMerge(int[] results, int[] a, int aRead, int b[], int bRead) {
int write = aRead + bRead, length, gallopPos;
if ((results == null) || (results.length < write)) {
results = new int[write];
}
if (aRead > 0 && bRead > 0) {
int c = Integer.compare(a[aRead - 1], b[bRead - 1]);
while (aRead > 0 && bRead > 0) {
switch (c) {
default:
gallopPos = gallopSearch(aRead, a, b[bRead-1]);
length = (aRead - gallopPos);
write -= length;
aRead = gallopPos;
System.arraycopy(a, gallopPos--, results, write, length);
c = -1;
break;
case -1:
gallopPos = gallopSearch(bRead, b, a[aRead-1]);
length = (bRead - gallopPos);
write -= length;
bRead = gallopPos;
System.arraycopy(b, gallopPos--, results, write, length);
c = 1;
break;
}
}
}
if (bRead > 0) {
if (b != results) {
System.arraycopy(b, 0, results, 0, bRead);
}
} else if (aRead > 0) {
if (a != results) {
System.arraycopy(a, 0, results, 0, aRead);
}
}
return results;
}
এটি করার সবচেয়ে কার্যকর উপায় এটি হওয়া উচিত।
কিছু উত্তরের একটি সদৃশ অপসারণ ক্ষমতা ছিল। এর জন্য একটি ও (এন) অ্যালগরিদম প্রয়োজন কারণ আপনাকে অবশ্যই প্রতিটি আইটেম তুলনা করতে হবে। সুতরাং বাস্তবের পরে প্রয়োগ করার জন্য এটির জন্য এখানে একা একা। আপনি যদি সেগুলির সবকটি দেখার প্রয়োজন হয় তবে আপনি নকলগুলি সন্ধান করতে পারেন, আপনি যদি সেগুলির অনেক কিছু পেয়ে থাকেন তবে আপনি একাধিক এন্ট্রিগুলি পুরো পথ ধরে ঘুরে দেখতে পারবেন না।
static public int removeDuplicates(int[] list, int size) {
int write = 1;
for (int read = 1; read < size; read++) {
if (list[read] == list[read - 1]) {
continue;
}
list[write++] = list[read];
}
return write;
}
আপডেট: পূর্ববর্তী উত্তর, ভৌতিক কোড নয় তবে উপরের থেকে পরিষ্কারভাবে নিকৃষ্টমান।
অপ্রয়োজনীয় হাইপার-অপটিমাইজেশন। এটি কেবলমাত্র শেষ বিটের জন্য অ্যারেকপি নয়, শুরুতেও ডাকে। ও (লগ (এন)) তে কোনও সূচক অ-ওভারল্যাপ প্রক্রিয়াজাত করে ডেটা বাইনারি অনুসন্ধান করে। ও (লগ (এন) + এন) হ'ল (এন) এবং কিছু ক্ষেত্রে এর প্রভাবটি উচ্চারণ করা হবে বিশেষত এমন জিনিসগুলিতে যেখানে মার্জিং অ্যারেগুলির মধ্যে কোনওরূপ ওভারল্যাপ নেই।
private static int binarySearch(int[] array, int low, int high, int v) {
high = high - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = array[mid];
if (midVal > v)
low = mid + 1;
else if (midVal < v)
high = mid - 1;
else
return mid; // key found
}
return low;//traditionally, -(low + 1); // key not found.
}
private static int[] sortedArrayMerge(int a[], int b[]) {
int result[] = new int[a.length + b.length];
int k, i = 0, j = 0;
if (a[0] > b[0]) {
k = i = binarySearch(b, 0, b.length, a[0]);
System.arraycopy(b, 0, result, 0, i);
} else {
k = j = binarySearch(a, 0, a.length, b[0]);
System.arraycopy(a, 0, result, 0, j);
}
while (i < a.length && j < b.length) {
result[k++] = (a[i] < b[j]) ? a[i++] : b[j++];
}
if (j < b.length) {
System.arraycopy(b, j, result, k, (b.length - j));
} else {
System.arraycopy(a, i, result, k, (a.length - i));
}
return result;
}