इस डेटा को संग्रहीत करने का सबसे कुशल तरीका क्या है?


9

मैं कुछ पुराने VB कोड के पुनर्लेखन का प्रभारी हूं। मैं समझता हूं कि यह कैसे काम करता है, लेकिन मुझे ऐसा लगता है कि उन्होंने जो किया वह करने के लिए कहीं अधिक कुशल तरीका है। मैं अभी पता नहीं लगा सकता कि यह क्या है। यहाँ एक आकस्मिक उदाहरण है कि डेटा आवश्यकताओं के संदर्भ में वास्तव में मैं क्या करने की आवश्यकता के समान है।

उपयोगकर्ता को अपनी कार के निर्माता, मेक, मॉडल और रंग को GUI में चुनना होगा। मेरे पास एक बड़ी टेक्स्ट फ़ाइल है जो कुछ इस तरह दिखती है:

Ford Truck F150 red
Ford Truck F150 blue
Ford Truck F150 black
Ford Truck F150 silver
Ford Truck F250 red
Ford Truck F250 green
Ford Sedan Taurus red
Ford Sedan Taurus green
Ford Sedan Taurus white
Ford...
...

Subaru SUV Forester blue
Subaru SUV Forester red
Subaru SUV Outback Black
Subaru SUV Outback Green
Subaru SUV Outback Blue
Subaru SUV Outback Red
Subaru...
...

etc.

इसलिए यदि पहला चयन सुबारू है, तो दूसरे बॉक्स (मेक) में ट्रक का चयन करने का विकल्प नहीं होना चाहिए क्योंकि कोई भी सुबारू ट्रक नहीं है। इसी तरह, यदि वे फोर्ड, सेडान और वृषभ का चयन करते हैं, तो अंतिम बॉक्स (रंग) को नीले रंग का चयन करने का विकल्प नहीं दिखाना चाहिए । या काला। या लाल, हरे या सफेद के अलावा कुछ भी।

मेरे साथ आने से पहले लोगों ने जो कोड लिखा था, वह (अजगर-य psuedocode में) था:

def getValidOptions():
    items = []
    for i from 0 to numRows:
        options = getLine().split()
        if selectingManufacturer:
            if options[0] not in items:
                items.append(options[0])
        else if selectingMake:
            if selectedManufacturer == options[0] and options[1] not in items:
               items.append(options[1])
        else if selectingModel:
            if selectedManufacturer == options[0] and selectedMake == options[1] and options[2] not in items:
                items.append(options[2])
        else if selectingColor:
            if selectedManufacturer == options[0] and selectedMake == options[1] and selectedModel == options[2] and options[3] not in items:
                items.append(options[3])
    return items

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

मैं या तो फ़ाइल में डेटा संग्रहीत करने के एक अलग तरीके की तलाश कर रहा हूं, या getValidOptionsफ़ंक्शन को अधिक सुंदर और अधिक कुशल बनाने के लिए इसे पार्स करने का एक अलग तरीका । क्या ऐसा कोई तरीका है जिससे मैं ऐसा कर सकूं?


2
डेटाबेस का उपयोग क्यों नहीं करते?
ट्यूलेंस कोरडोवा

जवाबों:


6

मेरे द्वारा पढ़े गए अन्य सभी उत्तर सॉफ्टवेयर विकास के दो बहुत ही बुनियादी नियमों की अनदेखी करते हैं:

  • आवश्यकताओं को पहले स्पष्ट करें (विशेषकर प्रदर्शन और भंडारण आवश्यकताओं)

  • यह सरल रखें, बेवकूफ (देखें KISS )

आपने "पाठ फ़ाइल बड़ी है" लिखी है, लेकिन बहुत बड़ी नहीं लिखी है , इसलिए मुझे लगता है कि वास्तव में आपके आकार के अलावा कुछ भी गलत नहीं है। इसलिए यदि फ़ाइल लोड करना वास्तव में बहुत लंबा नहीं होता है, और आपका आईटी विभाग या कोई अन्य व्यर्थ डिस्क स्थान के बारे में शिकायत नहीं करता है, और किसी को भी फाइल को बनाए रखने में कोई समस्या नहीं है, तो फ़ाइल प्रारूप को वैसे ही रहने दें - जैसे कि कम मत समझना। सादगी का मूल्य।

