আমি কেন ডেক ওভার স্ট্যাক ব্যবহার করব?


157

Stackআমার ব্যবহারের ক্ষেত্রে আমার একটি ডেটা কাঠামো দরকার । আমার আইটেমগুলিকে ডেটা স্ট্রাকচারে ঠেলাতে সক্ষম হওয়া উচিত এবং আমি কেবল স্ট্যাক থেকে শেষ আইটেমটি পুনরুদ্ধার করতে চাই। স্ট্যাক জন্য JavaDoc বলেছেন:

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

Deque<Integer> stack = new ArrayDeque<>();

আমি অবশ্যই এখানে সিঙ্ক্রোনাইজড আচরণটি চাই না কারণ আমি কোনও পদ্ধতিতে এই ডেটাস্ট্রাকচার স্থানীয়ভাবে ব্যবহার করব। এগুলি বাদে কেন এখানে আমার Dequeচেয়ে বেশি পছন্দ করা উচিত Stack?

পিএস: ডেকের জাভাদোক বলেছেন:

ডিকগুলি LIFO (সর্বশেষ-প্রথম-আউট) স্ট্যাক হিসাবেও ব্যবহার করা যেতে পারে। এই ইন্টারফেসটি উত্তরাধিকার স্ট্যাক বর্গের অগ্রাধিকার হিসাবে ব্যবহার করা উচিত।


1
এটি আরও বেকড-ইন পদ্ধতিগুলি সরবরাহ করে বা তার পরিবর্তে "একটি আরও সম্পূর্ণ এবং ধারাবাহিক সেট" সরবরাহ করে, যদি আপনি সেগুলি গ্রহণ করেন তবে আপনি যে কোডটি লিখতে হবে তা হ্রাস করবে?

উত্তর:


190

একটি বিষয় হিসাবে, এটি উত্তরাধিকারের দিক থেকে আরও বোধগম্য। আমার দৃষ্টিতে যে বিষয়টি Stackপ্রসারিত হয়েছে Vectorতা সত্যই অদ্ভুত। জাভা শুরুর দিকে, উত্তরাধিকার আইএমওকে অতিরিক্ত ব্যবহার করা হয়েছিল - এটির Propertiesএকটি উদাহরণ।

আমার জন্য, আপনার উদ্ধৃত দস্তাবেজের মধ্যে গুরুত্বপূর্ণ শব্দটি সামঞ্জস্যপূর্ণDequeক্রিয়াকলাপগুলির একটি সেট উন্মোচন করে যা সংগ্রহের পুনরাবৃত্তি ইত্যাদির শুরু বা শেষ থেকে আইটেমগুলি আনা / যুক্ত / সরাতে সক্ষম - এবং এটিই। অবস্থান অনুসারে কোনও উপাদান অ্যাক্সেস করার ইচ্ছাকৃত কোনও উপায় নেই, যা Stackপ্রকাশ করে কারণ এটি একটি সাবক্লাস Vector

ওহ, এবং Stackএর কোনও ইন্টারফেসও নেই, সুতরাং যদি আপনি জানেন যে আপনার Stackঅপারেশনগুলির দরকার হয় তবে আপনি একটি নির্দিষ্ট কংক্রিট শ্রেণীর কাছে প্রতিশ্রুতিবদ্ধ হন, যা সাধারণত ভাল ধারণা নয়।

মন্তব্যগুলিতে যেমন উল্লেখ করা হয়েছে, Stackএবং এর Dequeবিপরীত পুনরাবৃত্তি আদেশ রয়েছে:

Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(new ArrayList<>(stack)); // prints 1, 2, 3


Deque<Integer> deque = new ArrayDeque<>();
deque.push(1);
deque.push(2);
deque.push(3);
System.out.println(new ArrayList<>(deque)); // prints 3, 2, 1

যা Deque.iterator () এর জন্য জাভাডক্সেও ব্যাখ্যা করা হয়েছে :

যথাযথ ক্রমে এই ডেকের উপাদানগুলির উপর একটি পুনরাবৃত্তিকে ফেরত দেয়। উপাদানগুলি প্রথম (মাথা) থেকে শেষ (লেজ) পর্যন্ত ক্রমানুসারে ফিরে আসবে।


10
অ্যারেডেকের জাভাদোক বলছেন "এই শ্রেণিটি স্ট্যাক হিসাবে ব্যবহৃত হওয়ার পরে স্ট্যাকের চেয়ে দ্রুত এবং কাতার হিসাবে ব্যবহৃত হলে লিংকডলিস্টের চেয়ে দ্রুততর হতে পারে।" .. আমি কীভাবে সুনির্দিষ্ট করব যে আমি এটি স্ট্যাক হিসাবে বা একটি সারি হিসাবে ব্যবহার করার ইচ্ছা করি কিনা?
গিগ

23
@ গীক: আপনি করবেন না। মুল বক্তব্যটি হ'ল যদি আপনি সারিবদ্ধ আচরণ চান , তবে আপনি ব্যবহার করতে পারেন LinkedList, তবে ArrayDequeue(প্রায়শই) দ্রুত হবে। আপনি যদি স্ট্যাক আচরণ চান, আপনি ব্যবহার করতে পারেন Stackতবে ArrayDeque(প্রায়শই) দ্রুত হবে be
জন স্কিটি

7
যদিও বিমূর্ততার ক্ষেত্রে এটি কম বুদ্ধিমান নয়? আমি বোঝাতে চাইছি, উভয়ই সমাধান বিমূর্ততার ক্ষেত্রে সত্যই ভাল নয়, কারণ Stackরেপ এক্সপোজার সমস্যা রয়েছে তবে আমি যদি স্ট্যাকের ডেটা কাঠামো চাই তবে আমি ধাক্কা, পপ এবং পিকের মতো পদ্ধতিগুলি কল করতে সক্ষম হতে চাই, এবং জিনিসগুলি নেই স্ট্যাকের অন্য প্রান্তটি দিয়ে করুন।
পিটিপ্যাবপ্রো

