কিভাবে সঠিক লুপ লিখবেন?


65

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

/**
 * Inserts the given value in proper position in the sorted subarray i.e. 
 * array[0...rightIndex] is the sorted subarray, on inserting a new value 
 * our new sorted subarray becomes array[0...rightIndex+1].
 * @param array The whole array whose initial elements [0...rightIndex] are 
 * sorted.
 * @param rightIndex The index till which sub array is sorted.
 * @param value The value to be inserted into sorted sub array.
 */
function insert(array, rightIndex, value) {
    for(var j = rightIndex; j >= 0 && array[j] > value; j--) {
        array[j + 1] = array[j];
    }   
    array[j + 1] = value; 
};

প্রথমদিকে আমি যে ভুলগুলি করেছিলাম তা হ'ল:

  1. J> = 0 এর পরিবর্তে আমি এটিকে j> 0 রেখেছি।
  2. অ্যারে [j + 1] = মান বা অ্যারে [জে] = মান কিনা তা বিভ্রান্ত হয়ে পড়ে।

এই জাতীয় ভুল এড়াতে কী কী সরঞ্জাম / মানসিক মডেল?


6
কোন পরিস্থিতিতে আপনি বিশ্বাস করেন যে j >= 0এটি একটি ভুল? আপনি যে অ্যাক্সেস করছেন array[j]এবং array[j + 1]প্রথমে এটি পরীক্ষা না করেই আমি আরও সতর্ক থাকব array.length > (j + 1)
বেন কট্রেল

5
@ লাইটনেসেসেসিন অরবিত যা বলেছিলেন তার অনুরূপ, আপনি সম্ভবত ইতিমধ্যে সমাধান করা সমস্যাগুলি সমাধান করছেন। সাধারণত কোনও মূল মডিউল বা শ্রেণিতে ( Array.prototypeজেএসের উদাহরণে) কোনও ডেটা স্ট্রাকচার ইতিমধ্যে বিদ্যমান আপনার কোনও লুপিংয়ের কথা বলতে চান । এটি আপনাকে প্রান্ত অবস্থার মুখোমুখি হতে বাধা দেয় কারণ mapসমস্ত অ্যারেতে কাজ করার মতো কিছু কাজ করে। সমস্ত একসাথে লুপিং এড়ানোর জন্য আপনি উপরের স্লাইস এবং কনটাক্ট ব্যবহার করে সমাধান করতে পারেন: কোডেপেন.আইও / অ্যানন / স্পেন / জেডওভডজি ?
জেদ স্নাইডার

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

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

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

উত্তর:


208

পরীক্ষা

না, গম্ভীরভাবে, পরীক্ষা।

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

সহজবোধ্য রাখো

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

এক এক করে বন্ধ

আপনার আঙ্গুলগুলি গণনা এবং আপনার আঙ্গুলের মধ্যে ফাঁকা স্থান গণনা করার মধ্যে পার্থক্যটি জানুন। কখনও কখনও ফাঁকা স্থানগুলি আসলে গুরুত্বপূর্ণ। আপনার আঙ্গুলগুলি আপনাকে বিরক্ত করতে দেবেন না। আপনার আঙুলটি আঙুল কিনা তা জেনে নিন। আপনার গোলাপী এবং থাম্বের মধ্যে ফাঁকটি স্থান হিসাবে গণ্য হয়েছে তা জেনে নিন।

মন্তব্য

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

সেরা মন্তব্য একটি ভাল নাম।

আপনি যদি একটি ভাল নামের সাথে যা বলতে চান তা যদি আপনি বলতে পারেন, তবে এটি একটি মন্তব্য দিয়ে আবার বলবেন না।

abstractions

অবজেক্টস, ফাংশন, অ্যারে এবং ভেরিয়েবলগুলি সমস্ত বিমূর্ততা যা কেবল তাদের দেওয়া নামগুলির মতোই ভাল। তাদের এমন নাম দিন যা নিশ্চিত করে যে লোকেরা যখন তাদের ভিতরে .ুকবে তখন তারা যা খুঁজে পেয়েছে তাতে অবাক হবে না।

সংক্ষিপ্ত নাম

স্বল্পস্থায়ী জিনিসের জন্য ছোট নাম ব্যবহার করুন। iএকটি ছোট স্কোপটিতে একটি সুন্দর টাইট লুপের একটি সূচকের একটি সূক্ষ্ম নাম যা এর অর্থ স্পষ্ট করে তোলে। যদি iঅন্য ধারণা এবং নামের সাথে বিভ্রান্ত হতে পারে তার সাথে লাইনের পরে লাইনের বাইরে ছড়িয়ে যাওয়ার জন্য যদি দীর্ঘ সময় বেঁচে থাকে iতবে iএকটি সুন্দর দীর্ঘ ব্যাখ্যামূলক নাম দেওয়ার সময় এসেছে।

দীর্ঘ নাম

লাইন দৈর্ঘ্যের বিবেচনার কারণে কখনও কখনও নাম ছোট করবেন না। আপনার কোড আউট করার জন্য অন্য কোনও উপায় সন্ধান করুন।

সাদা ব্যবধান

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

লুপ নির্মাণ

আপনার ভাষায় লুপ কাঠামো শিখুন এবং পর্যালোচনা করুন। একটি ডিবাগার হাইলাইট for(;;)লুপ দেখা খুব শিক্ষণীয় হতে পারে। সমস্ত ফর্ম শিখুন। while, do while, while(true), for each। আপনি সহজেই পালাতে পারবেন এমন সহজ ব্যবহার করুন। পাম্প priming তাকান । আপনার কাছে থাকলে কী breakএবং কী শিখুন continuec++এবং মধ্যে পার্থক্য জানুন ++c। যতক্ষণ না আপনি সবসময় বন্ধ হওয়ার দরকার হয় ততক্ষণ তাড়াতাড়ি ফিরে আসতে ভয় পাবেন না। অবশেষে এমন কিছু অবরুদ্ধ করে বা পছন্দ করে যেটি এটি খোলার সময় স্বয়ংক্রিয়ভাবে বন্ধ হওয়ার জন্য চিহ্নিত করে: বিবৃতি ব্যবহার করে / সংস্থান দিয়ে চেষ্টা করুন

লুপ বিকল্প

পারলে অন্য কিছু লুপিং করতে দিন। এটি চোখে সহজ এবং ইতিমধ্যে ডিবাগ করা হয়েছে। এই নানা রূপে আসবে: সংগ্রহ বা স্ট্রিম তা সনাক্ত করতে মঞ্জুর map(), reduce(), foreach(), এবং অন্যান্য ধরনের পদ্ধতি যে একটি ল্যামডা প্রযোজ্য। মত বিশেষ বৈশিষ্ট্য অনুসন্ধান করুন Arrays.fill()। পুনরাবৃত্তিও রয়েছে তবে কেবল বিশেষ ক্ষেত্রে জিনিসগুলি সহজ করে তোলা আশা করে। বিকল্পটি দেখতে কেমন তা না দেখা পর্যন্ত সাধারণত পুনরাবৃত্তি ব্যবহার করবেন না।

ওহ, এবং পরীক্ষা।

পরীক্ষা, পরীক্ষা, পরীক্ষা।

আমি পরীক্ষার কথা উল্লেখ করেছি?

আরও একটি জিনিস ছিল। মনে নেই। একটি টি দিয়ে শুরু ...


36
ভাল উত্তর, তবে আপনার পরীক্ষার কথা উল্লেখ করা উচিত। ইউনিট পরীক্ষায় অসীম লুপের সাথে একজন কীভাবে ডিল করে? এই ধরনের লুপগুলি কি 'ব্রেক' করে না পরীক্ষাগুলি ???
গেমএলকেমিস্ট

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

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

15
@ কোডযোগি ডুডের সমস্ত dueণ টিডিডি তবে পরীক্ষার >> টিডিডি-তে। কোনও মান আউটপুট করা টেস্টিং হতে পারে, আপনার কোডে দ্বিতীয় সেট চোখ পরীক্ষা করা হচ্ছে (আপনি এটি কোড রিভিউ হিসাবে আনুষ্ঠানিক করতে পারেন তবে আমি প্রায় 5 মিনিটের কথোপকথনের জন্য কাউকে কেবল ধরা করি)। পরীক্ষা হ'ল কোনও সম্ভাবনা যা আপনি আপনার ব্যর্থ হওয়ার অভিপ্রায়টি প্রকাশ করেন। হ্যালো আপনি আপনার মায়ের সাথে একটি ধারণার মাধ্যমে কথা বলে আপনার কোডটি পরীক্ষা করতে পারেন। শাওয়ারে টাইলের দিকে তাকানোর সময় আমি আমার কোডগুলিতে বাগগুলি পেয়েছি। টিডিডি একটি কার্যকর আনুষ্ঠানিক শৃঙ্খলা যা আপনি প্রতিটি দোকানে খুঁজে পাবেন না। আমি একবারে কোথাও কোডিং করি নি যেখানে লোকেরা পরীক্ষা করে নি।
candied_orange

12
আমি টিডিডি শোনার আগে বছর কয়েক বছর কোডিং এবং পরীক্ষা করছিলাম। এখনই কেবল আমি বুঝতে পারি যে প্যান্ট না পরে কডিংয়ে ব্যয় করা বছরগুলির সাথে সেই বছরগুলির সম্পর্ক lation
candied_orange

