ডেটা স্ট্রাকচার: Oোকান, মুছে ফেলুন, অন্তর্ভুক্ত করুন, এলোমেলো উপাদান পান, সমস্ত ও (1)


96

একটি সাক্ষাত্কারে আমাকে এই সমস্যাটি দেওয়া হয়েছিল। আপনি কিভাবে উত্তর দিতে হবে?

O (1) সময়ে নিম্নলিখিত ক্রিয়াকলাপ সরবরাহ করে এমন একটি ডেটা স্ট্রাকচার ডিজাইন করুন:

  • .োকান
  • অপসারণ
  • থাকে
  • এলোমেলো উপাদান পান

আমরা কি ধরণের ডেটাতে অতিরিক্ত বিধিনিষেধ গ্রহণ করতে পারি? যেমন কোনও সদৃশ ইত্যাদি নেই
সঞ্জীবকুমার হীরমঠ

অবশ্যই, কোনও সদৃশ নেই, আপনি এমনকি জাভা বা সি # এর মতো ভাষায় ডেটা স্ট্রাকচারে অন্তর্নির্মিত ব্যবহার করতে পারেন।
গিল্ডনার 21

4
আমি লক্ষ করেছি যে কোনও স্পেসিফিকেশন পুনরায় নেই: অর্ডার / অর্ডারড
চার্লস ডাফি

7
আমি জানি এই পোস্টটির উত্তর আমার কাছে দেওয়া হয়েছে তবে তারা যদি আপনাকে ও (1) এলোমেলোভাবে অ্যাক্সেস সরবরাহ করতে চান তবে এটি আরও বোধগম্য হবে।
রমসিনব

আপনি কি এর সঠিক সমাধান খুঁজে পেয়েছেন?
বালাজী বোগগ্রাম রমনারায়ণ

উত্তর:


145

হ্যাশটেবল এইচ এবং একটি অ্যারে নিয়ে গঠিত একটি ডেটা কাঠামো বিবেচনা করুন The হ্যাশটেবল কীগুলি ডেটা কাঠামোর উপাদান এবং মানগুলি অ্যারেতে তাদের অবস্থান positions

  1. সন্নিবেশ (মান): অ্যারেতে মান সংযোজন করুন এবং আমাকে এ। এ সেট করুন [মান] = i।
  2. অপসারণ (মান): আমরা এ এর ​​মধ্যে সর্বশেষ উপাদানটির সাথে ক এর মান সমেত এমন কক্ষটি প্রতিস্থাপন করতে যাচ্ছি যা সূচকের এম তে অ্যারেতে সর্বশেষ উপাদান হয়। আমি এইচ [মান], মান অ্যারের সূচক মুছে ফেলা যাক। A [i] = d, H [d] = i সেট করুন, অ্যারের আকার এক এক করে হ্রাস করুন এবং এইচ থেকে মান সরিয়ে নিন
  3. (মান) রয়েছে: এইচ সি কনটেইনস (মান) প্রদান করুন
  4. getRandomElement (): চলুন r = এলোমেলো (এ এর বর্তমান আকার)। A [r] ফিরিয়ে দিন।

যেহেতু অ্যারের আকারে স্বয়ংক্রিয়ভাবে বৃদ্ধি হওয়া দরকার তাই এটি একটি উপাদান যুক্ত করতে ও (1) orষধটি করা হবে, তবে আমার ধারণা এটি ঠিক আছে that's


এটি আমার কাছে যা ছিল তার কাছাকাছি, তবে আমি নিজেই কীগুলির হিসাবে উপাদানগুলির ব্যবহারটি মিস করেছি ....
গিল্ডনার

এটি আকর্ষণীয় যে আমি এই প্রশ্নটি একটি গুগল ফোনের স্ক্রিনে পেয়েছি এবং কিছু লড়াইয়ের পরে একই সমাধানে আটকে গিয়েছি। আমি কিছুটা বাস্তবায়ন ঘটিয়েছি এবং দ্বিতীয় ফোনের স্ক্রিনে বরাদ্দ করেছি।
আন্দ্রে তাল্নিকভ

অ্যারেতে অ্যাপেন্ডের মান: এটি কীভাবে ও (1)?
বালাজী বোগগ্রাম রমনারায়ণ

