2013-06-30 10 views
6

मैं एक प्रोग्रामिंग प्रतियोगिता के लिए अभ्यास कर रहा हूं जिसमें मुझे प्रत्येक समस्या का विकल्प होगा कि क्या Python या C++ का उपयोग करना है, इसलिए मैं किसी भी भाषा में समाधान के लिए खुला हूं - जो भी भाषा इस समस्या के लिए सबसे उपयुक्त है।ASCII कला के भीतर ASCII कला सेगमेंट कैसे मिलान करें?

पिछली समस्या का यूआरएल http://progconz.elena.aut.ac.nz/attachments/article/74/10%20points%20Problem%20Set%202012.pdf है, समस्या एफ ("मैप्स") है।

असल में इसमें एएससीआईआई कला के एक छोटे टुकड़े की बड़ी घटनाओं के मिलान की घटनाएं शामिल हैं। सी ++ में मैं एएससीआईआई कला के प्रत्येक टुकड़े के लिए एक वेक्टर बना सकता हूं। समस्या यह है कि छोटे टुकड़े बहु-रेखा होने पर इसका मिलान कैसे करें।

मुझे नहीं पता कि इसके बारे में कैसे जाना है। मैं नहीं चाहता कि मेरे लिए लिखे गए सभी कोड, समस्या के लिए जरूरी तर्क का एक विचार।

किसी भी मदद के लिए धन्यवाद।

यहाँ मैं अब तक क्या कर लिया है:

#include <cstdlib> 
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <vector> 

using namespace std; 

int main(int argc, char** argv) 
{ 
    int nScenarios, areaWidth, areaHeight, patternWidth, patternHeight; 

    cin >> nScenarios; 

    for(int a = 0; a < nScenarios; a++) 
    { 
     //get the pattern info and make a vector 
     cin >> patternHeight >> patternWidth; 
     vector< vector<bool> > patternIsBuilding(patternHeight, vector<bool>(patternWidth, false)); 

     //populate data 
     for(int i = 0; i < patternHeight; i++) 
     { 
      string temp; 
      cin >> temp; 
      for(int j = 0; j < patternWidth; j++) 
      { 
       patternIsBuilding.at(i).at(j) = (temp[ j ] == 'X'); 
      } 
     } 

     //get the area info and make a vector 
     cin >> areaHeight >> areaWidth; 
     vector< vector<bool> > areaIsBuilding(areaHeight, vector<bool>(areaWidth, false)); 

     //populate data 
     for(int i = 0; i < areaHeight; i++) 
     { 
      string temp; 
      cin >> temp; 
      for(int j = 0; j < areaWidth; j++) 
      { 
       areaIsBuilding.at(i).at(j) = (temp[ j ] == 'X'); 
      } 
     } 


     //now the vectors contain a `true` for a building and a `false` for snow 
     //need to find the matches for patternIsBuilding inside areaIsBuilding 
     //how? 

    } 


    return 0; 
} 

संपादित करें: टिप्पणी नीचे मैं J.F. Sebastian से अजगर में एक समाधान मिल गया है से। यह काम करता है लेकिन मुझे यह सब समझ में नहीं आता है। मैंने टिप्पणी की है कि मैं क्या कर सकता था लेकिन कथन को count_pattern फ़ंक्शन में समझने में सहायता की आवश्यकता है।

#function to read a matrix from stdin 
def read_matrix(): 

    #get the width and height for this matrix 
    nrows, ncols = map(int, raw_input().split()) 

    #get the matrix from input 
    matrix = [ raw_input() for _ in xrange(nrows) ] 

    #make sure that it all matches up 
    assert all(len(row) == ncols for row in matrix) 

    #return the matrix 
    return matrix 

#perform the check, given the pattern and area map 
def count_pattern(pattern, area): 

    #get the number of rows, and the number of columns in the first row (cause it's the same for all of them) 
    nrows = len(pattern) 
    ncols = len(pattern[0]) 

    #how does this work? 
    return sum(
     pattern == [ row[ j:j + ncols ] for row in area[ i:i + nrows ] ] 
     for i in xrange(len(area) - nrows + 1) 
     for j in xrange(len(area[i]) - ncols + 1) 
    ) 

#get a number of scenarios, and that many times, operate on the two inputted matrices, pattern and area 
for _ in xrange(int(raw_input())): 
    print count_pattern(read_matrix(), read_matrix()) 
+0

एक प्रारंभिक बिंदु के रूप में, मैं डी सुझाव देता है कि आप बड़े हिस्से और छोटे हिस्से को 2 डी सरणी के रूप में परिभाषित करते हैं, संभावित रूप से बूलियन जहां 'सत्य' एक इमारत को इंगित करता है और 'झूठा' बर्फ को इंगित करता है। फिर, आपको बड़े मैट्रिक्स के भीतर प्रत्येक घटना को छोटे मैट्रिक्स को खोजने के लिए कुछ लूप-फ़ू का उपयोग करना होगा। – Vulcan

+0

@ वल्कन धन्यवाद, ऐसा लगता है कि यह काम करेगा। मुझे इसमें जाना होगा। हो सकता है कि इसे एक उत्तर के रूप में जोड़ें ताकि मैं इसे स्वीकार कर सकूं :) – stackunderflow

+0

मैं अपनी टिप्पणी से एक उत्तर के रूप में संतुष्ट नहीं हूं (यही कारण है कि यह एक टिप्पणी है), लेकिन मैं एक वास्तविक मैट्रिक्स-भीतर-मैट्रिक्स स्थान लिखने पर एक शॉट ले सकता हूं कलन विधि। मैं सी ++ या पायथन से बहुत परिचित नहीं हूं, इसलिए यह मेरे लिए एक अच्छा अभ्यास होगा, लेकिन यह न भूलें कि आप कोड के साथ हमेशा अपने प्रश्न का उत्तर दे सकते हैं! – Vulcan

