C++ गहराई से

C++ भाषा ट्यूटोरियल

इस ट्यूटोरियल के शुरुआती सेक्शन में, पिछले दो मॉड्यूल में पहले से दी गई बुनियादी जानकारी दी गई है. साथ ही, इसमें बेहतर कॉन्सेप्ट के बारे में ज़्यादा जानकारी दी गई है. इस मॉड्यूल में हमारा फ़ोकस, डाइनैमिक मेमोरी के साथ-साथ ऑब्जेक्ट और क्लास के बारे में ज़्यादा जानकारी पर है. कुछ बेहतर विषयों के बारे में भी बताया गया है, जैसे कि इनहेरिटेंस, पॉलीमॉरफ़िज़्म, टेंप्लेट, अपवाद, और नेमस्पेस. हम बाद में, बेहतर C++ कोर्स पर इन विषयों पर चर्चा करेंगे.

ऑब्जेक्ट-ओरिएंटेड डिज़ाइन

ऑब्जेक्ट-ओरिएंटेड डिज़ाइन के लिए, यह एक बेहतरीन ट्यूटोरियल है. हम इस मॉड्यूल के प्रोजेक्ट में यहां दिए गए तरीके को लागू करेंगे.

उदाहरण #3 से जानें

इस मॉड्यूल में, हमारा फ़ोकस पॉइंटर, ऑब्जेक्ट-ओरिएंटेड डिज़ाइन, मल्टी-डाइमेंशनल अरे, और क्लास/ऑब्जेक्ट की मदद से ज़्यादा प्रैक्टिस करने पर है. नीचे दिए गए उदाहरणों की मदद से देखें. हम इस बात पर ज़ोर नहीं दे सकते कि एक अच्छा प्रोग्रामर बनने के लिए सबसे ज़रूरी है, सिर्फ़ प्रैक्टिस, प्रैक्टिस, और प्रैक्टिस !

कसरत #1: पॉइंटर की मदद से ज़्यादा प्रैक्टिस करें

अगर आपको पॉइंटर के साथ अन्य तरीकों की ज़रूरत है, तो इस रिसॉर्स को पढ़ें. इसमें पॉइंटर के सभी पहलुओं के बारे में बताया गया है. साथ ही, प्रोग्राम के कई उदाहरण भी दिए गए हैं.

इस प्रोग्राम का आउटपुट क्या होगा? कृपया इस प्रोग्राम को न चलाएं, बल्कि आउटपुट तय करने के लिए मेमोरी की इमेज बनाएं.

void Unknown(int *p, int num);
void HardToFollow(int *p, int q, int *num);

void Unknown(int *p, int num) {
  int *q;

  q = #
  *p = *q + 2;
  num = 7;
}

void HardToFollow(int *p, int q, int *num) {
  *p = q + *num;
  *num = q;
  num = p;
  p = &q;
  Unknown(num, *p);
}

main() {
  int *q;
  int trouble[3];

  trouble[0] = 1;
  q = &trouble[1];
  *q = 2;
  trouble[2] = 3;

  HardToFollow(q, trouble[0], &trouble[2]);
  Unknown(&trouble[0], *q);

  cout << *q << " " << trouble[0] << " " << trouble[2];
}

मैन्युअल तरीके से आउटपुट तय करने के बाद, प्रोग्राम को चलाकर देखें कि आप सही नतीजे देख रहे हैं या नहीं.

एक्सरसाइज़ #2: क्लास और ऑब्जेक्ट के साथ ज़्यादा प्रैक्टिस करें

अगर आपको क्लास और ऑब्जेक्ट के साथ ज़्यादा प्रैक्टिस की ज़रूरत है, तो यहां एक ऐसा संसाधन दिया गया है जो दो छोटी क्लास को लागू करता है. कसरत करने के लिए कुछ समय निकालें.

व्यायाम #3: बहु-आयामी सरणियां

इस प्रोग्राम में शामिल हों: 

const int kStudents = 25;
const int kProblemSets = 10;

// This function returns the highest grade in the Problem Set array.
int get_high_grade(int *a, int cols, int row, int col) {
  int i, j;
  int highgrade = *a;

  for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
      if (*(a + i * cols + j) > highgrade)  // How does this line work?
        highgrade = *(a + i*cols + j);
  return highgrade;
}

