অবজেক্টগুলিকে বদলে দেওয়ার দক্ষ উপায়


20

আমি কিছু কুইজ সফ্টওয়্যার জন্য একটি প্রোগ্রাম লিখছি। আমার কাছে প্রশ্ন, উত্তর, বিকল্পগুলি, চিহ্ন এবং নেতিবাচক চিহ্নগুলির জন্য অ্যারেলিস্টগুলি সমন্বিত একটি প্রশ্ন শ্রেণি রয়েছে। এটার মতো কিছু:

class question
{
    private ArrayList<Integer> index_list;
    private ArrayList<String> question_list;        
    private ArrayList<String> answer_list;      
    private ArrayList<String> opt1_list;        
    private ArrayList<String> opt2_list;    
}

আমি সমস্ত প্রশ্ন বদল করতে চাই, তবে প্রশ্নগুলি বদলের জন্য, সমস্ত বস্তু পরিবর্তন করা দরকার। আমি এই সমস্যার সাথে এইভাবে যোগাযোগ করতে পারতাম:

প্রথমত, আমি এই নকশাটি ব্যবহার না করতাম এবং স্ট্রিংকে ArrayList<String>উদাহরণ ভেরিয়েবল হিসাবে টাইপ না করতাম এবং তারপরে Collections.shuffleঅবজেক্টগুলিকে বদলে দেওয়ার পদ্ধতিটি ব্যবহার করতাম । তবে আমার দল এই নকশার উপর জোর দেয়।

এখন, প্রশ্ন শ্রেণিতে প্রশ্নগুলির প্রবেশের ফলে বর্ধমান অ্যারেলিস্টগুলি রয়েছে। কীভাবে এখন প্রশ্ন গুলো করবেন?


30
আমি বিস্মৃতিতে কথা বলতে ঘৃণা করি তবে আপনার দল যদি এই নকশার প্রতি জোর দেয় তবে সেগুলি ভুল। তাদের বলুন! তাদের বলুন যে আমি এটি বলেছিলাম (এবং আমি এটি ইন্টারনেটে লিখেছি, তাই আমার ঠিক থাকতে হবে)।
জোছিম সউর 11

10
হ্যাঁ, তাদের বলুন যে এখানে প্রচুর লোক আছেন যা আপনাকে বলে যে এই ধরণের নকশাটি একটি সাধারণ প্রাথমিক ভুল।
ডক ব্রাউন

6
কৌতূহলের বাইরে: আপনার দলটি এই ডিজাইনে কী কী সুবিধা দেখছে?
জোছিম সউর

9
জাভা নামকরণের কনভেনশনগুলি হ'ল শ্রেণীর নামের জন্য ক্যামেলকেস এবং ভেরিয়েবল নামের জন্য উটকেস।
তুলিনাস কর্ডোভা

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

উত্তর:


95

আপনার দল একটি সাধারণ সমস্যায় ভুগছে: বস্তু অস্বীকার

এর সাথে সম্পর্কিত সমস্ত তথ্যের সাথে একটি প্রশ্ন রাখে এমন এক শ্রেণীর পরিবর্তে, আপনি একটি ক্লাস তৈরি করার চেষ্টা করেন যা একটি প্রশ্নে সমস্ত প্রশ্নকেquestion ধারণ করে

এটি সম্পর্কে যাবার জন্য এটিই ভুল উপায় এবং আপনি যা করার চেষ্টা করছেন তা জটিল করে তোলে ! সমান্তরাল অ্যারে (বা তালিকাগুলি) বাছাই করা বাজে ব্যবসায় এবং এটির জন্য কোনও সাধারণ এপিআই নেই, কেবল কারণ আপনি সাধারণত এটিকে এড়াতে চান

আমি আপনাকে আপনার কোডটি এভাবে পুনর্গঠন করার পরামর্শ দিচ্ছি:

class Question
{
    private Integer index;
    private String question;        
    private String answer;      
    private String opt1;        
    private String opt2;    
}

// somewhere else
List<Question> questionList = new ArrayList<Question>();

এইভাবে, আপনার প্রশ্নটি বদল করা তুচ্ছ হয়ে উঠবে (ব্যবহার করে Collections.shuffle()):

Collections.shuffle(questionList);

39
এটি এমনকি অস্বীকৃতিও অস্বীকার করে না এটি ডেটা স্ট্রাকচার অস্বীকার
জে কে।

22

আপনি না। আপনি সূচকের অন্য তালিকা / সারি তৈরি করেন এবং এটি পরিবর্তন করুন। তারপরে আপনি সূচকগুলি পুনরায় সরিয়ে দিন যা আপনার অন্যান্য সংগ্রহের "শিফলেড" ক্রমটি চালায়।

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


10
আমি এই পর্যন্ত ভোট দিতে অনিচ্ছুক আছি: এটা পরবর্তী সবচেয়ে ভালো সমাধান হলো iff এই নকশা প্রকৃতপক্ষে সংশোধন করা হয়েছে, কিন্তু এই নকশা উপর এমন গোঁ তাই ভুল, যে আমি এটা সম্পর্কে কোন পরামর্শ দিতে চাইবেন না। (মেহ, যাইহোক যাইহোক ;-))
জোছিম সাউর

3
@ জোয়াচিমসৌয়ার - আমি সম্মত হওয়ার পরেও প্রচুর অন্যান্য (কম আপত্তিকর) পরিস্থিতি রয়েছে যেখানে মূল সংগ্রহটি স্থির থাকতে হবে যখন তাদের মধ্য দিয়ে চলার পথটি পরিবর্তিত হওয়া দরকার।
টেলাস্টিন

