একটি অ্যারের ইন্টারলেভ করার জন্য স্থানটিতে অ্যালগরিদম


62

আপনি উপাদান একটি অ্যারে দেওয়া হয়2n

a1,a2,,an,b1,b2,bn

কাজটি হ'ল অ্যারেটি ইন্টারলাইভ করা যায়, একটি স্থান-স্থান অ্যালগরিদম ব্যবহার করে ফলে ফলাফলগুলি অ্যারের মতো দেখায়

b1,a1,b2,a2,,bn,an

যদি স্থানটির প্রয়োজন না হয় তবে আমরা সহজেই একটি নতুন অ্যারে তৈরি করতে পারি এবং একটি সময় আলগোরিদিম প্রদানে উপাদানগুলি অনুলিপি করতে পারি ।O(n)

স্থানের প্রয়োজনীয়তার সাথে, একটি বিভাজন এবং বিজয়ী অ্যালগরিদম আলগোরিদিমকে ।θ(nlogn)

সুতরাং প্রশ্নটি হ'ল:

সেখানে কোনও সময় অ্যালগরিদম রয়েছে, যা স্থানে রয়েছে?O(n)

(দ্রষ্টব্য: আপনি অভিন্ন দামের ওয়ার্ড র‌্যাম মডেল ধরে নিতে পারেন, তাই স্থানটিতে in স্থান সীমাবদ্ধতা) এ অনুবাদ করা হয়েছে।O(1)


1
এটি স্ট্যাকওভারফ্লোতে রয়েছে তবে তারা কোনও মানের সমাধান দেয় না। উপরের বিপরিতে উত্তর: "এই সমস্যা হিসেবে তুচ্ছ নয় মানুষ আউট করা হতে হোমওয়ার্ক উচ্চহাস্য একটা নেই।। ArXiv উপর সমাধান " কিন্তু arXiv সমাধান কিছু সংখ্যা তত্ত্ব + + অন্যান্য কাগজপত্র মধ্যে উল্লেখ নিদর্শনাবলী প্রয়োজন। এখানে একটি সংক্ষিপ্ত সমাধান পেয়ে ভাল লাগবে।
জো

1
এছাড়াও cstheory করুন: cstheory.stackexchange.com/questions/13943/...
ইউভাল Filmus

স্ট্যাক ওভারফ্লো অন্য একটি থ্রেড: stackoverflow.com/questions/15996288/...
Nayuki

উত্তর:


43

জো দ্বারা লিঙ্ক করা কাগজ থেকে অ্যালগোরিদমের উপর বিস্তারিত যা উত্তর এখানে: http://arxiv.org/abs/0805.1598

প্রথমে একটি আলগোরিদিম বিবেচনা করি যা বিভাজন এবং বিজয় ব্যবহার করে।Θ(nlogn)

1) ভাগ এবং বিজয়

আমাদের দেওয়া হয়

a1,a2,,b1,b2,bn

এখন বিভাজন এবং বিজয় ব্যবহার করতে, কিছু , আমরা অ্যারেটি পাওয়ার চেষ্টা করিm=Θ(n)

[a1,a2,,am,b1,b2,,bm],[am+1,,an,bm+1,bn]

এবং পুনরাবৃত্তি।

লক্ষ্য করুন যে একটি চক্রীয় স্থানান্তর

b1,b2,bm,am+1,an

am+1,an,b1,bm

স্থান দ্বারা ।m

এটি একটি ক্লাসিক এবং তিনটি বিপরীতমুখী এবং সময়ে স্থানে করা যায় ।O(n)

সুতরাং বিভাজন এবং বিজয় আপনাকে অনুরূপ পুনরাবৃত্তি সহ একটি অ্যালগরিদম দেয় ।Θ(nlogn)T(n)=2T(n/2)+Θ(n)

2) আবর্তন চক্র

এখন, সমস্যার আরেকটি উপায় হ'ল বিযুক্তি চক্রের সেট হিসাবে অনুচ্ছেদটিকে বিবেচনা করুন।