72

প্রোগ্রামিং যখন এটি চিন্তা করা দরকারী:

এবং অনির্ধারিত অঞ্চল অন্বেষণ করার সময় (যেমন সূচকগুলি নিয়ে জাগ্রত করা) খুব কার্যকর, খুব কার্যকর হতে পারে কেবলমাত্র সেগুলি সম্পর্কে চিন্তা না করে বরং এগুলি দৃ the ়তার সাথে কোডে স্পষ্ট করে তোলা ।

আসুন আপনার আসল কোডটি গ্রহণ করুন:

/**
 * Inserts the given value in proper position in the sorted subarray i.e. 
 * array[0...rightIndex] is the sorted subarray, on inserting a new value 
 * our new sorted subarray becomes array[0...rightIndex+1].
 * @param array The whole array whose initial elements [0...rightIndex] are 
 * sorted.
 * @param rightIndex The index till which sub array is sorted.
 * @param value The value to be inserted into sorted sub array.
 */
function insert(array, rightIndex, value) {
    for(var j = rightIndex; j >= 0 && array[j] > value; j--) {
        array[j + 1] = array[j];
    }   
    array[j + 1] = value; 
};

এবং আমাদের কি আছে তা পরীক্ষা করুন:

  • পূর্ব শর্ত: array[0..rightIndex]সাজানো হয়
  • অবস্থা-পরে: array[0..rightIndex+1]বাছাই করা হয়
  • আক্রমণকারী: 0 <= j <= rightIndexতবে এটি কিছুটা অপ্রয়োজনীয় মনে হচ্ছে; বা @ জুলে মন্তব্যগুলিতে "বৃত্তাকার" শেষে, মন্তব্য করা হয়েছে for n in [j, rightIndex+1] => array[j] > value
  • আক্রমণকারী: "বৃত্তাকার" শেষে, array[0..rightIndex+1]বাছাই করা হয়

সুতরাং আপনি প্রথমে একটি is_sortedফাংশন পাশাপাশি minঅ্যারে স্লাইসে কাজ করে একটি ফাংশন লিখতে পারেন এবং তারপরে দৃsert়ভাবে বলতে পারেন:

function insert(array, rightIndex, value) {
    assert(is_sorted(array[0..rightIndex]));

    for(var j = rightIndex; j >= 0 && array[j] > value; j--) {
        array[j + 1] = array[j];

        assert(min(array[j..rightIndex+1]) > value);
        assert(is_sorted(array[0..rightIndex+1]));
    }   
    array[j + 1] = value; 

    assert(is_sorted(array[0..rightIndex+1]));
};

আপনার লুপের অবস্থা কিছুটা জটিল হওয়ার বিষয়টিও রয়েছে; জিনিসগুলি বিভক্ত করে আপনি নিজের উপর এটিকে আরও সহজ করতে চাইতে পারেন:

function insert(array, rightIndex, value) {
    assert(is_sorted(array[0..rightIndex]));

    for (var j = rightIndex; j >= 0; j--) {
        if (array[j] <= value) { break; }

        array[j + 1] = array[j];

        assert(min(array[j..rightIndex+1]) > value);
        assert(is_sorted(array[0..rightIndex+1]));
    }   
    array[j + 1] = value; 

    assert(is_sorted(array[0..rightIndex+1]));
};

এখন, লুপ সহজবোধ্য (হয় jথেকে যায় rightIndexকাছে 0)।

অবশেষে, এখন এটি পরীক্ষা করা দরকার:

  • সীমানা পরিস্থিতি সম্পর্কে চিন্তা করুন ( rightIndex == 0, rightIndex == array.size - 2)
  • এর valueচেয়ে ছোট array[0]বা বড় হওয়ার কথা ভাবুনarray[rightIndex]
  • মনে valueসমান হচ্ছে array[0], array[rightIndex]অথবা কিছু মধ্যম সূচক

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


8
@ কোডডোগি: সাথে ... পরীক্ষা বিষয়টি হ'ল, সমস্ত কিছুকে দৃser়ভাবে প্রকাশ করা অবৈধ হতে পারে : যদি দাবিটি কেবল কোডটি পুনরায় করে তবে তা নতুন কিছু এনে দেয় না (পুনরাবৃত্তি মানের সাথে সহায়তা করে না)। এই কারণেই এখানে আমি লুপটিতে দৃsert়তা জানাইনি 0 <= j <= rightIndexবা array[j] <= valueএটি কোডটি পুনরাবৃত্তি করবে। অন্যদিকে, is_sortedএকটি নতুন গ্যারান্টি নিয়ে আসে, সুতরাং এটি মূল্যবান। এরপরে, পরীক্ষার জন্য এটিই। আপনি যদি insert([0, 1, 2], 2, 3)আপনার ফাংশনে কল করেন এবং আউটপুট না হয় [0, 1, 2, 3]তবে আপনি একটি বাগ খুঁজে পেয়েছেন।
ম্যাথিউ এম।

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

1
@ ক্যান্ডিওড ওরেঞ্জ: কোডটি নকল করে আমি আক্ষরিক অর্থে বলতে চাইছি array[j+1] = array[j]; assert(array[j+1] == array[j]);। এই ক্ষেত্রে, মানটি খুব কম মনে হচ্ছে (এটি একটি অনুলিপি / পেস্ট)। আপনি যদি অর্থটির সদৃশ হন তবে অন্য ফ্যাশনে প্রকাশ করেন তবে তা আরও মূল্যবান হয়ে ওঠে।
ম্যাথিউ এম।

10
হোয়ারের বিধি: 1969 সাল থেকে সঠিক লুপগুলি লিখতে সহায়তা করে "" তবুও, এই কৌশলগুলি এক দশকেরও বেশি সময় ধরে পরিচিত হলেও, বেশিরভাগ পোড়ামগ্রাম তাদের সম্পর্কে কখনও শুনেনি "।
জোকার_ভিডি

1
@MatthieuM। আমি একমত যে এর খুব কম মান আছে। তবে আমি এটিকে একটি অনুলিপি / পেস্ট হওয়ার কারণে বলে মনে করি না। বলুন আমি রিফ্যাক্টর করতে চেয়েছিলাম insert()যাতে এটি পুরানো অ্যারে থেকে নতুন অ্যারে অনুলিপি করে কাজ করে। এটি আপনার অন্যদের ভঙ্গ না করেই করা যেতে পারে assert। তবে এটি শেষ নয়। আপনার অন্যান্যগুলি কীভাবে assertডিজাইন করা হয়েছিল তা কেবল দেখায় ।
candied_orange

29

ইউনিট টেস্টিং / টিডিডি ব্যবহার করুন

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

কল্পনা করুন যে আপনাকে এমন একটি পদ্ধতি প্রয়োগ করতে হবে যা শূন্যের চেয়ে উচ্চতর মানেরগুলিকে বিপরীত ক্রমে গ্রহণ করবে। আপনি কোন পরীক্ষার মামলাগুলির কথা ভাবতে পারেন?

  1. একটি অনুক্রমের একটি মান রয়েছে যা শূন্যের চেয়ে উচ্চতর।

    প্রকৃত: [5]। প্রত্যাশিত: [5]

    সর্বাধিক সরল বাস্তবায়ন যা প্রয়োজনীয়তাকে সন্তুষ্ট করে কেবল কলারের কাছে সোর্স ক্রমটি ফিরিয়ে আনার অন্তর্ভুক্ত।

  2. একটি অনুক্রমের দুটি মান থাকে, উভয়ই শূন্যের চেয়ে উচ্চতর।

    প্রকৃত: [5, 7]। প্রত্যাশিত: [7, 5]

    এখন, আপনি কেবল ক্রমটি ফিরিয়ে দিতে পারবেন না, তবে এটির বিপরীত হওয়া উচিত। আপনি কি একটি for (;;)লুপ ব্যবহার করবেন , অন্য কোনও ভাষা নির্মাণ বা লাইব্রেরি পদ্ধতিতে কিছু আসে যায় না।

  3. একটি অনুক্রমের তিনটি মান থাকে, একটি শূন্য।

    প্রকৃত: [5, 0, 7]। প্রত্যাশিত: [7, 5]

    মানগুলি ফিল্টার করার জন্য এখন আপনার কোডটি পরিবর্তন করা উচিত। আবার, এটি ifআপনার প্রিয় ফ্রেমওয়ার্ক পদ্ধতিতে একটি বিবৃতি বা একটি কলের মাধ্যমে প্রকাশ করা যেতে পারে ।

  4. আপনার অ্যালগরিদমের উপর নির্ভর করে (যেহেতু এটি হোয়াইট-বক্স টেস্টিং, বাস্তবায়নের বিষয়টি গুরুত্বপূর্ণ) আপনার খালি সিকোয়েন্স [] → []কেস বিশেষভাবে পরিচালনা করতে হতে পারে, নাও পারে । অথবা আপনি কি নিশ্চিত করতে পারে যে প্রান্ত ক্ষেত্রে যেখানে সব মান ঋণাত্মক [-4, 0, -5, 0] → []সঠিকভাবে পরিচালিত হয়, অথবা এমনকি যে সীমানা নেতিবাচক মান হল: [6, 4, -1] → [4, 6]; [-1, 6, 4] → [4, 6]। তবে অনেক ক্ষেত্রে আপনার উপরে বর্ণিত কেবলমাত্র তিনটি পরীক্ষা থাকবে: কোনও অতিরিক্ত পরীক্ষা আপনাকে আপনার কোড পরিবর্তন করতে দেবে না এবং তাই অপ্রাসঙ্গিক হবে।