4
@ আমাদ্মি - ভাল, জাভাতে আমার ধারণা এটি করা উচিত। সিউডো কোডে,
সমন্বিতগুলি

4
অ্যারের প্রয়োজন কেন, কেন আমরা হ্যাশম্যাপ ব্যবহার করতে পারি না।
অঙ্কিত জালানী

22

ও (1) চেহারাটি হ্যাশ করা ডেটা কাঠামোকে বোঝায় ।

তুলনামূলক ভাবে:

  • ও (1) সন্নিবেশ করান / মুছে ফেলা ও (এন) এর সাথে সংযুক্ত লিঙ্কটি বোঝায়।
  • O (1) সন্নিবেশ করুন, ও (এন) মুছুন এবং ও (এন) চেহারাটি অ্যারে-ব্যাকড তালিকাকে বোঝায়
  • ও (লগএন) সন্নিবেশ / মুছুন / চেহারা কোনও গাছ বা গাদা বোঝায়।

এটি একটি শুরু, কিন্তু শেষ প্রয়োজন সম্পর্কে কি? আপনি কি হ্যাশ ডেটা স্ট্রাকচার থেকে একটি এলোমেলো উপাদান (ডেটা কাঠামোর প্রতিটি উপাদানের সমান সম্ভাবনা সহ) পেতে পারেন?
গিল্ডনার 21

4
@ লেগ ১৯৮০, আমার ধারণা আপনি এটি করতে পারেন:hashtable.get((int)(Math.random()*hashtable.size()));
সিএমআর

4
হুম, আমি এমন কোনও হ্যাশ টেবিল সম্পর্কে জানি না যা আপনাকে সেই জাতীয় উপাদানটি পেতে দেয় এবং যদি কোনও থাকে তবে আমি ভাবতে পারি না যে এটি একটি ধ্রুবক সময় কাজ করবে। আমি উভয় গণনা ভুল প্রমাণ করতে আগ্রহী হবে।
গিল্ডনার

@ লেগ ১৯৮০ ... আপনি ক্লোজারের ভেক্টরগুলি যেমন "ধ্রুবক সময়" হয় তেমনভাবে আপনি সহজেই স্থির সময়ে এটি করতে পারতেন - লগ 32 (এন) যখন আপনার হার্ডওয়ার দ্বারা এন এর সম্ভাব্য মানগুলি সীমাবদ্ধ থাকে যেমন বৃহত্তমতম লগ 32 () মান হয় ... 7 এর মতো কিছু, যা কার্যকরভাবে ধ্রুবক সময়।
চার্লস ডাফি

"অ্যারে-ব্যাকড লিস্ট" বলতে আপনার অর্থ: অ্যারে?
হেনগামে

5

আপনি এটি পছন্দ করতে পারেন না, কারণ তারা সম্ভবত একটি চতুর সমাধান খুঁজছেন, তবে কখনও কখনও এটি আপনার বন্দুকগুলিকে আটকে রাখার জন্য অর্থ প্রদান করে ... একটি হ্যাশ টেবিল ইতিমধ্যে প্রয়োজনীয়তাগুলি পূরণ করে - অন্য যে কোনও কিছুর চেয়ে সম্ভবত সামগ্রিকভাবে উন্নত (যদিও দৃor়ভাবে ধীরে ধীরে ধীরে ধীরে লক্ষ্য করা যায়) সময় এবং অন্যান্য সমাধানের সাথে বিভিন্ন সমঝোতা সহ)

প্রয়োজনীয় যেটি জটিল তা হল "এলোমেলো উপাদান" নির্বাচন: একটি হ্যাশ টেবিলের মধ্যে আপনাকে এই জাতীয় উপাদানটির জন্য স্ক্যান বা তদন্ত করতে হবে।

