सामग्री पर जाएँ
Topos Uranos

सारांश

अब तक पाठ्यक्रम का हर संग्रह एक ही प्रकार का डेटा रखता था: अंक, क़द, तालिका के खाने। लेकिन किसी समस्या की सत्ताओं के कई लक्षण होते हैं, और वे अलग-अलग प्रकार के होते हैं: किसी विद्यार्थी का एक नाम और एक अंक होता है; किसी पुस्तक का एक शीर्षक, एक लेखक और एक वर्ष। यह पाठ रिकॉर्ड प्रस्तुत करता है, वह संयुक्त प्रकार जिसे प्रोग्रामर स्वयं struct से परिभाषित करता है ताकि इन लक्षणों को एक ही नाम के नीचे समूहित कर सके। पाठ रिकॉर्ड के होने के कारण से, यानी समानांतर वेक्टरों की भंगुरता से, शुरू होता है; फिर struct की परिभाषा, प्रारंभिक मान वाले उसके फ़ील्ड, और ब्रेस तथा डेज़िग्नेटेड इनिशियलाइज़र से रिकॉर्ड बनाने पर आता है; उसके बाद फ़ंक्शनों के पैरामीटर और परिणाम के रूप में रिकॉर्ड; रिकॉर्डों के वेक्टर, जिन्हें संरचित बाइंडिंग से ट्रैवर्स किया जाता है और किसी एक फ़ील्ड के अनुसार क्रमबद्ध किया और खोजा जाता है, साथ में स्थिर सॉर्टिंग का प्रश्न; और अंत में किसी समस्या को ऐसे प्रकारों से मॉडल करने की कला पर समाप्त होता है जो उसके क्षेत्र-विषय को प्रतिबिंबित करें।

अधिगम उद्देश्य

  1. फ़ील्डों और प्रारंभिक मानों वाला struct परिभाषित करना, और ब्रेस इनिशियलाइज़ेशन से, डेज़िग्नेटेड इनिशियलाइज़र के साथ भी, रिकॉर्ड बनाना।
  2. ऐसे फ़ंक्शन लिखना जो रिकॉर्ड लेते और लौटाते हैं, पास करने का तरीक़ा चुनते हुए।
  3. प्रक्षेप के साथ std::ranges::sort, std::ranges::stable_sort और std::ranges::find से रिकॉर्डों के वेक्टर को किसी एक फ़ील्ड के अनुसार क्रमबद्ध करना और उसमें खोजना, और स्थिर सॉर्टिंग को अस्थिर सॉर्टिंग से अलग पहचानना।
  4. किसी समस्या के डेटा को रिकॉर्डों से मॉडल करना और यह उचित ठहराना कि कौन-से फ़ील्ड और प्रकार चुने जाते हैं।

डेटा को समूहित करना

समानांतर वेक्टर

मान लीजिए कि किसी प्रोग्राम को किसी समूह के हर विद्यार्थी का नाम, अंक और आयु रखनी है। पाठ तालिकाएँ तक जो देखा गया है उससे, हाथ के पास का हल तीन वेक्टर हैं, हर लक्षण के लिए एक, इस परिपाटी के साथ कि इंडेक्स ii तीनों में एक ही व्यक्ति को दर्शाता है: names[i], grades[i] और ages[i]। इन्हें समानांतर वेक्टर कहते हैं। तालिका काम नहीं आती, क्योंकि उसके सभी खाने एक ही प्रकार के होने चाहिए, और नाम कोई संख्या नहीं है।

C++ प्रोग्राम
#include <algorithm>#include <cstddef>#include <print>#include <string>#include <vector>​int main(){    const std::vector<std::string> names{"आना", "लुइस", "एवा"};    std::vector<int> grades{6, 4, 7};    const std::vector<int> ages{19, 22, 20};    std::ranges::sort(grades);    for (std::size_t i{0}; i < names.size(); ++i) {        std::println("{}: अंक {}, आयु {} वर्ष", names[i], grades[i], ages[i]);    }}
आउटपुट
आना: अंक 4, आयु 19 वर्षलुइस: अंक 6, आयु 22 वर्षएवा: अंक 7, आयु 20 वर्ष

प्रोग्राम विद्यार्थियों को अंक के अनुसार क्रमबद्ध करना चाहता था, और उसने केवल अंकों को क्रमबद्ध किया। वह बिना किसी चेतावनी के कंपाइल होता है, और न मेमोरी त्रुटियों के डिटेक्टर, AddressSanitizer, के पास कुछ बताने को है, न अपरिभाषित व्यवहार के डिटेक्टर, UndefinedBehaviorSanitizer, के पास; फिर भी उसका आउटपुट ग़लत है: आना के 6 अंक थे और वह 4 अंकों के साथ दिखती है। तीनों वेक्टरों को जोड़ने वाली परिपाटी कहीं भी ऐसी जगह लिखी नहीं है जिसे कंपाइलर पढ़ सके, इसलिए उसे तोड़ने से कुछ भी नहीं रोकता। इससे समानांतर वेक्टरों की भंगुरता निकलती है: हर संक्रिया जो किसी अवयव को खिसकाती, जोड़ती या हटाती है, उसे सभी वेक्टरों में, उसी तरह और उसी क्रम में, दोहराना पड़ता है; और किसी एक को भूल जाना ही डेटा को चुपचाप बिगाड़ने के लिए काफ़ी है।

उदाहरणपंक्तियाँ जो बेमेल हो जाती हैं और कार्ड जो पूरे के पूरे खिसकते हैं

तीन समानांतर वेक्टर बनाम कार्डों का एक वेक्टर, जिसमें हर कार्ड में एक व्यक्ति का तीनों डेटा है।

प्रमाण

  1. स्तंभ 0 एक व्यक्ति का वर्णन करता है: names[0], grades[0] और ages[0] आना का नाम, अंक और आयु हैं। इन्हें जोड़ने वाला केवल इंडेक्स है।

  2. std::ranges::sort(grades) केवल एक पंक्ति को फिर से क्रम में लगाता है। बाक़ी दो को इसका पता नहीं चलता: स्तंभ 0 अब आना का नाम, लुइस का अंक और आना की आयु एक साथ रखता है, जो किसी के नहीं हैं।

  3. विकल्प: केवल एक वेक्टर, जिसके अवयव कार्ड हैं। हर कार्ड में एक व्यक्ति का तीनों डेटा होता है, और उनके बीच का संबंध अब इंडेक्स के बारे में कोई परिपाटी नहीं, बल्कि स्वयं कार्ड है।

  4. अंक के अनुसार क्रमबद्ध करना पूरे कार्ड खिसकाता है: लुइस का कार्ड अपने नाम और अपनी आयु के साथ पहले स्थान पर आ जाता है। कोई भी डेटा बाक़ी से अलग नहीं हो सकता, क्योंकि संक्रिया उन्हें अलग-अलग देखती ही नहीं।

यदि ऐसा है, तो समस्या जो माँगती है वह एक ऐसा प्रकार है जिसके मान कार्ड हों: एक मान जिसमें एक नाम, एक अंक और एक आयु हो, और जो एक संपूर्ण वस्तु की तरह कॉपी हो, किसी फ़ंक्शन को पास हो, किसी वेक्टर में रखा जाए और क्रमबद्ध हो। C++ इसे तैयार नहीं देती, क्योंकि हर समस्या के कार्ड अलग होते हैं; लेकिन वह प्रोग्रामर को इसे परिभाषित करने देती है। वही प्रकार रिकॉर्ड है।