উত্তর:
কেবল সর্বশেষ n অক্ষর ব্যবহার করে তুলনা করুন std::string::compare
:
#include <iostream>
bool hasEnding (std::string const &fullString, std::string const &ending) {
if (fullString.length() >= ending.length()) {
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
} else {
return false;
}
}
int main () {
std::string test1 = "binary";
std::string test2 = "unary";
std::string test3 = "tertiary";
std::string test4 = "ry";
std::string ending = "nary";
std::cout << hasEnding (test1, ending) << std::endl;
std::cout << hasEnding (test2, ending) << std::endl;
std::cout << hasEnding (test3, ending) << std::endl;
std::cout << hasEnding (test4, ending) << std::endl;
return 0;
}
এই ফাংশনটি ব্যবহার করুন:
inline bool ends_with(std::string const & value, std::string const & ending)
{
if (ending.size() > value.size()) return false;
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}
std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()
ডিবাগ মোডে, এটি ছুঁড়ে দেয়:_DEBUG_ERROR("string iterator not decrementable");
ব্যবহার করুন boost::algorithm::ends_with
(উদাহরণস্বরূপ http://www.boost.org/doc/libs/1_34_0/doc/html/boost/algorithm/ends_with.html দেখুন ):
#include <boost/algorithm/string/predicate.hpp>
// works with const char*
assert(boost::algorithm::ends_with("mystring", "ing"));
// also works with std::string
std::string haystack("mystring");
std::string needle("ing");
assert(boost::algorithm::ends_with(haystack, needle));
std::string haystack2("ng");
assert(! boost::algorithm::ends_with(haystack2, needle));
দ্রষ্টব্য, যে c ++ 20 স্টাড :: স্ট্রিং থেকে শুরু করে অবশেষে প্রারম্ভ_ও এবং শেষ_সমেত প্রদান করবে । মনে হচ্ছে এমন একটি সম্ভাবনা রয়েছে যে সি ++ এর সি ++ এর 30 টি স্ট্রিং অবশেষে ব্যবহারযোগ্য হয়ে উঠতে পারে, আপনি যদি এটি দূরবর্তী ভবিষ্যত থেকে না পড়েন তবে আপনি এই শুরুগুলি / শেষগুলি ব্যবহার করতে পারেন:
#include <string>
static bool endsWith(const std::string& str, const std::string& suffix)
{
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
}
static bool startsWith(const std::string& str, const std::string& prefix)
{
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
}
এবং কিছু অতিরিক্ত সহায়ক ওভারলোডস:
static bool endsWith(const std::string& str, const char* suffix, unsigned suffixLen)
{
return str.size() >= suffixLen && 0 == str.compare(str.size()-suffixLen, suffixLen, suffix, suffixLen);
}
static bool endsWith(const std::string& str, const char* suffix)
{
return endsWith(str, suffix, std::string::traits_type::length(suffix));
}
static bool startsWith(const std::string& str, const char* prefix, unsigned prefixLen)
{
return str.size() >= prefixLen && 0 == str.compare(0, prefixLen, prefix, prefixLen);
}
static bool startsWith(const std::string& str, const char* prefix)
{
return startsWith(str, prefix, std::string::traits_type::length(prefix));
}
আইএমও, সি ++ স্ট্রিংগুলি স্পষ্টতই অকার্যকর এবং এগুলি বাস্তব বিশ্বের কোডে ব্যবহার করার জন্য তৈরি করা হয়নি। তবে একটি আশা আছে যে এটি কমপক্ষে আরও ভাল হয়ে উঠবে।
আমি প্রশ্নটি সি ++ এর জন্য জানি, তবে কারও যদি এটির জন্য কোনও ভাল অল এর ফ্যাশনযুক্ত সি ফাংশন প্রয়োজন হয়:
/* returns 1 iff str ends with suffix */
int str_ends_with(const char * str, const char * suffix) {
if( str == NULL || suffix == NULL )
return 0;
size_t str_len = strlen(str);
size_t suffix_len = strlen(suffix);
if(suffix_len > str_len)
return 0;
return 0 == strncmp( str + str_len - suffix_len, suffix, suffix_len );
}
std::mismatch
পদ্ধতি যখন পিছন করতে ব্যবহৃত এই উদ্দেশ্যে পরিবেশন করা যাবে উভয় স্ট্রিং শেষ থেকে বারবার:
const string sNoFruit = "ThisOneEndsOnNothingMuchFruitLike";
const string sOrange = "ThisOneEndsOnOrange";
const string sPattern = "Orange";
assert( mismatch( sPattern.rbegin(), sPattern.rend(), sNoFruit.rbegin() )
.first != sPattern.rend() );
assert( mismatch( sPattern.rbegin(), sPattern.rend(), sOrange.rbegin() )
.first == sPattern.rend() );
std::equal
: আপনার আগে থেকেই পরীক্ষা করে নেওয়া উচিত যে অনুমিত প্রত্যয়টি আপনি যে স্ট্রিংটি অনুসন্ধান করছেন তার চেয়ে দীর্ঘ নয় that এটি যা অপরিজ্ঞাত আচরণের দিকে পরিচালিত করে তা তদন্ত করতে অবহেলা করা।
আমার মতে সবচেয়ে সহজ, সি ++ সমাধানটি হ'ল:
bool endsWith(const string& s, const string& suffix)
{
return s.rfind(suffix) == std::abs(s.size()-suffix.size());
}
s
শুধু এটা শেষে পরীক্ষা পরিবর্তে!
std::string::size()
একটি ধ্রুবক সময় অপারেশন; এটির দরকার নেই strlen
।
দিন a
একটি স্ট্রিং এবং হতে b
স্ট্রিং তোমার জন্য দেখুন। ব্যবহারের a.substr
শেষ এন অক্ষর পেতে a
এবং b তাদের তুলনা (যেখানে n এর দৈর্ঘ্য হল b
)
অথবা ব্যবহার std::equal
(অন্তর্ভুক্ত <algorithm>
)
উদা:
bool EndsWith(const string& a, const string& b) {
if (b.size() > a.size()) return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
}
মামলার সংবেদনশীল সংস্করণ ( অনলাইন ডেমো ) দিয়ে আমি জোসেফের সমাধানটি প্রসারিত করি
static bool EndsWithCaseInsensitive(const std::string& value, const std::string& ending) {
if (ending.size() > value.size()) {
return false;
}
return std::equal(ending.rbegin(), ending.rend(), value.rbegin(),
[](const char a, const char b) {
return tolower(a) == tolower(b);
}
);
}
উপরের মত একই, এখানে আমার সমাধান
template<typename TString>
inline bool starts_with(const TString& str, const TString& start) {
if (start.size() > str.size()) return false;
return str.compare(0, start.size(), start) == 0;
}
template<typename TString>
inline bool ends_with(const TString& str, const TString& end) {
if (end.size() > str.size()) return false;
return std::equal(end.rbegin(), end.rend(), str.rbegin());
}
starts_with
'স্ট্রিং :: তুলনা' কেন ব্যবহার করে? না কেন std::equal(start.begin(), start.end(), str.begin())
?
আরেকটি বিকল্প হ'ল রেজেেক্স ব্যবহার করা। নিম্নলিখিত কোডটি অনুসন্ধানকে আপার / লোয়ার ক্ষেত্রে সংবেদনশীল করে তুলেছে:
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
return std::regex_search(str,
std::regex(std::string(suffix) + "$", std::regex_constants::icase));
}
সম্ভবত এত দক্ষ না, তবে কার্যকর করা সহজ।
আপনি স্ট্রিং :: আরফাইন্ড ব্যবহার করতে পারেন
মন্তব্যের ভিত্তিতে পূর্ণ উদাহরণ:
bool EndsWith(string &str, string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();
if(keylen =< strlen)
return string::npos != str.rfind(key,strlen - keylen, keylen);
else return false;
}
স্ট্রিংয়ের প্রত্যয় রয়েছে কিনা তা নীচে ব্যবহার করে দেখুন:
/*
Check string is end with extension/suffix
*/
int strEndWith(char* str, const char* suffix)
{
size_t strLen = strlen(str);
size_t suffixLen = strlen(suffix);
if (suffixLen <= strLen) {
return strncmp(str + strLen - suffixLen, suffix, suffixLen) == 0;
}
return 0;
}
<algorithms>
বিপরীত পুনরাবৃত্তি সহ স্ট্যান্ড :: সমান অ্যালগরিদম ব্যবহার করুন :
std::string LogExt = ".log";
if (std::equal(LogExt.rbegin(), LogExt.rend(), filename.rbegin())) {
…
}
গ্রাজেগরজ বেজিয়ার সাড়া সম্পর্কে Regarding আমি এই বাস্তবায়নটি ব্যবহার করেছি, তবে আসলটির একটি বাগ রয়েছে (আমি যদি ".." সাথে ".so" তুলনা করি তবে সত্য ফিরে আসে)। আমি পরিবর্তিত ফাংশন প্রস্তাব:
bool endsWith(const string& s, const string& suffix)
{
return s.size() >= suffix.size() && s.rfind(suffix) == (s.size()-suffix.size());
}
আমি ভেবেছিলাম কোনও কাঁচামুক্ত সমাধান পোস্ট করা বোধগম্য যা কোনও লাইব্রেরির ফাংশন ব্যবহার করে না ...
// Checks whether `str' ends with `suffix'
bool endsWith(const std::string& str, const std::string& suffix) {
if (&suffix == &str) return true; // str and suffix are the same string
if (suffix.length() > str.length()) return false;
size_t delta = str.length() - suffix.length();
for (size_t i = 0; i < suffix.length(); ++i) {
if (suffix[i] != str[delta + i]) return false;
}
return true;
}
একটি সাধারণ যোগ করা std::tolower
আমরা এই ক্ষেত্রে সংবেদনশীল করতে পারি
// Checks whether `str' ends with `suffix' ignoring case
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
if (&suffix == &str) return true; // str and suffix are the same string
if (suffix.length() > str.length()) return false;
size_t delta = str.length() - suffix.length();
for (size_t i = 0; i < suffix.length(); ++i) {
if (std::tolower(suffix[i]) != std::tolower(str[delta + i])) return false;
}
return true;
}
অনুরূপ "স্টার্ট উইথ" -র সমস্যাটির দুর্দান্ত উত্তরটি পেয়েছে:
আপনি কেবল স্ট্রিংয়ের শেষ স্থানে অনুসন্ধানের সমাধানটি গ্রহণ করতে পারেন:
bool endsWith(const std::string& stack, const std::string& needle) {
return stack.find(needle, stack.size() - needle.size()) != std::string::npos;
}
এইভাবে আপনি এটি সংক্ষিপ্ত, দ্রুত করতে পারবেন, স্ট্যান্ডার্ড সি ++ ব্যবহার করতে এবং এটিকে পঠনযোগ্য করে তুলতে পারেন।
আপনি যদি আমার মতো হন এবং সি ++ পিউরিজমে না হন তবে এখানে একটি পুরানো স্কুল হাইব্রিড। স্ট্রিংগুলি মুষ্টিমেয় অক্ষরের চেয়ে বেশি হলে কিছুটা সুবিধা রয়েছে কারণ বেশিরভাগ memcmp
বাস্তবায়ন যখন সম্ভব হয় তখন মেশিনের শব্দের সাথে তুলনা করে।
চরিত্র সেটটি নিয়ন্ত্রণে রাখতে হবে। উদাহরণস্বরূপ, যদি এই পদ্ধতিটি utf-8 বা wchar প্রকারের সাথে ব্যবহৃত হয় তবে কিছু অসুবিধা রয়েছে কারণ এটি চরিত্রের ম্যাপিং সমর্থন করে না - যেমন যখন দুটি বা ততোধিক অক্ষর যুক্তিযুক্তভাবে অভিন্ন হয় ।
bool starts_with(std::string const & value, std::string const & prefix)
{
size_t valueSize = value.size();
size_t prefixSize = prefix.size();
if (prefixSize > valueSize)
{
return false;
}
return memcmp(value.data(), prefix.data(), prefixSize) == 0;
}
bool ends_with(std::string const & value, std::string const & suffix)
{
size_t valueSize = value.size();
size_t suffixSize = suffix.size();
if (suffixSize > valueSize)
{
return false;
}
const char * valuePtr = value.data() + valueSize - suffixSize;
return memcmp(valuePtr, suffix.data(), suffixSize) == 0;
}
আমার দুই সেন্ট:
bool endsWith(std::string str, std::string suffix)
{
return str.find(suffix, str.size() - suffix.size()) != string::npos;
}