অ্যারে সূচকগুলির পরিবর্তে পুনরাবৃত্তি কেন ব্যবহার করবেন?


239

নিম্নলিখিত দুটি লাইন কোড নিন:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

এবং এই:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

আমাকে বলা হয়েছে যে দ্বিতীয় উপায়ে পছন্দ হয়। ঠিক এটাই কেন?


72
দ্বিতীয় উপায়টি পছন্দ করা হয় আপনি এতে পরিবর্তন some_iterator++করুন ++some_iterator। পোস্ট-ইনক্রিমেন্ট একটি অপ্রয়োজনীয় অস্থায়ী পুনরুক্তি তৈরি করে।
জেসন

6
end()আপনার ঘোষণার ধারাটিও আনা উচিত ।
অরবিটে হালকা ঘোড়দৌড়

5
@ তোমালাক: অযোগ্যের সাথে সি ++ বাস্তবায়ন ব্যবহার করা যে কারও vector::endকাছে সম্ভবত লুপ থেকে উত্তোলন করা হয়েছে কিনা তা নিয়ে চিন্তার আরও খারাপ সমস্যা রয়েছে। ব্যক্তিগতভাবে আমি স্পষ্টতা পছন্দ করি - এটি যদি findসমাপ্তির শর্তে কল হত তবে আমি চিন্তিত ছিলাম।
স্টিভ জেসপ

13
@ তোমালাক: এই কোডটি ম্লান নয় (ভাল, পোস্ট-ইনক্রিমেন্ট সম্ভবত)) এটি সংক্ষিপ্ত এবং স্পষ্ট, যতদূর সি ++ পুনরাবৃত্তি সংক্ষিপ্ততার অনুমতি দেয়। আরও ভেরিয়েবল যুক্ত করা অকাল অপটিমাইজেশনের জন্য জ্ঞানীয় প্রচেষ্টা যোগ করে। এটাই opালু।
স্টিভ জেসপ

7
@ তোমালাক: যদি এটি কোনও বাধা না হয় তবে এটি অকাল। তোমার দ্বিতীয় বিন্দু, আমার কিম্ভুতকিমাকার মনে হয় যেহেতু সঠিক তুলনা মধ্যে নেই it != vec.end()এবং it != end, এটা মাঝে (vector<T>::iterator it = vec.begin(); it != vec.end(); ++it)এবং (vector<T>::iterator it = vec.begin(), end = vec.end(); it != end; ++it)। চরিত্রগুলি গণনা করার দরকার নেই। যে কোনও উপায়ে একে অপরের চেয়ে বেশি পছন্দ করুন, তবে আপনার পছন্দের সাথে অন্য ব্যক্তির মতবিরোধ "slালু" নয়, এটি কম ভেরিয়েবল সহ সরল কোডের পক্ষে পছন্দ এবং এটি পড়ার সময় চিন্তা করা কম।
স্টিভ জেসপ

উত্তর:


210

Vector.size () একটি দ্রুত অপারেশন হলেই প্রথম ফর্মটি কার্যকর। এটি ভেক্টরগুলির ক্ষেত্রে সত্য, তবে তালিকার জন্য নয় example এছাড়াও, আপনি লুপটির দেহের মধ্যে কী করার পরিকল্পনা করছেন? যদি আপনি উপাদানগুলি অ্যাক্সেস করার পরিকল্পনা করে থাকেন

T elem = some_vector[i];

তারপরে আপনি ধারনাটি operator[](std::size_t)সংজ্ঞায়িত করেছেন যে এটি তৈরি করছেন । আবার, এটি ভেক্টরের পক্ষে সত্য তবে অন্যান্য ধারকগুলির পক্ষে নয়।

পুনরাবৃত্তকারীদের ব্যবহার আপনাকে ধারক স্বাধীনতার কাছাকাছি নিয়ে আসে । আপনি এলোমেলোভাবে অ্যাক্সেস ক্ষমতা বা দ্রুত size()অপারেশন সম্পর্কে অনুমান করছেন না , কেবলমাত্র ধারকটির পুনরাবৃত্তি ক্ষমতা রয়েছে।

আপনি স্ট্যান্ডার্ড অ্যালগরিদম ব্যবহার করে আপনার কোডটি আরও বাড়িয়ে তুলতে পারেন। এটা কি আপনি অর্জন করার চেষ্টা করছেন তার উপর ভিত্তি করে, আপনি ব্যবহার ঈষত পরিবর্তন std::for_each(), std::transform()ইত্যাদি। সুস্পষ্ট লুপের চেয়ে মানক অ্যালগরিদম ব্যবহার করে আপনি চক্রটি পুনরায় উদ্ভাবন করা এড়িয়ে চলেছেন। আপনার কোডটি আরও কার্যকর হতে পারে (সঠিক আলগোরিদম বেছে নেওয়া হলে) সঠিক এবং পুনরায় ব্যবহারযোগ্য।


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

