সি ++ এ বনাম হ্যাশ_ম্যাপ মানচিত্র


117

সি ++ এর সাথে hash_mapএবং আমার একটি প্রশ্ন রয়েছে map। আমি বুঝতে পারি যে mapএটি এসটিএলে রয়েছে, তবে hash_mapএটি কোনও মানদণ্ড নয়। দুজনের মধ্যে পার্থক্য কী?

উত্তর:


133

এগুলি খুব আলাদা উপায়ে প্রয়োগ করা হয়।

hash_map( unordered_mapটিআর 1 এবং বুস্টে; পরিবর্তে সেগুলি ব্যবহার করুন) একটি হ্যাশ টেবিল ব্যবহার করুন যেখানে টেবিলের একটি স্লটে কী হ্যাশ করা হবে এবং মানটি সেই চাবিটির সাথে তালিকায় থাকা একটি তালিকায় সংরক্ষণ করা হবে।

map ভারসাম্য বাইনারি অনুসন্ধান গাছ হিসাবে সাধারণত প্রয়োগ করা হয় (সাধারণত একটি লাল / কালো গাছ)।

একটি unordered_mapসংগ্রহ মৌলকে ব্যবহার করার জন্য সামান্য ভাল পারফরম্যান্স দিতে হবে, কিন্তু একটি map(যেমন এটা সাজানো ক্রম, যা শুরু থেকে শেষ পর্যন্ত ট্র্যাভেরসাল পারবেন মধ্যে সংরক্ষিত হয়) অতিরিক্ত দরকারী বৈশিষ্ট্য থাকবে। unordered_mapসন্নিবেশ করাতে এবং মুছতে দ্রুত হবে map


7
পারফরম্যান্স সম্পর্কে আমি আপনার সাথে পুরোপুরি একমত নই। কর্মক্ষমতাটি বেশ কয়েকটি পরামিতি দ্বারা প্রভাবিত হয় এবং আমি কোনও প্রোগ্রামারকে মাত্র 10 টি প্রবেশের জন্য একটি আনর্ডারড_ম্যাপ ব্যবহার করে তিরস্কার করব কারণ "এটি দ্রুত"। প্রথমে ইন্টারফেস / কার্যকারিতা সম্পর্কে চিন্তা করুন, পরে কার্য সম্পাদন করুন।
ম্যাথিউ এম।

24
ঠিক আছে, হ্যাঁ, আপনি যদি নিজের সমস্যাটি বুঝতে পারেন তবে এটি সহায়তা করে। মাত্রার নির্দিষ্ট অর্ডার পর্যন্ত এটি সম্ভবত ধোয়ার কার্য সম্পাদন-ভিত্তিক, তবে উভয় পাত্রে পারফরম্যান্সের বৈশিষ্ট্যগুলি বোঝা গুরুত্বপূর্ণ কারণ তারা বিভিন্ন পরিমাণে ডেটা ভলিউম বড় হওয়ার সাথে সাথে বিচ্যুত হয়।
জো

7
মজার বিষয় হচ্ছে, আমি একটি অ্যাপ্লিকেশনটিতে একটি বর্ধিত :: আনর্ডারড_ম্যাপের সাহায্যে একটি স্টডি :: মানচিত্রটি সরিয়ে দিয়েছি যাতে আমি প্রচুর এলোমেলোভাবে অনুসন্ধান করি, তবে মানচিত্রের সমস্ত কীতে পুনরাবৃত্তিও করি। আমি সন্ধানের ক্ষেত্রে প্রচুর সময় সাশ্রয় করেছি, তবে এটি পুনরাবৃত্তির মাধ্যমে ফিরে পেয়েছি, তাই আমি মানচিত্রে ফিরে গিয়ে অ্যাপ্লিকেশনটির কার্যকারিতা উন্নত করার জন্য অন্যান্য উপায়গুলি খুঁজছি am
এরিক গ্যারিসন

4
@ এরিকগ্রিসন যদি আপনি উপাদানগুলি সন্নিবেশ করা এবং মুছার চেয়ে অনেক বেশি পরিমাণে এলোমেলো অ্যাক্সেস এবং পুনরাবৃত্তি ব্যবহার করেন তবে আপনার গাছ এবং হ্যাশ_ম্যাপ উভয়তে আপনার বস্তু থাকতে পারে (উভয় ক্ষেত্রে একই পয়েন্টারে একটি পয়েন্টার বা আরও ভাল একটি শেয়ার্ড_পিটার সংরক্ষণ করে) যদি আপনি প্রকৃত উদাহরণ ব্যবহার করেন)। তারপরে আপনার কাছে হ্যাশ_ম্যাপ এবং ও (এন) পুনরাবৃত্তির সময় মানচিত্রের মাধ্যমে ও (1) সময় অ্যাক্সেসের সময় থাকবে। অবশ্যই, আপনাকে প্রতিটি সময়ই উভয় থেকে পয়েন্টার যুক্ত করতে এবং সরাতে হবে। আপনি সহজেই একটি কাস্টম ধারক শ্রেণি লিখতে পারেন যা সম্ভবত এটির জন্য টেমপ্লেটও রয়েছে যা আপনার জন্য এই আচরণটি সজ্জিত করে।
স্প্রাইটে

