বাছাই করতে সি লাইব্রেরি ফাংশন


99

সি স্ট্যান্ডার্ড লাইব্রেরিতে বাছাই করতে কোনও লাইব্রেরি ফাংশন রয়েছে কি?


22
@ আলেকজান্দ্রু, এসওর পুরো বিষয়টি হ'ল যে কোনও দক্ষতা স্তরের প্রোগ্রামিং-সংক্রান্ত সমস্ত প্রশ্নের জন্য একটি জায়গা হতে হবে । আপনার কি মনে হয় গুগল লোকেরা যখন আপনার সেই প্রশ্নটি ব্যবহার করবে তখন তাদের কোথায় নির্দেশ দেওয়া উচিত? যে শক্তিগুলি এটি এখানে আসতে চায় - যখন এসও সেই প্রশ্নের জন্য শীর্ষস্থানীয় গুগল লিঙ্ক হয়, তখন আমাদের কাজ হয়ে যায়।
paxdiablo

4
আমার মূল কোডটি অলস ছিল এবং সম্ভবত কোনও Google এর অনুসন্ধানে আপনি কী খুঁজে পেতেন তার চেয়ে অনেক বেশি আলাদা different তবে সম্প্রদায়ের ইনপুটগুলির পরে আপনার কীভাবে কীসোর্টটি ব্যবহার করতে হবে তার একটি ভাল প্রয়োগের একটি উদাহরণ রয়েছে।
পুনরায় চালু করুন

@ প্যাক্সিয়াব্লো: যদি এটি হয় তবে তারা স্ট্যান্ডার্ড লিব ডকুমেন্টেশনগুলি কেবল হোস্ট করতে পারে - আমি সন্দেহ করি যে এই প্রশ্নটি এখানে প্রচলিত রেফারেন্সের উপরে কিছু যুক্ত করবে। কিছু জটিল ক্ষেত্রে, সম্ভবত - তবে কেবল একটি মৌলিক ফাংশন সন্ধান করতে?
ইমন নেরবোন

4
এমনকি এর মতো প্রশ্নগুলি আটকে কোডারগুলির জন্য সহায়ক ডেটাবেস হিসাবে এসওয়ের শেষ পরিপূর্ণতায় অবদান রাখে।
লিটল গ্রিন

7
এছাড়াও অনেক ক্ষেত্রে লোকেরা কী সন্ধান করতে হয় তা জানেন না। আপনি যদি জানেন যে সি এর কিউসোর্ট () ডকুমেন্টেশন নামে একটি সাজানো ফাংশন রয়েছে তবে সহজেই অ্যাক্সেসযোগ্য, তবে আপনি যদি জানেন না কি কোন উত্সটি ব্যবহার করা উচিত তা কী অনুসন্ধান করা উচিত।
পুনরায় চালু করুন

উত্তর:


124

qsort()আপনি খুঁজছেন ফাংশন হয়। আপনি এটিকে আপনার অ্যারের ডেটার বিন্দুতে, সেই অ্যারেতে উপাদানের সংখ্যা, প্রতিটি উপাদানের আকার এবং তুলনা ফাংশন দিয়ে কল করেন।

এটি এর যাদু করে এবং আপনার অ্যারে স্থানে বাছাই করা হয়। একটি উদাহরণ অনুসরণ করে:

#include <stdio.h>
#include <stdlib.h>
int comp (const void * elem1, const void * elem2) 
{
    int f = *((int*)elem1);
    int s = *((int*)elem2);
    if (f > s) return  1;
    if (f < s) return -1;
    return 0;
}
int main(int argc, char* argv[]) 
{
    int x[] = {4,5,2,3,1,0,9,8,6,7};

    qsort (x, sizeof(x)/sizeof(*x), sizeof(*x), comp);

    for (int i = 0 ; i < 10 ; i++)
        printf ("%d ", x[i]);

    return 0;
}

4
আপনি যদি ভবিষ্যতে কখনও ধরণের পরিবর্তন করেন তবে নমুনা সরবরাহ করার জন্য +1 করে আপনার সত্যিকারের আকারের (* x) ব্যবহার করা উচিত।
paxdiablo

14
সাধারণ ক্ষেত্রে, একে অপরের থেকে বিয়োগ করে ইনটগুলি তুলনা করার প্রয়াসের ফলে ওভারফ্লো হবে। প্রথম থেকেই খারাপ অভ্যাস থেকে দূরে থাকাই ভাল। ব্যবহার করুনreturn (f > s) - (f < s);
এএনটি

4
ঠিক আছে, বেশিরভাগ পরামর্শ অনুসারে পরিবর্তিত হয়েছে। আমি @ ক্রিসল, এই লাইনটি আঁকছি যেহেতু আমার অ্যারেগুলি কখনই এতো বড় হয় না :-) এবং, @ অ্যান্ড্রেটি চতুর হলেও হ্যাক, আমি আমার কোডটি পাঠযোগ্য হতে পছন্দ করি :-)
প্যাক্সিডিয়ালো

