ترتيب مصفوفة حسب الفهرس: فك الغموض باستخدام C++

يعتبر فرز المصفوفات مهمة أساسية في البرمجة، ولكن ماذا لو كنت تحتاج فقط إلى الفهارس للقيم المفروزة بدلاً من القيم المفروزة نفسها؟ هذه المشكلة الشائعة قد أثارت اهتمام العديد من المطورين، وخاصة أولئك الذين يستخدمون C أو C++. في هذا المنشور، سنكشف كيفية فرز مصفوفة حسب القيمة مع إرجاع فهارس العناصر بالترتيب المفروز.

التحدي

تخيل أن لديك مصفوفة من الأعداد الصحيحة، وهدفك هو فرزها بترتيب تصاعدي. ومع ذلك، بدلاً من إرجاع الأعداد المفروزة نفسها، تريد مصفوفة تشير إلى الفهارس الأصلية لهذه الأعداد المفروزة. على سبيل المثال، given the input array:

الإدخال:  1، 3، 4، 9، 6

يجب أن تعكس النتائج فهارس القيم المفروزة:

الإخراج: 1، 2، 3، 5، 4

تطور في الفرز

من المحتمل أنك تستخدم خوارزمية فرز مثل إجراء فرز الصدفة المذكور في الاستفسار. ومع ذلك، يمكن أن تؤدي بعض عمليات التنفيذ البرمجية إلى أخطاء، خاصة عند التعامل مع المؤشرات. يهدف هذا المنشور إلى توضيح كيفية العمل مع المصفوفات في C/C++ وإنشاء وظيفة فرز تلبي المتطلبات المحددة.

الخطوة 1: إنشاء مصفوفة من المؤشرات

لتسهيل الفرز دون فقدان المعلومات الموضعية، يمكننا إنشاء مصفوفة من المؤشرات التي تشير إلى عناصر المصفوفة الأصلية. بهذه الطريقة، عندما نقوم بفرز المؤشرات، فإننا بشكل غير مباشر نفرز قيم المصفوفة الأصلية مع الاحتفاظ بخريطة الفهارس. إليك كيفية القيام بذلك:

int* intArray; // سيتم تهيئته بقيمك الصحيحة.
int arrayLen;  // طول المصفوفة الصحيحة.

int** pintArray = new int*[arrayLen]; // إنشاء مصفوفة من المؤشرات.
for(int i = 0; i < arrayLen; ++i)
{
    pintArray[i] = &intArray[i]; // تشير إلى العناصر المعنية.
}

الخطوة 2: فرز مصفوفة المؤشرات

بمجرد أن تكون لديك المؤشرات جاهزة، يمكنك تطبيق أي خوارزمية فرز (مثل فرز الصدفة) لفرز المؤشرات بناءً على القيم التي تشير إليها. إليك عرضًا بسيطًا:

SortIntPointers(pintArray, arrayLen); // يقوم بفرز مصفوفة المؤشر بناءً على القيم.

الخطوة 3: تعيين الفهارس المفروزة

بعد فرز المؤشرات، يمكنك بعد ذلك التنقل من خلالهم وتعيين مواقعهم المفروزة المقابلة مرة أخرى إلى مصفوفة المؤشرات الأصلية. وهذا يضمن حصولك على الفهارس المناسبة.

for(int i = 0; i < arrayLen; ++i)
{
    *pintArray[i] = i; // تعيين مواضع الفهرس المفروز.
}

مثال كامل للتنفيذ

وضع كل شيء معًا، إليك مثال كامل يتبع الخطوات الموضحة أعلاه:

void SortIntPointers(int** pArray, int ArrayLength) {
    int flag = 1;    
    int* temp;    
    
    for (int i = 1; (i <= ArrayLength) && flag; i++)
    {
        flag = 0;
        for (int j = 0; j < ArrayLength - 1; j++)
        {
            if (*pArray[j + 1] < *pArray[j]) // تغيير إلى ترتيب تصاعدي
            { 
                temp = pArray[j]; // تبديل العناصر
                pArray[j] = pArray[j + 1];
                pArray[j + 1] = temp;
                flag = 1; // حدث تبديل.
            }
        }
    }
}

// قم بتهيئة وفرز مؤشراتك كما هو موضح سابقًا.

الخاتمة

يمكن أن يكون فرز المصفوفات حسب الفهرس دون فقدان تتبع مواضعها الأصلية مهمًا صعبًا، خاصة عند التعامل مع المؤشرات في C/C++. من خلال إنشاء مصفوفة من المؤشرات وفرزها، يمكنك إدارة هذا التحدي بشكل فعال. تذكر تنفيذ معالجة الأخطاء واعتبار الحالات الحدية لكتابة كود أكثر متانة. برمجة سعيدة!