4
এটি আমাকে বিভ্রান্ত করে: "এটি ভেক্টরদের ক্ষেত্রে সত্য, তবে উদাহরণগুলির জন্য নয়" " কেন? মস্তিষ্ক সহ যে কেউ size_tসদস্যকে পরিবর্তনশীল রাখে size()
GManNGG

19
@ জিএমান - প্রায় সব বাস্তবায়নে আকার () ভেক্টরদের জন্য তালিকার জন্য তত দ্রুত। মানকটির পরবর্তী সংস্করণটির এটি সত্য হওয়া দরকার। আসল সমস্যাটি হ'ল অবস্থান অনুসারে পিছিয়ে পড়া own
ড্যানিয়েল আরউইকার

8
@ জিএমান: তালিকার আকার সংরক্ষণ করতে ও (1) এর পরিবর্তে তালিকাটি স্লাইসিং এবং স্প্লিকিংয়ের জন্য ও (এন) হওয়া প্রয়োজন।

5
সি ++ 0 এক্স-তে, size()সদস্য ক্রিয়াকলাপটি সমর্থন করে এমন সমস্ত ধারকগুলির জন্য স্থায়ী সময় জটিলতা থাকা দরকার যার মধ্যে রয়েছে std::list
জেমস ম্যাকনেলিস

54

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


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

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

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


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

5
@ অ্যাবারগ্লাস তারা মোটেও ভাঙেনি, আপনি কেবল তাদের অভ্যস্ত নন, এ কারণেই আপনার যখন আপনার দরকার নেই তখনও আমি সেগুলি ব্যবহার করার পক্ষে পরামর্শ দিই! অর্ধ-খোলা ব্যাপ্তিগুলি একটি সাধারণ ধারণা এবং প্রেরণেলগুলি যা কখনও সরাসরি অ্যাক্সেস করা হয় না তা প্রোগ্রামিংয়ের মতোই পুরানো।
মার্ক রান্সম

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

53

কারণ আপনি আপনার কোডটি কিছু_ভেক্টর তালিকার নির্দিষ্ট প্রয়োগের সাথে বেঁধে দিচ্ছেন না। আপনি যদি অ্যারে সূচকগুলি ব্যবহার করেন তবে এটি অ্যারের কিছু ফর্ম হতে হবে; যদি আপনি পুনরাবৃত্তি ব্যবহার করেন আপনি যে কোনও তালিকা প্রয়োগের ক্ষেত্রে সেই কোডটি ব্যবহার করতে পারেন।


23
স্ট্যান্ড :: তালিকা ইন্টারফেস ইন্টেনটালি অপারেটর [] (আকার_ টি এন) সরবরাহ করে না কারণ এটি ও (এন) হবে।
MSalters

33

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

সুতরাং এটি দুটি জিনিস সরবরাহ করে:

  • ব্যবহারের বিমূর্ততা: আপনি কেবল কয়েকটি উপাদানকে পুনরাবৃত্তি করতে চান, কীভাবে এটি করবেন সে সম্পর্কে আপনার যত্ন নেই
  • কর্মক্ষমতা

1
"এটি বর্তমান নোডের দিকে একটি পয়েন্টার বজায় রাখবে এবং এটিকে [দক্ষতা সম্পর্কে ভাল জিনিস] অগ্রসর করবে" - হ্যাঁ, পুনরাবৃত্তির ধারণাটি বুঝতে লোকেরা কেন সমস্যা হয় তা আমি পাই না। তারা ধারণাগুলি কেবল পয়েন্টার একটি সুপারস্টার। আপনি যখন কেবলমাত্র কোনও পয়েন্টারকে এটি ক্যাশে করতে পারেন তখন কেন কিছু উপাদানগুলির অফসেট বারবার গণনা করবেন? ভাল, এটিই পুনরাবৃত্তিকারীরাও করেন।
আন্ডারস্কোর_

27

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

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

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

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


23

আপনি যদি পুনরুক্তি করার সময় ভেক্টরের আইটেমগুলি যোগ / সরিয়ে ফেলতে চলেছেন তবে আপনি একটি পুনরায় ব্যবহার করতে চাইবেন might

some_iterator = some_vector.begin(); 
while (some_iterator != some_vector.end())
{
    if (/* some condition */)
    {
        some_iterator = some_vector.erase(some_iterator);
        // some_iterator now positioned at the element after the deleted element
    }
    else
    {
        if (/* some other condition */)
        {
            some_iterator = some_vector.insert(some_iterator, some_new_value);
            // some_iterator now positioned at new element
        }
        ++some_iterator;
    }
}

