2012-10-05 19 views
14

मेरे पास एक बहुआयामी सरणी है, मैं उस सरणी में किसी विशेष तत्व के आस-पास के तत्व प्राप्त करना चाहता हूं।एक सरणी में किसी तत्व के आस-पास के तत्व खोजें

उदाहरण के लिए अगर मैं निम्नलिखित है:

[[1,2,3,4,5,6] 
[8,9,7,5,2,6] 
[1,6,8,7,5,8] 
[2,7,9,5,4,3] 
[9,6,7,5,2,1] 
[4,7,5,2,1,3]] 

कैसे मैं सभी 8 ऊपर से कोई भी तत्व के आसपास तत्वों पाते हैं? और मैं किनारों पर तत्वों का ख्याल कैसे रखूं?

एक तरह से मुझे पता चला है कि इसके लिए 9 लाइन कोड लिखना है, जो स्पष्ट है, लेकिन क्या कोई बेहतर समाधान है?

+6

उपयोग सापेक्ष ('%') किनारों पर मामलों का ख्याल रखना ... – Baz

उत्तर

2
for (i = 0; i < array.length; i++) { 
      for (j = 0; j < array[i].length; j++) { 
       for (x = Math.max(0, i - 1); x <= Math.min(i + 1, array.length); x++) { 
        for (y = Math.max(0, j - 1); y <= Math.min(j + 1, 
          array[i].length); y++) { 
         if (x >= 0 && y >= 0 && x < array.length 
           && y < array[i].length) { 
          if(x!=i || y!=j){ 
          System.out.print(array[x][y] + " "); 
          } 
         } 
        } 
       } 
       System.out.println("\n"); 
      } 
     } 

वाले सभी लोगों को जवाब दे दिया है के लिए धन्यवाद, लेकिन मैं यह पता लगा मैं अभी मिला है, और इसके बाद के संस्करण समाधान है जो this post की मदद से। धन्यवाद फिर से :)

+0

@ vineetrok .. अच्छा है कि आपको एक समाधान मिला .. लेकिन सवाल यहां पोस्ट करने से पहले आपने खोज क्यों नहीं की ?? –

+1

हाँ मैंने किया, लेकिन मैं इस शब्द "आस-पास" तत्वों का उपयोग कर रहा था, जिस क्षण मैंने "पड़ोसी" का उपयोग किया था, मुझे एक और प्रश्न में जवाब मिला: पी – md1hunox

+0

@ विनीत्रोक .. ठीक है .. तो आप इस सवाल को चिह्नित करने के लिए एक जवाब स्वीकार कर सकते हैं हल हो गया .. –

4

(i, j) के लिए -

   (i - 1, j - 1) 
       (i - 1, j) 
       (i - 1, j + 1) 

       (i, j - 1) 
       (i, j + 1) 

       (i + 1, j - 1) 
       (i + 1, j) 
       (i + 1, j + 1) 

अब, किनारों पर, आप num % row == 0 के लिए जाँच कर सकते हैं>, तो इसकी पंक्ति में बढ़त ... और, num % col == 0 तो इसकी स्तंभ धार। ।

एक सूचकांक (i, j) को देखते हुए .. आप में तत्वों पा सकते हैं -:

यहाँ आप कैसे आगे बढ़ सकते हैं है i - 1 के लिए i, और फिर i + 1 के लिए एक पंक्तियां। (नोट: - सूचकांक i के लिए आप सिर्फ j - 1 तक पहुँचने के लिए है, और j + 1)

इसके बाद आप भी row edge और column edge के लिए जाँच कर सकते हैं ..

यहाँ, आप नीचे दिए गए कोड को देखने के कर सकते हैं, कैसे यह भी हो सकता है: -

// Array size 
    int row = 6; 
    int col = 6; 
    // Indices of concern 
    int i = 4; 
    int j = 5; 

    // To the left of current Column 
    int index = i - 1; 
    for (int k = -1; k < 2; k++) { 
     if (index % row > 0 && ((j + k) % col) > 0) { 
      System.out.println(arr[index][j + k]); 
     } 
    } 


    // In the current Column 
    index = i; 

    // Increment is 2 as we don't want (i, j) 
    for (int k = -1; k < 2; k = k + 2) {    
     if (index % row > 0 && ((j + k) % col) > 0) { 
      System.out.println(arr[index][j + k]); 
     } 
    } 

    // To the right of current Column 
    index = i + 1; 
    for (int k = -1; k < 2; k++) { 
     if (index % row > 0 && ((j + k) % col) > 0) { 
      System.out.println(arr[index][j + k]); 
     } 

    } 

