سؤال

هل لدى أي من مكتبات C ++ الشهيرة فئة (أو فصول) تسمح للمطور باستخدام المصفوفات ذات المؤشرات التعسفية دون التضحية بالسرعة؟

لإعطاء هذا السؤال المزيد من النموذج الملموس ، أود أن تكتب كود مماثل للوجود أدناه:

//An array with indices in [-5,6)
ArbitraryIndicesArray<int> a = ArbitraryIndicesArray<int>(-5,6);  
for(int index = -5;index < 6;++index)
{
    a[index] = index;
}
هل كانت مفيدة؟

المحلول

حقا يجب أن تستخدم ناقل مع الإزاحة. أو حتى صفيف مع إزاحة. إن الإضافة أو الطرح الإضافي لن يحدث أي فرق في سرعة تنفيذ البرنامج.

إذا كنت تريد شيئًا بنفس السرعة بالضبط مثل صفيف C الافتراضي ، فيمكنك تطبيق الإزاحة على مؤشر الصفيف:

int* a = new int[10];
a = a + 5;
a[-1] = 1;

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

كما هو مذكور في التعليقات ، بعد تغيير مؤشر الصفيف ، لا يمكنك بعد ذلك الحذف باستخدام هذا المؤشر. يجب عليك إعادة ضبطها على البداية الفعلية للمصفوفة. البديل هو أنك تبقي دائمًا المؤشر إلى البداية ولكنك تعمل مع مؤشر آخر معدّل.

//resetting the array by adding the offset (of -5)
delete [] (a - 5);

نصائح أخرى

أ std::vector<int> سيفعل الخدعة هنا.
ACESS عشوائي لعنصر واحد في المتجه هو فقط O (1).

إذا كنت بحاجة حقًا إلى المؤشرات المخصصة ، فيمكنك إنشاء فئة صغيرة خاصة بك بناءً على متجه لتطبيق مجموعة.

استخدم فئة الخريطة من STL:

std::map<int, int> a;
for( int index = -5; index < 6; ++index )
{ 
    a[index] = index; 
}

يتم تنفيذ MAP داخليًا كحاوية مصنفة ، والتي تستخدم بحثًا ثنائيًا لتحديد موقع العناصر.

هذا موضوع قديم ولكن للمرجعية ...

Boost.Multiarray لديه نظام نطاقات لتحديد أي نطاق فهرس.

المصفوفات في objexxfcl المكتبة لديها دعم كامل لنطاقات الفهرس التعسفي.

هذه هي مكتبات صفيف متعددة الأبعاد. بالنسبة إلى صفيف OP 1D ، يجب أن يكون غلاف المتجه STD :: أعلاه كافياً.

تم تحرير الإجابة لأنني لست ذكيًا جدًا.

لف std::vector وإزاحة في فئة وتقديم operator[]:

template <class T>
class ArbVector
{
    private:
        int _offset;
        std::vector<T> container;
    public:
        ArbVector(int offset) : _offset(offset) {}
        T& operator[](int n) { return container[n + _offset] }
};

لست متأكدًا مما إذا كان هذا يجمع ، لكنك تحصل على الفكرة.

لا تستمد من std::vector رغم ذلك ، انظر التعليقات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top