বন্ধ হ্যাশিং / ওপেন অ্যাড্রেসিংয়ের জন্য, প্রদত্ত যে কোনও বালতি দখলে যাওয়ার সম্ভাবনা রয়েছে size() / capacity(), তবে অত্যন্ত গুরুত্বপূর্ণভাবে এটি সাধারণত একটি হ্যাশ-টেবিল প্রয়োগের দ্বারা ধ্রুবক গুণক পরিসরে রাখা হয় (উদাহরণস্বরূপ, টেবিলটি বর্তমানের সামগ্রীর চেয়ে বড় হতে পারে 1.2x বলে পারফরম্যান্স / মেমরি টিউনিং এর উপর নির্ভর করে x 10x)। এর অর্থ দাঁড়ায় গড়ে আমরা 1.2 থেকে 10 বালতি অনুসন্ধান করতে পারি - ধারকটির মোট আকারের চেয়ে সম্পূর্ণ স্বতন্ত্র; এমোরিটাইজড ও (1)।

আমি দুটি সহজ পদ্ধতির কল্পনা করতে পারি (এবং আরও অনেক মজাদারভাবে):

  • র্যান্ডম বালতি থেকে রৈখিক অনুসন্ধান করুন

    • খালি / মান-রাখা বালতি আলা বিবেচনা করুন "--এইসি ----- বি - ডি": আপনি বলতে পারেন যে প্রথম "এলোমেলো" নির্বাচনটি ন্যায্য যদিও এটি বি এর পক্ষে, যদিও বি এর পক্ষে পক্ষে থাকার সম্ভাবনা বেশি ছিল না অন্যান্য উপাদানগুলির তুলনায়, তবে আপনি যদি একই মানগুলি ব্যবহার করে বার বার "এলোমেলো" নির্বাচনগুলি করেন তবে স্পষ্টভাবে বি বার বার পছন্দ করা অনাকাঙ্ক্ষিত হতে পারে (যদিও প্রশ্নের মধ্যে কিছুতেই সম্ভাবনারও দাবি নেই)
  • যতক্ষণ না আপনি একটি জনবহুল একটি খুঁজে পান ততক্ষণ এলোমেলো বালতি চেষ্টা করুন

    • "কেবল" সক্ষমতা () / আকার () গড় বালতি পরিদর্শন করা (উপরে হিসাবে) - তবে ব্যবহারিক দিক থেকে আরও ব্যয়বহুল কারণ এলোমেলো সংখ্যার জেনারেশন তুলনামূলকভাবে ব্যয়বহুল, এবং অসীম অসম্ভব খারাপতম ক্ষেত্রে আচরণ যদি অসীম খারাপ ...
      • প্রাথমিকভাবে এলোমেলোভাবে নির্বাচিত বালতি থেকে প্রাক-উত্পাদিত র্যান্ডম অফসেটগুলির একটি তালিকা ব্যবহার করার জন্য একটি দ্রুত আপস করা হবে, তাদের বালতি গণনায়% -ing করা

কোনও দুর্দান্ত সমাধান নয়, তবে সর্বদা দ্বিতীয় সূচকের অ্যারে বজায় রাখার মেমরি এবং পারফরম্যান্সের ওভারহেডগুলির চেয়ে আরও ভাল সামগ্রিক আপস হতে পারে।


3

সম্ভবত সেরা সমাধান হ্যাশ টেবিল + অ্যারে, এটি আসল দ্রুত এবং নির্বিচারক।

তবে সর্বনিম্ন রেট দেওয়া উত্তর (কেবল একটি হ্যাশ টেবিল ব্যবহার করুন!) আসলে দুর্দান্তও!

  • রি-হ্যাশিং সহ হ্যাশ টেবিল, বা নতুন বালতি নির্বাচন (যেমন বালতিতে একটি উপাদান, কোনও লিঙ্কযুক্ত তালিকা নেই)
  • getRandom () বারবার এলোমেলো বালতি খালি না হওয়া পর্যন্ত বাছাই করার চেষ্টা করে।
  • একটি ব্যর্থ-নিরাপদ হিসাবে, সম্ভবত getRandom (), N (উপাদানগুলির সংখ্যা) ব্যর্থ চেষ্টা করার পরে, এলোমেলো সূচী i [0, N-1] এ নিয়ে যায় এবং তারপর হ্যাশ টেবিলটি লাইনরেখা যায় এবং # i-th উপাদানটি ধরে তোলে ।

