সি ++ স্ট্রিং == এবং তুলনা () এর মধ্যে পার্থক্য?


363

আমি ব্যবহার সম্পর্কে কিছু সুপারিশ পড়েছি

std::string s = get_string();
std::string t = another_string();

if( !s.compare(t) ) 
{

পরিবর্তে

if( s == t )
{

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

পার্থক্য কি? কোন প্রসঙ্গে একটি উপায়ে অন্য উপযোগী হওয়া উচিত?

আমি কেবলমাত্র সেই ক্ষেত্রেই বিবেচনা করছি যেখানে আমার জানা দরকার যে স্ট্রিংটি অন্য স্ট্রিংয়ের সমান মান।


5
প্রথমটি সত্যটি ফিরে আসবে যেখানে দ্বিতীয়টি মিথ্যা প্রত্যাবর্তন করে এবং এর বিপরীতে।
ভিক্টর সেহর

56
প্রথমটি সবে পঠনযোগ্য এবং দ্বিতীয়টি সহজেই পড়া এবং বোঝা যায়।
ম্যাথিউ এম।

3
আমি এই জাতীয় "তুলনা" ফাংশন ব্যবহার করি: if(x.compare(y) == 0)<- সমান চিহ্ন, এটি সমান। আইএমও ব্যবহার করে !কেবল কোডটি অপঠনযোগ্য করে তোলে।
আর মার্টিনহো ফার্নান্দেস

1
এটি লক্ষ করা উচিত যে == প্রতিটি ক্ষেত্রে আপনার জন্য কাজ করে না। স্ট্রিং অপারেটরকে তুলনা করতে ওভারলোড করে, তাই == তুলনা বলার মতোই। বিকল্পভাবে, আপনি যদি এমন বস্তুগুলিতে চেষ্টা করেন যা == অপারেটরকে ওভারলোড করে না, আপনি তাদের ঠিকানাটির সাথে মেমরির তুলনা করছেন, না অভ্যন্তরীণ উপাদানগুলি। তুলনা কল করা আরও "নিরাপদ"। স্ট্যান্ডিং :: স্ট্রিং ব্যবহারের ক্ষেত্রে আপনি ভাল আছেন।
ডিউক্রো

এক পার্থক্য: compareরিটার্ন -1যদি sকম tএবং +1যদি sচেয়ে বেশী tসময় ==আগমন true/false। ননজারো পূর্ণসংখ্যা হয় trueএবং 0হয় false
GyuHyeon Choi

উত্তর:


450

এই স্ট্যান্ডার্ড সম্পর্কে বলতে হয় operator==

21.4.8.2 অপারেটর ==

template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                const basic_string<charT,traits,Allocator>& rhs) noexcept;

রিটার্নস: lhs.compare (আরএইচএস) == 0।

দেখে মনে হচ্ছে পার্থক্য খুব একটা নেই!


5
পাঠকদের জন্য নোট: এই বিষয়ে বিশদ জানতে দয়া করে ফ্রেডরিক হামিদির উত্তরটি পড়ুন কারণ প্রাসঙ্গিক পার্থক্য রয়েছে। যদিও আমি আনন্দিত বো পারসন দেখায় যে দুটি পরীক্ষা অবশ্যই একই মানটি ফিরে আসবে। !s.compare(t)এবং s == tএকই মান আসতে হবে, কিন্তু ফাংশন তুলনায় আরো তথ্য প্রদান করে তুলনা s == t, এবং s == tআরো ভালো পঠনযোগ্য যখন আপনি কি দেখেন না হয় কিভাবে স্ট্রিং ভিন্ন কিন্তু শুধুমাত্র যদি তারা বিসদৃশ্য।
সিডগ্রাহাম

143

স্টাড :: স্ট্রিং :: তুলনা () একটি প্রদান করে int:

  • সমান যদি শূন্য হয় sএবং tসমান হয়,
  • এর চেয়ে কম হলে শূন্যের চেয়ে sকম t,
  • এর চেয়ে বড় হলে শূন্যের চেয়ে sবড় t

আপনি যদি চান যে আপনার প্রথম কোড স্নিপেট দ্বিতীয়টির সমতুল্য হয়, এটি আসলে পড়তে হবে:

if (!s.compare(t)) {
    // 's' and 't' are equal.
}

সাম্যতা অপারেটর কেবল সমতার জন্য পরীক্ষা করে (তাই এটির নাম) এবং ফেরত দেয় a bool

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

সম্পাদনা: স্টিভ জেসোপ মন্তব্যগুলিতে compare()যেমন উল্লেখ করেছেন, দ্রুত বাছাই এবং বাইনারি অনুসন্ধান অ্যালগরিদমের জন্য সবচেয়ে কার্যকর is প্রাকৃতিক ধরণের এবং দ্বৈতত্ত্বীয় অনুসন্ধানগুলি শুধুমাত্র স্ট্যান্ড :: কম দিয়ে প্রয়োগ করা যেতে পারে ।


নোট করুন যে গাছ বা গাছের মতো জীবের সাথে কাজ করার সময় এই আচরণটি প্রায়শই কার্যকর।
প্লাজমাএইচএইচ

প্রকৃতপক্ষে এটি, আমি কেবল পদ্ধতি এবং সাম্য অপারেটরের মধ্যে পার্থক্যগুলি নির্দেশ করছিলাম :)
ফ্রেডরিক হামিদি