आप एल्गोरिथ्म की दक्षता के बारे में भी शिकायत कर रहे हैं, जो वास्तव में उतना कुशल नहीं है जितना कि यह हो सकता है, लेकिन इसका एक बहुत बड़ा लाभ है: यह मस्तिष्क-मृत सरल है और काम करता है। इसलिए जब तक यह पर्याप्त कुशल है, तब तक किसी भी समय से पहले अनुकूलन लागू न करें।

तो मान लें कि कार्यक्रम काफी तेजी से काम करता है, आपको पहले क्या पूछना चाहिए कि आप सादगी और DRY सिद्धांत के संदर्भ में कोड को कैसे सुधार सकते हैं? और यह वास्तव में एक बिंदु है जिसे सुधारना चाहिए, क्योंकि वर्तमान कोड DRY नहीं है। आपके उदाहरण में, लगभग समान कोड ब्लॉक परीक्षण में चार बार दिखाई देता है यदि "उच्च स्तर" पर विकल्प वर्तमान लाइन से मेल खाते हैं, जिसके परिणामस्वरूप चार बार एक ही तरह का "एपेंड" कॉल होता है (आपके वास्तविक कोड में, पुनरावृत्ति होती है कम से कम छह बार, जैसा कि आपने लिखा)। आप आसानी से एक संख्यात्मक चयन स्तर की शुरुआत करके, या पहले से ही चयनित विकल्पों को क्रमबद्ध सूची में पास करके इससे बच सकते हैं। अपने छद्म कोड का उपयोग करके, यह कुछ की तर्ज पर होता है

# selectedOptions is a list, containing either nothing, or "selectedManufacturer"
# or [selectedManufacturer, selectedMake], ..., and so on
def getValidOptions(selectedOptions):
    items = []
    level = selectedOptions.size()
    for i from 0 to numRows:
        options = getLine().split()
        if selectedOptions == options[0:level-1] and options[level] not in item:
            items.append(options[level])
    return items

तो यह अनिवार्य रूप से एक ही एल्गोरिथ्म है जिसमें कोई दोहराया गया कोड नहीं है।

चूंकि यह स्पष्ट है कि इसे एक getValidOptionsसे अधिक बार (कम से कम एक बार प्रति स्तर) कहा जाना चाहिए, मैं केवल एक अनुकूलन लागू करने का सुझाव देता हूं (यदि यह पहले से ही मामला नहीं है): सुनिश्चित करें कि getLineफ़ंक्शन मुख्य मेमोरी से अपना डेटा खींचता है, और नहीं करता है डिस्क से फाइल को बार-बार पढ़ें।


आप numRows लूप से पहले "स्तर = selectOptions.size ()" को स्थानांतरित करना चाहते हैं।
एआई ब्रेवेरी

6

ठीक है, आपके पास एक पेड़ जैसी संरचना है, जहां प्रत्येक निर्माता के लिए आपके पास मॉडल का एक पेड़ है, और प्रत्येक मॉडल के लिए आपके पास एक रंग है (और इसी तरह)।

इसलिए, आप दो चरणों में इस डेटा की प्रक्रिया को अलग कर सकते हैं:

  1. पाठ फ़ाइल के किसी भी अद्यतन के बाद, आपको उस फ़ाइल को संसाधित करना होगा और इसे पेड़ की संरचना में बदलना होगा।
  2. एप्लिकेशन लोड करते समय, आप केवल ट्री संरचना को लोड करते हैं।