"সম্ভাব্য অসীম লুপস" এর কারণে লোকেরা এটি পছন্দ করতে পারে না এবং আমি খুব স্মার্ট লোকদেরও এই প্রতিক্রিয়া দেখতে পেয়েছি তবে এটি ভুল! অসীম সম্ভাবনাযুক্ত ঘটনাগুলি কেবল ঘটে না

আপনার সিউডো-এলোমেলো উত্সের ভাল আচরণটি ধরে নিচ্ছেন - যা এই নির্দিষ্ট আচরণের জন্য প্রতিষ্ঠা করা কঠিন নয় - এবং হ্যাশ টেবিলগুলি সর্বদা কমপক্ষে 20% পূর্ণ থাকে, এটি দেখতে সহজ:

এটি কখনও ঘটবে না যে getRandom () এর জন্য 1000 বারের বেশি চেষ্টা করতে হবে। শুধু কখনও না । প্রকৃতপক্ষে, এই জাতীয় ইভেন্টের সম্ভাবনা 0.8 ^ 1000, যা 10 ^ -97 - তাই একবারে ঘটতে পারে এমন এক বিলিয়নের মধ্যে একবারে সুযোগ পাওয়ার জন্য আমাদের এটি 10 ​​^ 88 বার পুনরাবৃত্তি করতে হবে। এমনকি যদি এই প্রোগ্রামটি সূর্যের মৃত্যুর আগ পর্যন্ত মানবজাতির সমস্ত কম্পিউটারে পূর্ণ-সময় চলমান থাকে, তা কখনই ঘটবে না


4
আপনি যদি ক্রমাগত মানহীন একটি বালতি বালতি বেছে নিতে বেছে নেন, তবে পৃথিবীতে কীভাবে সবচেয়ে খারাপ পরিস্থিতি হে (1) এ যখন আপনি একটি এলোমেলো উপাদান বেছে
নেন

@ ব্যবহারকারী 1147505 - আপনি এই নম্বরটি কোথায় পেয়েছেন: "0.8 ^ 1000"?
হেনগামেহ

আপনি কীভাবে এটি পৌঁছেছেন: "হ্যাশ টেবিল সর্বদা কমপক্ষে 20% পূর্ণ থাকে"
হেনগামে

আপনি যে পদ্ধতিটি দিয়ে এলোমেলো বালতি চয়ন করতে পারেন দয়া করে লিখতে পারেন?
হেনগামেহ

3

এই প্রশ্নের জন্য আমি দুটি ডেটা স্ট্রাকচার ব্যবহার করব

  • হ্যাশ মানচিত্র
  • অ্যারেলিস্ট / অ্যারে / ডাবল লিংকডলিস্ট।

পদক্ষেপ: -

  1. সন্নিবেশ: - হ্যাশম্যাপ - টাইম জটিলতা ও (1) এর মধ্যে এক্স ইতিমধ্যে উপস্থিত কিনা তা পরীক্ষা করুন। যদি উপস্থিত না হয় তবে অ্যারেলিস্টের শেষে যুক্ত করুন - সময় জটিলতা ও (1)। এটিকে হ্যাশম্যাপে যোগ করুন কী হিসাবে এবং সর্বশেষ সূচককে মান হিসাবে - টাইম জটিলতা ও (1)।
  2. সরান: - হ্যাশম্যাপ - টাইম জটিলতা ও (1) এ এক্স উপস্থিত কিনা তা পরীক্ষা করুন। যদি উপস্থিত থাকে তবে এর সূচকটি সন্ধান করুন এবং এটি হ্যাশম্যাপ - টাইম জটিলতা ও (1) থেকে সরান। অ্যারেলিস্টে এই উপাদানটি শেষের উপাদানটির সাথে অদলবদল করুন এবং শেষ উপাদানটি সরিয়ে দিন - টাইম জটিলতা হে (1)। হ্যাশম্যাপ - টাইম জটিলতা ও (1) এ সর্বশেষ উপাদানটির সূচক আপডেট করুন।
  3. গেটর্যান্ডম: - অ্যারেলিস্টের শেষ সূচক থেকে 0 থেকে এলোমেলো সংখ্যা তৈরি করুন। অ্যারেলিস্ট উপাদানটি এলোমেলো সূচক উত্পন্ন - টাইম জটিলতা ও (1) এ প্রদান করুন।
  4. অনুসন্ধান: - কী হিসাবে এক্সের জন্য হ্যাশম্যাপে দেখুন। - সময় জটিলতা ও (1)।

