1 डी सरणी पर 2 डी सरणी का नक्शा बनाएं


90

मैं 1 डी सरणी के साथ 2 डी सरणी का प्रतिनिधित्व करना चाहता हूं। एक फ़ंक्शन दो संकेत (एक्स, वाई) और स्टोर करने के लिए मूल्य पारित करेगा। ये दो संकेत 1D सरणी के एकल तत्व का प्रतिनिधित्व करते हैं, और उसी के अनुसार इसे सेट करते हैं। मुझे पता है कि 1D सरणी में arrayWidth × arrayHeight का आकार होना चाहिए, लेकिन मुझे नहीं पता कि प्रत्येक तत्व को कैसे सेट किया जाए।

उदाहरण के लिए, मैं (4,2,3) से (2,4,3) कैसे भेद करूं? मैंने x * y के रूप में सरणी सेट करने की कोशिश की, लेकिन 2 * 4 और 4 * 2 के परिणामस्वरूप सरणी में एक ही स्थान होगा और मुझे उन्हें अलग करने की आवश्यकता होगी।

जवाबों:


163

आपको यह तय करने की आवश्यकता है कि क्या सरणी तत्वों को पंक्ति क्रम या स्तंभ क्रम में संग्रहीत किया जाएगा और फिर इसके बारे में संगत होना चाहिए। http://en.wikipedia.org/wiki/Row-major_order

C भाषा बहुआयामी सरणियों के लिए पंक्ति क्रम का उपयोग करती है

एकल आयामी सरणी के साथ इसे अनुकरण करने के लिए, आप पंक्ति सूचकांक को चौड़ाई से गुणा करते हैं, और कॉलम इंडेक्स को इस प्रकार जोड़ते हैं:

 int array[width * height];

 int SetElement(int row, int col, int value)
 {
    array[width * row + col] = value;  
 }

7
मुझे लगता है कि यह उत्तर अधिक स्पष्ट है, खासकर शुरुआती लोगों के लिए यह बेहतर है कि वे एक पंक्ति में फ़ंक्शन न लिखें ... !! यह वैसे भी बुरा व्यवहार है .. :)
लाइपिस

3
यह उत्तर उस समय के लिए भी उपयोगी होता है जब आपके पास एक कंपाइलर (जैसे एम्बेडेड सिस्टम) होता है जिसमें उचित बहुआयामी सरणी समर्थन नहीं होता है
एलेक्स मार्शल

1
यह आश्चर्यजनक है कि कितने लोग एक ही प्रश्न का सही उत्तर दे सकते हैं, लेकिन उनमें से केवल एक ही इसे इस तरह से कहता है जिसे समझना आसान है। यह एक उत्तर के रूप में सरल है क्योंकि यह हो जाता है। हालांकि, जॉन केवल एक ही है जो वास्तव में इसके लिए एक अच्छा जवाब प्रदान करता है। शेष सभी कचरा है जो केवल उन लोगों द्वारा आसानी से समझा जा सकता है जो पहले से ही उत्तर जानते हैं। धन्यवाद जॉन, वास्तव में विदेशी के बजाय अंग्रेजी में बोलने के लिए। बस यह दिखाने के लिए जाता है कि कुछ लोग शिक्षण में कितने बुरे हैं, और जॉन नोवेलर जैसे अच्छे शिक्षक कैसे जानते हैं कि कैसे सरलता और हर किसी की तुलना में अधिक प्रभावी ढंग से संवाद करना है।
user2948630

6
यह दिखाने के लिए अच्छा होगा कि इस मैपिंग को कैसे उल्टा किया जाए: यदि 1 डी सरणी का सूचकांक है alpha, और 2 डी सरणी का Nसूचकांकों के साथ दोनों दिशाओं में आयाम है x, y, तो @ जॉन्कॉनलर के अनुसार alpha=x+N*y,। इसका उल्टा तरीका सेटिंग x=alpha%Nऔर होगा y= (alpha-alpha%N)/N
टिम

मैं लगभग हर दिन यहाँ आता हूँ!
फेलिप गुटिरेज

23

1 डी सरणी सूचकांक में 2 डी सरणी सूचकांकों की पुनर्गणना के लिए सामान्य सूत्र है