4
@ প্যাক্সিডিয়াবল: এই "হ্যাক" একটি সুপ্রতিষ্ঠিত প্রতিমা। তার নুনের মূল্যবান যে কোনও প্রোগ্রামার তাৎক্ষণিকভাবে সনাক্ত করে। পঠনযোগ্যতার উপর এর কোনও নেতিবাচক প্রভাব নেই।
এএনটি

4
"20.২০.২.২" তে জ্যামিশ আইএসও সি 99৯ স্ট্যান্ডার্ড এন 1256, qsort"পয়েন্ট 4" ফাংশনটি যদি দুটি উপাদান সমান হিসাবে তুলনা করে, ফলাফল অনুসারে বাছাই করা অ্যারেতে তাদের ক্রমটি অনির্ধারিত। "
12431234123412341234123

62

সি / সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে ফাংশন <stdlib.h>রয়েছে qsort

এটি বিশ্বের সেরা দ্রুত সাজানোর বাস্তবায়ন নয় তবে এটি যথেষ্ট দ্রুত এবং ব্যবহার করা খুব সহজ ... কিউসোর্টের আনুষ্ঠানিক বাক্য গঠনটি হ'ল:

qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);

আপনার কেবলমাত্র যা প্রয়োগ করতে হবে তা হল তুলনা_ফানশন, যা "কনস্ট বেড" টাইপের দুটি যুক্তি গ্রহণ করে, যা যথাযথ ডেটা কাঠামোতে ফেলে দেওয়া যেতে পারে এবং তারপরে এই তিনটি মানের মধ্যে একটি ফিরিয়ে আনতে পারে:

  • নেতিবাচক, যদি একটি খ আগে হওয়া উচিত
  • 0, সমান হলে খ
  • ধনাত্মক, যদি একটি খ পরে করা উচিত

1. পূর্ণসংখ্যার একটি তালিকার তুলনা :

সহজেই পূর্ণসংখ্যায় a এবং b নিক্ষেপ করুন x < y, যদি x-yএটি নেতিবাচক হয়x == y , x-y = 0, x > y, x-yইতিবাচক x-yএকটি শর্টকাট পথ এখান থেকে কি :) বিপরীত হয় *x - *yথেকে *y - *xকমে মধ্যে বাছাইয়ের জন্য / বিপরীত ক্রম

int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}

2. স্ট্রিংগুলির একটি তালিকার তুলনা :

স্ট্রিং তুলনা করার জন্য, আপনার lib strcmpভিতরে ফাংশন প্রয়োজন <string.h>strcmpডিফল্টরূপে ফিরে আসবে, 0, যথাযথভাবে ... বিপরীত ক্রমে সাজানোর জন্য, কেবল স্ট্রাইক দ্বারা ফিরে আসা চিহ্নটি বিপরীত করুন

#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}

3. ভাসমান পয়েন্ট সংখ্যা তুলনা :

int compare_function(const void *a,const void *b) {
double *x = (double *) a;
double *y = (double *) b;
// return *x - *y; // this is WRONG...
if (*x < *y) return -1;
else if (*x > *y) return 1; return 0;
}

৪. একটি কী এর উপর ভিত্তি করে রেকর্ডের তুলনা করা :

কখনও কখনও আপনাকে আরও জটিল স্টাফগুলি যেমন রেকর্ড হিসাবে বাছাই করতে হবে। qsortলাইব্রেরি ব্যবহার করে এটি করার সহজ উপায় এখানে ।

typedef struct {
int key;
double value;
} the_record;

int compare_function(const void *a,const void *b) {
the_record *x = (the_record *) a;
the_record *y = (the_record *) b;
return x->key - y->key;
}

4
খুব সুন্দর উত্তর, তবে তুলনা ফাংশনের রিটার্ন মানটির ব্যাখ্যা পিছনের দিকে। এছাড়াও, কয়েকটি উদাহরণে, আপনি xy কৌশলটি করছেন, যা ত্রুটিপূর্ণ ফলাফল দিতে পারে (এবং একটি সাধারণ তুলনার চেয়ে কম সুস্পষ্ট)।
অ্যাড্রিয়ান ম্যাকার্থি

ঠিক আছে, আমি এখন যতটা উদ্বিগ্ন .. এটি প্রতিটি প্রতিযোগিতার জন্য কাজ করে;)
whacko__ ক্র্যাকো

4
Xy ট্রিক কাজ করে না যদি x এবং y এর মধ্যে পার্থক্য বৃহত্তম উপস্থাপনযোগ্য int এর চেয়ে বেশি হয়। সুতরাং দুটি ধনাত্মক সংখ্যার তুলনা করার সময় এটি ঠিক আছে, তবে তুলনা করতে ব্যর্থ হবে, যেমন, INT_MAX এবং -10। উত্সাহিত যদিও কারণ আমি খুব বিভিন্ন ধরণের বাছাইয়ের সমস্ত উদাহরণ পছন্দ করি।
ডগলাস

