দুটি সারি ব্যবহার করে একটি স্ট্যাক বাস্তবায়নের কী লাভ?


34

আমার নীচের হোমওয়ার্কের প্রশ্ন রয়েছে:

দুটি সারি ব্যবহার করে স্ট্যাকের পদ্ধতিগুলি পুশ (x) এবং পপ () প্রয়োগ করুন।

এটি আমার কাছে অদ্ভুত বলে মনে হচ্ছে কারণ:

  • একটি স্ট্যাক হয় একটি (LIFO) কিউ
  • এটি বাস্তবায়নের জন্য আপনার কেন দুটি সারি প্রয়োজন হবে তা আমি দেখতে পাচ্ছি না

আমি আশেপাশে অনুসন্ধান করেছি:

এবং একটি দম্পতি সমাধান খুঁজে। এটিই আমি শেষ করেছি:

public class Stack<T> {
    LinkedList<T> q1 = new LinkedList<T>();
    LinkedList<T> q2 = new LinkedList<T>();

    public void push(T t) {
        q1.addFirst(t);
    }

    public T pop() {
        if (q1.isEmpty()) {
            throw new RuntimeException(
                "Can't pop from an empty stack!");
        }

        while(q1.size() > 1) {
            q2.addFirst( q1.removeLast() );
        }

        T popped = q1.pop();

        LinkedList<T> tempQ = q1;
        q1 = q2;
        q2 = tempQ;

        return popped;
    }
}

তবে আমি বুঝতে পারছি না যে একক সারিতে কী কী সুবিধা হবে; দুটি সারি সংস্করণ অর্থহীন জটিল বলে মনে হচ্ছে।

বলুন যে আমরা 2 টির (যেমন আমি উপরে করেছি) আরও বেশি কার্যকর হওয়ার জন্য বেছে নিয়েছি, pushএকই থাকবে এবং popকেবল শেষ উপাদানটির পুনরাবৃত্তি প্রয়োজন এবং এটি ফিরিয়ে আনতে হবে। উভয় ক্ষেত্রে, pushহবে O(1), এবং popহবে O(n); তবে একক সারির সংস্করণটি অত্যন্ত সহজতর হবে। এটি কেবল লুপের জন্য একক প্রয়োজন require

আমি কিছু অনুপস্থিত করছি? এখানে যে কোনও অন্তর্দৃষ্টি প্রশংসা করা হবে।


17
একটি সারি সাধারণত একটি ফিফো কাঠামো উল্লেখ করে থাকে যখন স্ট্যাকটি একটি লাইফো কাঠামো। জাভাতে লিংকডলিস্টের ইন্টারফেসটি হ'ল ডেক (ডাবল এন্ড সারি) যা ফিফো এবং লিফো উভয়কেই অ্যাক্সেস দেয়। অনুষ্ঠান পরিবর্তন করার চেষ্টা করুন সারি LinkedList বাস্তবায়ন ইন্টারফেস বদলে।

12
দুটি সাধারণ স্ট্যাক ব্যবহার করে একটি সারি প্রয়োগ করা সবচেয়ে সাধারণ সমস্যা। খাঁটি কার্যকরী ডেটা স্ট্রাকচারের উপর ক্রিস ওকাসাকির বইটি আকর্ষণীয় মনে হতে পারে।
এরিক লিপার্ট

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


11
"একটি স্ট্যাক হ'ল (লাইফো) সারি" ... হুম, একটি সারি একটি অপেক্ষার রেখা। পাবলিক রেস্টরুম ব্যবহারের জন্য লাইনের মতো। আপনি যে রেখাগুলিতে অপেক্ষা করেন সেগুলি কি কখনও লাইফোর ফ্যাশনে আচরণ করে? "লাইফো সারি" শব্দটি ব্যবহার বন্ধ করুন, এটি অযৌক্তিক।
মেহরদাদ

উত্তর:


44

কোনও সুবিধা নেই: এটি নিখুঁত একাডেমিক অনুশীলন।

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

আপনি রিয়েল ওয়ার্ল্ড টিএম এ কোডটি কখনই ব্যবহার করবেন না । এই অনুশীলনটি থেকে আপনাকে কী সরিয়ে নিতে হবে তা হল "বাক্সের বাইরে কীভাবে ভাবুন" এবং কোডটি পুনরায় ব্যবহার করুন।


দয়া করে মনে রাখবেন যে আপনার বাস্তবায়নে সরাসরি প্রয়োগের পরিবর্তে আপনার কোডে java.util.Queue ইন্টারফেস ব্যবহার করা উচিত :

Queue<T> q1 = new LinkedList<T>();
Queue<T> q2 = new LinkedList<T>();