int main() {
 int grades[kStudents][kProblemSets] = {
   {75, 70, 85, 72, 84},
   {85, 92, 93, 96, 86},
   {95, 90, 83, 76, 97},
   {65, 62, 73, 84, 73}
 };
 int std_num = 4;
 int ps_num = 5;
 int highest;

 highest = get_high_grade((int *)grades, kProblemSets, std_num, ps_num);
 cout << "The highest problem set score in the class is " << highest << endl;

 return 0;
}

इस प्रोग्राम में एक लाइन है जिस पर "यह लाइन कैसे काम करती है?" लिखा है - क्या तुम इसे समझ सकते हो? यहां हमने इसकी पूरी जानकारी दी है.

एक ऐसा प्रोग्राम लिखें जो तीन डिम ऐरे को शुरू करता है और तीसरे डाइमेंशन की वैल्यू को तीनों इंडेक्स के योग से भरता है. यहां हमारा समाधान है.

व्यायाम #4: OO के डिज़ाइन का एक विस्तृत उदाहरण

यहां ऑब्जेक्ट-ओरिएंटेड डिज़ाइन का उदाहरण दिया गया है. इसमें, शुरू से लेकर आखिर तक पूरी प्रोसेस पूरी की जाती है. फ़ाइनल कोड, Java की प्रोग्रामिंग लैंग्वेज में लिखा जाता है. हालांकि, आपके पास किताब को पूरी तरह से समझने का विकल्प होता है.

कृपया समय निकालकर इस पूरे उदाहरण को देखें. यह इस प्रोसेस और इसे सपोर्ट करने वाले डिज़ाइन टूल की एक शानदार इमेज है.

यूनिट टेस्टिंग

शुरुआती जानकारी

टेस्टिंग, सॉफ़्टवेयर इंजीनियरिंग प्रक्रिया का एक अहम हिस्सा है. यूनिट टेस्ट एक खास तरह का टेस्ट है, जो सोर्स कोड के एक छोटे मॉड्यूल के फ़ंक्शन की जांच करता है.यूनिट की जांच इंजीनियर हमेशा करते हैं. आम तौर पर, यूनिट की जांच उसी समय की जाती है जब वे मॉड्यूल की कोडिंग करते हैं. कंपोज़र और डेटाबेस क्लास की जांच करने के लिए, आपने जिन टेस्ट ड्राइवर का इस्तेमाल किया है वे यूनिट टेस्ट के उदाहरण हैं.

यूनिट टेस्ट में ये विशेषताएं होती हैं. वे...

  • आइसोलेशन में किसी कॉम्पोनेंट की जांच करना
  • सारणिक होते हैं
  • आम तौर पर, एक क्लास पर मैप करता है
  • डेटाबेस, फ़ाइलें, नेटवर्क जैसे बाहरी संसाधनों की निर्भरता से बचें
  • तेज़ी से काम करना
  • को किसी भी क्रम में चलाया जा सकता है

ऐसे अपने-आप काम करने वाले फ़्रेमवर्क और तरीके उपलब्ध हैं जो बड़े सॉफ़्टवेयर इंजीनियरिंग संगठनों में यूनिट टेस्टिंग के लिए सहायता और एक जैसे तरीकों का इस्तेमाल करते हैं. कुछ बेहतरीन ओपन सोर्स यूनिट टेस्टिंग फ़्रेमवर्क हैं जिनके बारे में हम इस लेख में आगे सीखेंगे. 

यूनिट टेस्टिंग के तहत होने वाले टेस्ट का उदाहरण नीचे दिया गया है.

आम तौर पर, हम इन चीज़ों की जांच करते हैं:

  1. मॉड्यूल इंटरफ़ेस की जांच यह पक्का करने के लिए की जाती है, ताकि यह पक्का किया जा सके कि जानकारी सही तरीके से अंदर और बाहर जा रही है.
  2. लोकल डेटा स्ट्रक्चर की जांच की जाती है, ताकि यह पक्का किया जा सके कि वे सही तरीके से डेटा सेव कर रहे हैं.
  3. सीमा की स्थितियों की जांच की जाती है, ताकि यह पक्का किया जा सके कि मॉड्यूल उन सीमाओं पर ठीक से काम करता है जो प्रोसेसिंग को सीमित या सीमित करती हैं.
  4. हम मॉड्यूल पर इंडिपेंडेंट पाथ की जांच करते हैं, ताकि यह पक्का किया जा सके कि हर पाथ को कम से कम एक बार एक्ज़ीक्यूट किया गया हो. इस तरह, मॉड्यूल में हर स्टेटमेंट को कम से कम एक बार एक्ज़ीक्यूट किया गया हो. 
  5. आखिर में, हमें यह जांच करनी होगी कि गड़बड़ियां ठीक से की गई हैं या नहीं.