উচ্চ বিমূর্ত স্তর স্তরের কাজ

যাইহোক, অনেক ক্ষেত্রে, আপনি বিদ্যমান অ্যালব্রেকশন স্তরে কাজ করে বিদ্যমান লাইব্রেরি / ফ্রেমওয়ার্ক ব্যবহার করে এই ত্রুটিগুলি বেশিরভাগ এড়াতে পারেন। এই লাইব্রেরি / ফ্রেমওয়ার্কগুলি অ্যারে বা দ্বিগুণ-লিঙ্কযুক্ত তালিকার মানগুলি সন্নিবেশ করানো বা অপসারণ করা, সিক্যুয়েন্সগুলি, বিভক্তকরণ এবং ক্রমগুলিতে যোগদান করা, ইত্যাদি সম্ভব করে তোলে etc.

সাধারণত, সীমার শর্তগুলি অপ্রাসঙ্গিকভাবে পরীক্ষা foreachকরে এর পরিবর্তে ব্যবহার করা যেতে পারে for: ভাষাটি এটি আপনার জন্য করে। পাইথনের মতো কিছু ভাষার এমনকি নির্মাণও নেই for (;;), তবে কেবল for ... in ...

সি # তে, লাইনকিউ সিকোয়েন্সগুলির সাথে কাজ করার সময় বিশেষত সুবিধাজনক।

var result = source.Skip(5).TakeWhile(c => c > 0);

তার forবৈকল্পিকের তুলনায় অনেক বেশি পঠনযোগ্য এবং কম ত্রুটিযুক্ত প্রবণ :

for (int i = 5; i < source.Length; i++)
{
    var value = source[i];
    if (value <= 0)
    {
        break;
    }

    yield return value;
}

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

18
: এক রুমে হাতি উল্লেখ করতে হচ্ছে জন্য আপনাকে ধন্যবাদ লুপ ব্যবহার করছেন না এ সব । লোকেরা কেন এখনও 1985 এর মতো কোড করে (এবং আমি উদার হচ্ছি) আমার বাইরে is BOCTAOE।
জারেড স্মিথ

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

6
@ মাইকেলকার্জলিং: আপনি লিনকিউ ব্যবহার করার সময় লুপটি উপস্থিত থাকে, তবে কোনও for(;;)নির্মাণ এই লুপটির খুব বর্ণনামূলক না হয় । একটি গুরুত্বপূর্ণ দিক হ'ল লিনকিউ (সেইসাথে পাইথন এবং অন্যান্য ভাষায় অনুরূপ উপাদানগুলির তালিকা বোঝার জন্য) সীমানা শর্তগুলি বেশিরভাগ অপ্রাসঙ্গিক করে তোলে, অন্তত মূল প্রশ্নের ক্ষেত্রের মধ্যে। তবে, লিনকিউ ব্যবহার করার সময় হুডের নীচে কী ঘটে তা বোঝার প্রয়োজনীয়তার বিষয়ে আমি আরও সম্মত হতে পারি না, বিশেষত যখন অলস মূল্যায়নের বিষয়টি আসে।
আর্সেনী মরজেনকো

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

15

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

0-ইনডেক্সেড অ্যারে সহ, আপনার স্বাভাবিক অবস্থা হতে চলেছে:

for (int i = 0; i < length; i++)

অথবা

for (int i = length - 1; i >= 0; i--)

এই নিদর্শনগুলি দ্বিতীয় প্রকৃতিতে পরিণত হওয়া উচিত, আপনার সেগুলি সম্পর্কে মোটেও চিন্তা করা উচিত নয়।

তবে সমস্ত কিছুই সেই সঠিক প্যাটার্ন অনুসরণ করে না। সুতরাং আপনি যদি এটি সঠিকভাবে লিখেছিলেন কিনা তা নিশ্চিত না হন তবে আপনার পরবর্তী পদক্ষেপটি এখানে রয়েছে:

মানগুলি প্লাগ করুন এবং আপনার নিজের মস্তিষ্কে কোডটি মূল্যায়ন করুন। আপনার পক্ষে যতটা সম্ভব চিন্তা করা এত সহজ করুন। যদি প্রাসঙ্গিক মান 0 হয় তবে কি হবে? তারা 1s হয় কি হবে?

for(var j = rightIndex; j >= 0 && array[j] > value; j--) {
    array[j + 1] = array[j];
}   
array[j + 1] = value;

আপনার উদাহরণে, আপনি নিশ্চিত নন যে এটির [জে] = মান বা [জে + 1] = মান হওয়া উচিত। এটি ম্যানুয়ালি মূল্যায়ন শুরু করার সময়:

আপনার অ্যারে দৈর্ঘ্য 0 থাকলে কী হয়? উত্তরটি সুস্পষ্ট হয়ে যায়: রাইটইন্ডেক্সটি অবশ্যই (দৈর্ঘ্য - 1) == -1 হওয়া উচিত, সুতরাং j -1 থেকে শুরু হয়, সুতরাং সূচক 0-এ সন্নিবেশ করতে আপনাকে 1 যুক্ত করতে হবে।

সুতরাং আমরা চূড়ান্ত শর্তটি সঠিক প্রমাণ করেছি, তবে লুপের অভ্যন্তরে নয়।

আপনার যদি 1 উপাদান, 10 দিয়ে অ্যারে থাকে এবং আমরা একটি 5 sertোকানোর চেষ্টা করি তবে কী হবে? একটি একক উপাদান সহ, ডানদিকের সূচক 0 থেকে শুরু হওয়া উচিত So সুতরাং লুপের মাধ্যমে প্রথমবার, জ = 0, সুতরাং "0> = 0 && 10> 5"। যেহেতু আমরা সূচক 0 তে 5 সন্নিবেশ করতে চাইছি, 10 টি সূচক 1 এ স্থানান্তরিত হওয়া উচিত, সুতরাং অ্যারে [1] = অ্যারে [0]। যেহেতু জে 0 হয়, অ্যারে [j + 1] = অ্যারে [j + 0] হয় তাই এটি ঘটে।

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

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

একবার আপনি যদি এটি সঠিক বলে মনে করেন, তবে এটি পরীক্ষার মাধ্যমে চালানো ভাল sure


4
আমি সত্যিই পছন্দ for (int i = 0; i < length; i++)। একবার আমি এই অভ্যাসে উঠলে আমি <=প্রায় প্রায়শই ব্যবহার বন্ধ করে দিয়েছিলাম এবং মনে হয়েছিল যে লুপগুলি আরও সহজ হয়েছে। তবে for (int i = length - 1; i >= 0; i--)তুলনায় অত্যধিক জটিল বলে মনে হচ্ছে: for (int i=length; i--; )( whileযদি আমি iএকটি ছোট সুযোগ / জীবন তৈরি করার চেষ্টা না করি তবে লুপ হিসাবে লিখতে সম্ভবত এটি আরও বেশি বুদ্ধিমান হবে )। I == দৈর্ঘ্য -১ (প্রাথমিকভাবে) আই == 0 এর মাধ্যমে ফলাফলগুলি এখনও লুপের মধ্য দিয়ে চলে, কেবলমাত্র কার্যকরী পার্থক্য হ'ল while()লুপটির পরে সংস্করণটি i == -1 দিয়ে শেষ হয় (যদি এটি বেঁচে থাকে), পরিবর্তে i = = 0।
তোগাম

2
@ টুগাম (আন্তঃ আমি = দৈর্ঘ্য; আই--;) সি / সি ++ এ কাজ করে কারণ 0 টি মিথ্যা হিসাবে মূল্যায়ন করে, তবে সমস্ত ভাষায় এর সমতা নেই। আমি অনুমান করি আপনি বলতে পারেন ---- ০।
ব্রাইস ওয়াগনার

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

1
@ ব্রাইস ওয়াগনার যদি আপনার প্রয়োজন হয় i-- > 0তবে ক্লাসিক রসিকতা কেন চেষ্টা করবেন না i --> 0,!
পোরগলজম্প

3
@porglezomp আহ, হ্যাঁ, চলে যায় অপারেটর । সি, সি ++, জাভা এবং সি # সহ বেশিরভাগ সি-এর মতো ভাষাতে এটি রয়েছে।
একটি সিভিএন

11

আমার মাথায় সঠিক কম্পিউটিং মডেল না থাকায় আমি খুব হতাশ হয়ে পড়েছি।

এই প্রশ্নের খুব আকর্ষণীয় বিষয় এবং এটি এই মন্তব্যটি তৈরি করেছে: -

একটি মাত্র উপায় আছে: আপনার সমস্যাটি আরও ভাল করে বুঝতে। তবে এটি আপনার প্রশ্ন হিসাবে সাধারণ। - টমাস জাঙ্ক

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

আমি এতগুলি ক্রিয়াকলাপ এবং ক্লাস দেখেছি যা একটি সম্পূর্ণ জগাখিচায় পরিণত হয়েছে কারণ লেখকরা সমস্যাটির পুরোপুরি সংজ্ঞা দেওয়ার আগে প্রয়োগকরণের সংজ্ঞা দেওয়ার চেষ্টা করেছেন। এবং এটি মোকাবেলা করা এত সহজ।