এটি আপনাকে চাইলে অন্যান্য Queueপ্রয়োগগুলিও ব্যবহার করতে দেয় এবং পাশাপাশি থাকা 2 টি পদ্ধতি লুকিয়ে রাখলে ইন্টারফেসের LinkedListস্পিরিট পেতে পারে Queue। এর মধ্যে রয়েছে get(int)এবং pop()(যখন আপনার কোড প্রনয়ন, একটি যুক্তিবিজ্ঞান ত্রুটি তোমার নিয়োগ সীমাবদ্ধতার সেখানে দেওয়া হয়। আপনার ভেরিয়েবল ঘোষণা যেমন Queueপরিবর্তে LinkedListএটা প্রকাশ হবে)। সম্পর্কিত পড়া: "ইন্টারফেসে প্রোগ্রামিং" বোঝা এবং ইন্টারফেস কেন কার্যকর?

1 আমার এখনও মনে আছে: অনুশীলনটি স্ট্যাক ইন্টারফেসে কেবলমাত্র পদ্ধতি ব্যবহার করে এবং কোনও java.util.Collections"স্ট্যাটিক কেবল" ইউটিলিটি ক্লাসে কোনও ইউটিলিটি পদ্ধতি ব্যবহার করে একটি স্ট্যাককে বিপরীত করা ছিল । সঠিক সমাধানটিতে অস্থায়ী হোল্ডিং অবজেক্ট হিসাবে অন্যান্য ডেটা স্ট্রাকচার ব্যবহার করা জড়িত: আপনাকে বিভিন্ন ডেটা স্ট্রাকচার, তাদের বৈশিষ্ট্য এবং এটি করতে কীভাবে তাদের একত্রিত করতে হবে তা জানতে হবে। আমার বেশিরভাগ CS101 ক্লাস স্ট্যাম্প করেছে যারা এর আগে কখনও প্রোগ্রাম করেনি।

2 পদ্ধতিগুলি এখনও রয়েছে, তবে আপনি টাইপ কাস্ট বা প্রতিবিম্ব ছাড়াই এগুলি অ্যাক্সেস করতে পারবেন না। সুতরাং এই নন-সারি পদ্ধতিগুলি ব্যবহার করা সহজ নয় ।


1
ধন্যবাদ। আমি বুঝতে পারি যে এটি উপলব্ধি করে। আমি আরও বুঝতে পেরেছিলাম যে আমি উপরের কোডটিতে "অবৈধ" অপারেশনগুলি ব্যবহার করছি (কোনও ফিফোর সামনের দিকে ঠেলা), তবে আমি মনে করি না যে এটি কোনও পরিবর্তন করে। আমি সমস্ত অপারেশনগুলিকে উল্টে দিয়েছি এবং এটি এখনও ইচ্ছামত কাজ করে। আমি গ্রহণ করার আগে আমি কিছুটা অপেক্ষা করতে যাচ্ছি কারণ আমি অন্য কোনও মানুষকে ইনপুট দেওয়া থেকে নিরুৎসাহিত করতে চাই না। যদিও ধন্যবাদ.
কারসিজিকেট

19

কোনও লাভ নেই। আপনি সঠিকভাবে বুঝতে পেরেছেন যে স্ট্যাক প্রয়োগের জন্য কুইউস ব্যবহার করা ভয়াবহ সময়ের জটিলতার দিকে নিয়ে যায়। কোনও (দক্ষ) প্রোগ্রামার কখনও "বাস্তব জীবনে" এর মতো কিছু করতে পারে না।

তবে এটা সম্ভব। আপনি অন্যটিকে বাস্তবায়নের জন্য একটি বিমূর্তি ব্যবহার করতে পারেন এবং বিপরীতে। একটি স্ট্যাক দুটি সারি হিসাবে প্রয়োগ করা যেতে পারে, এবং একইভাবে আপনি দুটি স্ট্যাকের ক্ষেত্রে একটি সারি প্রয়োগ করতে পারেন could এই অনুশীলনের সুবিধা হ'ল:

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

আসলে, এটি একটি দুর্দান্ত অনুশীলন। আমার এখনই এটি করা উচিত :)


3
@ জনকজেলম্যান আপনার সম্পাদনার জন্য ধন্যবাদ, তবে আমি আসলে "ভয়ঙ্কর সময়ের জটিলতা" বোঝাতে চাইছি। একটি লিঙ্ক-তালিকা-ভিত্তিক স্ট্যাকের জন্য push, peekএবং popঅপারেশন হে (1) এ আছে। পুনরায় আকার পরিবর্তনযোগ্য অ্যারে-ভিত্তিক স্ট্যাকের জন্য একই, pushও (1) মোড়কযুক্ত ও (এন) সবচেয়ে খারাপ ক্ষেত্রে বাদে । এর সাথে তুলনা করে, একটি সারিতে-ভিত্তিক স্ট্যাক ও (এন) পুশ, ও (1) পপ এবং উঁকি, বা বিকল্পভাবে ও (1) ধাক্কা, ও (এন) পপ এবং উঁকি দিয়ে অত্যন্ত নিম্নমানের।
আমন

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

