কেন `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.