অনুমানটি দেওয়া হয় (অনুমান থেকে শুরু করে )1

j2jmod2n+1

যদি আমরা কোনওভাবে ধ্রুবক অতিরিক্ত স্থান ব্যবহার করে চক্রগুলি ঠিক কী তা জানতাম, তবে আমরা একটি উপাদান বাছাই করে অনুভূতিটি উপলব্ধি করতে পারি , নির্ধারণ করতে পারি যে সেই উপাদানটি কোথায় যায় (উপরের সূত্রটি ব্যবহার করে), উপাদানটিকে অস্থায়ী স্থানে স্থাপন করে, রাখুন উপাদান যে লক্ষ্য অবস্থান মধ্যে এবং চক্র বরাবর অবিরত। একবার যখন আমরা একটি চক্র সম্পন্ন করি তখন আমরা পরবর্তী চক্রের একটি উপাদানের দিকে চলে যাই এবং সেই চক্রটি অনুসরণ করি এবং আরও অনেক কিছু।AA

এটি আমাদেরকে সময় অ্যালগরিদম দেবে, তবে এটি ধরে নেওয়া হয়েছে যে আমরা "কোনওভাবে সঠিক চক্রগুলি কী তা জানতাম" এবং book space স্থান সীমাবদ্ধতার মধ্যে এই বই-রাখার চেষ্টা করছিলাম এই সমস্যাটি কি কঠিন করে তোলে।O(n)O(1)

এই যেখানে কাগজ সংখ্যা তত্ত্ব ব্যবহার করে।

এটি দেখানো যেতে পারে যে, , অবস্থান , positions এ থাকা উপাদানগুলি বিভিন্ন চক্রে থাকে এবং প্রতিটি চক্রের একটি উপাদান থাকে অবস্থানে ।2n+1=3k13,32,,3k13m,m0

এটি জেনারেটর তা ব্যবহার করে ।2(Z/3k)

সুতরাং , চক্রের অনুসরণ অনুসরণ করে তখন আমাদের একটি সময় অ্যালগরিদম দেয়, প্রতিটি চক্র হিসাবে, আমরা ঠিক জানি কোথায় শুরু করতে হবে: ক্ষমতা ( সহ ) (সেগুলি স্পেসে গণনা করা যায় ।2n+1=3kO(n)31O(1)

3) ফাইনাল অ্যালগরিদম

এখন আমরা উপরের দুটিটি একত্রিত করি: ভাগ করুন এবং বিজয়ী করুন + পেরমুটেশন চক্র।

আমরা একটি ডিভাইড এবং বশীভূত কিন্তু বাছাই যাতে একটি শক্তি এবং ।m2m+13m=Θ(n)

সুতরাং উভয় "অর্ধ" এর পুনরাবৃত্তি করার পরিবর্তে, আমরা কেবলমাত্র একটিতে পুনরাবৃত্তি করি এবং ta অতিরিক্ত কাজ করি।Θ(n)

এটি আমাদের পুনরাবৃত্তি (কিছুটা ) এবং এটি আমাদেরকে একটি সময়, স্পেস অ্যালগরিদম!T(n)=T(cn)+Θ(n)0<c<1O(n)O(1)


4
ঐটা সুন্দর.
রাফেল

1
খুব সুন্দর. ক্রমচারণের উদাহরণগুলির মধ্যে দিয়ে এখন আমি এটির বেশিরভাগটি বুঝতে পারি understand দুটি প্রশ্ন: 1. আপনি প্রকৃতপক্ষে মান এমটি কীভাবে খুঁজে পাবেন? কাগজ দাবি করে যে এটি ও (লগ এন) লাগে, কেন? ২. একই ধরণের পদ্ধতির সাহায্যে অ্যারে ডি-ইন্টারলিভ করা কি সম্ভব?
num3ric