4
পাশাপাশি পূর্ণসংখ্যার তুলক এবং কী তুলনাকারী উভয় ক্ষেত্রে ওভারফ্লো সমস্যা, স্ট্রিং তুলনা ফাংশনটি ভুল। একটি অ্যারের বাছাই intকরার সময়, তুলনামূলককে যে মানগুলি দেওয়া হয়েছে তা উভয়ই int *ছদ্মবেশ ধারণ করে void *। একটি অ্যারের বাছাই char *করার সময়, তুলনামূলককে যে মানগুলি দেওয়া হয়েছে তা উভয়ই char **ছদ্মবেশ ধারণ করে void *। অতএব, সঠিক কোড হতে হবে: int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }
জোনাথন লেফলার

4
সংখ্যার তুলনাগুলির জন্য যা ওভারফ্লো প্রতিরোধী, বিবেচনা করুন if (x > y) return +1; else if (x < y) return -1; else return 0;বা আপনি যদি একটি সাধারণ অভিব্যক্তি চান, তবে return (x > y) - (x < y);। এটি সর্বদা সি স্তরে দুটি তুলনা মূল্যায়ন করে, তবে অপটিমাইজার এটি এড়াতে সক্ষম হতে পারে। বিয়োগফল স্বাক্ষরযুক্ত মানগুলিতে কাজ করে না। আপনি যখন কোনও কাঠামোর ধারাবাহিকের সাথে কাজ করছেন তখন প্রথম সংস্করণটি ভাল কাজ করে - প্রথমে কোনও কাঠামোর 2 সংখ্যক পূর্ণ সদস্যের তুলনা করা এবং যদি তারা সমান হয় তবে দুটি ডাবল, তারপরে দুটি স্ট্রিং ইত্যাদি করার একাধিক উপায় রয়েছে, সি হিসাবে পাশাপাশি পার্ল।
জোনাথন লেফলার

9

নিশ্চিতরূপে: qsort()এটি একটি সাজানোর একটি বাস্তবায়ন (এটির নাম হিসাবে সম্ভবত চিকুইসোর্টের প্রয়োজন হয় না)।

ম্যান 3 কিউসোর্ট চেষ্টা করে দেখুন বা http://linux.die.net/man/3/qsort এ পড়ুন


7
qsortকুইকসোর্ট ব্যবহার করে প্রয়োগ করতে হবে না।
জেমস ম্যাকনেলিস

6

ঠিক স্ট্যান্ডার্ড লাইব্রেরিতে না থাকাকালীন, https://github.com/swenson/sort এর মাত্র দুটি হেডার ফাইল রয়েছে যাতে আপনি বিস্ময়করভাবে দ্রুত বাছাই করার রাউটের বিস্তৃত পরিসরে অ্যাক্সেস পেতে অন্তর্ভুক্ত করতে পারেন:

# নির্ধারিত SORT_NAME int64
# নির্ধারণ SORT_TYPE int64_t
# নির্ধারিত SORT_CMP (x, y) ((x) - (y))
# অন্তর্ভুক্ত
/ * আপনার এখন int64_quick_sort, int64_tim_sort ইত্যাদির অ্যাক্সেস রয়েছে, যেমন, * /
int64_quick_sort (আরআর, 128); / * ধরে নিন আপনার কিছুটা ইনআর * বা আরআর রয়েছে [128]; * /

এটি স্ট্যান্ডার্ড লাইব্রেরির চেয়ে কমপক্ষে দ্বিগুণ দ্রুত হওয়া উচিত qsortকারণ এটি ফাংশন পয়েন্টার ব্যবহার করে না এবং এর মধ্যে আরও অনেকগুলি বাছাইকরণ অ্যালগরিদম বিকল্প রয়েছে।

এটি সি 89 এ রয়েছে, সুতরাং প্রতিটি সি সংকলকটি মূলত কাজ করা উচিত।



4

ব্যবহার করুন qsort()মধ্যে <stdlib.h>

@paxdiablo qsort()আইএসও / আইইসি 9899 ফাংশন কনর্ফাম করে 1990 ( `` আইএসও C90 '')।


3

এখানে বেশ কয়েকটি সি বাছাইয়ের ফাংশন পাওয়া যায় stdlib.h। আপনি man 3 qsortএকটি ইউনিক্স মেশিনে তাদের একটি তালিকা পেতে পারেন তবে সেগুলির মধ্যে রয়েছে:

  • হিপসোর্ট
  • কুইকোর্ট
  • সংযুক্তি

7
হিপসোর্ট এবং মার্জোর্ট মানক হয় না।
টেকনোইজ করুন

4
দুটোই কোকোয়ার্স্ট নয়। মানটি কোন অ্যালগরিদম ব্যবহার করা হয় তা নির্দেশ দেয় না।
paxdiablo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.