माइनस साइन क्यों होता है, '-', आमतौर पर प्लस साइन की तरह ही ओवरलोड नहीं किया जाता है?


64

प्लस चिन्ह +का उपयोग जोड़ और स्ट्रिंग संघनन के लिए किया जाता है, लेकिन इसका साथी: ऋण चिह्न, -आमतौर पर तार के घटाव या घटाव के अलावा किसी अन्य मामले के लिए नहीं देखा जाता है। उसके कारण या सीमाएँ क्या हो सकती हैं?

जावास्क्रिप्ट में निम्नलिखित उदाहरण पर विचार करें:

var a = "abcdefg";
var b = "efg";

a-b == NaN
// but
a+b == "abcdefgefg"

35
कौन से "yy" को हटाया जाना चाहिए?
गैसच

12
अगर मैं '+' संकेत के व्यवहार के साथ जाता हूं, तो सबसे सही मायने रखता है।
दिग्विजय यादव

46
यह काफी बुरा है कि बाइनरी +ऑपरेटर दो पूरी तरह से असंबंधित अर्थ "संख्यात्मक जोड़" और "स्ट्रिंग समालोचना" के साथ अतिभारित है। शुक्र है, कुछ भाषाएं अलग-अलग .संघटन ऑपरेटर प्रदान करती हैं, जैसे (Perl5, PHP), ~(Perl6), &(VB), ++(हास्केल),…
amon

6
@MasonWheeler वे उपयोग करते हैं ->(लगता है कि सी में dereferencing सदस्य का उपयोग करें, क्योंकि वर्चुअल विधि कॉल आवश्यक रूप से सूचक-जैसे अप्रत्यक्ष रूप से शामिल होते हैं)। भाषा डिज़ाइन का कोई नियम नहीं है जिसके लिए .ऑपरेटर का उपयोग करने के लिए मेथड कॉल / मेंबर एक्सेस की आवश्यकता होती है , हालाँकि यह एक तेजी से होने वाला आम सम्मेलन है। क्या आप जानते हैं कि स्मालटाक के पास कोई विधि कॉल ऑपरेटर नहीं है? सिंपल जुक्सपोजिशन object methodपर्याप्त है।
आमोन

20
पायथन ओवरलोड माइनस करता है , सेट घटाव के लिए (और इसे उपयोगकर्ता-परिभाषित प्रकारों में भी अधिभारित किया जा सकता है)। पायथन सेट चौराहे / यूनियन / आदि के लिए अधिकांश बिटवाइज ऑपरेटरों को भी अधिभार देता है।
केविन

जवाबों:


116

संक्षेप में, स्ट्रिंग्स पर कोई विशेष रूप से उपयोगी घटाव-जैसा ऑपरेशन नहीं है जिसे लोग एल्गोरिदम के साथ लिखना चाहते हैं।

+ऑपरेटर आम तौर पर एक additive के संचालन को दर्शाता है monoid , कि, एक पहचान तत्व के साथ एक साहचर्य ऑपरेशन है:

  • ए + (बी + सी) = (ए + बी) + सी
  • ए + 0 = 0 + ए = ए

यह पूर्णांक जोड़, स्ट्रिंग संघनन और सेट यूनियन जैसी चीजों के लिए इस ऑपरेटर का उपयोग करने के लिए समझ में आता है क्योंकि वे सभी एक ही बीजीय संरचना है:

1 + (2 + 3) == (1 + 2) + 3
1 + 0 == 0 + 1 == 1

"a" + ("b" + "c") == ("a" + "b") + "c"
"a" + "" == "" + "a" == "a"

और हम इसे एक concatफ़ंक्शन की तरह काम एल्गोरिदम लिखने के लिए उपयोग कर सकते हैं जो किसी भी "सुगम" चीजों के अनुक्रम पर काम करता है, जैसे:

def concat(sequence):
    return sequence.reduce(+, 0)

जब घटाव -शामिल हो जाता है, तो आप आमतौर पर एक समूह की संरचना के बारे में बात करते हैं , जो प्रत्येक तत्व ए के लिए एक व्युत्क्रम invA जोड़ता है , इसलिए:

  • A + =A = −A + A = 0

और जब यह पूर्णांक और फ्लोटिंग-पॉइंट घटाव जैसी चीजों के लिए समझ में आता है, या यहां तक ​​कि अंतर भी सेट करता है, तो यह तार और सूचियों के लिए बहुत अधिक समझ में नहीं आता है। का विलोम क्या है "foo"?

एक संरचना है जिसे रद्द करने वाला मोनॉइड कहा जाता है , जिसमें आक्रमण नहीं होता है, लेकिन रद्द करने की संपत्ति होती है, ताकि:

  • ए - ए = ०
  • ए - 0 = ए
  • (ए + बी) - बी = ए