2
@ num3ric: 1) আপনি সর্বোচ্চ ক্ষমতা এটি যা হয় । সুতরাং এটি । 2)। হ্যাঁ, এটি সম্ভব, আমি বিশ্বাস করি যে আমি কোথাও স্ট্যাকওভারফ্লোতে একটি উত্তর যুক্ত করেছি। এই ক্ষেত্রে আমি বিশ্বাস করি এমন চক্রের নেতারা ( = পাওয়ার ) এর মধ্যে এসেছিলেন । 3<nO(logn)2a3b2m+13
আর্যভট্ট

@ আর্যভট্ট কেন আমরা দুটি "অর্ধেক" এর পরিবর্তে কেবল একটি "অর্ধ" এর উপর পুনরাবৃত্তি করব?
sinoTrinity

1
@ আর্যভট্ট এই অ্যালগরিদমটি কি আরও দুটি অ্যারে ইন্টারলাইভ করা যেতে পারে? উদাহরণস্বরূপ কে বা অনুরূপ কিছু। a1,a2,,an,b1,b2,,bn,c1,c2,,cnc1,b1,a1,c2,b2,a2,,cn,bn,an
ডাব

18

আমি নিশ্চিত যে আমি একটি অ্যালগরিদম পেয়েছি যা সংখ্যা তত্ত্ব বা চক্র তত্ত্বের উপর নির্ভর করে না। মনে রাখবেন যে কাজ করার জন্য কয়েকটি বিশদ রয়েছে (সম্ভবত আগামীকাল) তবে আমি নিশ্চিত যে তারা কার্যকর হবে। আমি ঘুমানোর কথা বলেছিলাম বলে হ্যান্ডওয়েভ, কারণ আমি সমস্যাগুলি আড়াল করার চেষ্টা করছি না :)

যাক Aপ্রথম বিন্যাস হতে Bদ্বিতীয়, |A| = |B| = Nএবং অনুমান N=2^kকিছু k, সরলতা জন্য। যাক A[i..j]এর subarray হতে Aসূচকের সঙ্গে iমাধ্যমে j, সমেত। অ্যারে 0-ভিত্তিক। ডান থেকে গণনা RightmostBitPos(i)করে ডানদিকের বিটটির (0-ভিত্তিক) অবস্থান যা '1' এর ফিরে আসা যাক i। অ্যালগরিদম নিম্নলিখিত হিসাবে কাজ করে।

GetIndex(i) {
    int rightPos = RightmostBitPos(i) + 1;
    return i >> rightPos;
}

Interleave(A, B, N) {
    if (n == 1) {
        swap(a[0], b[0]);
    }
    else {
        for (i = 0; i < N; i++)
            swap(A[i], B[GetIndex(i+1)]);

        for (i = 1; i <= N/2; i*=2)
            Interleave(B[0..i/2-1], B[i/2..i-1], i/2);

        Interleave(B[0..N/2], B[N/2+1..N], n/2);
    }
}

আসুন 16 টি সংখ্যার একটি অ্যারে নেওয়া যাক এবং কেবলমাত্র সেগুলি অদলবদল ব্যবহার করে আন্তঃবিভাজন শুরু করি এবং কী ঘটে তা দেখুন:

1 2 3 4 5 6 7 8    | 9 10 11 12 13 14 15 16
9 2 3 4 5 6 7 8    | 1 10 11 12 13 14 15 16
9 1 3 4 5 6 7 8    | 2 10 11 12 13 14 15 16
9 1 10 4 5 6 7 8   | 2 3 11 12 13 14 15 16
9 1 10 2 5 6 7 8   | 4 3 11 12 13 14 15 16
9 1 10 2 11 6 7 8  | 4 3 5 12 13 14 15 16
9 1 10 2 11 3 7 8  | 4 6 5 12 13 14 15 16
9 1 10 2 11 3 12 8 | 4 6 5 7 13 14 15 16
9 1 10 2 11 3 12 4 | 8 6 5 7 13 14 15 16

বিশেষ আগ্রহের দ্বিতীয় অ্যারের প্রথম অংশ:

|
| 1
| 2
| 2 3
| 4 3
| 4 3 5
| 4 6 5
| 4 6 5 7
| 8 6 5 7

