"সি ++ কনটেইনার পছন্দ" নামে একটি সুপরিচিত চিত্র (প্রতারণা পত্রক) রয়েছে। পছন্দসই ব্যবহারের জন্য সেরা ধারক চয়ন করার জন্য এটি একটি ফ্লো চার্ট।
ইতিমধ্যে এর C ++ 11 সংস্করণ রয়েছে কিনা তা কি কেউ জানেন?
এটি আগেরটি:
"সি ++ কনটেইনার পছন্দ" নামে একটি সুপরিচিত চিত্র (প্রতারণা পত্রক) রয়েছে। পছন্দসই ব্যবহারের জন্য সেরা ধারক চয়ন করার জন্য এটি একটি ফ্লো চার্ট।
ইতিমধ্যে এর C ++ 11 সংস্করণ রয়েছে কিনা তা কি কেউ জানেন?
এটি আগেরটি:
উত্তর:
আমি জানি না, তবে এটি অনুমান করা যায় যে এটি পাঠ্যভাবে করা যেতে পারে। এছাড়াও, চার্টটি সামান্য বন্ধ রয়েছে, কারণ list
সাধারণভাবে এটির মতো ভাল ধারক নয় এবং হয়ও না forward_list
। উভয় তালিকাগুলি কুলুঙ্গি প্রয়োগের জন্য খুব বিশেষ ধারক।
এই জাতীয় চার্ট তৈরি করতে আপনার কেবল দুটি সহজ গাইডলাইন প্রয়োজন:
পারফরম্যান্স নিয়ে চিন্তিত হওয়া প্রথমে প্রথমে অকেজো। আপনি যখন কয়েক হাজার (বা আরও বেশি) আইটেম পরিচালনা করতে শুরু করেন তখন বড় হে বিবেচনাগুলি কেবল সত্যই কিক হয় kick
দুটি বড় ধরণের পাত্রে রয়েছে:
find
অপারেশন রয়েছেএবং তারপর আপনি তাদের উপরে বিভিন্ন অ্যাডাপ্টারের নির্মাণ করতে পারেন: stack
, queue
, priority_queue
। আমি অ্যাডাপ্টারগুলি এখানে রেখে দেব, সেগুলি সনাক্তকরণের জন্য যথেষ্ট দক্ষ are
প্রশ্ন 1: সহযোগী ?
প্রশ্ন 1.1: আদেশ দেওয়া হয়েছে ?
unordered_
ধারক ব্যবহার করুন, অন্যথায় এটির traditionalতিহ্যবাহী অর্ডার করা অংশটি ব্যবহার করুন।প্রশ্ন 1.2: পৃথক কী ?
map
, অন্যথায় একটি ব্যবহার করুনset
প্রশ্ন 1.3: সদৃশ ?
multi
, অন্যথায় তা করবেন না।উদাহরণ:
মনে করুন যে আমার সাথে এক অনন্য আইডি যুক্ত বেশ কয়েকজন ব্যক্তি রয়েছেন এবং আমি তার আইডি থেকে যতটা সম্ভব সম্ভব কোনও ব্যক্তির ডেটা পুনরুদ্ধার করতে চাই।
আমি একটি find
ফাংশন চাই , এইভাবে একটি সাহসী ধারক
1.1। আমি অর্ডার সম্পর্কে কম যত্ন নিতে পারি না, এইভাবে একটি unordered_
ধারক
1.2। আমার কী (আইডি) এর সাথে সম্পর্কিত মানটির থেকে পৃথক, এইভাবে কmap
1.3। আইডি অনন্য, সুতরাং কোনও সদৃশ প্রবেশ করা উচিত নয়।
চূড়ান্ত জবাব হচ্ছে, std::unordered_map<ID, PersonData>
।
প্রশ্ন 2: স্মৃতি স্থিতিশীল ?
list
প্রশ্ন 2.1: কোনটি ?
list
; একটি forward_list
শুধুমাত্র কম মেমরির পদচিহ্নের জন্য দরকারী।প্রশ্ন 3: গতিশীল আকারের ?
{ ... }
সিনট্যাক্স ব্যবহার করে ), তারপরে একটি ব্যবহার করুন array
। এটি প্রচলিত সি-অ্যারে প্রতিস্থাপন করে তবে সুবিধাজনক ফাংশন সহ।প্রশ্ন 4: দ্বৈত-সমাপ্ত ?
deque
, অন্যথায় একটি ব্যবহার করুন vector
।আপনি নোট করবেন যে ডিফল্টরূপে, যদি না আপনার কোনও এসোসিয়েটিভ ধারক প্রয়োজন হয়, আপনার পছন্দটি একটি হবে vector
। দেখা যাচ্ছে এটি সুটার এবং স্ট্রাস্ট্রপের সুপারিশও ।
array
ডিফল্ট গঠনমূলক ধরণের প্রয়োজন হয় না; 2) এস বাছাইয়ের ক্ষেত্রে multi
ডুপ্লিকেট অনুমোদিত হওয়ার বিষয়ে তেমন কিছু নয় তবে সেগুলি রাখার বিষয়টি সম্পর্কে (আপনি নকলগুলি নন- multi
ধারক পাত্রে রাখতে পারেন, এটি ঘটে কেবলমাত্র একটি রাখা হয়)।
map.find(key)
অনেক বেশি প্রসারণযোগ্য std::find(map.begin(), map.end(), [&](decltype(map.front()) p) { return p.first < key; }));
, তাই এটি অর্থাত্পকভাবে গুরুত্বপূর্ণ, এটি সেই find
সদস্যের চেয়ে বরং সদস্যের কাজ <algorithm>
। ও (1) বনাম ও (লগ এন) হিসাবে, এটি শব্দার্থকে প্রভাবিত করে না; আমি উদাহরণ থেকে "দক্ষতা" মুছে ফেলব এবং এটিকে "সহজেই" দিয়ে প্রতিস্থাপন করব।
deque
এই সম্পত্তিটিও কি আছে?
deque
উপাদানের স্থিতিশীল হয় শুধুমাত্র যদি আপনি ধাক্কা পারেন শেষে / POP; আপনি যদি মাঝখানে সন্নিবেশ / মুছতে শুরু করেন তবে তৈরি করা শূন্যস্থান পূরণ করতে N / 2 টি উপাদান পর্যন্ত পরিবর্তন করা হবে।
আমি ম্যাথিউয়ের উত্তরটি পছন্দ করি তবে আমি ফ্লোচার্টটিকে এটি আবার চালু করতে যাচ্ছি:
ডিফল্টরূপে, আপনার যদি স্টাফের ধারক দরকার হয় তবে ব্যবহার করুন std::vector
। সুতরাং, প্রতিটি অন্যান্য ধারক কেবল কিছু কার্যকারিতা বিকল্প সরবরাহ করে ন্যায্য std::vector
।
std::vector
এর বিষয়বস্তুগুলি চলনযোগ্য-গঠনমূলক হিসাবে প্রয়োজন, কারণ এটি চারপাশে আইটেমগুলি বদল করতে সক্ষম হওয়া প্রয়োজন। বিষয়বস্তুতে রাখার জন্য এটি কোনও ভয়াবহ বোঝা নয় (নোট করুন যে ডিফল্ট কনস্ট্রাক্টরগুলির প্রয়োজন নেই , ধন্যবাদ emplace
এবং আরও কিছু)। তবে অন্যান্য পাত্রে বেশিরভাগ ক্ষেত্রেই কোনও নির্দিষ্ট নির্মাণকারীর প্রয়োজন হয় না (আবারও ধন্যবাদ জানাই emplace
)। সুতরাং আপনার যদি এমন কোনও অবজেক্ট থাকে যেখানে আপনি মুভি কনস্ট্রাক্টরকে পুরোপুরি বাস্তবায়ন করতে পারবেন না , তবে আপনাকে অন্য কিছু বাছাই করতে হবে।
এ std::deque
হ'ল সাধারণ প্রতিস্থাপন, এর অনেকগুলি বৈশিষ্ট্য রয়েছে std::vector
তবে আপনি কেবলমাত্র ডেকের উভয় প্রান্তে সন্নিবেশ করতে পারেন। মাঝখানে সন্নিবেশ করানো প্রয়োজন। একটি std::list
বিষয়বস্তুতে কোনও প্রয়োজন রাখে না।
std::vector<bool>
এটি না. ভাল, এটা মান। তবে এটি vector
সাধারণ অর্থে কোনও নয়, কারণ std::vector
সাধারণত পরিচালনা করা অপারেশন নিষিদ্ধ। এবং এটা অবশ্যই ধারণ করে না bool
গুলি ।
অতএব, যদি আপনার vector
কোনও ধারক থেকে সত্যিকারের আচরণের প্রয়োজন হয় তবে আপনি এটিটি থেকে bool
পাবেন না std::vector<bool>
। সুতরাং আপনি একটি দিয়ে দিতে হবে std::deque<bool>
।
আপনি একটি কন্টেইনারে উপাদান খুঁজে পেতে প্রয়োজন, এবং অনুসন্ধান ট্যাগ মাত্র একটি সূচক হতে পারে না, তাহলে আপনি পরিত্যাগ করার প্রয়োজন হতে পারে std::vector
পক্ষে set
এবং map
। মূল শব্দটি " মে " নোট করুন ; বাছাই std::vector
করা কখনও কখনও যুক্তিসঙ্গত বিকল্প হয়। বা বুস্ট.কন্টেইনারগুলি flat_set/map
, যা একটি সাজানো কার্যকর করে std::vector
।
এগুলির এখন চারটি ভিন্নতা রয়েছে যার প্রত্যেকটির নিজস্ব চাহিদা রয়েছে।
map
যখন অনুসন্ধান ট্যাগটি আপনি যে আইটেমটি নিজেরাই সন্ধান করছেন তেমন জিনিস নয় তখন ব্যবহার করুন । না হলে ব্যবহার করুন ক set
।unordered
যখন আপনি একটি আছে অনেক কন্টেইনারে আইটেম এবং অনুসন্ধান করুন কর্মক্ষমতা একেবারে হওয়া প্রয়োজন O(1)
বদলে O(logn)
।multi
একই অনুসন্ধান ট্যাগ পেতে আপনার যদি একাধিক আইটেমের প্রয়োজন হয় তবে ব্যবহার করুন ।আপনার যদি কোনও নির্দিষ্ট তুলনা ক্রিয়াকলাপের ভিত্তিতে আইটেমগুলির একটি ধারক সর্বদা বাছাই করার প্রয়োজন হয় তবে আপনি এ ব্যবহার করতে পারেন set
। বা multi_set
যদি আপনার একই মানটির জন্য একাধিক আইটেমের প্রয়োজন হয়।
বা আপনি বাছাই করা ব্যবহার করতে পারেন std::vector
তবে আপনাকে এটি বাছাই করে রাখতে হবে।
যখন পুনরাবৃত্তিকারী এবং রেফারেন্সগুলি অবৈধ হয় তখন কখনও কখনও উদ্বেগ থাকে। আপনার যদি আইটেমগুলির একটি তালিকার প্রয়োজন হয়, যেমন আপনার অন্যান্য বিভিন্ন স্থানে সেই আইটেমগুলিতে পুনরাবৃত্তকারী / পয়েন্টার রয়েছে, তবে std::vector
অবৈধকরণের দিকে দৃষ্টি নিবদ্ধ করা উপযুক্ত নাও হতে পারে। যে কোনও সন্নিবেশ ক্রিয়াকলাপটি বর্তমান আকার এবং সামর্থ্যের উপর নির্ভর করে অবৈধতার কারণ হতে পারে।
std::list
দৃ firm় গ্যারান্টি সরবরাহ করে: একটি পুনরাবৃত্তিকারী এবং এর সাথে সম্পর্কিত রেফারেন্স / পয়েন্টার কেবল তখনই অবৈধ হয় যখন আইটেমটি নিজেই ধারক থেকে সরানো হয়। std::forward_list
স্মৃতি যদি একটি গুরুতর উদ্বেগ হয় সেখানে আছে।
যদি এটি খুব শক্তিশালী গ্যারান্টি থাকে তবে std::deque
একটি দুর্বল তবে দরকারী গ্যারান্টি সরবরাহ করে। মাঝখানে সন্নিবেশ থেকে অবৈধকরণের ফলাফল, তবে মাথা বা লেজে সন্নিবেশগুলি কেবল পুনরাবৃত্তকারীদের অবৈধকরণের কারণ , পাত্রে আইটেমের পয়েন্টার / রেফারেন্স নয়।
std::vector
কেবল শেষে সস্তায় সন্নিবেশ সরবরাহ করে (এবং তারপরেও, আপনি সক্ষমতা ফুটিয়ে তুললে এটি ব্যয়বহুল হয়ে যায়)।
std::list
পারফরম্যান্সের ক্ষেত্রে ব্যয়বহুল (প্রতিটি নতুন সন্নিবেশ করা আইটেমটির জন্য একটি মেমরি বরাদ্দ খরচ হয়), তবে এটি সামঞ্জস্যপূর্ণ । এটি কার্যত কোনও পারফরম্যান্স ব্যয়ের জন্য আইটেমগুলি প্রায়শই বদল করার পাশাপাশি মাঝে মাঝে পারফরম্যান্সের std::list
কোনও ক্ষতি না করে একই ধরণের অন্যান্য ধারকগুলির সাথে আইটেম বাণিজ্য করার জন্য মাঝে মাঝে অনিবার্য ক্ষমতাও সরবরাহ করে । আপনার যদি প্রচুর পরিমাণে জিনিসগুলি বদলাতে হয় তবে ব্যবহার করুন std::list
।
std::deque
মাথা এবং লেজে স্থির সময় সন্নিবেশ / অপসারণ সরবরাহ করে তবে মাঝখানে সন্নিবেশ মোটামুটি ব্যয়বহুল হতে পারে। সুতরাং আপনার যদি সামনে এবং পিছনের দিক থেকে জিনিসগুলি যুক্ত / সরানোর প্রয়োজন হয় তবে std::deque
আপনার যা প্রয়োজন তা হতে পারে।
এটি লক্ষ করা উচিত যে, শব্দার্থবিজ্ঞান স্থানান্তরিত করার জন্য ধন্যবাদ, std::vector
সন্নিবেশ সম্পাদনাটি আগের মতো খারাপ হতে পারে না। কিছু বাস্তবায়ন একধরণের মুভ সিমানটিক-ভিত্তিক আইটেম অনুলিপি (তথাকথিত "স্বাপ্টিমাইজেশন") বাস্তবায়িত করেছিল, কিন্তু এখন যে চলন্ত ভাষার অঙ্গ, এটি মান দ্বারা বাধ্যতামূলক।
std::array
আপনি যদি সম্ভব সবচেয়ে কম গতিশীল বরাদ্দ চান তবে এটি একটি সূক্ষ্ম ধারক। এটি একটি সি-অ্যারের চারপাশে কেবল একটি মোড়ক; এর অর্থ হ'ল এটির আকার অবশ্যই সংকলন সময়ে জানা উচিত । আপনি যদি এটি নিয়ে বেঁচে থাকতে পারেন তবে ব্যবহার করুন std::array
।
যা বলা হচ্ছে , একটি আকার ব্যবহার std::vector
এবং reserve
আইএনও করা একটি গণ্ডির জন্য ঠিক পাশাপাশি কাজ করবে std::vector
। এইভাবে, প্রকৃত আকারটি পৃথক হতে পারে এবং আপনি কেবল একটি মেমরি বরাদ্দ পান (যদি না আপনি ক্ষমতাটি ফুটিয়ে তোলেন)।
std::sort
এমন কিছু রয়েছে std::inplace_merge
যা সহজেই নতুন উপাদানগুলি (একটি std::lower_bound
+ std::vector::insert
কলের পরিবর্তে ) সহজেই আকর্ষণীয় । ভালো লাগার কথা flat_set
এবং flat_map
!
vector<bool>
হয় vector<char>
।
std::allocator<T>
এই প্রান্তিককরণটিকে সমর্থন না করে (এবং কেন এটি হবে না আমি জানি না), তবে আপনি সর্বদা আপনার নিজস্ব কাস্টম বরাদ্দকারীকে ব্যবহার করতে পারেন।
std::vector::resize
একটি ওভারলোড রয়েছে যা কোনও মূল্য নেয় না (এটি কেবলমাত্র নতুন আকার নেয়; কোনও নতুন উপাদান স্থানে-স্থানে নির্ধারিত হবে)। এছাড়াও, সংকলকগণ কেন মান প্যারামিটারগুলি যথাযথভাবে সারিবদ্ধ করতে অক্ষম, এমনকি যখন তাদের সেই সারিবদ্ধকরণের ঘোষণা দেওয়া হয়?
bitset
বুলের
উপরের ফ্লোচার্টের সি ++ 11 সংস্করণ এখানে। [মূলত এর মূল লেখক, মিকেল পারসনকে অ্যাট্রিবিউট ছাড়াই পোস্ট করা হয়েছে ]
এখানে একটি দ্রুত স্পিন, যদিও এটি সম্ভবত কাজের প্রয়োজন
Should the container let you manage the order of the elements?
Yes:
Will the container contain always exactly the same number of elements?
Yes:
Does the container need a fast move operator?
Yes: std::vector
No: std::array
No:
Do you absolutely need stable iterators? (be certain!)
Yes: boost::stable_vector (as a last case fallback, std::list)
No:
Do inserts happen only at the ends?
Yes: std::deque
No: std::vector
No:
Are keys associated with Values?
Yes:
Do the keys need to be sorted?
Yes:
Are there more than one value per key?
Yes: boost::flat_map (as a last case fallback, std::map)
No: boost::flat_multimap (as a last case fallback, std::map)
No:
Are there more than one value per key?
Yes: std::unordered_multimap
No: std::unordered_map
No:
Are elements read then removed in a certain order?
Yes:
Order is:
Ordered by element: std::priority_queue
First in First out: std::queue
First in Last out: std::stack
Other: Custom based on std::vector?????
No:
Should the elements be sorted by value?
Yes: boost::flat_set
No: std::vector
আপনি লক্ষ্য করতে পারেন যে এটি সি ++ 03 সংস্করণ থেকে বন্যভাবে পৃথক হয়েছে , মূলত এই কারণে যে আমি লিঙ্কযুক্ত নোডগুলি পছন্দ করি না to সংযুক্ত নোড পাত্রে সাধারণত কয়েকটি বিরল পরিস্থিতিতে বাদে কোনও লিঙ্কযুক্ত কনটেইনার দ্বারা কার্য সম্পাদনে বীট দেওয়া যায়। আপনি যদি না জানেন যে এই পরিস্থিতিগুলি কী এবং আপনার উত্সাহের অ্যাক্সেস রয়েছে তবে লিঙ্কযুক্ত নোড পাত্রে ব্যবহার করবেন না। (এসটিডি :: তালিকা, এসটিডি :: স্লিস্ট, স্টাডি :: মানচিত্র, এসটিডি :: মাল্টিম্যাপ, স্ট্যান্ড :: সেট, স্ট্যান্ড :: মাল্টিসেট)। এই তালিকাটি বেশিরভাগ ক্ষেত্রে ছোট এবং মাঝারি পার্শ্বযুক্ত পাত্রে ফোকাস করে, কারণ (ক) যা আমরা কোডে ব্যবহার করি তার 99.99%, এবং (খ) বিপুল সংখ্যক উপাদানের কাস্টম অ্যালগরিদম প্রয়োজন, ভিন্ন ধারক নয়।