2010-11-16 17 views
10

मैं युगल की एन-आयामी सरणी बनाना चाहता हूं। संकलन समय पर, आयामों की संख्या n ज्ञात नहीं है।एन-आयामी ऐरे

मैंने सरणी को एक शब्दकोश के रूप में परिभाषित कर दिया, जिसमें कुंजी विभिन्न अक्षों से संबंधित इंक की सरणी है (इसलिए 3-आयामी सरणी में, मैं [5, 2, 3] की आपूर्ति करता हूं सरणी में (5, 2, 3) पर डबल।

हालांकि, मुझे डिक्शनरी (0, 0, ... 0) से (एम 1, एम 2, ... एमएन) के साथ शब्दकोश को पॉप्युलेट करने की भी आवश्यकता है। , जहां एम 1 से एमएन प्रत्येक धुरी की लंबाई है।

मेरा प्रारंभिक विचार नेस्टेड फॉर-लूप बनाने के लिए था, लेकिन जैसा कि मुझे अभी भी पता नहीं है कि मुझे कितने की आवश्यकता होगी (प्रत्येक आयाम के लिए 1), मैं कर सकता हूं संकलन समय पर ऐसा नहीं करें।

मैं हो पे मैंने प्रश्न को समझ में लाया है, लेकिन मुझे विस्तार से भागों से पूछने के लिए स्वतंत्र महसूस करें।

+0

सरणी का उपयोग कैसे किया जाएगा? –

+0

इसका उपयोग फैक्टोरियल मार्कोव रैंडम फील्ड गणनाओं में किया जाएगा, जहां हमारे पास प्रत्येक में एम सेगमेंट के साथ एन परतें हैं। हम प्रत्येक मनाए गए मूल्य के लिए प्रत्येक मनाए गए मूल्य, या निरंतर मूल्यों के मामले में, दो matrices, साधनों और भिन्नता के लिए संभावनाओं का एक मैट्रिक्स बनाना चाहते हैं। – SimonPip

उत्तर

6

इस मामले पर एक त्वरित फॉलोअप:

हमने सफलता के साथ Array.CreateInstance विधि का उपयोग किया, लेकिन जैसा कि किसी ने भविष्यवाणी की थी, यह काफी अक्षम था, और इसके अतिरिक्त पठनीयता समस्याओं को भी बनाया गया था।

इसके बजाय, हमने एक विधि विकसित की है, जहां एन-आयामी सरणी को 1-आयामी (सामान्य) सरणी में परिवर्तित किया गया है।

public static int NDToOneD(int[] indices, int[] lengths) 
{ 
    int ID = 0; 
    for (int i = 0; i < indices.Length; i++) 
    { 
    int offset = 1; 
    for (int j = 0; j < i; j++) 
{ 
     offset *= lengths[j]; 
} 
    ID += indices[i] * offset; 
    } 
    return ID; 
} 

1DtoND(int[] indices, int[] arrayLengths) 
{ 
    int[] indices = new int[lengths.Length]; 
    for (int i = lengths.Length - 1; i >= 0; i--) 
    { 
    int offset = 1; 
    for (int j = 0; j < i; j++) 
    { 
     offset *= lengths[j]; 
    } 
    int remainder = ID % offset; 
    indices[i] = (ID - remainder)/offset; 
    ID = remainder; 
    } 
    return indices; 
} 

यह अनिवार्य रूप से एक पूर्णांक में कार्टेशियन निर्देशांक के रूपांतरण पर एक सामान्यीकरण है और फिर से वापस।

हमारे परीक्षण को औपचारिक रूप से लागू नहीं किया गया है, इसलिए हमने जो भी गति प्राप्त की है, वह पूरी तरह से अचूक है, लेकिन मेरी मशीन के लिए, नमूना आकार के आधार पर, यह 30-50% गति प्रदान करता है, और कोड की पठनीयता में सुधार हुआ है एक व्यापक मार्जिन द्वारा।

आशा है कि इससे किसी भी व्यक्ति को इस प्रश्न पर ठोकरने में मदद मिलेगी।

0

आप एक बहुआयामी सरणी का उपयोग क्यों नहीं करते: double[,,] array = new double[a,b,c]? सभी सरणी तत्व स्वचालित रूप से आपके लिए 0.0 में प्रारंभ किए जाते हैं।

वैकल्पिक रूप से, आप एक दांतेदार सरणी double[][][] इस्तेमाल कर सकते हैं, लेकिन प्रत्येक उप सरणी एक for पाश में प्रारंभ करने की आवश्यकता होगी:

int a, b, c; 
double[][][] array = new double[a][][]; 

for (int i=0; i<a; i++) { 
    double[i] = new double[b][]; 

    for (int j=0; j<b; j++) { 
     double[i][j] = new double[c]; 
    } 
} 

संपादित करें: नहीं पता था आयाम की संख्या रन-टाइम था। ऊपर एक और जवाब जोड़ा गया।

+1

क्योंकि मुझे संकलन समय पर आयामों की संख्या पता नहीं है।क्षमा करें, अगर (5, 2, 3) उदाहरण आपको भ्रमित कर देता है। यह भी हो सकता है (5, 3, 2, 8, 7, 6, 32)। :) – SimonPip

15

एक n आयामी सरणी बनाने के लिए, आप Array.CreateInstance विधि का उपयोग कर सकते हैं:

Array array = Array.CreateInstance(typeof(double), 5, 3, 2, 8, 7, 32)); 

array.SetValue(0.5d, 0, 0, 0, 0, 0, 0); 
double val1 = (double)array.GetValue(0, 0, 0, 0, 0, 0); 

array.SetValue(1.5d, 1, 2, 1, 6, 0, 30); 
double val2 = (double)array.GetValue(1, 2, 1, 6, 0, 30); 

सरणियों को पॉप्युलेट करने के लिए आप वर्तमान आयाम की लंबाई वापस जाने के लिए Rank संपत्ति और GetLength विधि का उपयोग कर सकते हैं, का उपयोग करते हुए छोरों के लिए नेस्टेड की एक जोड़ी एक हे ऐसा करने के लिए (एन^मी) algo (चेतावनी - अपरीक्षित):

private bool Increment(Array array, int[] idxs, int dim) { 
    if (dim >= array.Rank) return false; 

    if (++idxs[idxs.Length-dim-1] == array.GetLength(dim)) { 
     idxs[idxs.Length-dim-1] = 0; 
     return Increment(array, idxs, dim+1); 
    } 
    return true; 
} 

Array array = Array.CreateInstance(typeof(double), ...); 
int[] idxs = new int[array.Rank]; 
while (Increment(array, idxs, 0)) { 
    array.SetValue(1d, idxs); 
} 
संबंधित मुद्दे