কোড: -

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;


public class JavaApplication1 {

    public static void main(String args[]){
       Scanner sc = new Scanner(System.in);
        ArrayList<Integer> al =new ArrayList<Integer>();
        HashMap<Integer,Integer> mp = new HashMap<Integer,Integer>();  
        while(true){
            System.out.println("**menu**");
            System.out.println("1.insert");
            System.out.println("2.remove");
            System.out.println("3.search");
            System.out.println("4.rendom");
            int ch = sc.nextInt();
            switch(ch){
                case 1 : System.out.println("Enter the Element ");
                        int a = sc.nextInt();
                        if(mp.containsKey(a)){
                            System.out.println("Element is already present ");
                        }
                        else{
                            al.add(a);
                            mp.put(a, al.size()-1);

                        }
                        break;
                case 2 : System.out.println("Enter the Element Which u want to remove");
                        a = sc.nextInt();
                        if(mp.containsKey(a)){

                            int size = al.size();
                            int index = mp.get(a);

                            int last = al.get(size-1);
                            Collections.swap(al, index,  size-1);

                            al.remove(size-1);
                            mp.put(last, index);

                            System.out.println("Data Deleted");

                        }
                        else{
                            System.out.println("Data Not found");
                        }
                        break;
                case 3 : System.out.println("Enter the Element to Search");
                        a = sc.nextInt();
                        if(mp.containsKey(a)){
                            System.out.println(mp.get(a));
                        }
                        else{
                            System.out.println("Data Not Found");
                        }
                        break;
                case 4 : Random rm = new Random();
                        int index = rm.nextInt(al.size());
                        System.out.println(al.get(index));
                        break;

            }
        }
    }

}

- সময়ের জটিলতা ও (1)। - স্পেস জটিলতা ও (এন)।


1

এখানে সেই সমস্যার একটি সি # সমাধান আমি একই প্রশ্ন জিজ্ঞাসা করে কিছুক্ষণ আগে এলাম। এটি অন্যান্য স্ট্যান্ডার্ড .NET ইন্টারফেসের সাথে যুক্ত, সরান, অন্তর্ভুক্ত এবং র্যান্ডম প্রয়োগ করে। এমন নয় যে কোনও সাক্ষাত্কারের সময় আপনার এ জাতীয় বিশদটি এর সাথে প্রয়োগ করা প্রয়োজন তবে এটি দেখার পক্ষে একটি দৃ concrete় সমাধান পেয়ে ভাল লাগল ...

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