"কোন প্রসঙ্গে একটি উপায়ে অন্য উপযোগী হওয়া উচিত?" কেবল আমাকে ভাবায় যে ওপি তুলনা () এর জন্য সম্ভাব্য ব্যবহারের ক্ষেত্রে ভাবতে পারে না।
প্লাজমাএইচএইচ

2
"যদি আপনি দুটি স্ট্রিং একে অপরের সাথে কীভাবে সম্পর্কযুক্ত তা সম্পর্কে আগ্রহী হন" - যদিও এর জন্য আইডিয়োমেটিক সি ++ std::lessএকটি ত্রি-দিকের তুলনামূলক তুলনায় কঠোর দুর্বল আদেশ (যেমন , যা এই ক্ষেত্রে মোট অর্ডারও) ব্যবহার করা হয় ।compare()আদলে অপারেশন জন্য std::qsortএবং std::bsearchহিসাবে অনুকরণে যারা বিরোধিতা, std:sortএবং std::lower_bound
স্টিভ জেসোপ

30

compareসাবস্ট্রিংগুলির তুলনা করার জন্য ওভারলোড রয়েছে। আপনি যদি পুরো স্ট্রিংগুলির সাথে তুলনা করছেন তবে আপনার কেবল ==অপারেটর ব্যবহার করা উচিত (এবং এটি কল দেয় compareবা না তা বেশ অপ্রাসঙ্গিক)।


30

অভ্যন্তরীণভাবে, string::operator==() ব্যবহার করা হয় string::compare()। দয়া করে দেখুন: সিপ্লাসপ্লাস -string::operator==()

পারফরম্যান্সের তুলনা করার জন্য আমি একটি ছোট অ্যাপ্লিকেশন লিখেছি এবং দৃশ্যত আপনি যদি ডিবাগ পরিবেশে আপনার কোডটি সংকলন এবং চালনা করেন তবে string::compare()তার চেয়ে কিছুটা দ্রুত string::operator==()। তবে আপনি যদি রিলিজ এনভায়রনমেন্টে আপনার কোডটি সংকলন ও চালনা করেন তবে উভয়ই প্রায় একই রকম।

এফওয়াইআই, এ জাতীয় উপসংহারটি সামনে আসতে আমি 1,000,000 পুনরাবৃত্তি করেছি।

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

ডিবাগ বিল্ড

স্ট্রিং :: অপারেটর == ()

        if (str1 == str2)
00D42A34  lea         eax,[str2]  
00D42A37  push        eax  
00D42A38  lea         ecx,[str1]  
00D42A3B  push        ecx  
00D42A3C  call        std::operator==<char,std::char_traits<char>,std::allocator<char> > (0D23EECh)  
00D42A41  add         esp,8  
00D42A44  movzx       edx,al  
00D42A47  test        edx,edx  
00D42A49  je          Algorithm::PerformanceTest::stringComparison_usingEqualOperator1+0C4h (0D42A54h)  

স্ট্রিং :: তুলনা ()

            if (str1.compare(str2) == 0)
00D424D4  lea         eax,[str2]  
00D424D7  push        eax  
00D424D8  lea         ecx,[str1]  
00D424DB  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0D23582h)  
00D424E0  test        eax,eax  
00D424E2  jne         Algorithm::PerformanceTest::stringComparison_usingCompare1+0BDh (0D424EDh)

আপনি দেখতে পাচ্ছেন যে স্ট্রিং :: অপারেটর == () এ এটি অতিরিক্ত ক্রিয়াকলাপ সম্পাদন করতে হবে (esp, 8 এবং Movzx edx যোগ করুন, আল)

রিলিজ বিল্ড

স্ট্রিং :: অপারেটর == ()

        if (str1 == str2)
008533F0  cmp         dword ptr [ebp-14h],10h  
008533F4  lea         eax,[str2]  
008533F7  push        dword ptr [ebp-18h]  
008533FA  cmovae      eax,dword ptr [str2]  
008533FE  push        eax  
008533FF  push        dword ptr [ebp-30h]  
00853402  push        ecx  
00853403  lea         ecx,[str1]  
00853406  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)  

স্ট্রিং :: তুলনা ()

            if (str1.compare(str2) == 0)
    00853830  cmp         dword ptr [ebp-14h],10h  
    00853834  lea         eax,[str2]  
    00853837  push        dword ptr [ebp-18h]  
    0085383A  cmovae      eax,dword ptr [str2]  
    0085383E  push        eax  
    0085383F  push        dword ptr [ebp-30h]  
    00853842  push        ecx  
