سؤال

ينطوي مشروع الفصل على فرز مجموعة من السلاسل، مع كل سلسلة تحتوي على عدد متساو من الأعمدة مثل هذا:

Cartwright Wendy 93 Williamson Mark 81 Thompson Mark 100 Anderson John 76 Turner Dennis 56

يقبل البرنامج حجة سطر الأوامر لأي عمود للفرز، ويجب طباعة السلاسل المرتبطة دون خصوصية.

أرغب في استخدام Strtok لتنفصل نسخا من كل سلسلة إلى أعمدة، وجعل الهياكل لكل سطر مثل هذا:

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}

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

تعديل: يقتصر الفرز على Qsort أو بنفسي إذا أردت حقا. إعطاء الاختيار، اخترت QSort. :)

تحرير رقم 2:يبدو أن إجماع إما استخدام متغير عالمي لرقم الأعمدة، أو استخدم QSort فقط لفرز صفيف من الهياكل. لم أفكر في فرز الهياكل، واستخدام المؤشر في طباعة السلسلة الأصلية. أعتقد أن هذا ما سأفعله. شكرا لمساعتكم جميعا!

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

المحلول

يمكنك اجتياز الهياكل مثل هذا:

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}
...

line*  Lines[max_lines]; // here you store the structs

int
cmp_lines( const void *elem1, const void *elem2 )
{
    line*  line1 = *(line**)elem1;
    line*  line2 = *(line**)elem2;
    // do the comparisons
}

qsort(Lines, max_lines, sizeof(line*), cmp_lines);

نصائح أخرى

على افتراض أنك لا تقتصر على استخدام QSort، يمكنك استخدام STD :: Trans، مع كائن Functor يخزن رقم العمود. إذا كان عليك استخدام Qsort، فسيكون أحد الحلوصية السريعة والقذرة لتخزين رقم العمود في متغير عالمي واستخدم ذلك في وظيفة المقارنة.

وظائف المقارنة المختلفة، كلها تأخذ الهيكل بأكملها، ولكن كل يستخدم عمود واحد فقط للمقارنة.

C ++ أو ج؟ بناء على علاماتك، أفترض أنه C ++. دعونا نحاول stl الطريقة.

يجب عليك استخدامها std::sort بدلا من qsort. std::sort يمكن أن تأخذ مؤشر الوظيفة فقط (مقارنة بديلها C)، ولكن أي هدف يمكن أن يسمى كدالة. قد تعرف أن مثيلات الفصل يمكن استدعاؤها كوظائف مع operator(). وبعد ثم الحل واضح: قم بإنشاء فئة "Functor" التي ستخلق وظائف مختلفة عند البناء. ستظل مكالمة الفرز بعد ذلك:

std::sort(array, array+size, comparator(2 /* sort by column #2 */));

تنشئ فئة Functor بفعالية ما يسمى "إغلاق": كائن وظيفي تم إنشاؤه ديناميكيا يحتوي على متغيرات محلية، ولكنه لا يشاركها بالكائنات الوظيفية الأخرى التي تم إنشاؤها بهذه الطريقة. انها تبدو مثل هذا:

class comparator{
  private: unsigned int field_n;
  public: comparator(unsigned int _field_n) : field_n(_field_n) {};
  public: int operator () (char const *  lhs, char const * rhs)
       { /* compare here fields with index field_n */ };
};

لاحظ أنه بدلا من مقارنة مؤشرات الفراغ "وظيفة" (أي مثيل الفصل الذي تنشئه) char * المعلمات، لذلك أنت لا تزعج نفسك مع نوع الصب.

في C، لسوء الحظ، لا يمكنك القيام بذلك في الاتجاه الآخر من إنشاء متغير عالمي.

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