पेड़ की संरचना को एक हैश , एक सहयोगी सरणी या जावा, PHP, जावास्क्रिप्ट या पायथन जैसी भाषाओं में एक शब्दकोश कहा जाता है । इस संरचना के साथ, आपके पास:

  • पहली कुंजी निर्माता हैं।
  • उनके मूल्य सिर्फ एक और हैश या शब्दकोश हैं जहां प्रत्येक कुंजी मॉडल है।
  • उनके मूल्य रंग हैं। या किसी अन्य संरचना को उनकी कुंजी में तीसरे स्तर पर रखते हुए और चौथे स्तर को महत्व देते हैं।
  • और इसी तरह...

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

  • C # : आप ट्री संरचना 1 को कार्यान्वित कर सकते हैं , और फिर इसे क्रमबद्ध रूप में चिह्नित कर सकते हैं।
  • VB.Net : आप एक अनुप्रयोग में ट्री संरचना उत्पन्न कर सकते हैं, और इसे एक फ़ाइल में क्रमबद्ध कर सकते हैं।
    • इसके लिए, ऐसा कुछ Runtime.Serialization.Formatters.Binary.BinaryFormatterउपयोगी हो सकता है, लेकिन मैं VB.Net के साथ अनुक्रमित करने में कोई विशेषज्ञ नहीं हूं।
  • जावास्क्रिप्ट : आप एक JSON फ़ाइल में ट्री संरचना उत्पन्न कर सकते हैं, जिसे हर बार ऐप लोड होने पर लोड किया जाना चाहिए।
  • PHP : आप ट्री डेटा संरचना का क्रमबद्ध संस्करण तैयार कर सकते हैं, या आप JSON को भी लोड कर सकते हैं।
  • जावा : आप उस डेटा संरचना को क्रमबद्ध कर सकते हैं, Classजो इंटरफ़ेस को लागू करता है java.io.Serializable

संदर्भ :

1: https://dvanderboom.wordpress.com/2008/03/15/treet-implementing-a-non-binary-tree-in-c/
- C # में एक पेड़ को लागू करने पर एक पूर्ण विवरण।
- एक टिप्पणी के लिए देखें जहां कोई उस वस्तु को क्रमबद्ध करने के बारे में पूछता है , और उस टिप्पणी के लिए उत्तर।


1
हाँ, मैंने एक पेड़ का उपयोग करने के बारे में सोचा था, लेकिन मुझे नहीं पता कि यह सबसे अच्छा विचार है क्योंकि C # में पेड़ की संरचना (जो मुझे पता है) में निर्मित नहीं है, और परियोजना बहुत छोटी है, इसलिए मुझे पता नहीं है कि क्या यह एक tree with an arbitrary number of nodesकार्यान्वयन पर काम करने में बहुत समय बिताने के लिए इसके लायक होगा ।
जेम्स

अभी तक मैं C # के साथ कोई विशेषज्ञ नहीं हूं, लेकिन कम से कम अन्य भाषाओं जैसे कि जावा और PHP में आपके पास कुछ प्रकार के शब्दकोष हो सकते हैं, जहां प्रत्येक कुंजी में दूसरे शब्दकोश के मूल्य हो सकते हैं।
निकोलस

मैंने अपना उत्तर अपडेट कर दिया। देखें कि आप हैश या शब्दकोश विकल्प के बारे में क्या सोचते हैं। मैंने एक दिलचस्प लेख के साथ एक संदर्भ भी जोड़ा।
निकोलस

3

डेटा को संग्रहीत करने का एक सरल तरीका यह है कि इसे किसी SQLite डेटाबेस में भर दिया जाए। अधिकांश SQL डेटाबेस के विपरीत, SQLite, अनुप्रयोग फ़ाइल प्रारूप के रूप में उपयोग के लिए अच्छी तरह से अनुकूल है। इस दृष्टिकोण के कई लाभ हैं:

  1. एक सीरियल कोड या एक deserializer कोड की जरूरत नहीं है।
  2. फ़ाइल कई मौजूदा कार्यक्रमों द्वारा संपादन योग्य और क्वेरी योग्य है।
  3. प्रश्न में आपके द्वारा उल्लेखित सशर्त गड़बड़ी से बचा जाता है। ड्रॉपडाउन को सीमित करने के लिए, प्रत्येक कॉलम (जैसे, select distinct model where manufacturer='ford' and color = 'red') के विरुद्ध एक सरल शब्द उत्पन्न करें ।