यह वह संरचना है जिसका आप वर्णन करते हैं, जहां "ab" - "b" == "a", लेकिन "ab" - "c"परिभाषित नहीं है। यह सिर्फ इतना है कि हमारे पास कई उपयोगी एल्गोरिदम नहीं हैं जो इस संरचना का उपयोग करते हैं। मुझे लगता है कि यदि आप समवर्ती को क्रमबद्धता के रूप में सोचते हैं, तो घटाव का उपयोग किसी तरह के पार्सिंग के लिए किया जा सकता है।


2
सेट (और मल्टी-सेट) के लिए घटाव समझ में आता है, क्योंकि दृश्यों के विपरीत, तत्व का क्रम कोई फर्क नहीं पड़ता।
कोड इनचॉस

@CodesInChaos: मैंने उनमें से एक उल्लेख जोड़ा, लेकिन मैं समूह के एक उदाहरण के रूप में सेट करने में वास्तव में सहज नहीं था- मुझे विश्वास नहीं है कि वे एक फॉर्म बनाते हैं, क्योंकि आप आम तौर पर सेट के व्युत्क्रम का निर्माण नहीं कर सकते।
जॉन पुरडी

12
दरअसल, +संख्याओं के लिए भी यह ऑपरेशन सराहनीय है A+B == B+A, जो इसे स्ट्रिंग कंसंट्रेशन के लिए खराब उम्मीदवार बनाता है । यह, भ्रामक ऑपरेटर पूर्वता +स्ट्रिंग स्ट्रिंग के लिए एक ऐतिहासिक गलती का उपयोग करता है। हालाँकि, यह सच है कि -स्ट्रिंग ऑपरेशन के लिए उपयोग करने से चीजें बहुत खराब हो जाती हैं ...
Holger

2
@ दर्घोग: सही है! .पर्ल पर्ल से उधार लिया गया; यह ~Perl6 में है, संभवतः अन्य।
जॉन पुरडी

1
@MartinBeckett, लेकिन आप देख सकते हैं कि व्यवहार भ्रामक हो सकता है .text.gz.text...
बोरिस स्पाइडर

38

क्योंकि किसी भी दो वैध तारों का संयोजन हमेशा एक वैध संचालन होता है, लेकिन विपरीत सच नहीं है।

var a = "Hello";
var b = "World";

यहां क्या होना a - bचाहिए? वास्तव में उस प्रश्न का उत्तर देने का कोई अच्छा तरीका नहीं है, क्योंकि प्रश्न ही मान्य नहीं है।


31
@ दिग्विजयवायद, अगर आप 5 आमों को 5 सेबों से हटाते हैं, तो क्या 5 आमों का एक काउंटर होना चाहिए? क्या यह कुछ नहीं करता है? क्या आप इस बात को अच्छी तरह से परिभाषित कर सकते हैं कि इसे मोटे तौर पर स्वीकार किया जा सकता है और सभी संकलकों और भाषाओं के व्याख्याकारों को इस ऑपरेटर को इस रूप में उपयोग करने के लिए कहा जा सकता है? यहीं बड़ी चुनौती है।
जेबी किंग

28
@DigvijayYadav: तो आपने इसे लागू करने के दो संभावित तरीकों का वर्णन किया है, और हर एक को वैध मानने का एक अच्छा तर्क है, इसलिए हम पहले से ही इस ऑपरेशन को निर्दिष्ट करने के विचार की गड़बड़ी कर रहे हैं। : पी
मेसन व्हीलर

13
@ हसी मुझे लगता है कि 5 + Falseस्पष्ट रूप से एक त्रुटि होनी चाहिए , क्योंकि एक संख्या एक बूलियन नहीं है और एक बूलियन एक संख्या नहीं है।
मेसन व्हीलर

6
@JDDvorak: उस बारे में विशेष रूप से "हास्केली" कुछ भी नहीं है; यह बुनियादी मजबूत टाइपिंग है।
मेसन व्हीलर

5
@DigvijayYadav तो (a+b)-b = a(उम्मीद है!), लेकिन (a-b)+bकभी-कभी a, कभी-कभी a+bइस बात पर निर्भर करता है कि bकोई विकल्प है aया नहीं? यह क्या पागलपन है?

28

क्योंकि -स्ट्रिंग हेरफेर के लिए ऑपरेटर के पास पर्याप्त "सिमेंटिक सामंजस्य" नहीं है। ऑपरेटर्स को केवल तभी ओवरलोड किया जाना चाहिए जब यह पूरी तरह से स्पष्ट हो कि ओवरलोड अपने ऑपरेंड्स के साथ क्या करता है, और स्ट्रिंग घटाव उस बार को पूरा नहीं करता है।

नतीजतन, विधि कॉल को प्राथमिकता दी जाती है:

public string Remove(string source, string toRemove)
public string Replace(string source, string oldValue, string newValue)

C # भाषा में, हम +स्ट्रिंग समाकलन के लिए उपयोग करते हैं क्योंकि प्रपत्र

var result = string1 + string2 + string3;

के बजाय

var result = string.Concat(string1, string2, string3);

सुविधाजनक और यकीनन पढ़ने में आसान है, भले ही एक फ़ंक्शन कॉल संभवतः सिमेंटिक दृष्टिकोण से अधिक "सही" है।

+ऑपरेटर वास्तव में केवल इस संदर्भ में एक बात हो सकता है। यह उतना सही नहीं है -, क्योंकि तारों को घटाने की धारणा अस्पष्ट है ( पैरामीटर के Replace(source, oldValue, newValue)साथ फ़ंक्शन कॉल के ""रूप में newValueपैरामीटर सभी संदेह को हटा देता है, और फ़ंक्शन का उपयोग सब्सट्रिंग को बदलने के लिए किया जा सकता है, न कि उन्हें हटाने के लिए)।

बेशक, समस्या यह है कि ऑपरेटर अधिभार ऑपरेटर को पारित किए जाने वाले प्रकारों पर निर्भर है, और यदि आप एक स्ट्रिंग पास करते हैं जहां एक संख्या होनी चाहिए थी, तो आपको वह परिणाम मिल सकता है जिसकी आपको उम्मीद नहीं थी। इसके अलावा, कई संघनन (यानी एक लूप में) के लिए, एक StringBuilderवस्तु बेहतर होती है, क्योंकि प्रत्येक का उपयोग +एक नया स्ट्रिंग बनाता है, और प्रदर्शन को नुकसान हो सकता है। इसलिए +ऑपरेटर सभी संदर्भों में उचित नहीं है।

ऐसे ऑपरेटर अधिभार हैं जो +स्ट्रिंग संगति के लिए ऑपरेटर की तुलना में बेहतर सिमेंटिक सामंजस्य रखते हैं । यहाँ एक है जो दो जटिल संख्याएँ जोड़ता है:

public static Complex operator +(Complex c1, Complex c2) 
{
    return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}

8
+1 दो तारों, ए और बी को देखते हुए, मैं एबी के बारे में सोच सकता हूं कि "ए के अंत से एक अनुगामी बी को हटा दें," "ए में कहीं से बी का एक उदाहरण हटा दें," "ए में कहीं से बी के सभी उदाहरणों को हटा दें।" , "या यहां तक ​​कि" बी से ए में पाए गए सभी पात्रों को हटा दें। "
कोरट अमोन

8

ग्रूवी भाषा की अनुमति नहीं है -:

println('ABC'-'B')

रिटर्न:

AC

तथा:

println( 'Hello' - 'World' )

रिटर्न:

Hello

तथा:

println('ABABABABAB' - 'B')

रिटर्न:

AABABABAB

11
दिलचस्प - तो यह पहली घटना को हटाने का विकल्प चुनता है? पूरी तरह से काउंटर-सहज व्यवहार के लिए एक अच्छा उदाहरण।
हल्क

9
इसलिए, हमारे पास वह ('ABABABABA' + 'B') - 'B'मूल्य है जो शुरुआती मूल्य के समान नहीं है 'ABABABABA'
बजे एक CVn

3
@ माइकलकॉर्जलिंग ओटीओएच, (A + B) - A == Bहर ए और बी के लिए क्या मैं इसे छोड़ दिया घटाव कह सकता हूं?
जॉन ड्वोरक

2
हास्केल में ++संघनन होता है। यह किसी भी सूची में काम करता है और एक स्ट्रिंग सिर्फ पात्रों की एक सूची है। इसमें वह भी है \\, जो बाएं तर्क से सही तर्क में प्रत्येक तत्व की पहली घटना को हटाता है।
जॉन ड्वोरक

3
मुझे ऐसा लगता है कि ये उदाहरण ठीक उसी तरह से हैं जैसे तार के लिए कोई माइनस ऑपरेटर नहीं होना चाहिए। यह असंगत है और सहज व्यवहार नहीं है। जब मुझे लगता है कि "-" मुझे यकीन है कि मत सोचो, "मिलान स्ट्रिंग के पहले उदाहरण को हटा दें, अगर ऐसा होता है, अन्यथा बस कुछ भी नहीं करें।"
एंडरलैंड

6

प्लस चिन्ह संभवतः संदर्भ में अधिक मामलों में समझ में आता है, लेकिन पाइथन में एक काउंटर-उदाहरण (शायद एक अपवाद जो नियम को साबित करता है) सेट ऑब्जेक्ट है, जो इसके लिए प्रदान करता है : -लेकिन नहीं+