अद्यतन: - उपरोक्त कोड आगे सरल किया जा सकता .. लेकिन मैं तुम्हें करने के लिए उस कार्य को छोड़ .. संकेत: -> दिशा जोड़ने - आप वहाँ से पाश के लिए एक कम कर सकते हैं ..

+0

कर रहे हैं कुछ '1's है कि या तो होना चाहिए' मैं 'या' जे' (केस 2 और केस 7)। – Baz

+0

@ रोहित जैन: धन्यवाद, मैंने इसे समझ लिया, लेकिन, मुझे यह है कि मुझे बहुआयामी सरणी के सभी तत्वों के लिए ऐसा करना है, इसलिए मुझे सभी पड़ोसी तत्वों के माध्यम से एक सामान्यीकृत तरीके का पता लगाने की आवश्यकता है – md1hunox

+1

@ vineetrok यदि आप प्रत्येक को बदलते हैं '(i, j)' से '(i% पंक्तियां, जे% cols) 'यह एक सामान्य मामले के रूप में काम करेगा। – Baz

8

आप प्रपत्र

[[-1,-1], [-1,0],[1,0]..and so on] 

और तरीका है जो समन्वय और के माध्यम से दिशा सरणी दोहराता बात लेता में 'दिशा सरणी' का उपयोग कर सकते समन्वय करने के लिए संख्याएं, जांचें इंडेक्स सीमा से बाहर नहीं हैं और परिणाम एकत्रित नहीं हैं। कुछ इस तरह:

private static int[][] directions = new int[][]{{-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0, -1}}; 

static List<Integer> getSurroundings(int[][] matrix, int x, int y){ 
    List<Integer> res = new ArrayList<Integer>(); 
    for (int[] direction : directions) { 
     int cx = x + direction[0]; 
     int cy = y + direction[1]; 
     if(cy >=0 && cy < matrix.length) 
      if(cx >= 0 && cx < matrix[cy].length) 
       res.add(matrix[cy][cx]); 
    } 
    return res; 
} 
+0

हाय, अच्छा समाधान। क्या यह विस्तार करना संभव है, उदाहरण के लिए, आसपास के तत्वों को एक ही इंडेक्स के आस-पास के तत्वों के आंतरिक सेट के आसपास प्राप्त करना संभव है? धन्यवाद। – Unheilig

1

बेस मामले सिर्फ अनुक्रमण स्थानांतरण द्वारा पड़ोसी तत्वों प्राप्त करने के लिए है। (i,j) के लिए यह (i + 1, j), (i - 1, j), किनारों पर आदि

हो जाएगा मैं दो तरीकों का उपयोग करें:

  1. Modulo % ऑपरेटर IndexOutOfBounds अपवाद से बचने के लिए, लेकिन यह कभी कभी गलत तत्वों सूचीकरण के साथ भ्रमित।
  2. डिफ़ॉल्ट तत्व की एक परत के साथ अपने मैट्रिक्स को लपेटें।यह matrices रखने के लिए कुछ extraspace जोड़ता है, लेकिन अपवाद, बहुत ifs और इतने पर पकड़ के बिना अपने कोड को और अधिक पठनीय बनाता है। मैट्रिक्स के रूप में प्रतिनिधित्व भूलभुलैया जब यह चाल अक्सर उपयोग किया जाता है।

उदाहरण: अपने डिफ़ॉल्ट तत्व है 0.

0 0 0 0 0 0 
0 1 2 3 4 0 
0 2 6 7 3 0 
0 1 3 5 7 0 
0 2 4 6 2 0 
0 0 0 0 0 0 

नोट: मत भूलना वास्तविक सरणी आकार के माध्यम से पुनरावृति, विस्तारित नहीं किया।

-1
(x-1, y-1) -> upper left 
(x-1, y) -> left 
(x-1, y+1) -> lower left 

(x, y+1) -> up 
(x, y) -> current position 
(x, y-1) -> down 

(x+1, y+1) -> upper right 
(x+1, y) -> right 
(x+1, y-1) -> lower right 

आप गाइड के रूप में उपयोग कर सकते हैं। अब आपको बस इतना करना है कि उन्हें पकड़ने की कोशिश में जोड़ें।

