कॉपी करने के बिना सी # डबल [] सरणी को डबल [] में परिवर्तित करना संभव है

मेरे पास .NET अनुप्रयोग में संख्याओं का विशाल 3 डी सरणी है। मुझे उन्हें एक COM पुस्तकालय में पास करने के लिए उन्हें 1 डी सरणी में परिवर्तित करने की आवश्यकता है। क्या सभी डेटा की एक प्रति बनाये बिना सरणी को बदलने का कोई तरीका है?

मैं इस तरह के रूपांतरण कर सकता हूं, लेकिन फिर मैं दो बार स्मृति की मात्रा का उपयोग करता हूं जो मेरे आवेदन में एक मुद्दा है:

  double[] result = new double[input.GetLength(0) * input.GetLength(1) * input.GetLength(2)];
  for (i = 0; i < input.GetLength(0); i++) 
    for (j = 0; j < input.GetLength(1); j++) 
      for (k = 0; k < input.GetLength(2); k++) 
        result[i * input.GetLength(1) * input.GetLength(2) + j * input.GetLength(2) + k)] = input[i,j,l];
  return result;
0

5 उत्तर

दुर्भाग्यवश, सी # सरणी को संगत स्मृति में होने की गारंटी नहीं है जैसे कि वे सी-तो, नं। एक तत्व-दर-तत्व प्रति के बिना डबल [] से डबल [] को परिवर्तित करने का कोई तरीका नहीं है।

0
जोड़ा

अपनी COM लाइब्रेरी के विवरण जानने के बिना, मैं .NET में एक मुखौटा वर्ग बनाने और यदि आवश्यक हो, तो COM को उजागर करने के लिए देखता हूं।
आपका मुखौटा एक डबल ले जाएगा [] और एक सूचकांक है जो [] से [] तक मैप करेगा।

संपादित करें: मैं टिप्पणियों में किए गए अंकों के बारे में सहमत हूं, लोरेंस सुझाव बेहतर है।

0
जोड़ा
मैं COM पुस्तकालय को बदलने में सक्षम नहीं हूं।
जोड़ा लेखक Hallgrim, स्रोत
यह काम नहीं करेगा। शाब्दिक डबल [] सरणी रखने के लिए COM आवश्यकता होगी। यदि कुछ भी हो, तो आप एक .NET क्लास बनाना चाहते हैं जिसने डबल [] अधिनियम को डबल की तरह बनाया []।
जोड़ा लेखक Jonathan Rupp, स्रोत

एक कामकाज के रूप में आप एक वर्ग बना सकते हैं जो सरणी को एक आयामी रूप में रखता है (शायद यहां तक ​​कि नंगे धातु के रूप में भी, ताकि आप इसे आसानी से COM लाइब्रेरी में पास कर सकें?) और उसके बाद ऑपरेटर [] को इस वर्ग पर अधिभारित करने के लिए अधिभारित करें आपके सी # कोड में एक बहुआयामी सरणी के रूप में।

0
जोड़ा

मुझे विश्वास नहीं है कि जिस तरह से सी # स्टोर करता है कि स्मृति में डेटा इसे सीए में एक साधारण कलाकार के समान ही व्यवहार्य बना देगा। क्यों शुरू करने के लिए 1 डी सरणी का उपयोग न करें और शायद इस प्रकार के लिए कक्षा बनाएं ताकि आप इसे अपने प्रोग्राम में एक्सेस कर सकें जैसे कि यह 3 डी सरणी थी?

0
जोड़ा

प्रॉक्सी के साथ डेटा तक पहुंच को इंगित करने पर विचार करें (सी ++ में इटरेटर/स्मार्ट-पॉइंटर्स के समान) । दुर्भाग्यवश, सिंटैक्स सी ++ के रूप में उतना साफ नहीं है जितना ऑपरेटर() ओवरलोड और ऑपरेटर के लिए उपलब्ध नहीं है [] एकल-तर्क है, लेकिन अभी भी बंद है।

बेशक, इस अतिरिक्त स्तर का अमूर्तता जटिलता और स्वयं का काम जोड़ती है, लेकिन यह आपको मौजूदा कोड में न्यूनतम परिवर्तन करने की अनुमति देगी जो डबल [] ऑब्जेक्ट्स का उपयोग करती है, जबकि आप दोनों के लिए एक डबल [] सरणी का उपयोग करने की अनुमति देते हैं इंटरऑप और आपके इन-सी # गणना।

class Matrix3
{
   //referece-to-element object
    public struct Matrix3Elem{
        private Matrix3Impl impl;
        private uint dim0, dim1, dim2;
       //other constructors
        Matrix3Elem(Matrix3Impl impl_, uint dim0_, uint dim1_, uint dim2_) {
            impl = impl_; dim0 = dim0_; dim1 = dim1_; dim2 = dim2_;
        }
        public double Value{
            get { return impl.GetAt(dim0,dim1,dim2); }
            set { impl.SetAt(dim0, dim1, dim2, value); }
        }
    }

   //implementation object
    internal class Matrix3Impl
    {
        private double[] data;
        uint dsize0, dsize1, dsize2;//dimension sizes
       //.. Resize() 
        public double GetAt(uint dim0, uint dim1, uint dim2) {
           //.. check bounds
            return data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ];
        }
        public void SetAt(uint dim0, uint dim1, uint dim2, double value) {
           //.. check bounds
            data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ] = value;
        }
    }

    private Matrix3Impl impl;

    public Matrix3Elem Elem(uint dim0, uint dim1, uint dim2){
        return new Matrix2Elem(dim0, dim1, dim2);
    }
   //.. Resize
   //.. GetLength0(), GetLength1(), GetLength1()
}

और फिर इस प्रकार का उपयोग पढ़ने और लिखने के लिए - 'foo [1,2,3]' अब 'foo.Elem (1,2,3)। वैल्यू' के रूप में लिखा गया है, दोनों पढ़ने मूल्यों और लेखन मानों में, पर असाइनमेंट और मूल्य अभिव्यक्ति के बाईं तरफ।

void normalize(Matrix3 m){

    double s = 0;
    for (i = 0; i < input.GetLength0; i++)     
        for (j = 0; j < input.GetLength(1); j++)       
            for (k = 0; k < input.GetLength(2); k++)
    {
        s += m.Elem(i,j,k).Value;
    }
    for (i = 0; i < input.GetLength0; i++)     
        for (j = 0; j < input.GetLength(1); j++)       
            for (k = 0; k < input.GetLength(2); k++)
    {
        m.Elem(i,j,k).Value /= s;
    }
}

फिर, विकास लागत में वृद्धि हुई, लेकिन डेटा साझा करता है, ओवरहेड की प्रतिलिपि हटाता है और संबंधित विकास लागत की प्रतिलिपि बनाता है। यह एक व्यापार है।

0
जोड़ा