4
@ জোনস্কিট এছাড়াও স্ট্যাকের পুনরাবৃত্তিটি ভুল, কারণ এটি উপরে থেকে নীচে থেকে নীচে থেকে পুনরাবৃত্তি করে। stackoverflow.com/questions/16992758/…
পাভেল

1
@ পেটিপ্যাবপ্রো: আপনি ঠিক বলেছেন। স্টেক হিসাবে ডেকু ব্যবহার করা এখনও স্ট্যাকের উত্তরাধিকার সূত্রে প্রাপ্ত ভেক্টর পদ্ধতি হিসাবে নন-লাইফো ব্যবহারের অনুমতি দেয়। সমস্যা এবং (এনক্যাপস্যুলেশন সঙ্গে) একটি সমাধান একটি ব্যাখ্যা এখানে পাওয়া যাবে: baddotrobot.com/blog/2013/01/10/stack-vs-deque
rics

4

এখানে স্ট্যাক শ্রেণির বর্ণনায় বর্ণিত অসঙ্গতির আমার ব্যাখ্যাটি দেওয়া হল।

আপনি যদি এখানে সাধারণ-উদ্দেশ্য বাস্তবায়নের দিকে নজর দেন - আপনি দেখতে পাবেন যে সেট, মানচিত্র এবং তালিকা বাস্তবায়নের জন্য একটি ধারাবাহিক পন্থা রয়েছে।

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

  • আমরা Set<String> set = new HashSet<String>();কারণ হিসাবে এখানে দেখুন ঘোষণার পছন্দসই শৈলী ব্যবহার করতে পারেন ।

তবে স্ট্যাক ক্লাস: 1) এর নিজস্ব ইন্টারফেস নেই; 2) ভেক্টর শ্রেণীর একটি সাবক্লাস - যা আকার পরিবর্তনযোগ্য অ্যারের উপর ভিত্তি করে; সুতরাং যেখানে স্ট্যাকের লিঙ্কযুক্ত তালিকা বাস্তবায়ন হয়?

ডেক ইন্টারফেসে দুটি রূপায়ণ (রিজেজেবল অ্যারে - অ্যারেডেক; লিঙ্কযুক্ত তালিকা - লিংকডলিস্ট) সহ আমাদের এ জাতীয় সমস্যা নেই।


2

ডেকু ওভার স্ট্যাক ব্যবহারের আরও একটি কারণ হ'ল স্ট্যাকটি প্রয়োগ না করে LIFO ধারণাটি প্রয়োগের সাথে তালিকায় রূপরেখা রূপান্তরগুলি ব্যবহার করার ক্ষমতা রাখে।

Stack<Integer> stack = new Stack<>();
Deque<Integer> deque = new ArrayDeque<>();

stack.push(1);//1 is the top
deque.push(1)//1 is the top
stack.push(2);//2 is the top
deque.push(2);//2 is the top

List<Integer> list1 = stack.stream().collect(Collectors.toList());//[1,2]

List<Integer> list2 = deque.stream().collect(Collectors.toList());//[2,1]

2

ডেকে স্ট্যাকের চেয়ে ভাল হওয়ার কয়েকটি কারণ এখানে রয়েছে:

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

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

পারফরম্যান্স: স্ট্যাকটি যে ভেক্টর শ্রেণিটি প্রসারিত করে তা মূলত একটি অ্যারেলিস্টের "থ্রেড-নিরাপদ" সংস্করণ। সিঙ্ক্রোনাইজেশনগুলি সম্ভবত আপনার অ্যাপ্লিকেশনটিতে একটি উল্লেখযোগ্য পারফরম্যান্স হিট করতে পারে। এছাড়াও, অপ্রয়োজনীয় কার্যকারিতা সহ অন্যান্য শ্রেণিগুলি বাড়ানো (# 2 তে উল্লিখিত) আপনার অবজেক্টগুলিকে ফুলে ফেঁপে উঠছে, সম্ভাব্যভাবে অতিরিক্ত অতিরিক্ত মেমরি এবং কর্মক্ষমতা ওভারহেডের জন্য ব্যয় করতে হবে।


-1

আমার জন্য এই নির্দিষ্ট পয়েন্টটি অনুপস্থিত ছিল: স্ট্যাকটি থ্রেডস্যাফ হিসাবে এটি ভেক্টর থেকে প্রাপ্ত, যদিও সর্বাধিক উপযুক্ত বাস্তবায়ন হয় না, এবং এইভাবে দ্রুত যদি আপনি কেবল এটি একটি থ্রেডে ব্যবহার করেন।



-1

পারফরম্যান্স একটি কারণ হতে পারে। আমি ব্যবহৃত একটি অ্যালগরিদম St..6 মিনিট থেকে 1.5 মিনিটের মধ্যে নেমে গেছে কেবল স্ট্যাকের সাথে ডেকের পরিবর্তে।



-6

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


1
দয়া করে প্রশ্নের শেষ অনুচ্ছেদটি দেখুন। জাভাদোক বলেছেন ডেকস ব্যবহার করা উচিত এবং আমি কেন জানতে চেয়েছিলাম?
গিক

2
আপনি মাঝখানে উপাদানগুলি অ্যাক্সেস করতে পারবেন না কারণ ডেক পছন্দ করা হয় । এটি দ্বিগুণ শেষ, তাই ফিফোর জন্য ফিলো হতে পারে।
থুফির

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