আপনি যদি সূচকগুলি ব্যবহার করে থাকেন তবে সন্নিবেশ এবং মুছে ফেলার জন্য আপনাকে অ্যারেতে / ডাউন আইটেমগুলি বদল করতে হবে।


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

একটি উপাদানের std::listতুলনায় সমস্ত উপাদানগুলির সাথে আইট্রেট করা বেশ ব্যয়বহুল std::vector, যদিও আপনি যদি এ এর ​​পরিবর্তে লিঙ্কযুক্ত তালিকা ব্যবহারের পরামর্শ দিচ্ছেন std::vector। পৃষ্ঠা 43 দেখুন: ecn.channel9.msdn.com/events/GoingNative12/GN12Cpp11Style.pdf আমার অভিজ্ঞতা অনুসারে, আমি এগুলির সবstd::vector চেয়ে std::listসন্ধান করছি এবং স্বেচ্ছাসেবক অবস্থানগুলিতে উপাদানগুলি সরিয়ে নিচ্ছি এমনকি তার চেয়ে দ্রুততর আমি খুঁজে পেয়েছি ।
ডেভিড স্টোন

সূচকগুলি স্থিতিশীল, তাই সন্নিবেশ এবং মুছে ফেলার জন্য অতিরিক্ত শফলিংয়ের কী প্রয়োজন তা আমি দেখতে পাই না।
মুসিফিল

... এবং একটি লিঙ্কযুক্ত তালিকার সাথে - যা এখানে ব্যবহার করা উচিত - আপনার লুপ বিবৃতিটি হবে for (node = list->head; node != NULL; node = node->next)আপনার কোডের প্রথম দুটি লাইন একসাথে রাখার চেয়ে ছোট (ঘোষণাপত্র এবং লুপ হেড)) সুতরাং আমি আবার বলছি - পুনরাবৃত্তকারীগুলি ব্যবহার করা এবং সেগুলি ব্যবহার না করার মধ্যে সংক্ষিপ্ততার মধ্যে খুব বেশি মৌলিক পার্থক্য নেই - আপনি এখনও একটি forবিবৃতিটির তিনটি অংশ সন্তুষ্ট করেছেন, এমনকি যদি আপনি ব্যবহার করেন while: ঘোষণা করুন, পুনরাবৃত্তি করুন, সমাপ্তি চেক করুন।
ইঞ্জিনিয়ার

16

উদ্বেগ বিচ্ছেদ

লুপটির 'কোর' উদ্বেগ থেকে পুনরাবৃত্তি কোডটি পৃথক করে দেওয়া খুব সুন্দর। এটি প্রায় একটি ডিজাইনের সিদ্ধান্ত।

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

এছাড়াও, std::for_eachউপায় হিসাবে, আপনি সংগ্রহটির অভ্যন্তরগুলি সম্পর্কে কিছু জিজ্ঞাসা করার পরিবর্তে কী করতে হবে তা বলুন

0x স্ট্যান্ডার্ডটি ক্লোজারগুলি প্রবর্তন করতে চলেছে, যা এই পদ্ধতির ব্যবহারকে আরও সহজ করে তুলবে - উদাহরণস্বরূপ রুবির অভিব্যক্তিপূর্ণ শক্তিটি দেখুন [1..6].each { |i| print i; }...

কর্মক্ষমতা

তবে সম্ভবত অনেক তদারকির বিষয়টি হ'ল, for_eachপদ্ধতির সাহায্যে পুনরাবৃত্তিকে সমান্তরাল করার সুযোগ পাওয়া যায় - ইন্টেল থ্রেডিং ব্লকগুলি সিস্টেমে প্রসেসরের সংখ্যার উপর দিয়ে কোড ব্লক বিতরণ করতে পারে!

দ্রষ্টব্য: algorithmsগ্রন্থাগারটি আবিষ্কার করার পরে এবং বিশেষত foreach, আমি হাস্যকরভাবে ছোট 'হেল্পার' অপারেটর স্ট্রাক্ট লিখে দু'তিন মাস পেরিয়েছি যা আপনার সহকর্মী বিকাশকারীদের পাগল করে তুলবে। এই সময়ের পরে, আমি আবার ব্যবহারিক পদ্ধতির দিকে ফিরে গিয়েছিলাম - ছোট লুপ মৃতদেহগুলি আর প্রাপ্য নয় foreach:)

পুনরাবৃত্তকারীদের অবশ্যই পড়ার রেফারেন্স হ'ল "বর্ধিত এসটিএল" বইটি ।

ইএফএটারের প্যাটার্নের শেষে জিওএফের একটি ছোট্ট ছোট্ট অনুচ্ছেদ রয়েছে, যা এই ব্র্যান্ডটির পুনরাবৃত্তির বিষয়ে কথা বলে; একে 'অভ্যন্তরীণ পুনরুক্তি' বলা হয়। এখানেও একবার দেখুন ।


15