4
হ্যা আমি জানি. এবং সূচকের সংকলন বদলানো সেই পরিস্থিতিতে সঠিক পদ্ধতি। আমার একমাত্র ভয় হ'ল ওপিএস দলটি তাদের নকশাটি পুনর্বিবেচনা না করে কেবল এটি গ্রহণ করবে এবং "যথেষ্ট ভাল" বলবে।
জোছিম সউর

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

@ জোয়াচিম সাউর: সূচকগুলিকে বদলে দেওয়া অবশ্যই বলা উচিত সমস্যার সর্বোত্তম সমাধান নয়। একটি বিকল্প জন্য আমার উত্তর দেখুন।
মাইকেল বর্গওয়ার্ট

16

আমি অন্যান্য উত্তরের সাথে একমত যে সঠিক সমাধানটি একটি সঠিক অবজেক্ট মডেল ব্যবহার করা।

তবে একাধিক তালিকাগুলি অভিন্ন উপায়ে বদলে দেওয়া আসলে বেশ সহজ:

Random rnd = new Random();
long seed = rnd.nextLong();

rnd.setSeed(seed);
Collections.shuffle(index_list, rnd);
rnd.setSeed(seed);
Collections.shuffle(question_list, rnd);
rnd.setSeed(seed);
Collections.shuffle(answer_list, rnd);
...

এটি ... এটি করার একটি পরিষ্কার উপায়! এখন, "বাছাই" মামলার জন্য আমাদের কেবল এমন একটি বীজ সন্ধান করতে হবে যা এই পদ্ধতিতে প্রয়োগ করার পরে একটি বাছাই করা তালিকা তৈরি করে এবং তারপরে আমরা এই বীজের সাথে সমস্ত তালিকাগুলি সাফ করে দেই!
জোচিম সউর

1
@ জোয়াচিমসৌয়ার: ভাল, বাছাই করা সমস্যার অংশ ছিল না। যদিও এটি একটি আকর্ষণীয় প্রশ্ন যদিও কোনও প্রদত্ত আরএনজির জন্য এই জাতীয় বীজ খুঁজে পাওয়ার পদ্ধতিগত উপায় আছে কিনা।
মাইকেল বর্গওয়ার্ট

2
@ মিশেলবার্গওয়ার্ট একবার 17 টিরও বেশি প্রশ্ন পেয়ে গেলে আপনি জাভা র্যান্ডম ব্যবহার করা 48 টি বিট (লগ_2 (17!) = 48.33)
র‌্যাচেট ফ্রিক

@ratchetfreak: আমার কাছে বাস্তব সমস্যা বলে মনে হচ্ছে না। এবং এটির পরিবর্তে SecureRandom ব্যবহার করা তুচ্ছ।
মাইকেল বর্গওয়ার্ট

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

3

একটি শ্রেণী তৈরি করুন Question2:

class Question2
{
    public Integer index_list;
    public String question_list;        
    public String answer_list;      
    public String opt1_list;        
    public String opt2_list;    
}

তারপর একটি ফাংশন একটি ম্যাপিং তৈরি questionকরতে ArrayList<Question2>, ব্যবহার Collection.Shuffleকরে ফলাফলের জন্য, এবং ম্যাপিং জন্য একটি দ্বিতীয় ফাংশন তৈরি ArrayList<Question2>ফিরে question

এরপরে, আপনার দলে যান এবং তাদের বোঝানোর চেষ্টা করুন যে ArrayList<Question2>পরিবর্তে এর পরিবর্তে ব্যবহার করা questionতাদের কোডকে অনেক উন্নত করবে, যেহেতু এটি তাদের যে অযথা রূপান্তরগুলি অনেকটা রক্ষা করবে।


1
এটি একটি ভাল ধারণা, তবে কেবলমাত্র একটি অগ্রাধিকার পরে ডিজাইন পরিবর্তন করার চেষ্টা ব্যর্থ হয়েছে।
সেবাস্তিয়ান রেডল

@ সেবাস্তিয়ানআরডেল: কোডের সমাধান দেওয়ার সময় কখনও কখনও লোকেরা আরও ভাল ডিজাইনের বোঝানো সহজ হয়।
ডক ব্রাউন

1

আমার মূল নির্বোধ এবং ভুল উত্তর:

আপনার প্রতিটি তালিকার জন্য লুপের জন্য nআইটেমটির n সাথে কেবল কমপক্ষে) এলোমেলো সংখ্যা এবং আদান- iপ্রদানের আইটেম তৈরি করুন ।

সিউডো কোডে:

for (in i = 0; i < question_list.length(); i++) {
  int random = randomNumber(0, questions_list.length()-1);
  question_list.switchItems(i, random);
  answer_list.switchItems(i, random);
  opt1_list.switchItems(i, random);
  opt2_list.switchItems(i, random);

}

হালনাগাদ:

কোডিং হরর নিবন্ধটি নির্দেশ করার জন্য the_lotus এর জন্য ধন্যবাদ। আমি এখন অনেক বেশি স্মার্ট বোধ করছি :-) যাইহোক জেফ আতউড ফিশার-ইয়েটস অ্যালগোরিদম ব্যবহার করে কীভাবে এটি সঠিকভাবে করবেন তা দেখায় :

for (int i = question_list.Length - 1; i > 0; i--){
  int n = rand.Next(i + 1); //assuming rand.Next(x) returns values between 0 and x-1
  question_list.switchItems(i, n);
  answer_list.switchItems(i, n);
  opt1_list.switchItems(i, n);
  opt2_list.switchItems(i, n);
}

এখানে মূল পার্থক্যটি হ'ল প্রতিটি উপাদানটি একবারে অদলবদল করা হয়।

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


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