आप हल्के से बंद हो गए, आप शायद हेज फंड के लिए काम नहीं करना चाहते हैं जहां क्वेंट बुनियादी एल्गोरिदम को नहीं समझते हैं :-)
मनमाने ढंग से आकार की डेटा संरचना को संसाधित करने का कोई तरीका नहीं है O(1)
यदि, इस मामले में, आपको कम से कम एक बार प्रत्येक तत्व का दौरा करने की आवश्यकता है। सबसे अच्छा आप के लिए आशा कर सकते हैं O(n)
इस मामले में, जहां में n
स्ट्रिंग की लंबाई है।
हालांकि, एक अलग रूप में के रूप में, एक मामूली O(n)
एल्गोरिथ्म होगा हो O(1)
तो, तकनीकी रूप से एक निश्चित इनपुट आकार के लिए, वे यहाँ सही हो सकता है। हालांकि, यह आमतौर पर नहीं है कि लोग जटिलता विश्लेषण का उपयोग कैसे करते हैं।
यह मुझे प्रतीत होता है कि आप उन्हें कई तरीकों से प्रभावित कर सकते थे।
सबसे पहले, उन्हें सूचित करके कि ऐसा करना संभव नहीं है O(1)
, जब तक कि आप ऊपर दिए गए "संदिग्ध" तर्क का उपयोग न करें।
दूसरा, पाइथोनिक कोड प्रदान करके अपने कुलीन कौशल दिखा रहा है जैसे:
inpStr = '123412345123456'
# O(1) array creation.
freq = [0] * 1000
# O(n) string processing.
for val in [int(inpStr[pos:pos+3]) for pos in range(len(inpStr) - 2)]:
freq[val] += 1
# O(1) output of relevant array values.
print ([(num, freq[num]) for num in range(1000) if freq[num] > 1])
यह आउटपुट:
[(123, 3), (234, 3), (345, 2)]
हालाँकि, आप अपनी इच्छा के अनुसार आउटपुट स्वरूप को संशोधित कर सकते हैं।
और, अंत में, उन्हें यह बताकर कि लगभग निश्चित रूप से एक समाधान के साथ कोई समस्या नहीं है O(n)
, क्योंकि ऊपर दिए गए कोड एक सेकंड में एक मिलियन-अंक स्ट्रिंग के लिए परिणाम देते हैं। यह काफी रैखिक रूप में अच्छी तरह से पैमाने पर लगता है, क्योंकि एक 10,000,000-वर्ण स्ट्रिंग को 3.5 सेकंड और 100,000,000-वर्ण वाले को 36 सेकंड लगते हैं।
और, अगर उन्हें इससे बेहतर की जरूरत है , तो इस तरह के सामान को समानांतर करने के तरीके हैं जो इसे गति प्रदान कर सकते हैं।
जीआईएल के कारण निश्चित रूप से एक भी अजगर दुभाषिया के भीतर नहीं है , लेकिन आप स्ट्रिंग को कुछ इस तरह विभाजित कर सकते हैं (द्वारा इंगित ओवरलैप vv
को सीमा क्षेत्रों के उचित प्रसंस्करण की अनुमति देना आवश्यक है):
vv
123412 vv
123451
5123456
आप इन श्रमिकों को अलग करने के लिए खेती कर सकते हैं और बाद में परिणामों को जोड़ सकते हैं।
इनपुट के बंटवारे और आउटपुट के संयोजन से किसी भी बचत को छोटे तारों (और संभवत: मिलियन अंकों के तार) के साथ झूलने की संभावना है, लेकिन बहुत बड़े डेटा सेटों के लिए, यह अच्छी तरह से अंतर कर सकता है। मेरा सामान्य मंत्र "उपाय, नहीं लगता" यहाँ, निश्चित रूप से लागू होता है।
यह मंत्र अन्य संभावनाओं पर भी लागू होता है , जैसे कि पायथन को पूरी तरह से दरकिनार करना और एक अलग भाषा का उपयोग करना जो तेज हो सकता है।
उदाहरण के लिए, निम्न सी कोड, जो पहले के पायथन कोड के समान हार्डवेयर पर चल रहा है, 0.6 सेकंड में सौ मिलियन अंकों को संभालता है , लगभग उसी समय जैसे पायथन कोड ने एक मिलियन को संसाधित किया । दूसरे शब्दों में, बहुत तेजी से:
#include <stdio.h>
#include <string.h>
int main(void) {
static char inpStr[100000000+1];
static int freq[1000];
// Set up test data.
memset(inpStr, '1', sizeof(inpStr));
inpStr[sizeof(inpStr)-1] = '\0';
// Need at least three digits to do anything useful.
if (strlen(inpStr) <= 2) return 0;
// Get initial feed from first two digits, process others.
int val = (inpStr[0] - '0') * 10 + inpStr[1] - '0';
char *inpPtr = &(inpStr[2]);
while (*inpPtr != '\0') {
// Remove hundreds, add next digit as units, adjust table.
val = (val % 100) * 10 + *inpPtr++ - '0';
freq[val]++;
}
// Output (relevant part of) table.
for (int i = 0; i < 1000; ++i)
if (freq[i] > 1)
printf("%3d -> %d\n", i, freq[i]);
return 0;
}