/// <summary>
/// This class represents an unordered bag of items with the
/// the capability to get a random item.  All operations are O(1).
/// </summary>
/// <typeparam name="T">The type of the item.</typeparam>
public class Bag<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
{
    private Dictionary<T, int> index;
    private List<T> items;
    private Random rand;
    private object syncRoot;

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    public Bag()
        : this(0)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="capacity">The capacity.</param>
    public Bag(int capacity)
    {
        this.index = new Dictionary<T, int>(capacity);
        this.items = new List<T>(capacity);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="collection">The collection.</param>
    public Bag(IEnumerable<T> collection)
    {
        this.items = new List<T>(collection);
        this.index = this.items
            .Select((value, index) => new { value, index })
            .ToDictionary(pair => pair.value, pair => pair.index);
    }

    /// <summary>
    /// Get random item from bag.
    /// </summary>
    /// <returns>Random item from bag.</returns>
    /// <exception cref="System.InvalidOperationException">
    /// The bag is empty.
    /// </exception>
    public T Random()
    {
        if (this.items.Count == 0)
        {
            throw new InvalidOperationException();
        }

        if (this.rand == null)
        {
            this.rand = new Random();
        }

        int randomIndex = this.rand.Next(0, this.items.Count);
        return this.items[randomIndex];
    }

    /// <summary>
    /// Adds the specified item.
    /// </summary>
    /// <param name="item">The item.</param>
    public void Add(T item)
    {
        this.index.Add(item, this.items.Count);
        this.items.Add(item);
    }

    /// <summary>
    /// Removes the specified item.
    /// </summary>
    /// <param name="item">The item.</param>
    /// <returns></returns>
    public bool Remove(T item)
    {
        // Replace index of value to remove with last item in values list
        int keyIndex = this.index[item];
        T lastItem = this.items[this.items.Count - 1];
        this.items[keyIndex] = lastItem;

        // Update index in dictionary for last item that was just moved
        this.index[lastItem] = keyIndex;

        // Remove old value
        this.index.Remove(item);
        this.items.RemoveAt(this.items.Count - 1);

        return true;
    }

    /// <inheritdoc />
    public bool Contains(T item)
    {
        return this.index.ContainsKey(item);
    }

    /// <inheritdoc />
    public void Clear()
    {
        this.index.Clear();
        this.items.Clear();
    }

    /// <inheritdoc />
    public int Count
    {
        get { return this.items.Count; }
    }

    /// <inheritdoc />
    public void CopyTo(T[] array, int arrayIndex)
    {
        this.items.CopyTo(array, arrayIndex);
    }

    /// <inheritdoc />
    public bool IsReadOnly
    {
        get { return false; }
    }

    /// <inheritdoc />
    public IEnumerator<T> GetEnumerator()
    {
        foreach (var value in this.items)
        {
            yield return value;
        }
    }

    /// <inheritdoc />
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    /// <inheritdoc />
    public void CopyTo(Array array, int index)
    {
        this.CopyTo(array as T[], index);
    }

    /// <inheritdoc />
    public bool IsSynchronized
    {
        get { return false; }
    }

    /// <inheritdoc />
    public object SyncRoot
    {
        get
        {
            if (this.syncRoot == null)
            {
                Interlocked.CompareExchange<object>(
                    ref this.syncRoot,
                    new object(),
                    null);
            }

            return this.syncRoot;

        }
    }
}

আমি নিশ্চিত নই যে আপনার নকল নম্বর থাকলে এটি কাজ করবে।
অ্যালেক্সআইআইপি

এটি নকলগুলি হ্যান্ডেল করে না কারণ @ গিল্ডার মনে করেছেন যে প্রশ্নের মন্তব্যে কোনও নকল নেই। যদি কোনও সদৃশ ArgumentExceptionবার্তা যুক্ত করা হয় তবে "একই কী সহ একটি আইটেম ইতিমধ্যে যুক্ত করা হয়েছে।" নিক্ষেপ করা হবে (অন্তর্নিহিত সূচক অভিধান থেকে)।
স্কট Lerch

1

আমরা hing (1) সময়ে অপারেশনগুলিকে সহায়তা করতে হ্যাশিং ব্যবহার করতে পারি।

সন্নিবেশ করুন (x) 1) হ্যাশ মানচিত্রের অনুসন্ধানের মাধ্যমে এক্স ইতিমধ্যে উপস্থিত আছে কিনা তা পরীক্ষা করুন। 2) উপস্থিত না থাকলে অ্যারের শেষে এটি sertোকান। 3) হ্যাশ টেবিলের মধ্যেও, এক্সকে কী হিসাবে এবং সর্বশেষ অ্যারে সূচক হিসাবে সূচক হিসাবে যুক্ত করা হয়।

অপসারণ (x) 1) হ্যাশ মানচিত্রের অনুসন্ধানের মাধ্যমে এক্স উপস্থিত কিনা তা পরীক্ষা করুন। ২) উপস্থিত থাকলে এর সূচীটি সন্ধান করুন এবং এটি হ্যাশ মানচিত্র থেকে সরিয়ে ফেলুন। 3) অ্যারেতে এই উপাদানটি দিয়ে সর্বশেষ উপাদানটি স্যুপ করুন এবং শেষ উপাদানটি সরান। সোয়াপিং করা হয়ে গেছে কারণ শেষ উপাদানটি ও (1) সময়ে সরানো যেতে পারে। 4) হ্যাশ মানচিত্রে সর্বশেষ উপাদানটির সূচক আপডেট করুন।