প্যাটার্নটি পরিষ্কার হওয়া উচিত: আমরা পর্যায়ক্রমে শেষ পর্যন্ত একটি সংখ্যা যুক্ত করি এবং সর্বনিম্ন সংখ্যাটি একটি উচ্চ সংখ্যার দ্বারা প্রতিস্থাপন করি। নোট করুন যে আমরা সর্বদা এমন একটি সংখ্যা যুক্ত করি যা আমরা ইতিমধ্যে থাকা সর্বাধিক সংখ্যার চেয়ে একটি বেশি। আমরা যদি কোনওভাবে নির্ধারণ করতে পারি যে কোনও নির্দিষ্ট সময়ে কোন সংখ্যাটি সবচেয়ে কম, তবে আমরা সহজেই তা করতে পারি।

এখন, আমরা কোনও প্যাটার্ন দেখতে পারি কিনা তা দেখতে আমরা আরও বড় উদাহরণগুলির জন্য যাই। নোট করুন যে উপরের উদাহরণটি তৈরি করতে আমাদের অ্যারের আকার ঠিক করার দরকার নেই। কিছু সময়ে, আমরা এই কনফিগারেশনটি পাই (দ্বিতীয় লাইনটি প্রতিটি সংখ্যা থেকে 16 টি বিয়োগ করে):

16 24 20 28 18 22 26 30 17 19 21 23 25 27 29 31
0   8  4 12  2  6 10 14  1  3  5  7  9 11 13 15

এখন এটি পরিষ্কারভাবে একটি প্যাটার্ন দেখায়: "1 3 5 7 9 11 13 15" সমস্ত 2 টি পৃথক, "2 6 10 14" সমস্ত 4 টি পৃথক এবং "4 12" 8 টি পৃথক। সুতরাং আমরা একটি অ্যালগরিদম তৈরি করতে পারি যা আমাদের জানায় যে পরবর্তী ক্ষুদ্রতম সংখ্যাটি কী হবে: বাইনারি সংখ্যাগুলি কীভাবে কাজ করে তা প্রক্রিয়াটি ঠিক ঠিক pretty অ্যারের শেষ অর্ধের জন্য আপনার কাছে কিছুটা আছে, দ্বিতীয় ত্রৈমাসিকের জন্য কিছুটা, এবং আরও কিছু।

যদি আমাদের এই বিটগুলি সংরক্ষণ করার জন্য পর্যাপ্ত স্থানের অনুমতি দেওয়া হয় (আমাদের বিটগুলির প্রয়োজন, তবে আমাদের গণনীয় মডেল এটির অনুমতি দেয় - অ্যারেতে একটি পয়েন্টারটির জন্য বিটসও প্রয়োজন), আমরা নির্ধারণ করতে পারি যে কোন সংখ্যাটি ও-তে পরিবর্তন করতে হবে সময় amorised।lognlognO(1)

অতএব আমরা অ্যারের প্রথমার্ধটিকে সময় এবং অদলবদলে তার আন্তঃবাহিত অবস্থায় পেতে পারি । তবে, আমাদের অ্যারের দ্বিতীয়ার্ধটি ঠিক করতে হবে, যা দেখে মনে হচ্ছে সমস্ত গণ্ডগোল হয়েছে ("8 6 5 7 13 14 15 16")।O(n)O(n)

এখন, যদি আমরা এই দ্বিতীয় অংশের প্রথমার্ধটি 'বাছাই' করতে পারি, আমরা "5 6 7 8 13 14 15 16" দিয়ে শেষ করব এবং পুনরায় এই অর্ধেকটি আন্তঃলিখন করা কৌশলটি করবে: আমরা এ অ্যারেটি ইন্টারলাইভ করব we সময় ( পুনরাবৃত্ত কলগুলি যার প্রতিটি ইনপুট আকার অর্ধেক করে দেয়)। দ্রষ্টব্য যে আমাদের কলগুলির লেজগুলি পুনরাবৃত্ত হওয়ার কারণে আমাদের কোনও স্ট্যাকের প্রয়োজন নেই, সুতরাং আমাদের স্পেসের ব্যবহার অবশেষ ।O(n)O(logn)O(1)