যদি আপনি সমস্যাটি পুরোপুরি বুঝতে না পারেন তবে আপনি সর্বোত্তম সমাধান (দক্ষতা বা স্বচ্ছতার দিক থেকে) কোডিং করার সম্ভাবনাও কম না, বা আপনি কোনও টিডিডি পদ্ধতিতে সত্যিকারের উপযোগী ইউনিট পরীক্ষা তৈরি করতে সক্ষম হতে পারবেন না।

আপনার কোডটিকে উদাহরণ হিসাবে এখানে নিন, এতে বেশ কয়েকটি সম্ভাব্য ত্রুটি রয়েছে যা আপনি এখনও উদাহরণ হিসাবে বিবেচনা করেননি: -

  • রাইটইনডেক্স খুব কম হলে কী হবে? (সূত্র: এটি ডেটা ক্ষতি জড়িত হবে )
  • রাইটইনডেক্স যদি অ্যারের সীমানার বাইরে থাকে? (আপনি কি একটি ব্যতিক্রম পাবেন, বা আপনি কেবল নিজেকে একটি বাফার ওভারফ্লো তৈরি করেছেন?)

কোডটির কার্য সম্পাদন এবং ডিজাইন সম্পর্কিত আরও কয়েকটি সমস্যা রয়েছে ...

  • এই কোডটি স্কেল করতে হবে? অ্যারে বাছাই করা সবচেয়ে ভাল বিকল্প, বা আপনি অন্যান্য বিকল্প (যেমন একটি লিঙ্কযুক্ত তালিকা?) তাকান?
  • আপনি আপনার অনুমান সম্পর্কে নিশ্চিত হতে পারেন? (আপনি অ্যারে বাছাই করা গ্যারান্টি দিতে পারেন, এবং তা না হলে কি?)
  • আপনি চাকা পুনরুদ্ধার করছেন? সাজানো অ্যারেগুলি একটি সুপরিচিত সমস্যা, আপনি কি বিদ্যমান সমাধানগুলি অধ্যয়ন করেছেন? আপনার ভাষায় ইতিমধ্যে কোনও সমাধান পাওয়া যায় (যেমন SortedList<t>সি # তে)?
  • আপনি নিজেই একবারে একটি অ্যারে এন্ট্রি অনুলিপি করা উচিত? বা আপনার ভাষা জেএসক্রিপ্টের মতো সাধারণ ক্রিয়াকলাপ সরবরাহ করে Array.Insert(...)? এই কোডটি আরও পরিষ্কার হবে?

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


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

@ ব্রাইস ওয়াগনার - একেবারে সত্য, তবে সমস্যাটি কী তা সম্পর্কে স্পষ্ট ধারণা ছাড়াই আপনি আসলে সমাধান করছেন যে আপনি 'হিট অ্যান্ড হোপ' কৌশলটিতে অন্ধকারের মধ্যে প্রচুর সময় ব্যয় করতে যাচ্ছেন যা এখন পর্যন্ত ওপি'র এই মুহুর্তে বৃহত্তম সমস্যা।
জেমস স্নেল

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

2
@ কোডযোগি, আমি মনে করি আপনি স্ট্যাক ওভারফ্লোতে এই সাইটটিকে বিভ্রান্ত করেছেন। এই সাইটটি কম্পিউটার টার্মিনালে নয়, হোয়াইটবোর্ডে প্রশ্নোত্তর পর্বের সমতুল্য । "আমাকে কোডটি দেখান" একটি চমত্কার স্পষ্ট ইঙ্গিত যে আপনি ভুল সাইটে আছেন on
ওয়াইল্ডকার্ড

2
@ উইল্ডকার্ড +1: আমার কাছে এই উত্তরটি কেন সঠিক তা সম্পর্কে একটি দুর্দান্ত সূচকটি "আমাকে কোডটি দেখান" এবং এটি সম্ভবত একটি মানব-উপাদান / নকশার সমস্যা যা কেবলমাত্র পারে তা প্রমাণ করার জন্য আমাকে আরও ভালভাবে কাজ করার প্রয়োজন হতে পারে মানব প্রক্রিয়া পরিবর্তন দ্বারা সম্বোধন করা - কোড পরিমাণ পরিমাণ এটি শেখাতে পারে না।
জেমস স্নেল

10

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

চ্যালেঞ্জটি হ'ল অ্যারে সেলগুলির ব্যাপ্তিগুলি কীভাবে ভাবেন । সুস্পষ্ট মানসিক মডেল ব্যতীত শেষ পয়েন্টগুলি অন্তর্ভুক্ত করা বা বাদ দেওয়ার ক্ষেত্রে তা বিভ্রান্তিকর হয়ে ওঠে।

অ্যারে রেঞ্জগুলি বর্ণনা করার সময়, কনভেনশনটি নিম্ন সীমাটি অন্তর্ভুক্ত করতে হবে , উপরের সীমাটি বাদ দেওয়া উচিত । উদাহরণস্বরূপ 0..3 পরিসীমাটি হল 0,1,2 ঘর। এই নিয়মাবলী 0-ইন্ডেক্স ভাষায় সর্বত্র ব্যবহার করা হয়, উদাহরণস্বরূপ slice(start, end)জাভাস্ক্রিপ্ট পদ্ধতি subarray ফেরৎ সূচক দিয়ে শুরু startপর্যন্ত কিন্তু সহ না সূচক end

অ্যারে সেলগুলির মধ্যে প্রান্তগুলি বর্ণনা করার জন্য আপনি যখন পরিসীমা সূচকগুলি সম্পর্কে চিন্তা করেন তখন এটি স্পষ্ট হয়। নীচের চিত্রটি 9 দৈর্ঘ্যের একটি অ্যারে এবং কক্ষের নীচে সংখ্যাগুলি প্রান্তগুলিতে প্রান্তিক করা হয়েছে এবং অ্যারে বিভাগগুলি বর্ণনা করার জন্য এটি ব্যবহৃত হয়। উদাহরণস্বরূপ এটি ২.৫ এর পরিসরের তুলনায় চিত্র থেকে স্পষ্ট যে কক্ষগুলি 2,3,4।

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │   -- cell indexes, e.g array[3]
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0   1   2   3   4   5   6   7   8   9   -- segment bounds, e.g. slice(2,5) 
        └───────────┘ 
          range 2..5

এই মডেলটি অ্যারের দৈর্ঘ্যের সাথে অ্যারের উপরের সীমানা হওয়ার সাথে সামঞ্জস্যপূর্ণ। দৈর্ঘ্য 5 সহ একটি অ্যারেতে কোষ 0..5 রয়েছে, যার অর্থ পাঁচটি ঘর 0,1,2,3,4 রয়েছে। এর অর্থ এই যে একটি বিভাগের দৈর্ঘ্য হ'ল উচ্চতর বাউন্ড বিয়োগ বিয়োগটি, অর্থাত্ ২.৫ বিভাগে ৫-২ = 3 কোষ রয়েছে।

উপরের বা নীচের দিকে পুনরুক্তি করার সময় এই মডেলটি মনে রাখলে শেষের পয়েন্টগুলি অন্তর্ভুক্ত করা বা বাদ দেওয়ার সময় এটি অনেক স্পষ্ট হয়। উপরের দিকে পুনরাবৃত্তি করার সময় আপনাকে সূচনা পয়েন্ট অন্তর্ভুক্ত করতে হবে তবে শেষ বিন্দুটি বাদ দিতে হবে। নীচের দিকে পুনরাবৃত্তি করার সময় আপনাকে প্রারম্ভ পয়েন্টটি (উচ্চতর বাউন্ড) বাদ দিতে হবে তবে শেষ পয়েন্টটি (নিম্ন সীমা) অন্তর্ভুক্ত করতে হবে।

যেহেতু আপনি আপনার কোডটিতে নীচের দিকে পুনরাবৃত্তি করছেন, আপনাকে নিম্ন বদ্ধ, 0 ​​টি অন্তর্ভুক্ত করা উচিত, যাতে আপনি যখন পুনরাবৃত্তি করেন j >= 0

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

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


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

3
"কম্পিউটার বিজ্ঞানে দুটি শক্ত জিনিস রয়েছে: ক্যাশে অবৈধকরণ, নামকরণের জিনিসগুলি এবং একের পর এক ত্রুটি" "
ডিজিটাল ট্রমা

1
@ কোডডোগি: আমি কী বলছি তা দেখানোর জন্য একটি ছোট চিত্র চিত্র যুক্ত করা হয়েছে।
জ্যাকবিবি

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

1
খুব। চমৎকার। উত্তর. এবং আমি যুক্ত করব যে এই অন্তর্ভুক্ত / একচেটিয়া সূচক কনভেনশনটি myArray.Lengthবা এর মান দ্বারাও উত্সাহিত হয় myList.Count- যা সর্বদা শূন্য-ভিত্তিক "ডানদিকের" সূচকের চেয়ে বেশি is ... ব্যাখ্যাটির দৈর্ঘ্য এই স্পষ্ট কোডিং হিউরিস্টিকগুলির ব্যবহারিক এবং সাধারণ প্রয়োগকে বোঝায়। টিএল; ডিআর জনতা নিখোঁজ রয়েছে।
রডারবব

5

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

আমি পরামর্শ দিচ্ছি যে আপনি কীভাবে লুপগুলি লিখতে হয় তা শিখে (পুনরায়) এই ঘাটতিটি সংশোধন করতে পারেন - এবং আমি কাগজ এবং পেন্সিল সহ কয়েকটি লুপের মাধ্যমে কয়েক ঘন্টা কাজ করার পরামর্শ দিই। এটি করার জন্য একটি বিকেল ছাড়ুন। তারপরে 45 মিনিট বা তার বেশি দিন ব্যয় করুন যতক্ষণ না আপনি সত্যই এটি পান।

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


4
আমি ওপির দক্ষতা সম্পর্কে এত দৃser় থাকব না। সীমানা ভুল করা সহজ, বিশেষত একটি চাপের মতো প্রসঙ্গে যেমন একটি নিয়োগের সাক্ষাত্কার। একজন অভিজ্ঞ বিকাশকারী সেই ভুলগুলিও করতে পারতেন, তবে স্পষ্টতই, একজন অভিজ্ঞ বিকাশকারী পরীক্ষার মাধ্যমে প্রথমে এই জাতীয় ভুলগুলি এড়াতে পারবেন।
আরসেনি মরজেনকো

3
@ মাইনমা ​​- আমি মনে করি যখন মার্ক আরও সংবেদনশীল হতে পারতেন, তবে আমি মনে করি তিনি ঠিক বলেছেন - সমস্যাটির সংজ্ঞা দেওয়ার জন্য বিবেচনা না করেই ইন্টারভিউর স্ট্রেস রয়েছে এবং কেবল হ্যাকিং কোড রয়েছে there's যেভাবে প্রশ্নের উত্তরটি খুব দৃ strongly়তার সাথে বলা হয়েছে এবং এটি এমন একটি যা আপনার দৃ foundation় ভিত্তি রয়েছে তা নিশ্চিত করে দীর্ঘমেয়াদে সবচেয়ে ভাল সমাধান করা যেতে পারে, আইডিই থেকে দূরে হ্যাক না করে
জেমস স্টেল

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

4
@ কোডযোগি যদি আপনার কোডিংয়ের সাথে 'ট্রায়াল এবং ত্রুটি' করতে হয় এবং আপনি 'হতাশ হচ্ছেন' এবং 'একই ভুলগুলি করছেন' তবে আপনি লিখতে শুরু করার আগে আপনার সমস্যাটি যথেষ্ট পরিমাণে বুঝতে পারছেন না সেগুলি লক্ষণ are । কেউ বলছেন না আপনি এটি বুঝতে পারেন নি, তবে আপনার কোডটি আরও ভালভাবে চিন্তা করা যেতে পারে এবং এগুলি লক্ষণ যে আপনি লড়াই করছেন যা আপনি বেছে নেওয়ার এবং এর কাছ থেকে শেখার বাছাই করার বাছাই করতে পারেন not
জেমস স্নেল

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

3

সম্ভবত আমার মন্তব্যে কিছুটা মাংস দেওয়া উচিত:

একটি মাত্র উপায় আছে: আপনার সমস্যাটি আরও ভাল করে বুঝতে। তবে এটি আপনার প্রশ্ন হিসাবে সাধারণ

আপনার কথা

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

আমি যখন পড়ি তখন trial and errorআমার অ্যালার্মের ঘন্টা বাজতে শুরু করে। অবশ্যই আমরা অনেকেই মনের অবস্থা জানি, যখন কেউ একটি ছোট সমস্যা সমাধান করতে চায় এবং তার মাথা অন্য জিনিসগুলির চারপাশে জড়িয়ে দেয় এবং কোডটি seemকরার জন্য, কী করার কথা বলে তা অনুমান করা শুরু করে । কিছু হ্যাকিশ সমাধান এ থেকে বেরিয়ে আসে - এবং তাদের মধ্যে কিছু খাঁটি প্রতিভা ; তবে সত্যি বলতে: তাদের বেশিরভাগই তা নয় । আমার অন্তর্ভুক্ত ছিল, এই অবস্থা জেনে।

আপনার কংক্রিট সমস্যা থেকে স্বাধীনভাবে আপনি কীভাবে উন্নতি করবেন সে সম্পর্কে প্রশ্ন জিজ্ঞাসা করেছেন:

1) পরীক্ষা

