কেন `std :: স্ট্রিং :: অনুসন্ধান () ures ব্যর্থতায় শেষ পুনরাবৃত্তিকে ফেরত দেয় না?


29

আমি std::string::findস্ট্যান্ডার্ড সি ++ ধারকগুলির সাথে বেমানান থাকার আচরণটি খুঁজে পাই ।

যেমন

std::map<int, int> myMap = {{1, 2}};
auto it = myMap.find(10);  // it == myMap.end()

তবে একটি স্ট্রিংয়ের জন্য,

std::string myStr = "hello";
auto it = myStr.find('!');  // it == std::string::npos

পরিবর্তে ব্যর্থ myStr.find('!')ফিরে আসা উচিত নয় কেন ?myStr.end()std::string::npos

যেহেতু std::stringঅন্যান্য ধারকগুলির সাথে তুলনা করার সময় এটি কিছুটা বিশেষ, আমি ভাবছি যে এর পিছনে কোনও আসল কারণ আছে কিনা। (আশ্চর্যের বিষয়, আমি এই কোথাও কাউকে জিজ্ঞাসাবাদ করতে পাইনি)।


5
আমি মনে করি কেবল যুক্তিসঙ্গত উত্তরই প্রশ্নের উত্তরের নিকটে: 'হটডগগুলি কেন 4 টি এবং 6-এ হটডগ বান হয়?' ওয়েল, এটি বিশ্বকে
— সুখী

পরীক্ষা করে দেখুন এই
— পক্ষীবিশেষ

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

মানচিত্রের জন্য, আপনার কাছে কোনও এনপোস পুনরুক্তিকারী না থাকতে পারে যাতে শেষ পুনরুক্তি ব্যবহৃত হয়। স্ট্রিংয়ের জন্য, আমরা এনপোস ব্যবহার করতে পারি, সুতরাং কেন নয় :)
— এলএফ

উত্তর:


28

শুরুতে, std::stringইন্টারফেসটি স্ফীত এবং বেমানান হিসাবে সুপরিচিত , এই বিষয়ে হার্ব সটারের গটউ ot৪ দেখুন । কিন্তু তা সত্ত্বেও, সেখানে পিছনে যুক্তি std::string::findএকটি সূচক ফিরে: std::string::substr। এই সুবিধাযুক্ত সদস্য ফাংশন সূচকগুলিতে পরিচালনা করে, যেমন

const std::string src = "abcdefghijk";

std::cout << src.substr(2, 5) << "\n";

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

const auto it = src.find('d'); // imagine this returns an iterator

std::cout << src.substr(std::distance(src.cbegin(), it));

এটি আপনি যা চান তা নাও হতে পারে। সুতরাং আমরা std::string::findএকটি সূচক ফেরত দিতে পারি , এবং আমরা এখানে আছি:

const std::string extracted = src.substr(src.find('d'));

যদি আপনি পুনরাবৃত্তকারীদের সাথে কাজ করতে চান তবে ব্যবহার করুন <algorithm>। উপরের হিসাবে তারা আপনাকে অনুমতি দেয়

auto it = std::find(src.cbegin(), src.cend(), 'd');

std::copy(it, src.cend(), std::ostream_iterator<char>(std::cout));

4
ভাল যুক্তি. যাইহোক, একটি পুনরাবৃত্তকারীকে std::string::findফিরিয়ে দেওয়ার size()পরিবর্তে npos, substrবেশ কয়েকটি অতিরিক্ত শাখা এড়ানো ছাড়াও তার সাথে সামঞ্জস্যতা বজায় রেখে, ফিরে আসতে পারে ।
— ইরেনন

1
@ ইরেনন হতে পারে, তবে std::string::substrইতিমধ্যে দ্বিতীয় সূচক ( npos) এর জন্য একটি ডিফল্ট প্যারামিটার দিয়ে "শেষ পর্যন্ত এখানে শুরু করুন" কেসটি ইতিমধ্যে covers েকে রেখেছে । আমার ধারণা প্রত্যাবর্তনটিও size()বিভ্রান্ত হবে এবং আক্ষরিক সেন্ডিনেল পছন্দ nposকরাই ভাল পছন্দ হতে পারে !?
— lubgr

@ লুবগ্রার তবে যদি std::string::findকোনও পুনরুক্তিকারী ফেরত দেয় std::string::substrতবে সম্ভবত শুরুর অবস্থানের জন্য একটি পুনরাবৃত্তিকে গ্রহণ করবে। অনুসন্ধানের সাথে আপনার উদাহরণটি এই বিকল্প পৃথিবীতে উভয় ক্ষেত্রেই এক রকম দেখাবে।
— ম্যাটিয়াস ওয়ালিন

নিবন্ধন করুন তবে std::string::substrএকটি পুনরাবৃত্ত যুক্তি দিয়ে আরও একটি ইউবি কেস (দ্বিগুণ-শেষের দৃশ্যটি যা সূচকগুলি বা পুনরুক্তিগুলির সাথে সমানভাবে ভাল ঘটতে পারে) ছাড়াও দরজা খুলে দেয়: অন্য স্ট্রিংকে বোঝায় এমন একটি পুনরাবৃত্তকারীকে পাস করা।
— lubgr

3

এটি কারণ std::stringদুটি ইন্টারফেস আছে:

  • সমস্ত পাত্রে সাধারণ পুনরাবৃত্তভিত্তিক ইন্টারফেস পাওয়া যায়
  • std::stringনির্দিষ্ট সূচক ভিত্তিক ইন্টারফেস

std::string::findসূচক ভিত্তিক ইন্টারফেসের অংশ , এবং সূচকগুলি ফেরত দেয়।

std::findসাধারণ পুনরাবৃত্তভিত্তিক ইন্টারফেস ব্যবহার করতে ব্যবহার করুন।

std::vector<char>আপনি সূচক ভিত্তিক ইন্টারফেস না চাইলে ব্যবহার করুন (এটি করবেন না)।

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