কারণ এটি বেশি বস্তু-কেন্দ্রিক। যদি আপনি কোনও সূচক দিয়ে পুনরাবৃত্তি করেন তবে আপনি ধরে নিচ্ছেন:

ক) objects বস্তুগুলিকে অর্ডার করা হয়েছে
খ) যে objects বস্তুগুলি একটি সূচক দ্বারা প্রাপ্ত করা যেতে পারে
গ) যে সূচক বৃদ্ধি প্রতিটি আইটেমকে আঘাত করবে
d) যে সূচকটি শূন্য থেকে শুরু হয়

একটি পুনরুক্তিকারী সহ, আপনি অন্তর্নিহিত বাস্তবায়ন কী তা না জেনে "আমাকে সবকিছু দিন যাতে আমি এটি দিয়ে কাজ করতে পারি" বলছেন। (জাভাতে, এমন সংগ্রহ রয়েছে যা সূচকের মাধ্যমে অ্যাক্সেস করা যায় না)

এছাড়াও, একটি পুনরুক্তি দিয়ে অ্যারের সীমা ছাড়িয়ে যাওয়ার বিষয়ে চিন্তা করার দরকার নেই।


2
আমি মনে করি না "অবজেক্ট অরিয়েন্টেড" সঠিক শব্দ। আইট্রেটাররা ডিজাইনে "অবজেক্ট ওরিয়েন্টেড" নয়। তারা অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ের চেয়ে ফাংশনাল প্রোগ্রামিংকে বেশি প্রচার করে কারণ তারা ক্লাস থেকে অ্যালগোরিদমকে আলাদা করতে উত্সাহ দেয়।
উইলহেমটেল

এছাড়াও, পুনরাবৃত্তিকারীরা সীমা ছাড়িয়ে যাওয়া এড়াতে সহায়তা করে না। স্ট্যান্ডার্ড অ্যালগরিদমগুলি করেন, তবে একা পুনরাবৃত্তি করেন না।
উইলহেমটেল

যথেষ্ট পরিমাণে উইলহেলমটেল, আমি জাভা কেন্দ্রিক দৃষ্টিভঙ্গি থেকে স্পষ্টতই এটি সম্পর্কে ভাবছি।
ছদ্মবেশী

1
এবং আমি মনে করি যে এটি ওওর প্রচার করে, কারণ এটি সংগ্রহটি কার্যকর করা থেকে সংগ্রহগুলি কার্যকর করে। অবজেক্টের সংকলন অগত্যা তাদের সাথে কাজ করতে কী অ্যালগরিদমগুলি ব্যবহার করা উচিত তা জানা উচিত নয়।
ছদ্মবেশী

আসলে সেখানে এসটিএল এর সংস্করণ রয়েছে যা পুনরাবৃত্তিকারীদের পরীক্ষা করেছে, এর অর্থ এটি যখন আপনি পুনরুক্তিকারীর সাথে কিছু করার চেষ্টা করবেন তখন এটি কিছু প্রকারের বাইরে ব্যতিক্রম ছুঁড়ে ফেলবে।
দাইমিন

15

পুনরাবৃত্তকারীদের সম্পর্কে আর একটি সুন্দর বিষয় হ'ল তারা আপনাকে আপনার কনস্ট্যান্ট-পছন্দটি (এবং প্রয়োগ করার) আরও ভাল অনুমতি দেয়। এই উদাহরণটি নিশ্চিত করে যে আপনি আপনার লুপের মাঝে ভেক্টরটি পরিবর্তন করবেন না:


for(std::vector<Foo>::const_iterator pos=foos.begin(); pos != foos.end(); ++pos)
{
    // Foo & foo = *pos; // this won't compile
    const Foo & foo = *pos; // this will compile
}

এটি যুক্তিসঙ্গত দেখাচ্ছে, তবে আমি এখনও সন্দেহ করি যে যদি এটি হওয়ার কারণ হয় const_iterator। যদি আমি লুপটিতে ভেক্টরটি পরিবর্তন করি তবে আমি এটি একটি কারণ হিসাবে করি এবং 99.9% সময়ের জন্য যে পরিবর্তন করা কোনও দুর্ঘটনা নয়, এবং বাকী সময়ের জন্য এটি লেখক কোডে কোনও ধরণের বাগের মতো কেবল একটি বাগ is ঠিক করা প্রয়োজন। কারণ জাভা এবং অন্যান্য অনেক ভাষায়, কোনও বিন্দু বস্তু নেই, তবে those ভাষাগুলির ব্যবহারকারীদের কোনও ক্ষেত্রেই সেই ভাষাগুলিতে কোনও সমর্থন বাধা নেই with
neevek

2
@ নতুনকে যদি তা হওয়ার কারণ না হয় const_iteratorতবে পৃথিবীতে এর কারণ কী হতে পারে?
আন্ডারস্কোর_১১