এটি অন্যরা বলেছিল এবং আমার যুক্ত করার মতো মূল্যবান কিছুই থাকবে না

2) সমস্যা বিশ্লেষণ

এ বিষয়ে কিছু পরামর্শ দেওয়া শক্ত। আমি আপনাকে কেবল দুটি ইঙ্গিত দিতে পারলাম যা সম্ভবত আপনাকে এই বিষয়ে আপনার দক্ষতা বাড়াতে সহায়তা করবে:

  • সুস্পষ্ট এবং সবচেয়ে তুচ্ছ একটি দীর্ঘমেয়াদে সবচেয়ে কার্যকর: অনেক সমস্যার সমাধান করুন। অনুশীলন এবং পুনরাবৃত্তি করার সময় আপনি মানসিকতা বিকাশ করে যা আপনাকে ভবিষ্যতের কাজের জন্য সহায়তা করে। প্রোগ্রামিং হ'ল কঠোর পরিশ্রমের মাধ্যমে উন্নত করা অন্যান্য ক্রিয়াকলাপের মতো

কোড কাটাস একটি উপায়, যা কিছুটা সাহায্য করতে পারে।

কীভাবে আপনি একজন দুর্দান্ত সংগীতশিল্পী হতে পারেন? এটি তত্ত্বটি জানতে এবং আপনার যন্ত্রের যান্ত্রিকতা বুঝতে সহায়তা করে। এটি প্রতিভা রাখতে সহায়তা করে। তবে শেষ পর্যন্ত মহৎত্ব অনুশীলন থেকে আসে; তত্ত্বটি বারবার প্রয়োগ করে, প্রতিবার ভাল হওয়ার জন্য প্রতিক্রিয়া ব্যবহার করে।

কোড কাটা

একটি সাইট, যা আমি খুব পছন্দ করি: কোড ওয়ার্স

চ্যালেঞ্জের মাধ্যমে দক্ষতা অর্জন করুন বাস্তব কোড চ্যালেঞ্জগুলির বিষয়ে অন্যদের সাথে প্রশিক্ষণ দিয়ে আপনার দক্ষতা উন্নত করুন

এগুলি অপেক্ষাকৃত ছোট সমস্যা, যা আপনাকে আপনার প্রোগ্রামিং দক্ষতা তীক্ষ্ণ করতে সহায়তা করে। এবং কি আমি সবচেয়ে পছন্দ কোড যুদ্ধ আপনি তুলনা করতে পারে, হয় আপনার এক সমাধান অন্যদের

বা হতে পারে, আপনি সম্প্রদায় থেকে প্রতিক্রিয়া পাবেন যেখানে এক্সারসিজম.আইও এর উপর আপনার দৃষ্টি দেওয়া উচিত ।

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

আমি জানি - যেমন উপরে আমি কখনও কখনও বলেছিলাম যে আপনি এমন অবস্থায় রয়েছেন - "সাধারণ" জিনিসগুলিকে আরও "মৃত সহজ" কাজে ভাঙ্গা কঠিন; তবে এটি অনেক সাহায্য করে।

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

3) একটি টুলবেল্ট বিকাশ করুন

আপনার ভাষা এবং আপনার সরঞ্জামগুলি জানার পাশাপাশি - আমি জানি এটি হ'ল চকচকে জিনিস যাগুলির বিকাশকারীরা প্রথমে চিন্তা করে - অ্যালগরিদম শিখুন (ওরফে পড়া)।

এখানে শুরু করার জন্য দুটি বই রয়েছে:

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

3 এ) প্রোগ্রামিং কনস্ট্রাক্টস জানুন

এই বিন্দুটি একটি ডেরাইভেটিভ - তাই বলে। আপনার ভাষাটি জানুন - এবং আরও ভাল: জেনে রাখুন, আপনার ভাষায় কোন গঠনগুলি সম্ভব

খারাপ বা inefficent কোড একটি সাধারণ বিন্দু, কখনও কখনও যে প্রোগ্রামার লুপ বিভিন্ন ধরনের মধ্যে পার্থক্য জানে না ( for-, while-এবং do-loops)। তারা একরকম সমস্ত পরিবর্তনযোগ্যভাবে ব্যবহারযোগ্য; তবে কিছু পরিস্থিতিতে অন্য লুপিং কনস্ট্রাক্ট বেছে নেওয়া আরও মার্জিত কোডের দিকে নিয়ে যায়।

এবং সেখানে ডাফের ডিভাইস রয়েছে ...

দ্রষ্টব্য:

অন্যথায় আপনার মন্তব্য ডোনাল ট্রাম্পের চেয়ে ভাল নয়।

হ্যাঁ, আমাদের আবার কোডিং দুর্দান্ত করা উচিত!

স্ট্যাকওভারফ্লো জন্য একটি নতুন লক্ষ্য।


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

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

"ট্রায়াল এবং ত্রুটি" এর উপর অ্যালার্মের ঘণির সাথে সম্পূর্ণ সম্মত হন। আমি মনে করি সমস্যা সমাধানের মানসিকতা পুরোপুরি শেখার সর্বোত্তম উপায় হ'ল কাগজ এবং পেন্সিল সহ অ্যালগরিদম এবং কোড চালানো।
ওয়াইল্ডকার্ড