getRandom () 1) 0 থেকে শেষ সূচক পর্যন্ত একটি এলোমেলো সংখ্যা তৈরি করুন। 2) এলো উপাদান এলোমেলোভাবে উত্পন্ন সূচক এ ফিরে আসুন।

অনুসন্ধান (এক্স) হ্যাশ মানচিত্রে এক্স এর জন্য একটি অনুসন্ধান করুন।


1

যদিও এটি বেশ পুরানো, তবে যেহেতু সি ++ তে কোনও উত্তর নেই, আমার দুটি সেন্ট এখানে।

#include <vector>
#include <unordered_map>
#include <stdlib.h>

template <typename T> class bucket{
    int size;
    std::vector<T> v;
    std::unordered_map<T, int> m;
public:
    bucket(){
        size = 0;
        std::vector<T>* v = new std::vector<T>();
        std::unordered_map<T, int>* m = new std::unordered_map<T, int>();
    }
    void insert(const T& item){
        //prevent insertion of duplicates
        if(m.find(item) != m.end()){
            exit(-1);
        }
        v.push_back(item);
        m.emplace(item, size);
        size++;

    }
    void remove(const T& item){
        //exits if the item is not present in the list
        if(m[item] == -1){
            exit(-1);
        }else if(m.find(item) == m.end()){
            exit(-1);
        }

        int idx = m[item];
        m[v.back()] = idx;
        T itm = v[idx];
        v.insert(v.begin()+idx, v.back());
        v.erase(v.begin()+idx+1);
        v.insert(v.begin()+size, itm);
        v.erase(v.begin()+size);
        m[item] = -1;
        v.pop_back();
        size--;

    }

     T& getRandom(){
      int idx = rand()%size;
      return v[idx];

     }

     bool lookup(const T& item){
       if(m.find(item) == m.end()) return false;
       return true;

     }
    //method to check that remove has worked
    void print(){
        for(auto it = v.begin(); it != v.end(); it++){
            std::cout<<*it<<" ";
        }
    }
};

সমাধানটি পরীক্ষা করার জন্য এখানে ক্লায়েন্ট কোডের একটি অংশ।

int main() {

    bucket<char>* b = new bucket<char>();
    b->insert('d');
    b->insert('k');
    b->insert('l');
    b->insert('h');
    b->insert('j');
    b->insert('z');
    b->insert('p');

    std::cout<<b->random()<<std::endl;
    b->print();
    std::cout<<std::endl;
    b->remove('h');
    b->print();

    return 0;
}

0

সি # 3.0 +। নেট ফ্রেমওয়ার্ক 4-এ, জেনেরিক Dictionary<TKey,TValue>হ্যাশটেবলের চেয়ে আরও ভাল কারণ আপনি উপাদানগুলিকে সঞ্চিত যেখানে অন্তর্নিহিত গতিশীল অ্যারেটিতে সূচীকরণের জন্য System.Linqএক্সটেনশন পদ্ধতিটি ব্যবহার করতে পারেন :ElementAt()KeyValuePair<TKey,TValue>

using System.Linq;

Random _generator = new Random((int)DateTime.Now.Ticks);

Dictionary<string,object> _elements = new Dictionary<string,object>();

....

Public object GetRandom()
{
     return _elements.ElementAt(_generator.Next(_elements.Count)).Value;
}

তবে যতদূর আমি জানি, একটি হ্যাশটেবল (বা এর অভিধান বংশধর) এই সমস্যার প্রকৃত সমাধান নয় কারণ পুট () কেবলমাত্র ও (1) নয়, সত্য ও (1) নয়, কারণ এটি হে (এন) ) গতিশীল পুনরায় আকারের সীমানায়।

এই সমস্যার কোন বাস্তব সমাধান আছে? আমি যা ভাবতে পারি তা হ'ল যদি আপনি কোনও অভিধান / হ্যাশটবিল প্রাথমিক ক্ষমতাটি যা প্রয়োজন তার চেয়ে বেশি মাত্রার একটি ক্রম নির্দিষ্ট করে থাকেন তবে আপনি ও (1) ক্রিয়াকলাপ পাবেন কারণ আপনাকে কখনই আকার পরিবর্তন করতে হবে না।


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

0

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


0