@ আসর_আর, আমিও ভাবছি। আমি এ বিষয়ে বিশেষজ্ঞ নই, উত্তরটি আমার কাছে উপলব্ধিযোগ্য নয়।
neevek

15

অন্যান্য দুর্দান্ত উত্তরগুলি বাদ দিয়ে ... intআপনার ভেক্টরের পক্ষে যথেষ্ট বড় নাও হতে পারে। পরিবর্তে, আপনি যদি সূচক ব্যবহার করতে চান তবে আপনার ধারকটির জন্য এটি size_typeব্যবহার করুন:

for (std::vector<Foo>::size_type i = 0; i < myvector.size(); ++i)
{
    Foo& this_foo = myvector[i];
    // Do stuff with this_foo
}

1
@ প্যাট নটজ, এটি একটি খুব ভাল বিষয়। এক্সটি 64৪-এ একটি এসটিএল-ভিত্তিক উইন্ডোজ অ্যাপ্লিকেশনটি পোর্ট করার সময়, আমাকে সম্ভবত কোনও কাটা কাটা আকারের আকার_t বরাদ্দ করার বিষয়ে শত শত সতর্কতা সহ্য করতে হয়েছিল।
bk1e

1
আকারের আকারগুলি স্বাক্ষরিত এবং INT স্বাক্ষরিত হয়েছে তা উল্লেখ করার প্রয়োজন নেই, সুতরাং আপনার সাথে তুলনা int iকরার জন্য অ-স্বজ্ঞাত, বাগ-লুকানো রূপান্তরগুলি চলছে myvector.size()
অ্যাড্রিয়ান ম্যাকার্থি

12

আমি সম্ভবত আপনি কল করতে পারেন নির্দেশ করা উচিত

std::for_each(some_vector.begin(), some_vector.end(), &do_stuff);


7

এসটিএল পুনরাবৃত্তকারীরা বেশিরভাগই সেখানে থাকে যাতে সাজানোর মতো এসটিএল অ্যালগরিদমগুলি ধারক স্বাধীন হতে পারে।

আপনি যদি কেবল কোনও ভেক্টরের সমস্ত এন্ট্রিগুলি লুপ করতে চান তবে কেবল সূচক লুপ স্টাইলটি ব্যবহার করুন।

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

for( size_t i = 0; i < some_vector.size(); ++i )
{
   T& rT = some_vector[i];
   // now do something with rT
}
'

5

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

আমি লুপের অভ্যন্তরে আইটেমটির জন্য একটি রেফারেন্সও দিতে চাই যাতে জায়গাটির চারপাশে প্রচুর স্কোয়ার বন্ধনী না থাকে:

for(size_t i = 0; i < myvector.size(); i++)
{
    MyClass &item = myvector[i];

    // Do stuff to "item".
}

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


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

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

1
এমনকি অগ্রিম প্রয়োজন হয় না ()। পুনরাবৃত্তির সূচক হিসাবে একই + = এবং - = অপারেটর রয়েছে (ভেক্টর এবং ভেক্টর-জাতীয় পাত্রে)।
MSalters

I prefer to use an index myself as I consider it to be more readableশুধুমাত্র কিছু পরিস্থিতিতে; অন্যদের মধ্যে সূচকগুলি খুব অগোছালো হয়ে যায়। and you can do random accessযা মোটেও সূচকগুলির অনন্য বৈশিষ্ট্য নয়: দেখুন en.cppreferences.com/w/cpp/concept/RandomAccessIterator
আন্ডারস্কোর_১১

3

দ্বিতীয় ফর্মটি আপনাকে আরও সঠিকভাবে কী করছে তা উপস্থাপন করে। আপনার উদাহরণস্বরূপ, আপনি i এর মান সম্পর্কে চিন্তা করেন না, সত্যিই - আপনি যা চান তা হ'ল পুনরাবৃত্তির পরবর্তী উপাদান।


3

এই উত্তরটির বিষয়ে আরও কিছুটা শিখার পরে, আমি বুঝতে পারি এটি একটি ওভারসিম্প্লিফিকেশন কিছুটা ছিল। এই লুপের মধ্যে পার্থক্য:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

এবং এই লুপ:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

মোটামুটি ন্যূনতম। প্রকৃতপক্ষে, লুপগুলি এইভাবে করা সিনট্যাক্সটি আমার উপর বাড়ছে বলে মনে হচ্ছে:

while (it != end){
    //do stuff
    ++it;
}

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