यह आपको एसक्यूएल सीखने के लिए मजबूर करता है, लेकिन कस्टम फ़ाइल प्रारूप सीखने की आवश्यकता से बचा जाता है।


1

मुझे लगता है कि आप फ़ाइल में बेतरतीब ढंग से लाइनों का उपयोग कर सकते हैं, और इस प्रकार फ़ाइल को रिकॉर्ड के एक सरणी के रूप में मान सकते हैं। यदि आप लाइनों को बेतरतीब ढंग से एक्सेस नहीं कर सकते हैं, तो आपके पास मौजूद एल्गोरिथ्म सबसे अच्छा है जो आप कर सकते हैं।

तेजी से पहुंच के लिए, डेटा को 6 फ़ाइलों में संग्रहीत करें, जहां प्रत्येक फ़ाइल अगले में एक इंडेक्स है।

फ्लैटफाइल इंडेक्स बनाने के लिए mny तरीके हैं। मैं आमतौर पर एक सबस्क्रिप्ट रेंज का उपयोग करता हूं। जैसा कि उपयोगकर्ता प्रत्येक चयन करता है, अगली फ़ाइल के पढ़ने को सीमित करने के लिए सीमा का उपयोग करें।

यहां बताया गया है कि मैं आपके द्वारा प्रदान किए गए नमूना डेटा के लिए सूचकांक कैसे बनाऊंगा।

बेशक फ़ाइल को सॉर्ट किया जाना चाहिए। मैंने चित्रण के लिए पंक्तियों को गिना है; फ़ाइल में लाइन नंबर नहीं दिखना चाहिए।

--| file3.dat |--
 0 Ford Truck F150 red
 1 Ford Truck F150 blue
 2 Ford Truck F150 black
 3 Ford Truck F150 silver
 4 Ford Truck F250 red
 5 Ford Truck F250 green
 6 Ford Sedan Taurus red
 7 Ford Sedan Taurus green
 8 Ford Sedan Taurus white
 9 Subaru SUV Forester blue
10 Subaru SUV Forester red
11 Subaru SUV Outback Black
12 Subaru SUV Outback Green
13 Subaru SUV Outback Blue
14 Subaru SUV Outback Red

पहला इंडेक्स बनाने के लिए, फ़ाइल में पहले तीन फ़ील्ड्स के प्रत्येक अनूठे संयोजन के लिए रिकॉर्ड बनाएं। प्रत्येक रिकॉर्ड में, पहली और अंतिम पंक्ति संख्याओं को संग्रहीत करें जिसमें संयोजन दिखाई देता है।

--| file2.dat |--
 0 Ford Truck F150       0   3
 1 Ford Truck F250       4   5
 2 Ford Sedan Taurus     6   8
 3 Subaru SUV Forester   9  10
 4 Subaru SUV Outback   11  14

पहले सूचकांक के पहले दो क्षेत्रों का उपयोग करके, दूसरे सूचकांक का निर्माण इसी तरह किया जाता है।

--| file1.dat |--
 0 Ford Truck        0   1
 1 Ford Sedan        2   2
 2 Subaru SUV        3   4

और तीसरा, इस मामले में शीर्ष स्तर, सूचकांक।

--| file0.dat |--
 0 Ford          0   1
 1 Subaru        2   2

मुझे लगता है कि मैं अवधारणा को ओवरएक्सप्लेन कर रहा हूं, लेकिन सामान्य तौर पर आप अंतिम फ़ील्ड को हटाकर और डुप्लिकेट रिकॉर्ड को समाप्त करके एक सूचकांक बनाते हैं।

आप कुछ अनावश्यक डेटा को समाप्त करके फ़ाइल संग्रहण आवश्यकता को कम कर सकते हैं।