এখন, প্রশ্নটি: অংশটি বাছাই করার কিছু অংশ আছে কি? 32 নম্বর চেষ্টা করে আমাদের "16 12 10 14 9 11 13 15" ঠিক করতে দেয়। নোট করুন যে আমাদের এখানে ঠিক একই প্যাটার্ন রয়েছে! "9 11 13 15", "10 14" এবং "12" একসাথে একইভাবে ফ্যাশনে আমরা আগে দেখেছি are

এখন, কৌশলটি এই উপ-বিভাগগুলি পুনরাবৃত্তভাবে আন্তঃলিখন করা ave আমরা "16" এবং "12" থেকে "12 16" ইন্টারলিভ করি। আমরা "12 16" এবং "10 14" থেকে "10 12 14 16" ইন্টারলিভ করি। আমরা "10 12 14 16" এবং "9 11 13 15" থেকে "9 10 11 12 13 14 15 16" ইন্টারলিভ করি। এটি প্রথম অংশটি সাজায়।

উপরের মতো ঠিক এই অপারেশনের মোট ব্যয় । এই সমস্ত যোগ করে, আমরা এখনও এর মোট চলমান সময় পেতে পরিচালনা করি ।O(n)O(n)

একটি উদাহরণ:

Interleave the first half:
1 2 3 4 5 6 7 8    | 9 10 11 12 13 14 15 16
9 2 3 4 5 6 7 8    | 1 10 11 12 13 14 15 16
9 1 3 4 5 6 7 8    | 2 10 11 12 13 14 15 16
9 1 10 4 5 6 7 8   | 2 3 11 12 13 14 15 16
9 1 10 2 5 6 7 8   | 4 3 11 12 13 14 15 16
9 1 10 2 11 6 7 8  | 4 3 5 12 13 14 15 16
9 1 10 2 11 3 7 8  | 4 6 5 12 13 14 15 16
9 1 10 2 11 3 12 8 | 4 6 5 7 13 14 15 16
9 1 10 2 11 3 12 4 | 8 6 5 7 13 14 15 16
Sort out the first part of the second array (recursion not explicit):
8 6 5 7 13 14 15 16
6 8 5 7 13 14 15 16
5 8 6 7 13 14 15 16
5 6 8 7 13 14 15 16
5 6 7 8 13 14 15 16
Interleave again:
5 6 7 8   | 13 14 15 16
13 6 7 8  | 5 14 15 16
13 5 7 8  | 6 14 15 16
13 5 14 8 | 6 7 15 16
13 5 14 6 | 8 7 15 16
Sort out the first part of the second array:
8 7 15 16
7 8 15 16
Interleave again:
7 8 | 15 16
15 8 | 7 16
15 7 | 8 16
Interleave again:
8 16
16 8
Merge all the above:
9 1 10 2 11 3 12 4 | 13 5 14 6 | 15 7 | 16 8

মজাদার. আপনি কি চেষ্টা করতে চান এবং একটি আনুষ্ঠানিক প্রমাণ লিখতে রাজি হন? আমি জানি যে আরও একটি অ্যালগরিদম রয়েছে (জো পাওয়া কাগজে উল্লিখিত) যা বিটগুলি নিয়ে কাজ করে। সম্ভবত আপনি এটি আবার আবিষ্কার করেছেন!
আর্যভট্ট

1

কোনও অতিরিক্ত স্টোরেজ ছাড়াই অ্যারের দুটি অংশকে আন্তঃবিবাহ করতে এখানে রৈখিক সময়ের অ্যালগরিদম-এ এক পুনরাবৃত্তিযোগ্য স্থান রয়েছে।