कोड कवरेज

असल में, हम टेस्टिंग के दौरान पूरी "कोड कवरेज" नहीं पा सकते. कोड कवरेज, विश्लेषण का एक तरीका है. इससे यह तय होता है कि टेस्ट केस सुइट ने सॉफ़्टवेयर सिस्टम के किन हिस्सों का इस्तेमाल किया है और कौनसे हिस्से नहीं चलाए गए हैं. अगर हम कोशिश करते हैं और 100% कवरेज हासिल कर लेते हैं, तो हम असल कोड लिखने के बजाय, यूनिट टेस्ट लिखने में ज़्यादा समय बिताएंगे! नीचे दिए गए सभी इंडिपेंडेंट पाथ के लिए, यूनिट टेस्ट करें. यह जल्द ही एक बड़ी समस्या बन सकती है.

इस डायग्राम में, लाल रेखाओं की जांच नहीं की गई है, जबकि बिना रंग वाली लाइनों की जांच की गई है.

पूरी तरह कवरेज देने के बजाय, हम सिर्फ़ उन जांचों पर ध्यान देते हैं जिनसे हमें यह भरोसा होता है कि मॉड्यूल ठीक से काम कर रहा है. हम इन चीज़ों के लिए जांच करते हैं:

  • शून्य केस
  • रेंज टेस्ट, जैसे कि पॉज़िटिव/नेगेटिव वैल्यू टेस्ट
  • किनारे वाले केस
  • असफलता के मामले
  • उन पाथ की जांच करना जो ज़्यादातर समय चल सकते हैं

यूनिट टेस्ट फ़्रेमवर्क

ज़्यादातर यूनिट टेस्ट फ़्रेमवर्क, किसी पाथ के चलने के दौरान वैल्यू की जांच करने के लिए, दावे का इस्तेमाल करते हैं. दावा ऐसे स्टेटमेंट होते हैं जिनसे यह पता चलता है कि कोई शर्त सही है या नहीं. दावा करने का नतीजा यह हो सकता है कि वह सफल हो, उसमें कोई गलती न हो या कोई गंभीर गड़बड़ी हो. दावा करने के बाद, कार्यक्रम सामान्य रूप से तब जारी रहता है, जब नतीजा सफल हो या कोई गंभीर समस्या न हो. अगर कोई गंभीर फ़ेल होता है, तो मौजूदा फ़ंक्शन रद्द कर दिया जाता है.

टेस्ट में ऐसा कोड होता है जो स्थिति सेट करता है या आपके मॉड्यूल में बदलाव करता है. इसके अलावा, इसमें कई ऐसे दावे भी होते हैं जिनसे उम्मीद के मुताबिक नतीजे मिलते हैं. अगर किसी टेस्ट में सभी दावे कामयाब होते हैं, यानी कि 'सही' दिखाता है, तो जांच हो जाती है. ऐसा नहीं होने पर पुष्टि नहीं होती.

टेस्ट केस में एक या कई टेस्ट होते हैं. हम टेस्ट को टेस्ट केस के हिसाब से ग्रुप में बांटते हैं. इससे पता चलता है कि जांच किए गए कोड का स्ट्रक्चर कैसा है. इस कोर्स में, हम सीपीपीयूनी को यूनिट टेस्ट फ़्रेमवर्क के तौर पर इस्तेमाल करने जा रहे हैं. इस फ़्रेमवर्क की मदद से, हम C++ में यूनिट टेस्ट लिख सकते हैं और उन्हें अपने-आप चला सकते हैं. इससे, जांच की सफलता या असफलता की रिपोर्ट मिलती है.

CPPUnit इंस्टॉलेशन

SourceForge से CPPUnit कोड डाउनलोड करें. कोई सही डायरेक्ट्री ढूंढें और वहां tar.gz फ़ाइल रखें. इसके बाद, सही cppunit फ़ाइल का नाम डालकर ये निर्देश (Linux, Unix में) डालें:

