डी

2012-04-25 17 views
5

में लाइनों की एक सरणी में फ़ाइल को पढ़ें, लाइनों की सरणी में टेक्स्ट फ़ाइल को पढ़ने का सही तरीका क्या है?डी

string[] readLines(string filename) { 
    auto f = File(filename); 
    scope(exit) f.close(); 
    string[] lines; 

    foreach (str; f.byLine) { 
    lines ~= str.idup; 
    } 

    return lines; 
} 

लेकिन जैसे कि यह एक सरणी प्रति पंक्ति का आकार परिवर्तन है, जो बहुत अक्षम है कर रहा है यह लग रहा है: मैं रोसेटा स्टोन पर निम्नलिखित पाया। मैं में पढ़ा लाइनों की संख्या का ट्रैक रखने और मानक दोहरीकरण विधि

int i = 0; 
    foreach (str; f.byLine) { 
    if (lines.length <= i + 1) { 
     lines.length = lines.length * 2 + 1; 
    } 
    lines[i] = str.idup; 
    i++; 
    } 
    lines.length = i; 

के माध्यम से सरणी का आकार बदलने लेकिन यह है कि मुझे आश्चर्य है कि अगर मैं सिर्फ मानक पुस्तकालय में कुछ अनदेखी नहीं कर रहा हूँ है कि पर्याप्त बॉयलरप्लेट कोड है हो सकता है कि पहले से ही यह मेरे लिए करता है।


संपादित करें: fwend की टिप्पणी अधिक दृश्यता देने: this article विस्तार से बताया गया है कि सरणी संभाजक काम करता है, और क्यों appending

उत्तर

4

वास्तव में क्रम से कुशलता से नियंत्रित किया जाता है, डी सरणी के आरक्षित अंतरिक्ष जब भी दोगुना होगा यह कमरे से बाहर चला जाता है, इसलिए आपको इसे हाथ से करने की आवश्यकता नहीं है। डी'एआर arrays here

+1

मैंने इसके माध्यम से पढ़ा, और सरणी –

+0

में संलग्न होने पर आंतरिक आकार बदलने की रणनीति के बारे में कुछ भी नहीं कहा हाँ, मैं बस इसे देख रहा था, लेकिन मुझे पता है कि यह कैसे काम करता है। अधिक जानकारी के लिए, डी वास्तव में स्मृति के दो आकारों में स्मृति आवंटित करता है, इसलिए अगर सरणी 32 बाइट्स से बड़ी हो जाती है, तो यह 64 बाइट्स के एक हिस्से में फिर से आवंटित की जाएगी। – ricochet1k

+0

ठीक है, धन्यवाद, –

4

आपको शायद शुरुआत में बहुत से पुनर्विक्रय मिलेंगे, लेकिन सरणी बढ़ने के साथ ही इसकी क्षमता बढ़नी चाहिए ताकि आगे बढ़ने के साथ आवंटित होने की संभावना कम हो। आप सरणी की capacity संपत्ति को प्रिंट कर सकते हैं हालांकि यह देखने के लिए कि यह कैसे बढ़ता है।

आप प्रदर्शन जोड़कर के बारे में विशेष रूप से चिंतित हैं, हालांकि, तो आप शायद std.array.Appender का उपयोग करना चाहिए, जिस स्थिति में, अपने कोड कुछ इस तरह दिखेगा:

string[] readLines(string filename) 
{ 
    auto file = File(filename); 
    auto lines = appender!(string[]); 

    foreach(line; file.byLine()) 
     lines.put(to!string(line)); 

    return lines.data; 
} 

Appender अधिक कुशल जोड़कर बनाने के लिए डिजाइन किया गया है और ~= से अधिक कुशल बनाने के लिए जो कुछ भी कर सकता है उसका लाभ उठाएगा।

4

हो सकता है कि यह:

import std.algorithm; 
import std.array; 
import std.file; 

string[] readLines(string input) 
{ 
    Appender!(string[]) result; 
    foreach (line; input.splitter("\n")) 
     result.put(line); 
    return result.data; 
} 

void main() 
{ 
    string input = cast(string)std.file.read("test.d"); 
    string[] lines = readLines(input); 
} 

यह काफी तेजी से होना चाहिए, क्योंकि परिणाम सिर्फ प्रीलोडेड इनपुट स्ट्रिंग की स्लाइस पैदा कर रही है और स्लाइस के आवंटन से नए सरणियों का आवंटन नहीं (अलग खुद को, IOW सूचक + लंबाई खेत)।