उदाहरण के लिए, प्रत्येक सूचकांक रिकॉर्ड में "पहला" सबस्क्रिप्ट हमेशा पूर्व रिकॉर्ड के "अंतिम" सबस्क्रिप्ट से एक अधिक होता है, या कोई पूर्व रिकॉर्ड नहीं होने पर शून्य। तो आपको "पहले" सदस्यता स्टोर करने की आवश्यकता नहीं है। मैं उन्हें चित्रण के लिए नीचे छोड़ रहा हूँ।

इसके अलावा, चूंकि आप चयन सूची को भरने के लिए प्रत्येक रिकॉर्ड में केवल अंतिम फ़ील्ड का उपयोग करेंगे, इसलिए आपको अन्य फ़ील्ड को संग्रहीत करने की आवश्यकता नहीं है।

इंडेक्स कैस्केड का न्यूनतम प्रतिपादन इस तरह दिखता है, जहां टिक 'एक संख्या को वास्तव में फ़ाइल में संग्रहीत नहीं होने का संकेत देता है।

--| file0.dat |--
 0' Ford         0'   1
 1' Subaru       2'   2

--| file1.dat |--
 0' Truck        0'   1
 1' Sedan        2'   2
 2' SUV          3'   4

--| file2.dat |--
 0' F150         0'   3
 1' F250         4'   5
 2' Taurus       6'   8
 3' Forester     9'  10
 4' Outback     11'  14

--| file3.dat |--
 0' red
 1' blue
 2' black
 3' silver
 4' red
 5' green
 6' red
 7' green
 8' white
 9' blue
10' red
11' Black
12' Green
13' Blue
14' Red

जब आप किसी इंडेक्स से चयन सूची भरते हैं, तो आप पढ़ी गई लाइनों को सीमित करने के लिए पिछले इंडेक्स में उपयोगकर्ता के चयन से "पहले" और "अंतिम" सदस्यता का उपयोग करते हैं।

उदाहरण:

आप सभी से पहली चयन सूची भरें file0.dat। (फोर्ड, सुबारू)

उपयोगकर्ता "फोर्ड" का चयन करता है। संबंधित सदस्यताएं 0 और 1 हैं।

आप दूसरी चयन सूची को लाइनों में से 1 के माध्यम से भरें file1.dat। (ट्रक, सेडान)

उपयोगकर्ता "सेडान" का चयन करता है। इसी सदस्यता 2 और 2 हैं।

जैसा कि आप देख सकते हैं, जब तक उपयोगकर्ता ने चयन किया है, उदाहरण के लिए, "फोर्ड" "सेडान" "वृषभ", तो आप पाएंगे कि आपको file3.datचौथी चयन सूची को भरने के लिए केवल 6 पंक्तियों के माध्यम से 6 पंक्तियों को पढ़ने की आवश्यकता है ।

मैं लंबे समय तक वर्णन के लिए माफी माँगता हूँ, लेकिन यहाँ बहुत देर हो चुकी है और मेरे पास एक छोटा लिखने का समय नहीं है।

जोड़ा: आगे के विचार पर, फ़ाइलों को एक में समेटा जा सकता है।

--| file.dat |--
 0' -            1'   2
 1' Ford         3'   4
 2' Subaru       5'   5
 3' Truck        6'   7
 4' Sedan        8'   8
 5' SUV          9'  10
 6' F150        11'  14
 7' F250        15'  16
 8' Taurus      17'  19
 9' Forester    20'  21
10' Outback     22'  25
11' red          -'   -
12' blue         -'   -
13' black        -'   -
14' silver       -'   -
15' red          -'   -
16' green        -'   -
17' red          -'   -
18' green        -'   -
19' white        -'   -
20' blue         -'   -
21' red          -'   -
22' Black        -'   -
23' Green        -'   -
24' Blue         -'   -
25' Red          -'   -

इसका उपयोग कई फ़ाइल संस्करण की तरह ही किया जाता है, सिवाय इसके कि आपको पहली सबस्क्रिप्ट रेंज में डमी फर्स्ट लाइन की आवश्यकता होती है।

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