gunzip filename.tar.gz
tar -xvf filename.tar

अगर आप Windows में काम कर रहे हैं, तो हो सकता है कि आपको tar.gz फ़ाइलों को निकालने के लिए एक सुविधा ढूंढने की ज़रूरत पड़े. अगला चरण लाइब्रेरी को कंपाइल करना है. cppunit डायरेक्ट्री में बदलें. वहां एक INSTALL फ़ाइल मौजूद है, जिससे खास निर्देश दिए गए हैं. आम तौर पर, आपको इन टेस्ट को पूरा करना होता है:

./configure
make install

अगर आपको समस्याएं आती हैं, तो INSTALL फ़ाइल देखें. लाइब्रेरी आम तौर पर, cppunit/src/cppunit डायरेक्ट्री में मौजूद होती हैं. यह देखने के लिए कि कंपाइलेशन काम कर रहा है या नहीं, cppunit/examples/सिंपल डायरेक्ट्री में जाएं और "make" टाइप करें. अगर सबकुछ ठीक से इकट्ठा होता है, तो इसका मतलब है कि आप पूरी तरह से तैयार हैं.

इसका एक बेहतरीन ट्यूटोरियल यहां दिया गया है. कृपया इस ट्यूटोरियल को देखें और कॉम्प्लेक्स नंबर क्लास और उससे जुड़े यूनिट टेस्ट बनाएं. cppunit/examples डायरेक्ट्री में कई और उदाहरण मौजूद हैं.

मुझे ऐसा क्यों करना होगा?",

इंडस्ट्री में यूनिट टेस्टिंग बहुत ज़रूरी है. इसकी कई वजहें हैं. आपको इसकी एक वजह तो पता है: कोड डेवलप करने के दौरान, हमें अपने काम की जांच करने के लिए किसी तरीके की ज़रूरत होती है. यहां तक कि जब हम एक बहुत छोटा प्रोग्राम बना रहे होते हैं, तब भी हम मन से जांच करने का कोई तरीका लिखते हैं, ताकि यह पक्का किया जा सके कि हमारा प्रोग्राम उम्मीद के मुताबिक काम करे.

लंबे अनुभव से, इंजीनियरों को पता है कि पहली कोशिश में ही कोई प्रोग्राम काम करने की बहुत कम संभावना है. यूनिट टेस्ट की मदद से इस आइडिया को आधार बनाया जाता है. ऐसा करने के लिए, टेस्टिंग प्रोग्राम को खुद से जांच करने की सुविधा दी जाती है और बार-बार इस्तेमाल किया जा सकता है. दावा किए गए दावे, आउटपुट की मैन्युअल तरीके से जांच करते हैं. साथ ही, नतीजों को आसानी से समझा जा सकता है (टेस्ट पास या फ़ेल हो जाता है), इसलिए इन टेस्ट को बार-बार चलाया जा सकता है. इससे आपको एक ऐसा सुरक्षा तरीका मिलता है जिससे कोड को बदलने में आसानी होती है.

इसे आसान शब्दों में समझ लें: तैयार किया गया कोड पहली बार CVS में सबमिट करने पर, यह बहुत अच्छी तरह से काम करता है. और कुछ समय तक यह बेहतरीन तरीके से काम करता रहता है. फिर एक दिन, कोई और आपका कोड बदल देगा. जल्द ही या बाद में, कोई व्यक्ति आपका कोड हैक कर लेगा. क्या आपको लगता है कि वे अपने-आप ध्यान देंगे? संभावना नहीं है. हालांकि, जब यूनिट टेस्ट लिखे जाते हैं, तो कुछ ऐसे सिस्टम होते हैं जो इन्हें हर दिन अपने-आप चला सकते हैं. इन्हें लगातार इंटिग्रेशन सिस्टम कहा जाता है. इसलिए, जब वह इंजीनियर X आपका कोड तोड़ता है, तो सिस्टम उसे तब तक खराब ईमेल भेजेगा, जब तक वह उस कोड को ठीक नहीं कर देता. भले ही, इंजीनियर X आप ही हों!