হুম ... প্রোগ্রামিং সম্পর্কে আপনার উত্তরের মাঝে প্রসঙ্গ ছাড়াই উদ্ধৃত কোন রাজনৈতিক প্রার্থীর কাছে আপনার কেন নন-সিক্যুটার ব্যাকরণিকভাবে দুর্বল জব?
ওয়াইল্ডকার্ড

2

যদি আমি সমস্যাটি সঠিকভাবে বুঝতে পারি তবে আপনার প্রশ্নটি হ'ল প্রথম চেষ্টা থেকে লুপগুলি কীভাবে পেতে হবে, কীভাবে আপনার লুপটি সঠিক তা নিশ্চিত করবেন না (যার জন্য উত্তরটি উত্তর হিসাবে বর্ণিত হিসাবে টেস্টিং হবে)।

আমি যা ভাল পদ্ধতির বিবেচনা করি তা হ'ল কোনও পুনরায় লুপ ছাড়াই প্রথম পুনরাবৃত্তিটি লেখা। আপনি এটি করার পরে, আপনার এটি লক্ষ্য করা উচিত যে এটি পুনরাবৃত্তির মধ্যে কী পরিবর্তন করা উচিত।

এটি কি 0 বা 1 এর মতো একটি সংখ্যা? তারপরে আপনার সম্ভবত সম্ভবত একটি বিগ এবং বিঙ্গো দরকার আপনারও শুরু আপনার have তারপরে ভাবেন আপনি একই জিনিসটি কতবার চালাতে চান এবং আপনারও শেষ পরিণতি হবে।

এটি যদি কতবার চালিত হয় ঠিক যদি আপনি না জানেন তবে আপনার জন্য দরকার নেই, তবে কিছুক্ষণ বা কিছুক্ষণের জন্য।

প্রযুক্তিগতভাবে, কোনও লুপটি অন্য যে কোনও লুপে অনুবাদ করা যেতে পারে তবে আপনি সঠিক লুপটি ব্যবহার করেন তবে কোডটি পড়া সহজ, তাই এখানে কিছু টিপস রয়েছে:

  1. যদি আপনি নিজেকে একটি () {...; বিরতি; writing লিখতে দেখেন তবে কিছু সময়ের জন্য আপনার প্রয়োজন এবং আপনার ইতিমধ্যে শর্ত রয়েছে

  2. "যখন" কোনও ভাষায় সর্বাধিক ব্যবহৃত লুপ হয় তবে এটি ইমো হওয়া উচিত নয়। আপনি যদি নিজেকে লেখেন বুল Ok = সত্য; যখন (চেক করুন) something কিছু করুন এবং আশা করছি কোনও সময়ে ঠিকঠাক পরিবর্তন করুন} তারপরে আপনাকে কিছুক্ষণের জন্য দরকার নেই, তবে কিছুক্ষণের জন্য প্রয়োজন কারণ এর অর্থ হ'ল প্রথম পুনরাবৃত্তিটি চালানোর জন্য আপনার যা কিছু দরকার তা আছে।

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


2

আমি কীভাবে পূর্ব / পোস্টের শর্তাদি এবং আক্রমণকারীদের সঠিক লুপটি বিকাশের জন্য ব্যবহার করতে পারি তার আরও বিশদ উদাহরণ দিতে চলেছি। একসাথে যেমন জোর দেওয়া হয় একটি স্পেসিফিকেশন বা চুক্তি বলা হয়।

আমি আপনাকে প্রতি লুপের জন্য এটি করার চেষ্টা করার পরামর্শ দিচ্ছি না। তবে আমি আশা করি যে আপনি চিন্তার প্রক্রিয়া জড়িত তা দেখতে দরকারী হবেন।

এটি করার জন্য, আমি আপনার পদ্ধতিটি মাইক্রোসফ্ট ড্যাফনি নামে একটি সরঞ্জামে অনুবাদ করব , যা এই জাতীয় স্পেসিফিকেশনের যথার্থতা প্রমাণ করার জন্য তৈরি করা হয়েছে। এটি প্রতিটি লুপের সমাপ্তিও পরীক্ষা করে। দয়া করে নোট করুন যে ড্যাফনির কোনও forলুপ নেই তাই তার whileপরিবর্তে আমাকে একটি লুপ ব্যবহার করতে হয়েছিল।

অবশেষে আমি দেখাব যে আপনি কীভাবে আপনার লুপের সামান্য সহজ সংস্করণটি ডিজাইনে এই জাতীয় স্পেসিফিকেশন ব্যবহার করতে পারেন। এই সহজ লুপ সংস্করণটি আসলে লুপের শর্ত j > 0এবং অ্যাসাইনমেন্টটি দেয় না array[j] = value- যেমনটি আপনার প্রাথমিক অন্তর্দৃষ্টি ছিল।

ড্যাফনি আমাদের পক্ষে প্রমাণ করবে যে এই দুটি লুপই সঠিক এবং একই কাজ।

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

প্রথম খণ্ড - পদ্ধতির জন্য একটি স্পেসিফিকেশন রচনা

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

method insert(arr:array<int>, rightIndex:int, value:int) returns (index:int)
  // the method will modify the array
  modifies arr
  // the array will not be null
  requires arr != null
  // the right index is within the bounds of the array
  // but not the last item
  requires 0 <= rightIndex < arr.Length - 1
  // value will be inserted into the array at index
  ensures arr[index] == value 
  // index is within the bounds of the array
  ensures 0 <= index <= rightIndex + 1
  // the array to the left of index is not modified
  ensures arr[..index] == old(arr[..index])
  // the array to the right of index, up to right index is
  // shifted to the right by one place
  ensures arr[index+1..rightIndex+2] == old(arr[index..rightIndex+1])
  // the array to the right of rightIndex+1 is not modified
  ensures arr[rightIndex+2..] == old(arr[rightIndex+2..])

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

পার্ট টু - একটি লুপ আক্রমণকারী নির্ধারণ করা

পদ্ধতির আচরণের জন্য এখন আমাদের একটি স্পেসিফিকেশন রয়েছে, আমাদের লুপ আচরণের একটি স্পেসিফিকেশন যুক্ত করতে হবে যা ড্যাফনিকে বুঝিয়ে দেবে যে লুপটি কার্যকর করে লুপটি শেষ হয়ে যাবে এবং এর ফলস্বরূপ কাঙ্ক্ষিত চূড়ান্ত অবস্থার ফলাফল ঘটবে array

নীচে আপনার মূল লুপটি যুক্ত করা হয়েছে, লুপের আক্রমণকারীদের সাথে ড্যাফনি সিনট্যাক্সে অনুবাদ করা হয়েছে। আমি মানটি সন্নিবেশ করা সূচকটি ফেরাতেও এটি পরিবর্তন করেছি।

{
    // take a copy of the initial array, so we can refer to it later
    // ghost variables do not affect program execution, they are just
    // for specification
    ghost var initialArr := arr[..];


    var j := rightIndex;
    while(j >= 0 && arr[j] > value)
       // the loop always decreases j, so it will terminate
       decreases j
       // j remains within the loop index off-by-one
       invariant -1 <= j < arr.Length
       // the right side of the array is not modified
       invariant arr[rightIndex+2..] == initialArr[rightIndex+2..]
       // the part of the array looked at by the loop so far is
       // shifted by one place to the right
       invariant arr[j+2..rightIndex+2] == initialArr[j+1..rightIndex+1]
       // the part of the array not looked at yet is not modified
       invariant arr[..j+1] == initialArr[..j+1] 
    {
        arr[j + 1] := arr[j];
        j := j-1;
    }   
    arr[j + 1] := value;
    return j+1; // return the position of the insert
}

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

নোট করুন যে ড্যাফনি এখানে নির্ভুলতার একটি প্রমাণ তৈরি করছে। এটি পরীক্ষার মাধ্যমে সম্ভবত প্রাপ্তির চেয়ে নির্ভুলতার আরও শক্তিশালী গ্যারান্টি।

পার্ট থ্রি - একটি সরল লুপ

এখন আমাদের একটি পদ্ধতি স্পেসিফিকেশন রয়েছে যা লুপের আচরণকে ক্যাপচার করে। আমরা এখনও লুপের আচরণ পরিবর্তন করি নি বলে আত্মবিশ্বাস বজায় রেখে আমরা নিরাপদে লুপটির বাস্তবায়নটি পরিবর্তন করতে পারি।

আমি লুপটি সংশোধন করেছি যাতে এটি লুপের শর্ত এবং আপনার চূড়ান্ত মান সম্পর্কে আপনার মূল স্বজ্ঞাতগুলির সাথে মেলে j। আমি যুক্তি দিয়ে বলব যে আপনি নিজের প্রশ্নে বর্ণিত লুপের চেয়ে এই লুপটি সহজ। এটি প্রায়শই jবরং ব্যবহার করতে সক্ষম হয় j+1

  1. জে শুরু করুন rightIndex+1

  2. লুপের শর্তটি এতে পরিবর্তন করুন j > 0 && arr[j-1] > value

  3. অ্যাসাইনমেন্টটি এতে পরিবর্তন করুন arr[j] := value

  4. ভিক্ষার চেয়ে লুপের শেষে লুপের কাউন্টারটি হ্রাস করুন