আমরা জাভা এর হ্যাশসেট ব্যবহার করে এটি করতে পারি না? এটি ডিফল্টরূপে ও (1) এ সমস্ত সন্নিবেশ, ডেল, সরবরাহ সরবরাহ করে। GetRandom এর জন্য আমরা সেট এর পুনরাবৃত্তির ব্যবহার করতে পারি যা যাই হোক এলোমেলো আচরণ দেয়। আমরা বাকি উপাদানগুলির চিন্তা না করে সেট থেকে প্রথম উপাদানটি পুনরাবৃত্তি করতে পারি

public void getRandom(){
    Iterator<integer> sitr = s.iterator();
    Integer x = sitr.next();    
    return x;
}

0
/* Java program to design a data structure that support folloiwng operations
   in Theta(n) time
   a) Insert
   b) Delete
   c) Search
   d) getRandom */
import java.util.*;

// class to represent the required data structure
class MyDS
{
   ArrayList<Integer> arr;   // A resizable array

   // A hash where keys are array elements and vlaues are
   // indexes in arr[]
   HashMap<Integer, Integer>  hash;

   // Constructor (creates arr[] and hash)
   public MyDS()
   {
       arr = new ArrayList<Integer>();
       hash = new HashMap<Integer, Integer>();
   }

   // A Theta(1) function to add an element to MyDS
   // data structure
   void add(int x)
   {
      // If ekement is already present, then noting to do
      if (hash.get(x) != null)
          return;

      // Else put element at the end of arr[]
      int s = arr.size();
      arr.add(x);

      // And put in hash also
      hash.put(x, s);
   }

   // A Theta(1) function to remove an element from MyDS
   // data structure
   void remove(int x)
   {
       // Check if element is present
       Integer index = hash.get(x);
       if (index == null)
          return;

       // If present, then remove element from hash
       hash.remove(x);

       // Swap element with last element so that remove from
       // arr[] can be done in O(1) time
       int size = arr.size();
       Integer last = arr.get(size-1);
       Collections.swap(arr, index,  size-1);

       // Remove last element (This is O(1))
       arr.remove(size-1);

       // Update hash table for new index of last element
       hash.put(last, index);
    }

    // Returns a random element from MyDS
    int getRandom()
    {
       // Find a random index from 0 to size - 1
       Random rand = new Random();  // Choose a different seed
       int index = rand.nextInt(arr.size());

       // Return element at randomly picked index
       return arr.get(index);
    }

    // Returns index of element if element is present, otherwise null
    Integer search(int x)
    {
       return hash.get(x);
    }
}

// Driver class
class Main
{
    public static void main (String[] args)
    {
        MyDS ds = new MyDS();
        ds.add(10);
        ds.add(20);
        ds.add(30);
        ds.add(40);
        System.out.println(ds.search(30));
        ds.remove(20);
        ds.add(50);
        System.out.println(ds.search(50));
        System.out.println(ds.getRandom());`enter code here`
    }
}

-2

আমরা কেন এলোমেলো উপাদান খুঁজে পেতে ইগচ% অ্যারেজাইজ ব্যবহার করি না। অ্যারের আকার সন্ধান করা হয় ও (এন) তবে আনুষাঙ্গিক জটিলতা হবে ও (1)।


-3

আমি মনে করি আমরা হ্যাশ টেবিলের সাথে দ্বিগুণ লিঙ্ক তালিকাটি ব্যবহার করতে পারি। কীটি উপাদান হবে এবং এর সম্পর্কিত মানটি দ্বিগুণ লিঙ্কলিস্টে নোড হবে।

  1. সন্নিবেশ (এইচ, ই): দ্বিগুণ লিঙ্কলিস্টে নোড sertোকান এবং এইচ [ই] = নোড হিসাবে প্রবেশ করুন; ও (1)
  2. মুছে ফেলুন (এইচ, ই): এই নোডের আগের দিকের এইচ (ই) দ্বারা নোড ঠিকানা পান এবং এইচ (ই) কে নুল হিসাবে মুছে ফেলুন এবং হে (1)
  3. (এইচ, ই) এবং গেটআরন্ডম (এইচ) অন্তর্ভুক্ত হ'ল ও (1)

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