उत्तर

2
#how does this work? 
return sum(
    pattern == [ row[ j:j + ncols ] for row in area[ i:i + nrows ] ] 
    for i in xrange(len(area) - nrows + 1) 
    for j in xrange(len(area[i]) - ncols + 1) 
) 

जनरेटर अभिव्यक्ति स्पष्ट के लिए लूप ब्लॉकों का उपयोग कर फिर से लिखा जा सकता है:

count = 0 
for i in xrange(len(area) - nrows + 1): 
    for j in xrange(len(area[i]) - ncols + 1): 
     count += (pattern == [ row[ j:j + ncols ] 
           for row in area[ i:i + nrows ] ]) 
return count 

तुलना (pattern == ..) सही/गलत है कि अजगर में 1/0 के बराबर हैं देता है।

सूची समझ है कि पैटर्न के साथ तुलना करने के लिए submatrixes बनाता पहले वापस जाने के लिए अनुकूलित किया जा सकता है:

count += all(pattern_row == row[j:j + ncols] 
      for pattern_row, row in zip(pattern, area[i:i + nrows])) 

या इसका उपयोग करते स्पष्ट के लिए लूप ब्लॉक:

for pattern_row, row in zip(pattern, area[i:i + nrows]): 
    if pattern_row != row[j:j + ncols]: 
     break # no match (the count stays the same) 
else: # matched (no break) 
    count += 1 # all rows are equal 
+0

+1 समाधान और स्पष्टीकरण के लिए धन्यवाद – stackunderflow

1

लाइनों के संदर्भ में मत सोचें। पूरे पृष्ठ को एक स्ट्रिंग में पढ़ें और किसी भी अन्य की तरह अंत-रेखा के चरित्र का इलाज करें।

(आप सोच सकते है कि यह एक गुप्त संकेत है, लेकिन तुम सिर्फ "एक विचार के लिए" पूछा कि यह कैसे करना है।)

संपादित करें: चूंकि आप चित्र के समग्र आयाम पता है, तुम पात्रों भरोसा कर सकते हैं दूसरी पंक्ति से मेल खाने के लिए जिस पैटर्न को आप मिलान करने का प्रयास कर रहे हैं उसकी पहली पंक्ति से आगे, और इसी तरह के बाद के लाइनों के लिए आगे बढ़ें।

+0

ठीक है। यह एक अच्छा मुद्दा है, लेकिन जिस समस्या से मैंने लिंक किया है, उस उदाहरण को देखते हुए, मैं नहीं देख सकता कि यह कैसे काम करेगा। न्यूलाइन गिनती है। क्षमा करें, मैं वास्तव में समझा नहीं सकता, लेकिन उदाहरण को देखकर आप इसे प्राप्त कर सकते हैं। – stackunderflow

+0

ईओएल को अनदेखा करके, इनपुट दो-आयामीता की सभी भावनाओं को खो देता है, जिसका अर्थ है कि इसे मैट्रिक्स-जैसे इनपुट से मेल नहीं किया जा सकता है। यदि आप सुझाव दे रहे हैं कि ईओएल को एक और चरित्र के साथ प्रतिस्थापित किया जाए और पूरे इनपुट को वेक्टर के रूप में माना जाता है, यह अनिवार्य रूप से यह पहले से ही करता है, लेकिन ईओएल मैट्रिक्स-जैसी प्रारूप में द्वि-आयामी जानकारी प्रदर्शित करने में सबसे स्पष्टता प्रदान करता है। – Vulcan

0
#include <iostream> 
#include <vector> 

using namespace std; 

int main(){ 

    int numOfRounds; 
    cin >> numOfRounds; 



    for(int round = 0; round < numOfRounds; round++){ 

     int out = 0; 

     int linesToMatch; 
     cin >> linesToMatch; 

     int sizeToMatch; 
     cin >> sizeToMatch; 

     vector <string> v; 
     string t; 

     for (int i = 0; i < linesToMatch; i++){ 
      cin >> t; 
      v.push_back(t); 
     } 

     string s = ""; 

     int rows; 
     cin >> rows; 

     int columns; 
     cin >> columns; 

     for (int j = 0; j < rows; j++){  //map->string 
      cin >> t; 
      s += t; 
     } 

     // main part of implementation 
     // it's mainly basic algebra and index tracking 
     for (int m = 0; m <= rows - linesToMatch; m++){ 
      for (int n = 0; n <= columns - sizeToMatch; n++){ 
       int x; 
       for (x = 0; x < linesToMatch; x++){ 
        int index = (m + x) * columns + n; 
        string newTemp(s.begin() + index, s.begin() + index + sizeToMatch); 
        if (newTemp != v.at(x)) break; 
       } 
       if (x == linesToMatch) out++; 
      } 
     } 

     cout << out << endl; 

    } 

} 
+0

क्षमा करें, मेरा मतलब यह नहीं है। यदि आप नीचे स्क्रॉल करते हैं तो आपको समस्या F (शीर्षक "मानचित्र") मिलती है। – stackunderflow

+0

पोस्ट को – dmi

+0

अपडेट किया गया था। हां यह मेरे लिए भी वही है, मैं ऐसा कर सकता हूं लेकिन मुझे नहीं पता कि मल्टीलाइन पैटर्न के साथ क्या करना है। – stackunderflow

संबंधित मुद्दे