সাধারণ ধারণাটি সহজ: সঠিক মানগুলি স্থানে অদলবদল করে অ্যারের প্রথম অর্ধ থেকে বাম থেকে ডানে হাঁটুন। আপনি অগ্রসর হওয়ার সাথে সাথে, এখনও অবধি ব্যবহৃত বাম মানগুলি ডান মান দ্বারা ফাঁকা স্থানটিতে সরে যায়। এগুলিকে আবার কীভাবে টেনে আনতে হবে তা একমাত্র কৌশল uring

আমরা আকারের অ্যারে দিয়ে 2 প্রায় সমান অংশে বিভক্ত করে শুরু করি।
[ left_items | right_items ]
আমরা এটি প্রক্রিয়া করার সাথে সাথে এটি হয়ে যায়
[ placed_items | remaining_left_items| swapped_left_items | remaining_right_items]

অদলবদল স্থানটি নিম্নোক্ত প্যাটার্নের সাথে বৃদ্ধি পায়: ক) সংলগ্ন ডান আইটেমটি সরিয়ে এবং বাম থেকে একটি নতুন আইটেমের মধ্যে অদলবদল করে স্থানটি বৃদ্ধি করুন; খ) বাম দিক থেকে একটি নতুন আইটেম সঙ্গে পুরানো আইটেম অদলবদল। বাম আইটেমগুলি যদি 1..N নাম্বার করা হয় তবে এই প্যাটার্নটি দেখতে দুর্দান্ত

step swapspace index changed
1    A: 1         0
2    B: 2         0
3    A: 2 3       1
4    B: 4 3       0     
5    A: 4 3 5     2
6    B: 4 6 5     1
7    A: 4 6 5 7   3
...

যার সূচির ক্রমটি পরিবর্তিত হয়েছে তা হ'ল OEIS A025480 , যা একটি সাধারণ প্রক্রিয়া দিয়ে গণনা করা যায়। এটি এখন পর্যন্ত সংযুক্ত আইটেমের সংখ্যা দিয়ে স্ব্যাপের অবস্থান সন্ধান করতে দেয় যা বর্তমান আইটেমটির সূচকও।

রৈখিক সময়ে ক্রমটির 1 ম অর্ধেকের জন্য আমাদের প্রয়োজনীয় তথ্যগুলি।

আমরা যখন মিডপয়েন্টে পৌঁছে যাব, অ্যারেতে তিনটি অংশ থাকবে: [ placed_items | swapped_left_items | remaining_right_items] আমরা যদি অদলবদল করা আইটেমগুলি আনস্র্যাম্বল করতে পারি, আমরা সমস্যাটিকে অর্ধেক আকারে কমিয়েছি এবং পুনরাবৃত্তি করতে পারি।

দ্বারা নির্মিত একটি ক্রম: swap 'র স্থান জট ছাড়ানো করার জন্য, আমরা নিম্নলিখিত সম্পত্তি ব্যবহার Nসংযোজন এবং swap_oldest অপারেশন উপস্থিত থাকবে পর্যায়ক্রমে N/2আইটেম যেখানে তাদের বয়সের দ্বারা দেওয়া হয় A025480(N/2)..A025480(N-1)(পূর্ণসংখ্যা বিভাগ, ছোট মানগুলি পুরানো)।

উদাহরণস্বরূপ, যদি বাম অর্ধেকটি মূলত ১.১৯ মান ধরে থাকে তবে অদলবদলের স্থানটি থাকতে পারে [16, 12, 10, 14, 18, 11, 13, 15, 17, 19]। A025480 (9..18) হ'ল [2, 5, 1, 6, 3, 7, 0, 8, 4, 9]এটি পুরানো থেকে সর্বাধিক নতুন আইটেমের সূচকের তালিকা।

সুতরাং আমরা এটা মাধ্যমে আগুয়ান এবং সোয়াপিং আমাদের swap 'র স্থান জট ছাড়ানো যাবে না S[i]দিয়ে S[ A(N/2 + i)]। এটিও লিনিয়ার সময়।