2
@ এরিকগ্যারিসন অবশ্যই, আপনি যদি এই পদ্ধতিটি ব্যবহার করেন তবে আপনি একটি সামান্য অতিরিক্ত স্থান দিয়ে অর্থ প্রদান করবেন। তবে, যেহেতু আপনি পয়েন্টার ব্যবহার করছেন, এটি খুব বেশি হওয়া উচিত নয়। আপনি যদি সত্যিই চান, আপনি ওভারবোর্ডে যেতে পারেন এবং নিজের কোনও এভিএল প্রয়োগ করতে পারেন এবং ন্যাশ পয়েন্টারটিকে হ্যাশ_ম্যাপে আপনার ডেটা টাইপ হিসাবে ব্যবহার করতে পারেন, এটি আপনাকে গাছের একটি নোডে ও (1) সময় অ্যাক্সেস দেবে আপনি যেখানেই প্রয়োজন সেখানে রৈখিকভাবে পুনরাবৃত্তি করতে সক্ষম হবেন। অবশ্যই এতে বেশ কিছুটা কোডিং জড়িত থাকবে এবং আমি নিশ্চিত নই যে আপনি যদি এলোমেলোভাবে অ্যাক্সেসের জায়গা এবং অবিচ্ছিন্ন অ্যাক্সেসের প্রয়োজন না পড়েন তবে এটি পরিশোধ করে।
23:44

35

hash_mapঅনেক লাইব্রেরি বাস্তবায়ন দ্বারা সরবরাহ করা একটি সাধারণ এক্সটেনশন ছিল। ঠিক এই কারণেই unordered_mapযখন এটি টিআর 1 এর অংশ হিসাবে সি ++ স্ট্যান্ডার্ডে যুক্ত করা হয়েছিল তখন এর নামকরণ করা হয়েছিল। মানচিত্রটি সাধারণত একটি লাল-কালো গাছের মতো ভারসাম্য বাইনারি গাছের সাথে প্রয়োগ করা হয় (প্রয়োগগুলি অবশ্যই পৃথকভাবে পৃথক হয়)। hash_mapএবং unordered_mapসাধারণত হ্যাশ টেবিলগুলি দিয়ে প্রয়োগ করা হয়। এভাবে অর্ডার বজায় থাকে না। unordered_mapসন্নিবেশ / মুছুন / ক্যোয়ারি হবে ও (1) (ধ্রুবক সময়) যেখানে মানচিত্রটি ও (লগ এন) হবে যেখানে এন ডাটা স্ট্রাকচারের আইটেমের সংখ্যা। তাই unordered_mapদ্রুত, এবং যদি আপনি আইটেমগুলির ক্রমটি যত্ন না করেন তবে তার চেয়ে বেশি পছন্দ করা উচিত map। কখনও কখনও আপনি অর্ডার বজায় রাখতে চান (কী দ্বারা নির্দেশিত) এবং এটির জন্য mapপছন্দ হবে।


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

একটি ভাল হ্যাশম্যাপের ও (1) এর প্রত্যাশিত ব্যয় হয়, এটির গ্যারান্টি নেই। খারাপ হ্যাশম্যাপগুলির একটি প্রত্যাশিত ব্যয় থাকতে পারে যা ও (1) নয়।
ক্লিয়ারার

14

কিছু মূল পার্থক্য জটিলতার প্রয়োজনীয়তার মধ্যে রয়েছে।

  • একটি mapপ্রয়োজন O(log(N))যেমন একটি হিসাবে প্রয়োগ করা যাচ্ছে, টিপে এবং খুঁজে বের করে অপারেশনের জন্য সময় লাল-কালো বৃক্ষ ডাটা স্ট্রাকচার।

  • একটি unordered_mapএকজন 'গড়' সময়ের প্রয়োজন O(1)টিপে এবং খুঁজে বের করে, কিন্তু একটি খারাপ-কেস সময় রাখার অনুমতি পায় O(N)। এটি হ্যাশ টেবিল ডেটা স্ট্রাকচার ব্যবহার করে প্রয়োগ করা হয়েছে ।

