এন উপাদানগুলির ক্রমবিন্যাস বর্ণনা করতে, আপনি দেখতে পাচ্ছেন যে প্রথম উপাদানটি যে অবস্থানের জন্য শেষ হয় সেখানে আপনার এন সম্ভাবনা রয়েছে, সুতরাং আপনি 0 এবং এন -1 এর মধ্যে একটি সংখ্যা দিয়ে এটি বর্ণনা করতে পারেন। পরবর্তী উপাদানটি যে অবস্থানে শেষ হয় সেই অবস্থানের জন্য আপনার কাছে এন -1 অবশিষ্ট সম্ভাবনা রয়েছে, সুতরাং আপনি 0 এবং এন -2 এর মধ্যে একটি সংখ্যা দিয়ে এটি বর্ণনা করতে পারেন।
আপনার নাম্বার না হওয়া পর্যন্ত আটকে দিন।
এন = 5 এর উদাহরণ হিসাবে, যে ক্রমটি আনে abcde
তা বিবেচনা করুন caebd
।
a
, প্রথম উপাদানটি দ্বিতীয় অবস্থানে শেষ হয়, সুতরাং আমরা এটি সূচক 1 নির্ধারণ করি ।
b
চতুর্থ অবস্থানে শেষ হয়, যা সূচক 3 হবে, তবে এটি তৃতীয়টি বাকি রয়েছে, সুতরাং আমরা এটি 2 নির্ধারণ করি ।
c
প্রথম অবশিষ্ট অবস্থানে শেষ হয়, যা সর্বদা 0 হয় ।
d
গত অবশিষ্ট স্থান, যা (শুধুমাত্র দুই অবশিষ্ট অবস্থানের মধ্যে) এ শেষ পর্যন্ত 1 ।
e
কেবলমাত্র অবশিষ্ট অবস্থানে শেষ হয়, 0 এ সূচকযুক্ত ।
সুতরাং আমরা সূচক ক্রম আছে {1, 2, 0, 1, 0} ।
এখন আপনি জানেন যে বাইনারি সংখ্যায় উদাহরণস্বরূপ, 'xyz' এর অর্থ z + 2y + 4x। দশমিক সংখ্যার জন্য
এটি z + 10y + 100x। প্রতিটি অঙ্ক কিছু ওজন দ্বারা গুণিত হয়, এবং ফলাফল সংক্ষিপ্ত করা হয়। ওজনের সুস্পষ্ট প্যাটার্নটি অবশ্যই ওজন ডাব্লু = বি ^ কে, বি এর সংখ্যার ভিত্তি এবং কে অঙ্কের সূচক। (আমি সর্বদা ডান থেকে অঙ্কগুলি গণনা করব এবং ডান দিকের অঙ্কের জন্য সূচক 0 থেকে শুরু করব Like একইভাবে যখন আমি 'প্রথম' সংখ্যাটি নিয়ে কথা বলি তখন আমি ডানদিকের অর্থ বুঝি))
কারণ কেন ডিজিটের জন্য ওজন এই প্যাটার্ন অনুসরণ যে সর্বোচ্চ সংখ্যা ট 0 থেকে ডিজিটের দ্বারা প্রতিনিধিত্ব করা যেতে পারে সর্বনিম্ন সংখ্যা শুধুমাত্র অঙ্ক ট + 1 টি ব্যবহার দ্বারা প্রতিনিধিত্ব করা যেতে পারে ঠিক 1 কম হতে হবে। বাইনারি-তে, 0111 অবশ্যই 1000 এর চেয়ে কম হবে dec দশমিক 0, 099999 অবশ্যই 100000 এর চেয়ে কম হতে হবে।
ভেরিয়েবল-বেসে এনকোডিং
পরবর্তী সংখ্যাগুলির ঠিক 1 হওয়ার মধ্যে ব্যবধানটি গুরুত্বপূর্ণ নিয়ম। এটি উপলব্ধি করে, আমরা একটি ভেরিয়েবল-বেস নম্বর দ্বারা আমাদের সূচী ক্রমটি উপস্থাপন করতে পারি । প্রতিটি অঙ্কের ভিত্তি হ'ল সেই অঙ্কটির জন্য বিভিন্ন সম্ভাবনার পরিমাণ। দশমিকের জন্য প্রতিটি অঙ্কের 10 টি সম্ভাবনা থাকে, আমাদের সিস্টেমের জন্য ডানদিকের অঙ্কের 1 সম্ভাবনা এবং বামদিকের n সম্ভাবনা থাকবে। তবে যেহেতু ডানদিকের অঙ্কটি (আমাদের ক্রমের সর্বশেষ সংখ্যা) সর্বদা 0 থাকে তাই আমরা এটিকে ছেড়ে চলে যাই। তার মানে আমরা বেস 2 থেকে এন রেখেছি। সাধারণভাবে, কে'এইচ ডিজিটের বেস বি [কে] = কে + ২ থাকবে digit ডিজিট k এর সর্বাধিক মান হ'ল [কে] = বি [কে] - 1 = কে + 1।
অঙ্কের ওজন [কে] এর ওজন সম্পর্কে আমাদের নিয়মের জন্য h [i] * w [i] এর যোগফলের প্রয়োজন যেখানে আমি i = 0 থেকে i = k এর সমষ্টি 1 * ডব্লু [কে + 1] এর সমান। পুনরাবৃত্তি স্থিত, ডব্লু [কে + 1] = ডব্লু [কে] + এইচ [কে] * ডব্লু [কে] = ডব্লু [কে] * (এইচ [কে] + ১)। প্রথম ওজন ডাব্লু [0] সর্বদা 1 হওয়া উচিত there সেখান থেকে শুরু করে, আমাদের নিম্নলিখিত মান রয়েছে:
k h[k] w[k]
0 1 1
1 2 2
2 3 6
3 4 24
... ... ...
n-1 n n!
(সাধারণ সম্পর্ক ডাব্লু [কে -১] = কে! প্রবর্তনের মাধ্যমে সহজেই প্রমাণিত হয়))
আমাদের ক্রম রূপান্তরকরণ থেকে আমরা যে সংখ্যাটি পাব তার পরে 0 থেকে এন -1 চলমান এস সহ [কে] * ডব্লু [কে] এর যোগফল হবে। এখানে [কে] হ'ল ক্রমটির কোথ (ডানদিকে, 0 থেকে শুরু) element উদাহরণস্বরূপ, আমাদের {1, 2, 0, 1, 0}, ডানদিকে অবস্থিত উপাদান সঙ্গে খুলে হিসেবে উল্লেখ আগে: {1, 2, 0, 1} । আমাদের যোগফল 1 * 1 + 0 * 2 + 2 * 6 + 1 * 24 = 37 ।
মনে রাখবেন যে আমরা যদি প্রতিটি সূচকের সর্বাধিক অবস্থান গ্রহণ করি তবে আমাদের কাছে {4, 3, 2, 1, 0} থাকত এবং তা 119 এ রূপান্তরিত হয় Since আমাদের নম্বর এনকোডিংয়ের ওজনগুলি বেছে নেওয়া হয়েছিল যাতে আমরা এড়াতে না পারি যে কোনও সংখ্যা, 0 থেকে 119 পর্যন্ত সমস্ত সংখ্যা বৈধ। এর মধ্যে যথাযথভাবে 120 রয়েছে, যা এন! আমাদের উদাহরণে এন = 5 এর জন্য, যথাযথভাবে বিভিন্ন ক্রমের সংখ্যা। সুতরাং আপনি আমাদের এনকোড করা নম্বরগুলি সমস্ত সম্ভাব্য ক্রমবিধি সম্পূর্ণরূপে নির্দিষ্ট করে দেখতে পারেন।
ভেরিয়েবল-বেস থেকে
ডিকোডিং ডিকোডিং বাইনারি বা দশমিক হিসাবে রূপান্তরিত করার অনুরূপ। সাধারণ অ্যালগরিদম হ'ল:
int number = 42;
int base = 2;
int[] bits = new int[n];
for (int k = 0; k < bits.Length; k++)
{
bits[k] = number % base;
number = number / base;
}
আমাদের চলক-বেস নম্বর জন্য:
int n = 5;
int number = 37;
int[] sequence = new int[n - 1];
int base = 2;
for (int k = 0; k < sequence.Length; k++)
{
sequence[k] = number % base;
number = number / base;
base++; // b[k+1] = b[k] + 1
}
এই সঠিকভাবে করতে {1, 2, 0, 1} আমাদের 37 ফিরে decodes ( sequence
হবে {1, 0, 2, 1}
এই কোড উদাহরণে কিন্তু যাই হোক না কেন ... যতদিন না পর্যন্ত আপনি সূচক যেমন উপযুক্তভাবে)। আমাদের আসল ক্রম {1, 2, 0, 1, 0 back ফিরে পেতে আমাদের কেবল ডান প্রান্তে 0 যুক্ত করতে হবে (মনে রাখবেন সর্বশেষ উপাদানটির নতুন অবস্থানের জন্য সর্বদা কেবল একটি সম্ভাবনা থাকে)}
একটি সূচী ক্রম ব্যবহার করে একটি তালিকা প্রেরণ
করা আপনি একটি নির্দিষ্ট সূচী ক্রম অনুসারে একটি তালিকা ক্রমাগত করতে নীচের অ্যালগরিদম ব্যবহার করতে পারেন। দুর্ভাগ্যক্রমে এটি একটি O (n²) অ্যালগরিদম।
int n = 5;
int[] sequence = new int[] { 1, 2, 0, 1, 0 };
char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];
bool[] set = new bool[n];
for (int i = 0; i < n; i++)
{
int s = sequence[i];
int remainingPosition = 0;
int index;
// Find the s'th position in the permuted list that has not been set yet.
for (index = 0; index < n; index++)
{
if (!set[index])
{
if (remainingPosition == s)
break;
remainingPosition++;
}
}
permuted[index] = list[i];
set[index] = true;
}
আদেশের সাধারণ প্রতিনিধিত্ব
সাধারণত আপনি যেমনটি করেছেন তেমন নির্বিচারে আপনি কোনও অনুচ্ছেদে প্রতিনিধিত্ব করবেন না, তবে আদেশটি প্রয়োগের পরে কেবল প্রতিটি উপাদানটির পরম অবস্থান দ্বারা। উদাহরণস্বরূপ {1, 2, 0, 1, 0} জন্য abcde
করতে caebd
স্বাভাবিকভাবে {1, 3, 0, 4, 2} দ্বারা প্রতিনিধিত্ব করা হয়। 0 থেকে 4 (বা সাধারণভাবে 0 থেকে এন -1) প্রতিটি সূচক এই উপস্থাপনায় ঠিক একবার ঘটে।
এই ফর্মটিতে একটি আদেশ প্রয়োগ করা সহজ:
int[] permutation = new int[] { 1, 3, 0, 4, 2 };
char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];
for (int i = 0; i < n; i++)
{
permuted[permutation[i]] = list[i];
}
এটি উল্টানো খুব মিল:
for (int i = 0; i < n; i++)
{
list[i] = permuted[permutation[i]];
}
আমাদের প্রতিনিধিত্ব থেকে সাধারণ উপস্থাপনায় রূপান্তর করুন
দ্রষ্টব্য যে আমরা যদি আমাদের সূচী ক্রম ব্যবহার করে একটি তালিকা অনুমোদনের জন্য আমাদের অ্যালগরিদম গ্রহণ করি এবং এটি পরিচয় অনুমানের {0, 1, 2, ..., n-1 to এ প্রয়োগ করি তবে আমরা পাই বিপরীত ক্রান্তিকরণ, সাধারণ আকারে উপস্থাপন। ( আমাদের উদাহরণে {2, 0, 4, 1, 3। )।
অ-উল্টানো প্রিমিউশন পেতে, আমি সবেমাত্র দেখানো ক্রমুয়েশন অ্যালগরিদম প্রয়োগ করি:
int[] identity = new int[] { 0, 1, 2, 3, 4 };
int[] inverted = { 2, 0, 4, 1, 3 };
int[] normal = new int[n];
for (int i = 0; i < n; i++)
{
normal[identity[i]] = list[i];
}
অথবা আপনি কেবল বিমুগ্ধ ক্রমুয়েশন অ্যালগরিদম ব্যবহার করে সরাসরি অনুমতি প্রয়োগ করতে পারেন:
char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];
int[] inverted = { 2, 0, 4, 1, 3 };
for (int i = 0; i < n; i++)
{
permuted[i] = list[inverted[i]];
}
নোট করুন যে সাধারণ আকারে ক্রমানুসারে কাজ করার জন্য সমস্ত অ্যালগরিদমগুলি হ'ল হ'ল (এন), যখন আমাদের ফর্মটিতে একটি অনুক্রমের প্রয়োগটি হ'ল ও (এন)। আপনার যদি বেশ কয়েকবার ক্রম প্রয়োগের প্রয়োজন হয় তবে প্রথমে এটি সাধারণ উপস্থাপনায় রূপান্তর করুন।