বাকি জটিলতা হ'ল শেষ পর্যন্ত আপনি এমন অবস্থানে পৌঁছে যাবেন যেখানে সঠিক মানটি নিম্ন সূচীতে হওয়া উচিত, তবে এটি ইতিমধ্যে সরিয়ে নেওয়া হয়েছে। নতুন অবস্থানটি সন্ধান করা সহজ: আইটেমটি কোথায় বদলেছে তা আবিষ্কার করতে কেবল সূচি গণনা করুন do যতক্ষণ না আপনি একটি অদলবদল অবস্থান না পান ততক্ষণে কয়েক ধাপ চেইন অনুসরণ করা প্রয়োজন।

এই মুহুর্তে, আমরা অর্ধেক অ্যারে একীভূত করেছি, এবং অন্য অর্ধে নিমজ্জিত অংশগুলির ক্রম বজায় রেখেছি ঠিক N/2 + N/4অদলবদল দিয়ে। আমরা মোট N + N/4 + N/8 + ....অ্যারেপের জন্য বাকি অ্যারের মাধ্যমে চালিয়ে যেতে পারি যা এর চেয়ে কম কঠোর 3N/2

কীভাবে A025480 গণনা করবেন:
এটি a(2n) = n, a(2n+1) = a(n).বিকল্প সূত্র হিসাবে OEIS এ সংজ্ঞায়িত করা হয়েছে a(n) = isEven(n)? n/2 : a((n-1)/2)। এটি বিটওয়াইজ অপারেশনগুলি ব্যবহার করে একটি সাধারণ অ্যালগরিদম বাড়ে:

index_t a025480(index_t n){
    while (n&1) n=n>>1;
    return n>>1;  
}

এটি এন এর সমস্ত সম্ভাব্য মানগুলির উপর একটি মোড়কযুক্ত ও (1) অপারেশন (1/2 প্রয়োজন 1 শিফট প্রয়োজন, 1/4 প্রয়োজন 2, 1/8 প্রয়োজন 3, ...) । আরও তাত্পর্যপূর্ণ একটি পদ্ধতি রয়েছে যা সর্বনিম্ন উল্লেখযোগ্য শূন্য বিটের অবস্থান সন্ধান করতে একটি ছোট সন্ধানের টেবিল ব্যবহার করে।

এটি দেওয়া হল, এখানে সি তে একটি বাস্তবায়ন রয়েছে:

static inline index_t larger_half(index_t sz) {return sz - (sz / 2); }
static inline bool is_even(index_t i) { return ((i & 1) ^ 1); }

index_t unshuffle_item(index_t j, index_t sz)
{
  index_t i = j;
  do {
    i = a025480(sz / 2 + i);
  }
  while (i < j);
  return i;
}

void interleave(value_t a[], index_t n_items)
{
  index_t i = 0;
  index_t midpt = larger_half(n_items);
  while (i < n_items - 1) {

    //for out-shuffle, the left item is at an even index
    if (is_even(i)) { i++; }
    index_t base = i;

    //emplace left half.
    for (; i < midpt; i++) {
      index_t j = a025480(i - base);
      SWAP(a + i, a + midpt + j);
    }

    //unscramble swapped items
    index_t swap_ct  = larger_half(i - base);
    for (index_t j = 0; j + 1 < swap_ct ; j++) {
      index_t k = unshuffle_item(j, i - base);
      if (j != k) {
        SWAP(a + midpt + j, a + midpt + k);
      }
    }
    midpt += swap_ct;
  }
}

এটি মোটামুটি ক্যাশে-বান্ধব অ্যালগরিদম হওয়া উচিত, যেহেতু 3 টির মধ্যে 2 টি অবস্থানের ক্রমানুসারে অ্যাক্সেস করা হয় এবং ডেটা প্রক্রিয়া করার পরিমাণ কঠোরভাবে হ্রাস পাচ্ছে। লুপের শুরুতে পরীক্ষাকে উপেক্ষা করে এই পদ্ধতিটি আউট-সাফাল থেকে একটি ইন-শফলে পরিণত হতে পারে is_even

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.