index = indexX * arrayWidth + indexY;

वैकल्पिक रूप से आप उपयोग कर सकते हैं

index = indexY * arrayHeight + indexX;

(यह मानते हुए कि arrayWidthएक्स अक्ष के साथ मापा जाता है, और arrayHeightवाई अक्ष के साथ)

बेशक, कोई भी कई अलग-अलग फ़ार्मुलों के साथ आ सकता है जो वैकल्पिक अद्वितीय मैपिंग प्रदान करते हैं, लेकिन आम तौर पर इसकी कोई आवश्यकता नहीं है।

C / C ++ में अंतर्निहित बहुआयामी सरणियों को मेमोरी में संग्रहीत किया जाता है ताकि अंतिम इंडेक्स सबसे तेजी से बदले, जिसका अर्थ है कि घोषित ऐरे के लिए

int xy[10][10];

तत्व xy[5][3]तुरंत xy[5][4]स्मृति में है। आप उस कन्वेंशन को फॉलो करना चाह सकते हैं, उपरोक्त दो फॉर्मूलों में से एक को चुनना, जिसके आधार पर आप इंडेक्स (X या Y) को दो में से "अंतिम" मानते हैं।


17

उदाहरण: हम SIZE_X और SIZE_Y आकार के 2D सरणी का प्रतिनिधित्व करना चाहते हैं। इसका मतलब है कि हमारे पास MAXX आकार की MAXY लगातार पंक्तियाँ होंगी। इसलिए सेट फंक्शन है

void set_array( int x, int y, int val ) { array[ x * SIZE_Y + y ] = val; }

यह होगा:

int get_array( int x, int y ) { return array[ x * SIZE_Y + y ]; }

1
आपका MAXXऔर MAXYमूल्यों भ्रमित करने वाले नाम हैं, की वजह से अधिकतम मान xऔर yकर रहे हैं MAXX - 1और MAXY - 1क्रमशः। शायद SIZE_Xऔर SIZE_Yबेहतर हो सकता है?
कैफे

3
[y * maxx + x] स्तंभ क्रम है, पंक्ति क्रम नहीं। यह वह तरीका है जो मतलाब काम करता है, लेकिन जिस तरह से आम तौर पर सी में काम करता है,
वैसा नहीं होता है

@ हर कोई: जब तक आप डेटा को छुआ नहीं रखेंगे, लेकिन विशुद्ध रूप से ये दोनों मिलेंगे / सेट कार्य करेंगे, और वे एक ही सूत्र का उपयोग करते हैं, आप इसे THIS की तरह या THAT की तरह कर सकते हैं। (गारंटी!)
१ '