কোডটি এখানে। নোট করুন যে লুপ আক্রমণকারীরা এখন আরও কিছুটা সহজ লিখেছেন:

method insert2(arr:array<int>, rightIndex:int, value:int) returns (index:int)
  modifies arr
  requires arr != null
  requires 0 <= rightIndex < arr.Length - 1
  ensures 0 <= index <= rightIndex + 1
  ensures arr[..index] == old(arr[..index])
  ensures arr[index] == value 
  ensures arr[index+1..rightIndex+2] == old(arr[index..rightIndex+1])
  ensures arr[rightIndex+2..] == old(arr[rightIndex+2..])
{
    ghost var initialArr := arr[..];
    var j := rightIndex+1;
    while(j > 0 && arr[j-1] > value)
       decreases j
       invariant 0 <= j <= arr.Length
       invariant arr[rightIndex+2..] == initialArr[rightIndex+2..]
       invariant arr[j+1..rightIndex+2] == initialArr[j..rightIndex+1]
       invariant arr[..j] == initialArr[..j] 
    {
        j := j-1;
        arr[j + 1] := arr[j];
    }   
    arr[j] := value;
    return j;
}

পার্ট ফোর - পিছনের লুপিং সম্পর্কে পরামর্শ

বেশ কয়েক বছর ধরে অনেকগুলি লুপ লিখেছেন এবং প্রমাণ করার পরে, পিছনের দিকে লুপিং সম্পর্কে আমার নীচের সাধারণ পরামর্শ রয়েছে।

হ্রাসটি শেষের পরিবর্তে লুপের শুরুতে সঞ্চালিত হলে পশ্চাৎ (হ্রাস) লুপটি সম্পর্কে চিন্তা করা এবং লিখতে প্রায় সর্বদা সহজ।

দুর্ভাগ্যক্রমে forঅনেক ভাষায় লুপ নির্মাণ এটিকে কঠিন করে তোলে।

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

পঞ্চম ভাগ - বোনাস

কেবলমাত্র সম্পূর্ণতার জন্য, আপনি যদি কোডটি rightIndex+1না দিয়ে পদ্ধতিতে পাস করেন তবে আপনার কোডটি এখানে পাবেন rightIndex। এই পরিবর্তনগুলি সমস্ত +2অফসেটগুলি সরিয়ে দেয় যা অন্যথায় লুপটির সঠিকতা সম্পর্কে চিন্তা করতে হবে।

method insert3(arr:array<int>, rightIndex:int, value:int) returns (index:int)
  modifies arr
  requires arr != null
  requires 1 <= rightIndex < arr.Length 
  ensures 0 <= index <= rightIndex
  ensures arr[..index] == old(arr[..index])
  ensures arr[index] == value 
  ensures arr[index+1..rightIndex+1] == old(arr[index..rightIndex])
  ensures arr[rightIndex+1..] == old(arr[rightIndex+1..])
{
    ghost var initialArr := arr[..];
    var j := rightIndex;
    while(j > 0 && arr[j-1] > value)
       decreases j
       invariant 0 <= j <= arr.Length
       invariant arr[rightIndex+1..] == initialArr[rightIndex+1..]
       invariant arr[j+1..rightIndex+1] == initialArr[j..rightIndex]
       invariant arr[..j] == initialArr[..j] 
    {
        j := j-1;
        arr[j + 1] := arr[j];
    }   
    arr[j] := value;
    return j;
}

2
আপনি যদি কম মন্তব্য করেন তবে আপনি যদি প্রশংসা করেন
ফ্লেমিংপেনগেইন

2

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

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

সুতরাং, বিশেষত এই ধরণের জিনিসটির জন্য এটি সঠিক হওয়ার বিষয়টি নিশ্চিত করার উপায় হ'ল সীমানা শর্তগুলি । জিনিসগুলি যেখানে পরিবর্তন হয় তার কয়েকটি প্রান্তে আপনার মাথায় কোডটি সন্ধান করুন। যদি হয় index == array-max, কি হয়? কি হবে max-1? কোডটি যদি কোনও ভুল ঘুরিয়ে দেয় তবে তা এই সীমানাগুলির একটিতে হবে। কিছু লুপগুলি প্রথম বা শেষ উপাদানটি নিয়ে পাশাপাশি লুপিংটি নির্মাণের জন্য সীমানাগুলি সঠিকভাবে পাওয়ার বিষয়ে চিন্তা করতে হবে; যেমন আপনি যদি উল্লেখ করেন a[I]এবং সর্বনিম্ন মান a[I-1]হয় তখন কী ঘটে I?

এছাড়াও, সেই ক্ষেত্রে দেখুন যেখানে (সঠিক) পুনরাবৃত্তির সংখ্যা চূড়ান্ত: যদি সীমাটি পূরণ হয় এবং আপনার 0 টি পুনরাবৃত্তি থাকে, তবে এটি কি কোনও বিশেষ কেস ছাড়াই কাজ করবে? এবং মাত্র 1 পুনরাবৃত্তির বিষয়ে কী, যেখানে সর্বনিম্ন সীমাটি একই সময়ে সর্বোচ্চ সীমাবদ্ধ?

প্রান্তের কেসগুলি (প্রতিটি প্রান্তের উভয় পক্ষের) পরীক্ষা করা হল লুপটি লেখার সময় আপনার কী করা উচিত এবং কোড পর্যালোচনায় আপনার কী করা উচিত।


1

আমি ইতিমধ্যে উল্লিখিত বিষয়গুলি পরিষ্কার করার চেষ্টা করব।

এই জাতীয় ভুল এড়াতে কী কী সরঞ্জাম / মানসিক মডেল?

সরঞ্জামসমূহ

আমার জন্য, আরও ভাল forএবং whileলুপগুলি লেখার বৃহত্তম সরঞ্জাম হ'ল কোনও লেখা forবা whileলুপ মোটেও নয়।

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

আমার বর্তমানে বিশেষ সুবিধাপ্রাপ্ত ভাষা, রুবি, ক্রিয়ামূলক পদ্ধতির (চালু গ্রহণ করেছে .each, .mapইত্যাদি) পুরো সামনের। এটি খুব শক্তিশালী। আমি শুধু কিছু রুবি কোড-বেস আমি কাজ করছি একটি দ্রুত গণনা করেনি: কোডের 10.000 সম্পর্কে লাইনে, সেখানে শূন্য forএবং প্রায় 5 while

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

মানসিক আদর্শ

মনে রাখবেন যে whileআপনি পেতে পারেন তারতমতম বিমূর্ততা, মাত্র এক ধাপ উপরে goto। আমার মতে, forএটি আরও ভাল পরিবর্তে আরও খারাপ করে তোলে যেহেতু এটি লুপের তিনটি অংশকে শক্ত করে একসাথে খণ্ড করে দেয়।

সুতরাং, যদি আমি কোনও বিবর্তনে থাকি যেখানে forএটি ব্যবহৃত হয়, তবে আমি নিশ্চিত তা নিশ্চিত করব যে সমস্ত 3 অংশ মৃত এবং সর্বদা একই। এর অর্থ আমি লিখব

limit = ...;
for (idx = 0; idx < limit; idx++) { 

তবে এর চেয়ে জটিল আর কিছুই নয়। হতে পারে, কখনও কখনও আমার একটি গণনা হবে তবে আমি এটি এড়াতে সর্বাত্মক চেষ্টা করব।

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

বিশেষত যদি শর্তটি জটিল অবস্থায় থাকে তবে আমি একটি "শর্ত-পরিবর্তনশীল" ব্যবহার করব যা স্পষ্ট করা সহজ, এবং শর্তটি whileনিজেই বিবৃতিতে রাখি না :

repeat = true;
while (repeat) {
   repeat = false; 
   ...
   if (complex stuff...) {
      repeat = true;
      ... other complex stuff ...
   }
}

(বা অবশ্যই এর মতো কিছু, অবশ্যই সঠিক পরিমাপে))

এটি আপনাকে একটি খুব সহজ মানসিক মডেল দেয় যা "এই পরিবর্তনশীল 0 থেকে 10 একঘেয়েভাবে চলমান" বা "এই লুপটি চলকটি মিথ্যা / সত্য না হওয়া পর্যন্ত চালিত হয়"। বেশিরভাগ মস্তিষ্কের বিমূর্ততার মাত্রাটি ঠিকঠাকভাবে পরিচালনা করতে সক্ষম বলে মনে হয়।

আশা করি এইটি কাজ করবে.


1

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

সাধারণভাবে, মনে রাখবেন যে একটি ফর্ম-লুপটি কেবল সিনট্যাকটিক চিনি যা কিছুক্ষণ লুপের চারদিকে নির্মিত হয়:

// pseudo-code!
for (init; cond; step) { body; }

সমান:

// pseudo-code!
init;
while (cond) {
  body;
  step;
}

(সম্ভবত লুপের স্থানীয় পদক্ষেপে ভেরিয়েবলগুলি ঘোষণার জন্য স্কোপের অতিরিক্ত স্তর সহ)।