00853843  lea         ecx,[str1]  
00853846  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)

সংকলক অপ্টিমাইজেশন সম্পাদন করার মতো উভয়ই এসেম্বলি কোডের সাথে খুব মিল রয়েছে।

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


10
'খুব অনুরূপ' ... আমি কোনও পার্থক্য দেখছি না, তাই না?
xtofl

আমিও না ... তারাও একই জিনিস। কোনও পার্থক্য নেই
ওয়াগনার প্যাট্রিয়োটা

1
টনির উদাহরণ থেকে @xtofl উত্পন্ন কোডগুলি রিলিজ বিল্ডে অভিন্ন, তারা ডিবাগ বিল্ডগুলিতে আলাদা।
জুলিয়ান হার্টি

6

compare()স্ট্রিম্প () এর সমতুল্য। ==সহজ সমতা পরীক্ষা করা হয়। compare()সুতরাং একটি ফেরান int, ==একটি বুলিয়ান।


5

compare()ফিরে আসবে false(ভাল,0স্ট্রিংগুলি সমান হলে ) ।

সুতরাং অন্যের জন্য হালকাভাবে বিনিময় করবেন না।

কোডটি আরও পঠনযোগ্য করে তোলে যা ব্যবহার করুন।


3

আপনি যদি কেবল স্ট্রিংয়ের সাম্যতা পরীক্ষা করতে চান তবে == অপারেটরটি ব্যবহার করুন। দুটি স্ট্রিং সমান কিনা তা নির্ধারণ করা অর্ডার দেওয়ার চেয়ে সহজ (যা তুলনা () যা দেয় তা) তাই এটি হতে পারে সমতা অপারেটরটি ব্যবহার করা আপনার ক্ষেত্রে আরও ভাল পারফরম্যান্স-ভিত্তিক পারে।

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


2

ধরুন দুটি স্ট্রিং এস এবং টি বিবেচনা করুন।
তাদের কিছু মান দিন।
যখন আপনি তাদের (s == টি) ব্যবহার করে তুলনা করেন এটি একটি বুলিয়ান মান দেয় (সত্য বা মিথ্যা, 1 বা 0)।
আপনি যখন s.compare (t) ব্যবহার করে তুলনা করেন , তখন এক্সপ্রেশনটি একটি মান দেয়
(i) 0 - যদি s এবং t সমান হয়
(ii) <0 - হয় যদি s এর প্রথম তুলনামূলক অক্ষরের মান এর চেয়ে কম হয় t বা s এর দৈর্ঘ্য টি এর চেয়ে কম।
(iii) > 0 - হয় যদি টিতে প্রথম তুলনামূলক অক্ষরের মান s এর চেয়ে কম হয় বা t এর দৈর্ঘ্য এস এর চেয়ে কম হয়।


1

একটি জিনিস যা এখানে আচ্ছাদিত নয় তা হ'ল এটি নির্ভর করে যদি আমরা স্ট্রিংকে সি স্ট্রিং, সি স্ট্রিংয়ের সাথে স্ট্রিং বা স্ট্রিংয়ের সাথে স্ট্রিংয়ের সাথে তুলনা করি।

একটি প্রধান পার্থক্য হ'ল দুটি স্ট্রিং আকারের সমতার তুলনা করার জন্য তুলনা করার আগে পরীক্ষা করা হয় এবং এটি তুলনামূলক তুলনায় == অপারেটরকে দ্রুত করে তোলে।

আমি এটি জি ++ দেবিয়ান 7 তে দেখতে দেখতে এখানে তুলনা করব

// operator ==
  /**
   *  @brief  Test equivalence of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __lhs.compare(__rhs) == 0; }

  template<typename _CharT>
    inline
    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
    operator==(const basic_string<_CharT>& __lhs,
           const basic_string<_CharT>& __rhs)
    { return (__lhs.size() == __rhs.size()
          && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
                            __lhs.size())); }

  /**
   *  @brief  Test equivalence of C string and string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __rhs.compare(@a __lhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const _CharT* __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __rhs.compare(__lhs) == 0; }

  /**
   *  @brief  Test equivalence of string and C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const _CharT* __rhs)
    { return __lhs.compare(__rhs) == 0; }

কোডটি ফর্ম্যাট করা হয় এবং সম্পাদকে ফর্ম্যাট করা হয় shown প্রদর্শন এটি ভুল পেয়েছে। বেসিক_সামগ্রীটি খুলুন এবং আপনার ওএসে অপারেটর == দেখুন। কোডটি আমার নয়, এটি সত্য যে আকারের চেকটি এই থ্রেডে অনুপস্থিত। আমি আরও দেখতে পেয়েছি যে প্রচুর লোক ভুল তথ্যের সাথে একমত পোষণ করে যা স্ট্যাক ওভারফ্লোয়ের ইউটিলিটিটিকে অস্বীকার করে।
ড্রাগোস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.