5

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

দুটি সারি তৈরি স্ট্যাক হিসাবে? এটি এমন একটি প্রসঙ্গে উপলব্ধি করতে পারে যেখানে আপনার কাছে বিশাল এবং দ্রুত সারিগুলির একটি গুচ্ছ উপলব্ধ রয়েছে। এটি অবশ্যই এই ধরণের জাভা অনুশীলন হিসাবে অকেজো। সেগুলি যদি চ্যানেল বা বার্তাগুলির সারি হয় তবে তা বোধগম্য হতে পারে। (যেমন: N বার্তা প্রেরণ করা হয়েছে, একটি ও (1) অপারেশন সহ সামনের দিকে আইটেমগুলিকে একটি নতুন কাতারে সরানোর জন্য))


হুম .. এটি আমাকে
শিটিং

বাহ, মিল সিপিইউ সত্যই আকর্ষণীয়। অবশ্যই একটি "কিউ মেশিন"।
রব

2

ব্যায়াম করা হয় অযথা বাস্তবসম্মত দৃষ্টিকোণ থেকে কল্পিত। মুল্যটি হ'ল স্ট্যাকটি প্রয়োগের জন্য আপনাকে একটি চৌকস উপায়ে কিউয়ের ইন্টারফেসটি ব্যবহার করতে বাধ্য করা। উদাহরণস্বরূপ, আপনার "এক সারি" সমাধানটির প্রয়োজন স্ট্যাক "পপ" ক্রিয়াকলাপের জন্য শেষ ইনপুট মান পেতে আপনার সারিটি দিয়ে পুনরাবৃত্তি করা উচিত। যাইহোক, একটি সারি ডেটা স্ট্রাকচার মানগুলির উপরে পুনরাবৃত্তি করতে দেয় না, আপনি এগুলি প্রথম-ইন, ফার্স্ট-আউট (ফিফো) এ অ্যাক্সেস করতে সীমাবদ্ধ।


2

অন্যরা যেমন ইতিমধ্যে উল্লেখ করেছে: বাস্তব-বিশ্বের কোনও সুবিধা নেই।

যাইহোক, আপনার প্রশ্নের দ্বিতীয় অংশের একটি উত্তর, কেন কেবল একটি সারি ব্যবহার করা উচিত নয়, তা জাভা ছাড়িয়ে।

জাভাতে এমনকি Queueইন্টারফেসেরও একটি size()পদ্ধতি রয়েছে এবং সেই পদ্ধতির সমস্ত মানক প্রয়োগগুলি হ'ল ও (1)।

সি / সি ++ প্রোগ্রামার বাস্তবায়িত হিসাবে নির্দোষ / ক্যানোনিকাল লিঙ্ক তালিকার পক্ষে এটি অগত্যা সত্য নয়, যা কেবল প্রথম এবং শেষ উপাদানটির প্রতি নির্দেশক এবং প্রতিটি উপাদানকে পরবর্তী উপাদানটির জন্য একটি পয়েন্টার রাখে।

যে ক্ষেত্রে size()হে (ঢ) এবং লুপ মধ্যে এড়িয়ে চলা উচিত। বা বাস্তবায়ন অস্বচ্ছ এবং কেবলমাত্র সর্বনিম্ন add()এবং প্রদান করে remove()

এ জাতীয় বাস্তবায়নের সাথে আপনাকে প্রথমে উপাদানগুলিকে দ্বিতীয় সারিতে স্থানান্তর n-1করে প্রথমে প্রথম সারিতে স্থানান্তর করতে হবে এবং অবশিষ্ট উপাদানটি ফিরিয়ে দিতে হবে।

এটি বলেছিল, আপনি যদি জাভা-স্থলে বাস করেন তবে সম্ভবত এটির মতো কিছু তৈরি হবে না।


size()পদ্ধতি সম্পর্কে ভাল পয়েন্ট । তবে, ও (1) size()পদ্ধতির অভাবে, স্ট্যাকটির বর্তমান আকারটি নিজেই নজর রাখার পক্ষে এটি ক্ষুদ্র। এক-সারি বাস্তবায়ন বন্ধ করার কিছুই নেই।
20:30 এ সিমেস্টার

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

0

এ জাতীয় বাস্তবায়নের জন্য ব্যবহারটি কল্পনা করা শক্ত, এটি সত্য। কিন্তু বিন্দু অধিকাংশ প্রমাণ করতে হবে যে এটা করা সম্ভব হয়

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

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

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