如何匹配ASCII艺术中的ASCII艺术片段?

6 c++ python ascii-art

我正在练习编程竞赛,我可以选择使用Python或C++来解决每个问题,因此我对任何一种语言的解决方案持开放态度 - 无论哪种语言最适合这个问题.

我坚持的过去问题的URL是http://progconz.elena.aut.ac.nz/attachments/article/74/10%20points%20Problem%20Set%202012.pdf,问题F("地图") .

基本上它涉及匹配一个大的ASCII艺术的出现.在C++中,我可以为每一段ASCII艺术创建一个向量.问题是当较小的部分是多线时如何匹配它.

我不知道该如何去做.我不希望为我编写所有代码,只是想知道问题所需的逻辑.

谢谢你的帮助.

这是我到目前为止所得到的:

#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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:从下面的评论我有一个Python的解决方案J.F. Sebastian.它有效,但我不明白.我已经评论了我能做什么,但需要帮助理解函数中的return语句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() )
Run Code Online (Sandbox Code Playgroud)

jfs*_*jfs 1

#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 )
)
Run Code Online (Sandbox Code Playgroud)

生成器表达式可以使用显式的 for 循环块重写:

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
Run Code Online (Sandbox Code Playgroud)

比较 ( pattern == ..) 返回 True/False,在 Python 中等于 1/0。

构建子矩阵以与模式进行比较的列表理解可以优化为更早返回:

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

或者使用显式的 for 循环块:

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
Run Code Online (Sandbox Code Playgroud)