সত্যটি হ'ল যদি সমস্ত পুনরাবৃত্তকারী আপনার চূড়ান্ত উদাহরণ হিসাবে ঠিক তেমনই কমপ্যাক্ট হন, ঠিক বাক্সের বাইরে, আমি তাদের সাথে সামান্য সমস্যা করতাম। অবশ্যই, এটি আসলে সমান for (Iter it = {0}; it != end; ++it) {...}- আপনি সবেমাত্র ঘোষণাটি রেখে গেছেন - সুতরাং ব্রিভটি আপনার দ্বিতীয় উদাহরণ থেকে খুব বেশি আলাদা নয়। তবুও, +1।
ইঞ্জিনিয়ার

3

সূচকে অতিরিক্ত mulঅপারেশন প্রয়োজন requires উদাহরণস্বরূপ, vector<int> vসংকলক রূপান্তর v[i]করে &v + sizeof(int) * i


সম্ভবত বেশিরভাগ ক্ষেত্রে পুনরাবৃত্তির তুলনায় উল্লেখযোগ্য অসুবিধা না হলেও সচেতন হওয়া ভাল জিনিস।
নোটার

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

2

পুনরাবৃত্তির সময় আপনাকে প্রক্রিয়া করার জন্য আইটেমের সংখ্যা জানতে হবে না। আপনার কেবল আইটেমটি প্রয়োজন এবং পুনরাবৃত্তিকারীরা খুব ভাল এটি করেন।


2

সূচকগুলির একটি সুবিধা হ'ল যে কোনও সূচকগুলির একটি সুবিধা হ'ল এটি যখন অবৈধ হয়ে উঠবে না আপনি যখন একটি উপযুক্ত পাত্রে যেমন যুক্ত হন std::vector, তাই পুনরাবৃত্তির সময় আপনি ধারকগুলিতে আইটেম যুক্ত করতে পারেন।

এটি পুনরাবৃত্তকারীদের দ্বারাও সম্ভব, তবে আপনাকে অবশ্যই কল করা উচিত reserve(), এবং সেইজন্য আপনি কতগুলি আইটেম যুক্ত করবেন তা জানতে হবে know


1

ইতিমধ্যে বেশ কয়েকটি ভাল পয়েন্ট। আমার কয়েকটি অতিরিক্ত মন্তব্য রয়েছে:

  1. ধরে নেওয়া যাক আমরা সি ++ স্ট্যান্ডার্ড লাইব্রেরি সম্পর্কে কথা বলছি, "ভেক্টর" বলতে একটি এলোমেলো অ্যাক্সেস ধারক বোঝায় যা সি-অ্যারে (এলোমেলো অ্যাক্সেস, কনটিজুওস মেমরি লেআউট ইত্যাদি) এর গ্যারান্টিযুক্ত রয়েছে। আপনি যদি 'কিছু_সামগ্রী' বলে থাকেন তবে উপরের উত্তরগুলির মধ্যে অনেকগুলি আরও সঠিক হত (ধারক স্বাধীনতা ইত্যাদি)।

  2. সংকলক অপ্টিমাইজেশনের উপর যে কোনও নির্ভরতা দূর করতে, আপনি কিছু_vector.size () ইনডেক্সড কোডের লুপ থেকে সরিয়ে নিতে পারেন, যেমন:

    আকার আকার_t numElems = কিছু_vector.size ();
    এর জন্য (আকার_t i = 0; i) 
  3. সর্বদা প্রাক-ইনক্রিমেন্ট পুনরাবৃত্তকারী এবং পোস্ট-ইনক্রিমেন্টগুলি ব্যতিক্রমী ক্ষেত্রে হিসাবে বিবেচনা করে।