সুতরাং, সাধারণত, unordered_mapদ্রুত হবে তবে কীগুলি এবং আপনার সংরক্ষণ করা হ্যাশ ফাংশনের উপর নির্ভর করে আরও খারাপ হতে পারে।


4

সি ++ স্পপটি এসটিএল ধারকগুলির জন্য আপনাকে অবশ্যই কোন অ্যালগরিদম ব্যবহার করতে হবে তা বলে না। এটি অবশ্য তাদের কর্মক্ষমতাতে কিছুটা প্রতিবন্ধকতা তৈরি করে, যা হ্যাশ টেবিলগুলি mapএবং অন্যান্য এসোসিয়েটিভ পাত্রে ব্যবহারের বিষয়টি অস্বীকার করে । (এগুলি সাধারণত লাল / কালো গাছের সাথে প্রয়োগ করা হয়)) হ্যাশ টেবিলগুলি বিতরণ করতে পারে তার চেয়ে এই পাত্রে জন্য এই সীমাবদ্ধতার জন্য সবচেয়ে খারাপ-খারাপ পারফরম্যান্স প্রয়োজন।

অনেক লোক সত্যিই হ্যাশ টেবিলগুলি চান না, তবে হ্যাশ-ভিত্তিক এসটিএল এসোসিয়েটিভ পাত্রে বছরের পর বছর ধরে একটি সাধারণ বর্ধন ছিল। ফলস্বরূপ, তারা unordered_mapসি ++ স্ট্যান্ডার্ডের পরবর্তী সংস্করণগুলিতে যুক্ত হয়েছিল ।


এটি আসলে টিআর 1 এ যুক্ত হয়েছিল (স্ট্যান্ড :: ট্র 1 :: আনর্ডার্ড_ম্যাপ), সি ++ 0x নয়
টেরি মাহাফি

আমি ভেবেছিলাম যে কারণটি mapসাধারণত একটি ভারসাম্য btree কারণ operator<()অবস্থান নির্ধারণের উপায় হিসাবে ব্যবহার করার কারণে ছিল ।
কিটসুনওয়াইএমজি

@ কেটিএস: কোনও এসটিএল বাস্তবায়ন কি আসলে একটি বি-ট্রি ব্যবহার করে?
বি কে

প্রযুক্তিগতভাবে সমস্ত বাইনারি অনুসন্ধান গাছ হ'ল বি-ট্রি (একটি 1-2 গাছ)। বলা হচ্ছে, আমি কোনও এসটিএল সম্পর্কে জানি না যা লাল / কালো ছাড়া অন্য কিছু ব্যবহার করে
KitsuneYMG

@ bk1e "যথাযথ" বি-গাছগুলি ডাটাবেসগুলিতে ব্যতিক্রমীভাবে কার্যকর, যেখানে আপনি "ফ্যাট" ট্রি নোডগুলি চান যা ডিস্ক পৃষ্ঠাগুলির সাথে ভালভাবে সাজায়। ওটিও, "সাধারণ" প্রোগ্রামগুলিতে ব্যবহৃত "ফ্ল্যাট" মেমরি মডেলটিতে এটি এতটা কার্যকর নয় - সমস্ত এসটিএল বাস্তবায়ন আমি জানি যে লাল-কালো গাছ ব্যবহার use
ব্র্যাঙ্কো দিমিত্রিজেভিক

3

mapbalanced binary search tree(সাধারণত ক rb_tree) থেকে প্রয়োগ করা হয় , যেহেতু এতে থাকা সমস্ত সদস্যকে balanced binary search treeসাজানো হয় তাই মানচিত্র;

hash_mapথেকে বাস্তবায়িত হয় hashtable.Since সব সদস্য hashtableunsorted হয় তাই সদস্যদের মধ্যে hash_map(unordered_map)সাজানো নয়।

hash_mapকোনও সি ++ স্ট্যান্ডার্ড লাইব্রেরি নয়, তবে এখন এটির নাম পরিবর্তন করে unordered_map(আপনি এটির পুনরায় নামকরণের কথা ভাবতে পারেন) এবং সি ++ স্ট্যান্ডার্ড লাইব্রেরি হয়ে যায় যেহেতু সি ++ 11 এই প্রশ্নটি দেখুন হ্যাশ_ম্যাপ এবং আনর্ডার্ড_ম্যাপের মধ্যে পার্থক্য? আরও বিশদ জন্য।