सॉफ़्टवेयर डेवलप करने, और बदलाव होने पर उस सॉफ़्टवेयर को सुरक्षित रखने में मदद करने के अलावा, यूनिट टेस्टिंग:

  • एक एक्ज़ीक्यूटेबल स्पेसिफ़िकेशन और दस्तावेज़ बनाता है, जो कोड के साथ सिंक में रहते हैं. दूसरे शब्दों में, यह जानने के लिए यूनिट टेस्ट पढ़ा जा सकता है कि मॉड्यूल किस तरह के काम करता है.
  • ज़रूरी शर्तों को अलग-अलग लागू करने में मदद करता है. बाहरी लोगों को दिखने वाले व्यवहार पर ज़्यादा ज़ोर देने की वजह से, आपको इसे लागू करने के तरीकों को आपस में जोड़ने के बजाय, साफ़ तौर पर इस बारे में सोचने का मौका मिलता है.
  • प्रयोग करने की सुविधा उपलब्ध है. किसी मॉड्यूल के काम करने के तरीके में गड़बड़ी होने पर, अगर आपके पास सुरक्षा का कोई ऐसा जाल है जो आपको चेतावनी दे सके, तो चीज़ों को आज़माने और अपने डिज़ाइन को फिर से कॉन्फ़िगर करने की संभावना बढ़ जाती है.
  • आपके डिज़ाइन को बेहतर बनाता है. यूनिट टेस्ट के बारे में पूरी जानकारी लिखने के लिए, अक्सर आपको अपने कोड को ज़्यादा टेस्ट करने लायक बनाना पड़ता है. जांच न किए जा सकने वाले कोड के मुकाबले, टेस्ट किया जा सकने वाला कोड अक्सर ज़्यादा मॉड्यूलर होता है.
  • क्वालिटी बेहतरीन बनाए रखता है. किसी गंभीर सिस्टम में छोटे-छोटे बग की वजह से कंपनी को लाखों डॉलर का नुकसान हो सकता है. इतना ही नहीं, उपयोगकर्ता की खुशी या भरोसा भी कम हो सकता है. यूनिट टेस्ट से मिलने वाले सुरक्षा के उपाय इस संभावना को कम करते हैं. इसकी मदद से, QA टीमों को शुरुआत में ही गड़बड़ियों का पता चल जाता है. इससे, वे गड़बड़ियों की रिपोर्ट करने के बजाय, बेहतर और मुश्किल से मुश्किल स्थितियों पर समय दे पाते हैं.

कंपोज़र डेटाबेस ऐप्लिकेशन के लिए, CPPUnit का इस्तेमाल करके, यूनिट की जांच लिखने के लिए कुछ समय निकालें. सहायता के लिए, cppunit/examples/ डायरेक्ट्री देखें.

Google कैसे काम करता है

शुरुआती जानकारी

कल्पना करें कि मध्य युग में एक साधु, अपने मठ के संग्रह में मौजूद हज़ारों पांडुलिपियों को देख रहा है.“अरस्तू का गाना कहां है...”

मॉनेस्टेरी लाइब्रेरी

उनकी अच्छी बात यह है कि यहां पांडुलिपियों को कॉन्टेंट के हिसाब से व्यवस्थित किया गया है. साथ ही, उनमें खास चिह्नों की जानकारी दी गई है, ताकि हर किताब में मौजूद जानकारी को आसानी से हासिल किया जा सके. इस तरह के संगठन के बिना, काम की पांडुलिपि को खोजना बहुत मुश्किल होगा.

बड़े कलेक्शन की लिखित जानकारी को सेव करने और वापस पाने की गतिविधि को जानकारी वापस पाने (आईआर) कहते हैं. सदियों से, इस गतिविधि की अहमियत बढ़ती गई है. खास तौर पर, काग़ज़ और प्रिंटिंग प्रेस जैसे आविष्कारों के साथ. यह कुछ ऐसा हुआ करता था जिसमें सिर्फ़ कुछ ही लोगों के लिए कोई जगह थी. हालांकि, अब करोड़ों लोग हर दिन किसी सर्च इंजन का इस्तेमाल करके या अपने डेस्कटॉप पर खोज करके, जानकारी पाने के काम में लगे रहते हैं.

जानकारी वापस पाने की प्रोसेस शुरू करना

टोपी पहनी हुई बिल्ली

डॉक्टर सूस ने 30 सालों में बच्चों की 46 किताबें लिखी हैं. उनकी किताबों में बिल्लियों, गायों, और हाथियों के बारे में जानकारी दी गई थी. क्या तुम्हें याद है कि किस कहानी में कौनसे जीव थे? जब तक आप माता-पिता नहीं होते, तब तक सिर्फ़ बच्चे ही आपको बता सकते हैं कि डॉक्टर सूस की कहानियों में किस तरह के जीव हैं:

(COW और BEE) या CROWS

इस समस्या को हल करने के लिए, हम जानकारी वापस पाने वाले कुछ क्लासिक मॉडल लागू करेंगे.

एक सामान्य तरीका है ब्रूट फ़ोर्स: डॉक्टर सीयूस की सभी 46 कहानियां इकट्ठा करें और पढ़ना शुरू करें. हर किताब के लिए देखें कि किस किताब में COW और BEE शब्द शामिल हैं. साथ ही, उन किताबों को भी खोजें जिनमें CROWS शब्द मौजूद है. इसमें कंप्यूटर बहुत तेज़ी से काम कर रहे हैं. अगर हमारे पास Dr. Seuss की किताबों का पूरा टेक्स्ट, डिजिटल फ़ॉर्मैट में है, जैसे कि टेक्स्ट फ़ाइलों के तौर पर, तो हम फ़ाइलों को बड़ा कर सकते हैं. डॉक्टर सूस की किताबों जैसे छोटे संग्रह के लिए, यह तकनीक सबसे अच्छी तरह काम करती है.

हालांकि, ऐसी कई स्थितियां हैं जिनमें हमें ज़्यादा की ज़रूरत होती है. उदाहरण के लिए, इस समय ऑनलाइन इकट्ठा किया गया सारा डेटा इतना बड़ा है कि grep को मैनेज नहीं कर सकता. हम सिर्फ़ उन दस्तावेज़ों को ही नहीं चाहते जो हमारी शर्तों के मुताबिक हों. हमने इस तरह के दस्तावेज़ों को उनकी प्रासंगिकता के हिसाब से रैंक किया है.

ग्रेप के अलावा एक और तरीका है, खोज करने से पहले कलेक्शन में दस्तावेज़ों की एक इंडेक्स बनाना. आईआर में मौजूद इंडेक्स, टेक्स्टबुक के पीछे मौजूद इंडेक्स की तरह होता है. हम डॉक्टर सियस की हर कहानी में मौजूद सभी शब्दों (या शर्तें) की एक सूची बनाते हैं. इस सूची में “द”, “और”, दूसरे कई शब्दों, पूर्वसर्ग वगैरह को शामिल नहीं किया जाता. (इन्हें स्टॉप-वर्ड कहा जाता है). इसके बाद, हम इस जानकारी को इस तरह से दिखाते हैं कि इसमें शब्द ढूंढने और उन खबरों की पहचान करने में आसानी हो जिनमें वे शामिल हैं.

उदाहरण के लिए, ऐसा मैट्रिक्स हो सकता है जिसमें सबसे ऊपर की कहानियां हों और हर लाइन में शब्द हों. किसी कॉलम में “1” दिखने का मतलब है कि उस कॉलम की स्टोरी में वह शब्द दिखता है.

किताबों और शब्दों की टेबल

हम हर पंक्ति या कॉलम को बिट वेक्टर के रूप में देख सकते हैं. लाइन का बिट वेक्टर बताता है कि वह शब्द किस स्टोरी में दिखता है. कॉलम का बिट वेक्टर बताता है कि स्टोरी में कौनसे शब्द दिखेंगे.

अपने मूल सवाल पर लौटते हैं:

(COW और BEE) या CROWS

हम इन शब्दों के लिए बिट वेक्टर लेते हैं और पहले हम थोड़ा-बहुत AND इस्तेमाल करते हैं. इसके बाद, नतीजों को थोड़ा-बहुत तिरछा करते हैं.

(100001 और 010011) या 000010 = 000011

जवाब: “मिस्टर ब्राउन कैन मू! क्या यू?” और “The Lorax”. यह बूलियन रिट्रीवल मॉडल का इलस्ट्रेशन है, जो “एग्ज़ैक्ट मैच” मॉडल है.

मान लीजिए कि हमें मैट्रिक्स को बड़ा करना था, ताकि उसमें डॉक्टर सूस की सभी कहानियां और काम के सभी शब्द शामिल किए जा सकें. मैट्रिक्स काफ़ी बड़ा होगा और एक अहम निगरानी यह है कि ज़्यादातर एंट्री 0 होंगी. ऐसा हो सकता है कि इंडेक्स के लिए मैट्रिक्स को सबसे सही तरीके से न दिखाया जाए. हमें सिर्फ़ 1's को सेव करने का तरीका ढूंढने की ज़रूरत है.

