الطريقة الأكثر فاعلية لتخزين مجموعة مختلطة من الزوجي و ints

StackOverflow https://stackoverflow.com/questions/1577696

  •  21-09-2019
  •  | 
  •  

سؤال

أحتاج إلى تخزين مجموعة من ints والزوجات (التي تمثل البيانات الاسمية والحقيقية) في C ++. من الواضح أنه يمكنني تخزينها جميعًا في std::vector<double> ، لكن هذا يبدو خطأ بعض الشيء ولا يحصل على نقاط مكافأة الجماليات.

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

لقد وجدت أيضا تعزيز :: البديل, والتي قد تكون مساعدة هنا.

معلومات إضافية: سيكون عدد العناصر الموجودة في المجموعة صغيرة (<100) ومعروفة عند تهيئة المجموعة.

الملخص: من الواضح أنه يمكنني حل هذا بطرق لا حصر لها ، لكنني غير متأكد من أن يكون حلًا جيدًا عندما تكون (1) كفاءة مهمة حقًا و (2) أريد أيضًا أن أكتب رمزًا لطيفًا إلى حد ما. ما هو أفضل رهان هنا؟

تحرير ، معلومات إضافية: تمثل المجموعة "صف" في مجموعة بيانات أكبر ، وتمثل عناصرها قيم "أعمدة" معينة. خصائص الصفوف معروفة ، لذلك من المعروف نوع البيانات المخزنة في أي موقف. "الكفاءة" التي أتحدث عنها هي في المقام الأول كفاءة استرداد القيمة int/double لعمود معين ، على الرغم من أن الإعداد السريع للقيم مهم أيضًا. لدي بعض الوظائف التي تعمل على البيانات التي تحتاج إلى استردادها بأسرع وقت ممكن. مثال:

typedef std::vector<double> Row;

void doubleFun(Row const &row)
{
    // Function knows there's always a double at index 0
    double value = row[0];
    ...
}

void integerFun(Row const &row)
{
    // Function knows there's always an integer at index 1
    int value = row[1];
    ...
}

بعد المزيد من التفكير وقراءة الاقتراحات حتى الآن ، يبدو أن تخزين أعمدة int والأعمدة المزدوجة في متجهين منفصلين هو حل صلب. المجموعة Row يمكن بعد ذلك تحديد عضوين مختلفين لاسترداد البيانات الاسمية والحقيقية التي يمكن أن تستخدمها الوظائف.

فقط تخزين ك vector<double> على ما يرام أيضًا ، لكن ذلك يعتمد على مدى سرعة التحويل بين Double و Int (وهو أمر مثير للإعجاب على الأرجح).

آسف لكوني غير واضح بعض الشيء في البداية ، آمل أن يكون أكثر وضوحًا والآن ويمكنني الحصول على المزيد من الأفكار حول هذا الموضوع.

هل كانت مفيدة؟

المحلول

هل طلب نقطة مهمة في الحاوية الخاصة بك؟

إذا لم يكن الأمر كذلك:

class MyContainer
{
    std::vector<double> doubles;
    std::vector<int>    ints;

    push(double value) { doubles.push_back(value); }
    push(int value)    { ints.push_back(value); }

   ....
};

قد يكون جزء التكرار (لتصفح الحاوية بأكملها) أكثر صعوبة ...

نصائح أخرى

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

ما يبقى أن يتم تعيينه (ولم أتمكن من معرفة سؤالك) كيف يمكنك إحداث الفرق بين القيم العادية والحقيقية. تظل المشكلة مفتوحة في أي حل قد تختاره.

يمكنك استخدام نوع الاتحاد واستخدام ذلك في المتجه الخاص بك. ولكن في هذه الحالة ، يجب أن يكون لديك طريقة ما لمعرفة عناصر المتجه التي يجب معاملتها على أنها INTS وأيها يجب أن تعامل على أنها الزوجي. لتتبع أي منها هي INTs وأي منها هي الزوجي الذي يمكنك استخدام bitset أو شيء من هذا القبيل.

لست متأكدًا مما إذا كان هدفك هو تجنب حسابات النقطة العائمة الثقيلة. إذا كان ذلك ، فقد تكون bitset أكثر كفاءة. إذا لم يكن الأمر كذلك ، ودقة int الدقيقة ليست مهمة ، فيمكنك أيضًا تخزينها كلها الزوجي.

#include <vector>
#include <bitset>

union di
{
    double d;
    int i;
};


int main(int argc, char* argv[])
{

    std::bitset<2> bitsetInts;

    std::vector<di> v;
    di e1;
    e1.d = 3.9;
    v.push_back(e1);

    di e2;
    e2.i = 3;
    bitsetInts.set(1);
    v.push_back(e2);

    return 0;
}

سأذهب ل boost::variant الحل ، يناسب احتياجاتك تماما.

هناك تعزيز tuple ، والتي يمكنك استخدامها إذا كنت تعرف الأنواع في وقت الترجمة. ولكن إذا كان عدد العناصر صغيرة ، فلا ينبغي أن يكون إهدار 100 بايت مصدر قلق.

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