for(int x=0; x<arr.length; x++){ 
    for(int y=0; y<arr[x].length; y++){ 
    if(arr[x][y] == 8){ 
    try{ 
     System.out.println("Upper Left is: " + arr[x-1][y-1]); 
    }catch(ArrayIndexOutOfBoundsException e){ 
    //do something 
    } 


    try{ 
     System.out.println("Left is: " + arr[x-1][y]); 
    }catch(ArrayIndexOutOfBoundsException e){ 
    //do something 
    } 

    //.....and others 
    } 
    } 
+0

'अपवाद' पकड़ना बहुत खराब शैली है। उचित उपclass का उपयोग करें ... – Baz

+0

आपको 'मॉड्यूलो (%)' ऑपरेटर का उपयोग करके सीमा जांच करना चाहिए .. आपको इस चीज़ के लिए 'try-catch' ब्लॉक' की आवश्यकता नहीं है .. –

+0

@gekkostate यदि आप अपवाद बदलते हैं, तो क्यों नहीं दूसरे को भी बदलें? – Baz

1

यह रूबी में लिखी गई आपकी समस्या का मेरा समाधान है। यदि तत्व किनारे पर है तो गणना करने के बजाय आप किनारे पर "ओवर" तत्वों तक पहुंच सकते हैं और वहां मौजूद "शून्य" मान या अपवादों को संभाल सकते हैं। फिर अंतिम सूची से "शून्य" मान हटा दें। यह समाधान गणना के रूप में उतना अच्छा नहीं है जितना कि "बिंदु" किनारे पर है या नहीं।

big_map = [[1,2,3,4,5,6], 
      [8,9,7,5,2,6], 
      [1,6,8,7,5,8], 
      [2,7,9,5,4,3], 
      [9,6,7,5,2,1], 
      [4,7,5,2,1,3]] 

# monkey patch classes to return nil. 
[NilClass, Array].each do |klass| 
    klass.class_eval do 
     def [](index) 
      return nil if index < 0 or index > self.size rescue nil 
      self.fetch(index) rescue nil 
     end 
    end 
end 

class Array 

    # calculate near values and remove nils with #compact method. 
    def near(i,j) 
     [ self[i - 1][j - 1], self[i - 1][j - 0], self[i - 1][j + 1], 
      self[i - 0][j - 1],      self[i - 0][j + 1], 
      self[i + 1][j - 1], self[i + 1][j - 0], self[i + 1][j + 1], 
     ].compact 
    end 
end 

puts big_map.near(1,1).inspect 
# => [1, 2, 3, 8, 7, 1, 6, 8] 

puts big_map.near(0,0).inspect 
# => [2, 8, 9] 

puts big_map.near(5,5).inspect 
# => [2, 1, 1] 
0

मैं वह एक ही समस्या पर काम कर रहा था और एक 2 डी मैट्रिक्स में किसी भी बिंदु के आसपास के संख्या को खोजने के लिए एक छोटे से अनुकूलित समाधान के साथ आया था, उम्मीद है कि इस मदद करता है, अगर मैं किसी भी तरह तर्क कोड छोटा कर सकते हैं टिप्पणी कृपया : -

import java.util.ArrayList; 

public class test { 
    public static void main(String[] arg){ 

     int[][] arr = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}}; 
     //int[][] arr = {{width,2,3},{4,5,6},{7,8,9}}; 
     ArrayList<Integer> al = new ArrayList<Integer>(); 
     int x = 2, y = 2; 
     int width = 2; //change the value of width, according to the requirement 
     for(int i = 0; i < 5; i++){ 
      for(int j = 0; j < 5; j++){ 
       if((i == (x-width) && ((y+width) >= j && j >= (y-width))) || (i == (x+width) && ((y+width) >= j && j >= (y-width))) || (j == (y-width) && ((x+width) >= i && i >= (x-width))) || (j == (y+width) && ((x+width) >= i && i >= (x-width))) ){ 
        //if(x >= 0 && i < (i+width) && y >= 0 && j < (j+width)) 
         { 
         al.add(arr[i][j]); 
         } 
       } 
      } 
     } 
     System.out.println(al); 
    } 

} 
0

यदि आप किनारों के लिए चक्रीय पड़ोसियों चाहते हैं या चक्रीय पड़ोसियों पर ध्यान नहीं देता उल्लेख नहीं किया। आप चाहते हैं यहाँ वहाँ लगता है मान लिया जाये कि चक्रीय पड़ोसियों है कोड,

List<Integer> getNeighbours(int[][] mat, int x, int y){ 
    List<Integer> ret = new ArrayList<Integer>(); 
    int rows = mat.length; 
    int cols = mat[0].length; 
    for(int i=-1,i<=1;i++) 
    for(int j=-1;j<=1;j++) 
     if(i||j) ret = ret.add(mat[(x+i)%rows][(y+j)%cols]); 
    return ret; 
} 
संबंधित मुद्दे