নীচে আমি দুই ধরণের মানচিত্র কীভাবে প্রয়োগ করা হয় তার উত্স কোড থেকে কিছু মূল ইন্টারফেস দেব।

মানচিত্র:

নীচের কোডটি কেবল এটি দেখানোর জন্যই, মানচিত্রটি কেবল একটি র‍্যাপার হয় balanced binary search tree, প্রায় সমস্ত এটির ফাংশনটি কেবল ফাংশনকেই অনুরোধ করে balanced binary search tree

template <typename Key, typename Value, class Compare = std::less<Key>>
class map{
    // used for rb_tree to sort
    typedef Key    key_type;

    // rb_tree node value
    typedef std::pair<key_type, value_type> value_type;

    typedef Compare key_compare;

    // as to map, Key is used for sort, Value used for store value
    typedef rb_tree<key_type, value_type, key_compare> rep_type;

    // the only member value of map (it's  rb_tree)
    rep_type t;
};

// one construct function
template<typename InputIterator>
map(InputIterator first, InputIterator last):t(Compare()){
        // use rb_tree to insert value(just insert unique value)
        t.insert_unique(first, last);
}

// insert function, just use tb_tree insert_unique function
//and only insert unique value
//rb_tree insertion time is : log(n)+rebalance
// so map's  insertion time is also : log(n)+rebalance 
typedef typename rep_type::const_iterator iterator;
std::pair<iterator, bool> insert(const value_type& v){
    return t.insert_unique(v);
};

hash_map:

hash_maphashtableযার কাঠামো কিছুটা এরকম থেকে কার্যকর করা হয়েছে :

এখানে চিত্র বর্ণনা লিখুন

নীচের কোডে, আমি এর প্রধান অংশ দেব hashtable, এবং তারপর দেয় hash_map

// used for node list
template<typename T>
struct __hashtable_node{
    T val;
    __hashtable_node* next;
};

template<typename Key, typename Value, typename HashFun>
class hashtable{
    public:
        typedef size_t   size_type;
        typedef HashFun  hasher;
        typedef Value    value_type;
        typedef Key      key_type;
    public:
        typedef __hashtable_node<value_type> node;

        // member data is buckets array(node* array)
        std::vector<node*> buckets;
        size_type num_elements;

        public:
            // insert only unique value
            std::pair<iterator, bool> insert_unique(const value_type& obj);

};

ভালো লেগেছে map'sশুধুমাত্র সদস্য rb_tree, hash_map'sশুধুমাত্র সদস্য hashtable। এটি নীচের মত মূল কোড:

template<typename Key, typename Value, class HashFun = std::hash<Key>>
class hash_map{
    private:
        typedef hashtable<Key, Value, HashFun> ht;

        // member data is hash_table
        ht rep;

    public:
        // 100 buckets by default
        // it may not be 100(in this just for simplify)
        hash_map():rep(100){};

        // like the above map's insert function just invoke rb_tree unique function
        // hash_map, insert function just invoke hashtable's unique insert function
        std::pair<iterator, bool> insert(const Value& v){
                return t.insert_unique(v);
        };

};

চিত্রের নীচে দেখানো হয় যখন একটি হ্যাশ_ম্যাপে 53 টি বালতি রয়েছে এবং কিছু মান সন্নিবেশ করা হয়, এটি অভ্যন্তরীণ কাঠামো।

এখানে চিত্র বর্ণনা লিখুন

নীচের চিত্রটি মানচিত্র এবং হ্যাশ_ম্যাপ (আনর্ডার্ড_ম্যাপ) এর মধ্যে কিছু পার্থক্য দেখায়, চিত্রটি কীভাবে মানচিত্র এবং আনর্ডারড_ম্যাপের মধ্যে নির্বাচন করতে হয় তা থেকে আসে ? :

এখানে চিত্র বর্ণনা লিখুন


1

আমি কী জানি তা জানিনা, তবে, হ্যাশ_ম্যাপটি () 150 কে স্বাক্ষরযুক্ত পূর্ণসংখ্যা কী এবং ভাসমান মানগুলি সাফ করতে 20 সেকেন্ডের বেশি সময় নেয় takes আমি কেবল চালিয়ে যাচ্ছি এবং অন্য কারও কোড পড়ছি।

এটি হ্যাশ_ম্যাপকে অন্তর্ভুক্ত করে।

#include "StdAfx.h"
#include <hash_map>

আমি এটি এখানে পড়ছি https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap

পরিষ্কার করে বলা () হ'ল ও (এন) এর আদেশ। আমার কাছে এটি খুব আশ্চর্যজনক, তবে এটি এইভাবে।

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