(some_iterator = কিছু_vector.begin (); কিছু_আরক্ষক! = কিছু_vector.end (); ++ কিছু_iterator) {// স্টাফ করুন}

সুতরাং ধারনা করা এবং std::vector<>ধারকের মতো সূচকযোগ্য , ধারাবাহিকভাবে ধারকটি পেরিয়ে অন্যের তুলনায় পছন্দ করার কোনও ভাল কারণ নেই। আপনার যদি বার বার পুরানো বা নতুন একাদশী সূচকগুলি উল্লেখ করতে হয় তবে সূচী সংস্করণটি আরও উপযুক্ত version

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


1

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

for(int i=0;i<anims.size();i++)
  for(int j=0;j<bones.size();j++)
  {
     int animIndex = i;
     int boneIndex = j;


     // in relatively short code I use indices i and j
     ... animation_matrices[i][j] ...

     // in long and complicated code I use indices animIndex and boneIndex
     ... animation_matrices[animIndex][boneIndex] ...


  }

এমনকি আমি উদাহরণস্বরূপ কিছু এলোমেলো "anim_matrix"-নামকরণ-পুনরাবৃত্তিকে "অ্যানিমেশন_মেট্রিকস [i]" এর মতো জিনিসগুলি সংক্ষেপে বলতে চাই না, কারণ তাহলে আপনি কোন স্পষ্ট দেখতে পাচ্ছেন না যে অ্যারে থেকে এই মানটি উত্পন্ন হয়েছে।


সূচকগুলি এই অর্থে আরও উন্নত তা আমি দেখতে পাচ্ছি না। : আপনি সহজে iterators ব্যবহার করতে পারে এবং মাত্র তাদের নাম একটি কনভেনশন বাছাই it, jt, ktএমনকি মাত্র ইত্যাদি বা ব্যবহার করা চালিয়ে i, j, k, ইত্যাদি এবং যদি আপনি জানেন যে ঠিক কি কোনো ইটারেটরে প্রতিনিধিত্ব করে, তাহলে আমাকে কিছু মত প্রয়োজন for (auto anim = anims.begin(); ...) for (auto anim_bone = anim->bones.begin(); ...) anim_bone->wobble()আরো বর্ণনামূলক হবে ক্রমাগত সূচক পছন্দ করার চেয়ে animation_matrices[animIndex][boneIndex]
আন্ডারস্কোর_১১

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

হাহাহা, সত্যই, আমি সত্যিই এটি আগে কত পুরানো তাকান না! আমি গতবারের মতো কোনওভাবেই ভেবে দেখিনি তা হ'ল আজকাল আমাদেরও রয়েছে পরিসর-ভিত্তিক forলুপ, যা আরও বেশি সংক্ষিপ্ত করে এটির পুনরুক্ত-ভিত্তিক পদ্ধতিটিকে তৈরি করে।
আন্ডারস্কোর_

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

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


1

যদি আপনার সি ++ 11 বৈশিষ্ট্যে অ্যাক্সেস থাকে তবে আপনি নিজের ভেক্টর (বা অন্য কোনও ধারক) এর উপরে পুনরাবৃত্তি করার জন্য একটি পরিসীমা-ভিত্তিক forলুপটি নীচের হিসাবে ব্যবহার করতে পারেন :

for (auto &item : some_vector)
{
     //do stuff
}

এই লুপটির সুবিধা হ'ল আপনি ভেরিয়েটের উপাদানগুলিকে itemভেরিয়েবলের মাধ্যমে সরাসরি অ্যাক্সেস করতে পারবেন , কোনও সূচককে বিশৃঙ্খলা তৈরি করার ঝুঁকি না চালিয়ে বা কোনও ইেটরেটরকে অবহেলা করার সময় কোনও ভুল না করে। এছাড়াও, স্থানধারক autoআপনাকে ধারক উপাদানগুলির ধরণের পুনরাবৃত্তি করতে বাধা দেয় যা আপনাকে ধারক-স্বাধীন সমাধানের আরও কাছাকাছি নিয়ে আসে।

মন্তব্য:

  • আপনার লুপে যদি উপাদান সূচক প্রয়োজন হয় এবং আপনার ধারকটির operator[]উপস্থিতি রয়েছে (এবং এটি আপনার পক্ষে যথেষ্ট দ্রুত) তবে আপনার প্রথম পথে আরও ভালভাবে যেতে পারেন।
  • forধারকটিতে / থেকে উপাদান যুক্ত / মুছতে একটি পরিসীমা ভিত্তিক লুপ ব্যবহার করা যাবে না। যদি আপনি এটি করতে চান, তবে ব্রায়ান ম্যাথিউসের দেওয়া সমাধানটি আরও ভাল করে আঁকুন।
  • আপনি আপনার কন্টেইনারে উপাদান পরিবর্তন করতে না চান তাহলে, তাহলে আপনি শব্দ ব্যবহার করা উচিত constনিম্নরূপ: for (auto const &item : some_vector) { ... }

0

"সিপিইউকে কী করতে হবে" বলার চেয়েও ভাল (আবশ্যক) "লাইব্রেরিগুলিকে আপনি কী চান" বলছেন "(ক্রিয়ামূলক)।

সুতরাং লুপগুলি ব্যবহারের পরিবর্তে আপনার স্টাইলের উপস্থিত অ্যালগোরিদমগুলি শিখতে হবে।



0

আমি সর্বদা অ্যারে সূচক ব্যবহার করি কারণ আমার অনেক প্রয়োগে "থম্পলনেল চিত্র প্রদর্শন করুন" এর মতো কিছু প্রয়োজন। তাই আমি এরকম কিছু লিখেছি:

some_vector[0].left=0;
some_vector[0].top =0;<br>

for (int i = 1; i < some_vector.size(); i++)
{

    some_vector[i].left = some_vector[i-1].width +  some_vector[i-1].left;
    if(i % 6 ==0)
    {
        some_vector[i].top = some_vector[i].top.height + some_vector[i].top;
        some_vector[i].left = 0;
    }

}

0

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


2
"ভেক্টরগুলির সাথে পুনরাবৃত্তকারী ব্যবহার করা অবিচ্ছিন্ন মেমরি ব্লকগুলিতে অবজেক্টগুলি রাখার খুব উপকার হারাবে যা তাদের অ্যাক্সেসকে সহজ করতে সহায়তা করে।" [তথ্যসূত্র প্রয়োজন]. কেন? আপনি কি মনে করেন যে একটি সংযোজিত পাত্রে কোনও পুনরাবৃত্তির বৃদ্ধি একটি সাধারণ সংযোজন হিসাবে প্রয়োগ করা যায় না?
আন্ডারস্কোর_

0

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

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

তাহলে আপনার প্রয়োজন ফরোয়ার্ড বলছি পাবে থাকে, তাহলে বিকাশকারী সূচিযোগ্য পাত্রে ব্যবহার সীমাবদ্ধ নয় - তারা কোন শ্রেণীর বাস্তবায়নে ব্যবহার করতে পারেন operator++(T&), operator*(T)এবং operator!=(const &T, const &T)

#include <iostream>
template <class InputIterator>
void printAll(InputIterator& begin, InputIterator& end)
{
    for (auto current = begin; current != end; ++current) {
        std::cout << *current << "\n";
    }
}

// elsewhere...

printAll(myVector.begin(), myVector.end());

আপনার অ্যালগরিদম আপনার প্রয়োজনের ক্ষেত্রে কাজ করে - কোনও ভেক্টরের মাধ্যমে পুনরাবৃত্তি করে - তবে এটি আপনি যে অ্যাপ্লিকেশনগুলি প্রত্যাশা করেন না সেগুলির জন্যও এটি কার্যকর হতে পারে:

#include <random>

class RandomIterator
{
private:
    std::mt19937 random;
    std::uint_fast32_t current;
    std::uint_fast32_t floor;
    std::uint_fast32_t ceil;

public:
    RandomIterator(
        std::uint_fast32_t floor = 0,
        std::uint_fast32_t ceil = UINT_FAST32_MAX,
        std::uint_fast32_t seed = std::mt19937::default_seed
    ) :
        floor(floor),
        ceil(ceil)
    {
        random.seed(seed);
        ++(*this);
    }

    RandomIterator& operator++()
    {
        current = floor + (random() % (ceil - floor));
    }

    std::uint_fast32_t operator*() const
    {
        return current;
    }

    bool operator!=(const RandomIterator &that) const
    {
        return current != that.current;
    }
};

int main()
{
    // roll a 1d6 until we get a 6 and print the results
    RandomIterator firstRandom(1, 7, std::random_device()());
    RandomIterator secondRandom(6, 7);
    printAll(firstRandom, secondRandom);

    return 0;
}

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

ইট্রেটাররাও নিজেকে সাজসজ্জাতে ndণ দেয় । লোকেরা পুনরুক্তি লিখতে পারে যা তাদের নির্মাত্রে একটি পুনরুক্তি করে এবং এর কার্যকারিতা প্রসারিত করে:

template<class InputIterator, typename T>
class FilterIterator
{
private:
    InputIterator internalIterator;

public:
    FilterIterator(const InputIterator &iterator):
        internalIterator(iterator)
    {
    }

    virtual bool condition(T) = 0;

    FilterIterator<InputIterator, T>& operator++()
    {
        do {
            ++(internalIterator);
        } while (!condition(*internalIterator));

        return *this;
    }

    T operator*()
    {
        // Needed for the first result
        if (!condition(*internalIterator))
            ++(*this);
        return *internalIterator;
    }

    virtual bool operator!=(const FilterIterator& that) const
    {
        return internalIterator != that.internalIterator;
    }
};

template <class InputIterator>
class EvenIterator : public FilterIterator<InputIterator, std::uint_fast32_t>
{
public:
    EvenIterator(const InputIterator &internalIterator) :
        FilterIterator<InputIterator, std::uint_fast32_t>(internalIterator)
    {
    }

    bool condition(std::uint_fast32_t n)
    {
        return !(n % 2);
    }
};


int main()
{
    // Rolls a d20 until a 20 is rolled and discards odd rolls
    EvenIterator<RandomIterator> firstRandom(RandomIterator(1, 21, std::random_device()()));
    EvenIterator<RandomIterator> secondRandom(RandomIterator(20, 21));
    printAll(firstRandom, secondRandom);

    return 0;
}

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

সি ++ টেম্পলেটগুলির শক্তির অংশ হ'ল আপনার পুনরাবৃত্ত ইন্টারফেস, যখন নির্দিষ্ট-দৈর্ঘ্যের সি অ্যারেগুলির পছন্দগুলি প্রয়োগ করা হয়, সহজ এবং দক্ষ পয়েন্টার গাণিতিকের সিদ্ধান্ত হয় , এটি সত্যিকারের শূন্য-ব্যতিক্রমী বিমূর্ততা তৈরি করে।

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