এটি বিভিন্ন ধরণের লুপগুলির জন্য সূক্ষ্ম, তবে আপনি যখন পিছনের দিকে হাঁটছেন তখন ধাপটি শেষ অবধি আসা অবাস্তব। যখন পিছন কাজ আমি খুঁজে বেশি সহজ মান লুপ সূচক শুরু করার পর আমি চান এবং সরাতে stepএই মত লুপ শীর্ষে অংশ:

auto i = v.size();  // init
while (i > 0) {  // simpler condition because i is one after
    --i;  // step before the body
    body;  // in body, i means what you'd expect
}

বা, লুপের জন্য হিসাবে:

for (i = v.size(); i > 0; ) {
    --i;  // step
    body;
}

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

for (i = v.size() - 1; i >= 0; --i) {
    body;
}

তবে যদি আপনার সূচী ভেরিয়েবলটি স্বাক্ষরবিহীন প্রকার হয় (তবে এটি সি বা সি ++ তে থাকতে পারে) তবে এটি একটি বিপর্যয়।

এটি মাথায় রেখে, আসুন আপনার সন্নিবেশ ফাংশনটি লিখি।

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

    function insert(array, size, value) {
      var j = size;
    
  2. নতুন মানটি পূর্বের উপাদানটির চেয়ে কম হলেও স্থানান্তরিত রাখুন। অবশ্য, পূর্ববর্তী উপাদান শুধুমাত্র চেক করা যাবে যদি হয় একটি পূর্ববর্তী উপাদান, তাই আমরা প্রথমে চেক করছি যে, আমরা খুব প্রারম্ভে নও আছে:

      while (j != 0 && value < array[j - 1]) {
        --j;  // now j become current
        array[j + 1] = array[j];
      }
    
  3. jআমরা ঠিক যেখানে নতুন মানটি চাই সেখানে এটি চলে যায় ।

      array[j] = value; 
    };
    

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


0

forলুপ আসলে কী করে এবং কীভাবে এটি কাজ করে তার মেকানিক্স সম্পর্কে আপনি কি কেবল বিভ্রান্ত ?

for(initialization; condition; increment*)
{
    body
}
  1. প্রথমত, সূচনাটি কার্যকর করা হয়
  2. তারপরে শর্তটি পরীক্ষা করা হয়
  3. যদি অবস্থাটি সত্য হয়, একবার শরীর চালানো হয়। না হলে 6 #
  4. ইনক্রিমেন্ট কোড কার্যকর করা হয়
  5. যান # 2
  6. লুপের সমাপ্তি

ভিন্ন কোড ব্যবহার করে এই কোডটি পুনরায় লিখতে আপনার পক্ষে কার্যকর হতে পারে। কিছুক্ষণ লুপ ব্যবহার করে এখানে একই রকম:

initialization
while(condition)
{
    body
    increment
}

এখানে আরও কিছু পরামর্শ দেওয়া হল:

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

* মনে রাখবেন যে আমি "ইনক্রিমেন্ট" শব্দটি ব্যবহার করার সময়, এটি কেবলমাত্র কিছু কোড যা শরীরের পরে এবং শর্ত পরীক্ষা করার আগে। এটি হ্রাস বা কিছু হতে পারে না।


1
ডাউনটা কেন?
ব্যবহারকারী 2023861

0

অতিরিক্ত অন্তর্দৃষ্টি চেষ্টা

জন্য অ তুচ্ছ আলগোরিদিম লুপ সঙ্গে, আপনি নিম্নলিখিত পদ্ধতি চেষ্টা করে দেখতে পারেন:

  1. 4 টি পজিশন সহ একটি নির্দিষ্ট অ্যারে তৈরি করুন , এবং সমস্যাটি অনুকরণ করার জন্য কিছু মান রেখে দিন;
  2. প্রদত্ত সমস্যা সমাধানের জন্য আপনার অ্যালগরিদমটি লিখুন , কোনও লুপ ছাড়াই এবং হার্ড-কোডেড ইনডেক্সিং সহ ;
  3. এর পর, হার্ড কোডেড indexings প্রতিস্থাপন কিছু পরিবর্তনশীল সঙ্গে আপনার কোডে iবা j, এবং বৃদ্ধি / প্রয়োজনীয় হিসাবে এই ভেরিয়েবল হ্রাস (কিন্তু এখনও যে কোন লুপ ছাড়া);
  4. আপনার কোডটি পুনরায় লিখুন, এবং প্রাক এবং পোস্টের শর্তগুলি পূরন করে একটি লুপের ভিতরে পুনরাবৃত্তিক ব্লকগুলি রাখুন ;
  5. [ ঐচ্ছিক ] আপনার লুপ পুনর্লিখন (/ জন্য যখন না / সময়) ফর্ম যদি আপনি চান করা;
  6. সবচেয়ে গুরুত্বপূর্ণ হ'ল আপনার অ্যালগরিদমটি সঠিকভাবে লেখা; এর পরে, আপনি প্রয়োজনবোধে আপনার কোড / লুপগুলি রিফ্যাক্টর এবং অপ্টিমাইজ করেন (তবে এটি কোডটি পাঠকের পক্ষে আর অপ্রয়োজনীয় হতে পারে)

তোমার সমস্যা

//TODO: Insert the given value in proper position in the sorted subarray
function insert(array, rightIndex, value) { ... };

লুপের বডিটি ম্যানুয়ালি একাধিকবার লিখুন

আসুন 4 পজিশন সহ একটি স্থির অ্যারে ব্যবহার করুন এবং লুপগুলি ছাড়াই ম্যানুয়ালি অ্যালগরিদম লেখার চেষ্টা করুন:

           //0 1 2 3
var array = [2,5,9,1]; //array sorted from index 0 to 2
var leftIndex = 0;
var rightIndex = 2;
var value = array[3]; //placing the last value within the array in the proper position

//starting here as 2 == rightIndex

if (array[2] > value) {
    array[3] = array[2];
} else {
    array[3] = value;
    return; //found proper position, no need to proceed;
}

if (array[1] > value) {
    array[2] = array[1];
} else {
    array[2] = value;
    return; //found proper position, no need to proceed;
}

if (array[0] > value) {
    array[1] = array[0];
} else {
    array[1] = value;
    return; //found proper position, no need to proceed;
}

array[0] = value; //achieved beginning of the array

//stopping here because there 0 == leftIndex

পুনরায় লিখুন, হার্ড কোডিং মানগুলি সরান

//consider going from 2 to 0, going from "rightIndex" to "leftIndex"

var i = rightIndex //starting here as 2 == rightIndex

if (array[i] > value) {
    array[i+1] = array[i];
} else {
    array[i+1] = value;
    return; //found proper position, no need to proceed;
}

i--;
if (i < leftIndex) {
    array[i+1] = value; //achieved beginning of the array
    return;
}

if (array[i] > value) {
    array[i+1] = array[i];
} else {
    array[i+1] = value;
    return; //found proper position, no need to proceed;
}

i--;
if (i < leftIndex) {
    array[i+1] = value; //achieved beginning of the array
    return;
}

if (array[i] > value) {
    array[i+1] = array[i];
} else {
    array[i+1] = value;
    return; //found proper position, no need to proceed;
}

i--;
if (i < leftIndex) {
    array[i+1] = value; //achieved beginning of the array
    return;
}

//stopping here because there 0 == leftIndex

একটি লুপ অনুবাদ করুন

সাথে while:

var i = rightIndex; //starting in rightIndex

while (true) {
    if (array[i] > value) { //refactor: this can go in the while clause
        array[i+1] = array[i];
    } else {
        array[i+1] = value;
        break; //found proper position, no need to proceed;
    }

    i--;
    if (i < leftIndex) { //refactor: this can go (inverted) in the while clause
        array[i+1] = value; //achieved beginning of the array
        break;
    }
}

রিফেক্টর / পুনর্লিখন / লুপটি যেভাবে আপনি চান:

সাথে while:

var i = rightIndex; //starting in rightIndex

while ((array[i] > value) && (i >= leftIndex)) {
    array[i+1] = array[i];
    i--;
}

array[i+1] = value; //found proper position, or achieved beginning of the array

সাথে for:

for (var i = rightIndex; (array[i] > value) && (i >= leftIndex); i--) {
    array[i+1] = array[i];
}

array[i+1] = value; //found proper position, or achieved beginning of the array

পিএস: কোড ধরে নেয় ইনপুটটি বৈধ, এবং সেই অ্যারেতে পুনরাবৃত্তি থাকবে না;


-1

এ কারণেই আমি যখনই সম্ভব সম্ভব, আরও বিমূর্ত ক্রিয়াকলাপের পক্ষে, কাঁচা সূচকগুলিতে চালিত লুপগুলি এড়াতে চাই।

এই ক্ষেত্রে, আমি এর মতো কিছু করব (সিউডো কোডে):

array = array[:(rightIndex - 1)] + value + array[rightIndex:]

-3

আপনার উদাহরণে লুপটির বডিটি বেশ স্পষ্ট। এবং এটি একেবারে সুস্পষ্ট যে কিছু উপাদান একেবারে শেষের দিকে পরিবর্তন করতে হবে। সুতরাং আপনি কোডটি লিখুন, তবে লুপটি শুরু না করে, শেষের শর্ত এবং চূড়ান্ত কার্যনির্বাহী।

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


1
আপনি দয়া করে কিছু উদাহরণ স্থাপন করতে পারেন?
কোডয়োগি

ওপির একটি উদাহরণ ছিল।
gnasher729

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