एक मैक्रो यहां अधिक उपयुक्त हो सकता है, इसलिए आप अनावश्यक फ़ंक्शन कॉल को स्टैक नहीं कर रहे हैं जो निम्न-स्तरीय डेटा एक्सेस माना जाता है (विशेषकर चूंकि छद्म -2 डी सरणियों में 1d-indexing कभी-कभी एक अनुकूलन तकनीक है।
krs013

यह मानते हुए कि कोड एक वर्ग का सदस्य है, यह कोड इनलेट हो जाएगा। अन्यथा स्पष्ट इनलाइन है ज्यादा एक मैक्रो की तुलना में बेहतर।
कोर्नेल किसिलेविकज

7

जैसा कि अन्य ने कहा है कि सी मानचित्र पंक्ति क्रम में हैं

   #include <stdio.h>

   int main(int argc, char **argv) {
   int i, j, k;
   int arr[5][3];
   int *arr2 = (int*)arr;

       for (k=0; k<15; k++) {
          arr2[k] = k;
          printf("arr[%d] = %2d\n", k, arr2[k]);
       }

       for (i=0; i<5; i++) {
         for (j=0; j< 3; j++) {
            printf("arr2[%d][%d] = %2d\n", i, j ,arr[i][j]);
         }
       } 
    } 

आउटपुट:

arr[0] =  0
arr[1] =  1
arr[2] =  2
arr[3] =  3
arr[4] =  4
arr[5] =  5
arr[6] =  6
arr[7] =  7
arr[8] =  8
arr[9] =  9
arr[10] = 10
arr[11] = 11
arr[12] = 12
arr[13] = 13
arr[14] = 14
arr2[0][0] =  0
arr2[0][1] =  1
arr2[0][2] =  2
arr2[1][0] =  3
arr2[1][1] =  4
arr2[1][2] =  5
arr2[2][0] =  6
arr2[2][1] =  7
arr2[2][2] =  8
arr2[3][0] =  9
arr2[3][1] = 10
arr2[3][2] = 11
arr2[4][0] = 12
arr2[4][1] = 13
arr2[4][2] = 14

3

पंक्ति प्रमुख उदाहरण का उपयोग कर:

A(i,j) = a[i + j*ld]; // where ld is the leading dimension
                      // (commonly same as array dimension in i)

// matrix like notation using preprocessor hack, allows to hide indexing
#define A(i,j) A[(i) + (j)*ld]

double *A = ...;
size_t ld = ...;
A(i,j) = ...;
... = A(j,i);

1

डेटा को इस तरह से संग्रहित करना महत्वपूर्ण है कि इसे उपयोग की जाने वाली भाषाओं में पुनर्प्राप्त किया जा सके। पंक्ति-प्रमुख क्रम में सी-भाषा स्टोर (पहली पंक्ति के सभी पहले आते हैं, फिर दूसरी पंक्ति के सभी, ...) 0 से चल रहे प्रत्येक सूचकांक के साथ आयाम -1 है। तो सरणी x [2] [3] का क्रम x [0] [0], x [0] [1], x [0] [2], x [1] [0], x [1] [है] 1], x [1] [2]। तो सी भाषा में, x [i] [j] को 1-आयामी सरणी प्रविष्टि X1dim [i * 3 + j] के समान स्थान पर संग्रहीत किया जाता है। यदि डेटा को इस तरह संग्रहीत किया जाता है, तो सी भाषा को पुनः प्राप्त करना आसान है।

फोरट्रान और MATLAB अलग हैं। वे कॉलम-मेजर ऑर्डर में स्टोर करते हैं (पहले कॉलम के सभी पहले आते हैं, फिर सभी दूसरी पंक्ति के, ...) और हर इंडेक्स 1 से इसके आयाम तक चलता है। इसलिए इंडेक्स ऑर्डर सी का उल्टा है और सभी सूचकांक 1 से अधिक हैं। यदि आप सी भाषा क्रम में डेटा संग्रहीत करते हैं, तो FORTRAN X_C_language [i] [j] X_FORTRAN (j + 1, i + 1) का उपयोग कर पा सकते हैं। उदाहरण के लिए, X_C_language [1] [2] X_FORTRAN (3,2) के बराबर है। 1-आयामी सरणियों में, वह डेटा मान X1dim_C_language [2 * Cdim2 + 3] पर है, जो X1dim_FORTRAN (2 * Fdim1 + 3 + 1) के समान स्थिति है। याद रखें कि Cdim2 = Fdim1 क्योंकि सूचकांकों का क्रम उल्टा है।

MATLAB FORTRAN के समान है। Ada समान रूप से C को छोड़कर सूचकांकों को सामान्य रूप से 1 पर शुरू करता है। किसी भी भाषा में C या FORTRAN आदेशों में से किसी एक में सूचकांक होंगे और सूचकांक 0 या 1 से शुरू होंगे और संग्रहीत डेटा पर प्राप्त करने के लिए तदनुसार समायोजित किए जा सकते हैं।

क्षमा करें यदि यह स्पष्टीकरण भ्रामक है, लेकिन मुझे लगता है कि प्रोग्रामर के लिए यह जानना सही और महत्वपूर्ण है।


-2

आपको जगह में एक साधारण सूचक के साथ 2d सरणी तक पहुंचने में सक्षम होना चाहिए। सरणी [x] [y] को सूचक में p [0x * चौड़ाई + 0y] [0x * चौड़ाई + 1y] ... [0x * चौड़ाई + n-1y] [1x * चौड़ाई + 0y] आदि के रूप में व्यवस्थित किया जाएगा। ।

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