बेहतर बनाने के कुछ तरीके

इस समस्या को हल करने के लिए IR में इस्तेमाल की जाने वाली संरचना को इनवर्टेड इंडेक्स कहा जाता है. हम शब्दों का शब्दकोश बनाते हैं और फिर हर शब्द के लिए, हमारे पास एक सूची होती है जिसमें उन दस्तावेज़ों को रिकॉर्ड किया जाता है जिनमें वह शब्द इस्तेमाल हुआ है. इस सूची को पोस्टिंग सूची कहा जाता है. एक साथ लिंक की गई सूची इस स्ट्रक्चर को बेहतर तरीके से दिखाती है, जैसा कि यहां दिखाया गया है.

अगर आपको लिंक की गई सूचियों के बारे में नहीं पता है, तो "C++ में लिंक की गई सूची" पर जाकर Google Search में खोजें. यहां आपको ऐसे कई संसाधन मिल जाएंगे जिनमें ऐसी सूची बनाने और उसके इस्तेमाल के बारे में जानकारी दी गई है. हम बाद के मॉड्यूल में इस बारे में ज़्यादा जानकारी देंगे.

ध्यान दें कि हम कहानी के नाम की जगह, दस्तावेज़ आईडी (DocIDs) का इस्तेमाल करते हैं. हम इन दस्तावेज़ों को क्रम से भी लगाते हैं, क्योंकि इनसे क्वेरी प्रोसेस करने में मदद मिलती है.

हम किसी क्वेरी को कैसे प्रोसेस करते हैं? मूल समस्या के लिए, हम पहले COW की पोस्ट की सूची देखते हैं. इसके बाद, बीईई की पोस्ट से जुड़ी सूची ढूंढते हैं. फिर हम उन्हें एक साथ “मर्ज” करते हैं:

  1. दोनों सूचियों में मार्कर रखें और एक साथ दो पोस्ट सूचियों पर जाएं.
  2. हर चरण में, दोनों पॉइंटर से दिखाए गए DocID की तुलना करें.
  3. अगर वे एक जैसे हैं, तो उस DocID को नतीजे की सूची में रखें या फिर छोटे docID की ओर इशारा करने वाले पॉइंटर को आगे बढ़ाएं.

यहां बताया गया है कि हम कोई इन्वर्टेड इंडेक्स कैसे बना सकते हैं:

  1. अपनी पसंद के हर दस्तावेज़ के लिए एक DocID असाइन करें.
  2. हर दस्तावेज़ के लिए, उससे जुड़े शब्दों (टोकनाइज़) की पहचान करें.
  3. हर शब्द के लिए, एक रिकॉर्ड बनाएं. इस रिकॉर्ड में शब्द, जहां वह दस्तावेज़ मौजूद है, और उस दस्तावेज़ में कितनी फ़्रीक्वेंसी होगी. ध्यान दें कि अगर किसी शब्द का नाम एक से ज़्यादा दस्तावेज़ों में है, तो उसके लिए कई रिकॉर्ड हो सकते हैं.
  4. रिकॉर्ड को शब्द के हिसाब से क्रम में लगाएं.
  5. किसी शब्द के एक-एक रिकॉर्ड को प्रोसेस करके शब्दकोश और पोस्ट की सूची बनाएं. साथ ही, एक से ज़्यादा दस्तावेज़ों में दिखने वाले शब्दों के एक से ज़्यादा रिकॉर्ड को भी जोड़ें. DocID की लिंक की गई सूची (क्रम से लगाए गए) बनाएं. हर शब्द के लिए एक अलग फ़्रीक्वेंसी भी होती है, जो किसी शब्द के सभी रिकॉर्ड की फ़्रीक्वेंसी का कुल योग होती है.

प्रोजेक्ट

ऐसे कई लंबे सादे टेक्स्ट दस्तावेज़ ढूंढें जिनके साथ आप प्रयोग कर सकते हैं. इस प्रोजेक्ट में, ऊपर बताए गए एल्गोरिदम का इस्तेमाल करके, दस्तावेज़ों से एक इन्वर्टेड इंडेक्स बनाया जाता है. क्वेरी के इनपुट के लिए, आपको एक इंटरफ़ेस और उन्हें प्रोसेस करने के लिए एक इंजन भी बनाना होगा. आपको फ़ोरम में प्रोजेक्ट पार्टनर मिल सकता है.