>>> set('abc') - set('bcd')
set(['a'])
>>> set('abc') + set('bcd')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'

यह +संकेत का उपयोग करने के लिए समझ में नहीं आता है क्योंकि इरादा अस्पष्ट हो सकता है - क्या इसका मतलब चौराहा या संघ है? इसके बजाय, यह |संघ और &प्रतिच्छेदन के लिए उपयोग करता है :

>>> set('abc') | set('bcd')
set(['a', 'c', 'b', 'd'])
>>> set('abc') & set('bcd')
set(['c', 'b'])

2
यह अधिक संभावना है क्योंकि सेट घटाव को गणित में परिभाषित किया गया है, लेकिन सेट जोड़ नहीं है।
मेहरदाद

"-" का उपयोग धूमिल लगता है; क्या वास्तव में आवश्यक है एक "लेकिन नहीं" ऑपरेटर जो पूर्णांक के साथ बिटवाइज़ अंकगणित करते समय भी उपयोगी होगा। यदि 30 ~ और 7 24 थे, तो ~ और सेट का उपयोग करने के साथ अच्छी तरह फिट होगा & | भले ही सेट की कमी हो ~ एक ऑपरेटर।
22

1
set('abc') ^ set('bcd')रिटर्न set(['a', 'd']), अगर आप सममित अंतर के बारे में पूछ रहे हैं।
हारून हॉल

3

" -" का उपयोग कुछ यौगिक शब्दों में किया जाता है (उदाहरण के लिए, "ऑन-साइट") विभिन्न भागों को एक ही शब्द में शामिल करने के लिए। -प्रोग्रामिंग भाषाओं में विभिन्न स्ट्रिंग्स को एक साथ जोड़ने के लिए हम " " का उपयोग क्यों नहीं करते हैं? मुझे लगता है कि यह सही समझ में आता है! इस +बकवास के साथ नरक करने के लिए !

हालाँकि, इसे थोड़ा और सार कोण से देखने का प्रयास करें।

आप स्ट्रिंग बीजगणित को कैसे परिभाषित करेंगे? आपके पास कौन से ऑपरेशन होंगे, और उनके लिए कौन से कानून होंगे? उनके संबंध क्या होंगे?

याद रखें, कोई अस्पष्टता बिल्कुल नहीं हो सकती है! हर संभव मामले को अच्छी तरह से परिभाषित किया जाना चाहिए, भले ही इसका मतलब यह हो कि ऐसा करना संभव नहीं है! आपका बीजगणित जितना छोटा होता है, उतना आसान होता है।

उदाहरण के लिए, वास्तव में दो तारों को जोड़ने या घटाने का क्या मतलब है?

यदि आप दो तार जोड़ते हैं (उदाहरण के लिए, चलो a = "aa"और b = "bb"), तो क्या आपको aabbइसका परिणाम मिलेगा a + b?

कैसे के बारे में b + a? क्या ऐसा होगा bbaa? क्यों नहीं aabb? यदि आप aaअपने जोड़ के परिणाम से घटाते हैं तो क्या होता है ? क्या आपकी स्ट्रिंग में नकारात्मक राशि की अवधारणा होगी aa?

अब इस उत्तर की शुरुआत में जाएं और spaceshuttleस्ट्रिंग के बजाय स्थानापन्न करें । सामान्यीकृत करने के लिए, किसी भी प्रकार के लिए किसी भी ऑपरेशन को परिभाषित या परिभाषित क्यों नहीं किया जाता है?

मैं जिस बिंदु को बनाने की कोशिश कर रहा हूं, वह यह है कि कुछ भी आपके लिए बीजगणित बनाने से कुछ भी नहीं रोक रहा है। यह सार्थक संचालन, या इसके लिए उपयोगी संचालन भी खोजना मुश्किल हो सकता है।

स्ट्रिंग्स के लिए, कॉनकैटनेटिंग बहुत ही समझदार है जिसे मैंने कभी देखा है। इससे कोई फर्क नहीं पड़ता कि ऑपरेशन को दर्शाने के लिए किस प्रतीक का उपयोग किया जाता है।


1
"स्ट्रिंग्स के लिए, कंक्रीटिंग बहुत ही समझदार है जिसे मैंने कभी देखा है" । फिर क्या आप पायथन से असहमत हैं 'xy' * 3 == 'xyxyxy'?
smci

3
@smci कि सिर्फ गुणा-के-दोहराया-अलावा है , निश्चित रूप से?
जॉन्सर्शपे

स्पेसकेशल्स को सुगम बनाने के लिए उचित संचालक क्या है?
श्री मिन्डोर

4
@ श्री। मिंडोर बैकस्पेस ... स्पेसक्राफ्ट के बीच की जगह को हटाने के लिए।
यंगजॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.