2017-10-12 11 views
6

कैसे std::unique उपयोग करने के लिए एक स्ट्रिंग से लगातार रिक्त स्थान को दूर करने पर cppreference पर एक उदाहरण नहीं है के साथ अद्वितीय उदाहरण:std :: कोई तुल्यता संबंध (लगातार space निकालें)

std::string s = "wanna go to  space?"; 
auto end = std::unique(s.begin(), s.end(), [](char l, char r){ 
    return std::isspace(l) && std::isspace(r) && l == r; 
}); 
// s now holds "wanna go to space?xxxxxxxx", where 'x' is indeterminate 
std::cout << std::string(s.begin(), end) << '\n'; 

हालांकि, के लिए आवश्यकताएं अनुभाग में अद्वितीय यह

तत्वों को दिए गए बाइनरी भविष्यवाणी पी का उपयोग करके तुलना की जाती है। व्यवहार अपरिभाषित है यदि यह समकक्ष संबंध नहीं है।

तो मेरा प्रश्न है: क्या दिया गया उदाहरण मान्य है? भविष्यवाणी स्पष्ट रूप से प्रतिबिंबित नहीं है (दो 'एन' वर्ण असमान की तुलना करते हैं) और इस प्रकार एक समानता संबंध नहीं है।

+0

यह एक समानता है। सभी गैर-रिक्त स्थान अद्वितीय हैं। – stark

+0

यह रिफ्लेक्सिविटी है जो टूटा हुआ है ('ए ~ ए'), समरूपता सही है ('~ ~बी ~ ए') – Jarod42

+0

@ जारोड 42: हाँ, मैंने इसे ठीक किया है, मेरा मतलब है रिफ्लेक्सिव – Andre

उत्तर

2

विधेय वास्तव में Equivalence_relation का सम्मान नहीं है, विशेष रूप से रिफ्लेक्सिविटी में:

a ~ a 

उदाहरण आप हालांकि मान्य हो सकता है बात, पहले 'n' दूसरा 'n' से अलग हो सकते हैं। समस्या स्वयं तुलना के साथ है जो गलत है (अंतरिक्ष चरित्र को छोड़कर)।

एक तरह से विधेय ठीक करने के लिए खाते में पता रखना है:

[](const char& l, const char& r) 
{ 
    return (&l == &r) 
     || (l == r && std::is_space(l)); 
} 

तथ्य यह है कि खुद के साथ तुलना ज्यादातर कि एल्गोरिथ्म के लिए बेकार है है, इसलिए यूबी यहाँ क्या लेखक सबसे कार्यान्वयन में उम्मीद करता है।

वैध कार्यान्वयन भविष्यवाणी की प्रतिबिंबिता की जांच कर सकता है, और यदि गलत कुछ भी (यूबी के रूप में) करता है।

+0

यह एक साफ चाल है। मैंने माना होगा (बिना किसी विशेष कारण के) कि भविष्यवाणी स्मृति के वास्तविक पहचान पर भरोसा किए बिना समानता के लिए पुनरावर्तक के 'value_type' की तुलना करना चाहिए। यह स्पष्ट है कि आप संदर्भ से गुजर सकते हैं, लेकिन इतना स्पष्ट नहीं है कि आपको समानता संबंध के लिए उस जानकारी का उपयोग करने की अनुमति है। – Andre

+1

पता लेना बेहतर नहीं है! किसी मूल्य की प्रतिलिपि परिणाम को बदलना नहीं है, उदा।'' const char n = 'n'; पूर्व (एन, एन)/* == सच * /; कॉन्स चार एन 2 = एन; पूर्व (एन, एन 2)/* == झूठा * /; '' –

+0

@ अर्नवोगेल: मैं कहूंगा कि यह अधिक कठिन है, भविष्य सही है ('कॉन्स्ट चार और' के लिए समानता की पूर्ति की आवश्यकता), लेकिन क्या यह दिया गया है इटरेटर? * "अस्वीकृत फॉरवर्ड के प्रकार को [MoveAssignable] (http://en.cppreference.com/w/cpp/concept/MoveAssignable) की आवश्यकताओं को पूरा करना होगा।" *। refence MoveAssignable नहीं हैं, 'char' है (लेकिन अन्य predicate का उपयोग कर)। – Jarod42

0

अद्वितीय:

"सभी लेकिन सीमा से बराबर तत्वों के हर लगातार समूह से पहले तत्व को समाप्त करता है" आप केवल एक अंतरिक्ष होने के लिए नमूना विधेय के लिए एक तत्व निर्धारित करते हैं तो सब सही है। समानता केवल रिक्त स्थान पर लागू की जानी चाहिए। 'एन' एक जगह नहीं है इसलिए भविष्यवाणी झूठी झूठी है।

संबंधित मुद्दे