यहां इस प्रोजेक्ट को पूरा करने की एक संभावित प्रक्रिया दी गई है:

  1. सबसे पहले, दस्तावेज़ों में शब्दों की पहचान करने के लिए एक रणनीति तय करें. उन सभी स्टॉप-शब्दों की एक सूची बनाएं जिनके बारे में आप सोच सकते हैं. एक ऐसा फ़ंक्शन लिखें जो फ़ाइलों में मौजूद शब्दों को पढ़ता हो, शब्दों को सेव करता हो, और स्टॉप-शब्दों को हटा देता हो. शब्दों की सूची को बार-बार देखने पर, आपको अपनी सूची में और स्टॉप-शब्द जोड़ने पड़ सकते हैं.
  2. अपने फ़ंक्शन की जांच करने के लिए सीपीपीयूनिट टेस्ट केस लिखें. साथ ही, अपने बिल्ड में सभी चीज़ों को एक साथ लाने के लिए एक मेकफ़ाइल भी लिखें. अपनी फ़ाइलों को CVS में जांचें. खास तौर पर तब, जब किसी पार्टनर के साथ काम किया जा रहा हो. आप इस बारे में रिसर्च कर सकते हैं कि रिमोट इंजीनियर के लिए अपना CVS इंस्टेंस कैसे खोला जाए.
  3. जगह की जानकारी का डेटा शामिल करने के लिए प्रोसेसिंग जोड़ें. जैसे, कौनसी फ़ाइल और फ़ाइल किस जगह पर मौजूद है? पेज नंबर या पैराग्राफ़ नंबर को तय करने के लिए, आपको कोई कैलकुलेशन करनी चाहिए.
  4. इस अतिरिक्त काम की क्षमता की जाँच करने के लिए CPPUnit के टेस्ट केस लिखें.
  5. इन्वर्टेड इंडेक्स तैयार करें और हर टर्म के रिकॉर्ड में जगह की जानकारी का डेटा स्टोर करें.
  6. ज़्यादा टेस्ट केस लिखें.
  7. उपयोगकर्ता को क्वेरी दर्ज करने की अनुमति देने के लिए इंटरफ़ेस डिज़ाइन करें.
  8. ऊपर बताए गए खोज एल्गोरिदम का इस्तेमाल करके, इन्वर्टेड इंडेक्स को प्रोसेस करें और उपयोगकर्ता को जगह की जानकारी का डेटा दिखाएं.
  9. इस आखिरी हिस्से में टेस्ट केस भी शामिल करना न भूलें.

हम सभी प्रोजेक्ट पर काम कर चुके हैं. प्रोजेक्ट पार्टनर ढूंढने और आइडिया शेयर करने के लिए, फ़ोरम और चैट का इस्तेमाल करें.

एक और सुविधा

कई आईआर सिस्टम में आम तौर पर होने वाले प्रोसेसिंग चरण को स्टेमिंग कहा जाता है. स्टेमिंग के पीछे मुख्य मकसद यह है कि “डेटा वापस पाना” पर जानकारी खोजने वाले उपयोगकर्ताओं की दिलचस्पी उन दस्तावेज़ों में भी होगी जिनमें “वापस पाना”, “फिर से हासिल किया गया”, “वापस पाना” वगैरह शामिल हों. खराब स्टेमिंग की वजह से, सिस्टम में गड़बड़ियों का खतरा हो सकता है. इसलिए, यह प्रोसेस थोड़ा मुश्किल है. उदाहरण के लिए, “जानकारी वापस पाने” में दिलचस्पी रखने वाले उपयोगकर्ता को स्टेमिंग की वजह से, “गोल्डन रिट्रीवर के बारे में जानकारी” नाम से कोई दस्तावेज़ मिल सकता है. स्टेमिंग के लिए एक उपयोगी एल्गोरिदम पोर्टर एल्गोरिदम है.

ऐप्लिकेशन: कहीं भी जाएं!

Panoramas.dk पर जाकर, इन सिद्धांतों से जुड़ा यह ऐप्लिकेशन देखें.