PDA:如何检查弹出的数量是偶数还是奇数

时间:2012-11-10 20:23:46

标签: compiler-construction pushdown-automaton

假设我们有无上下文语言L = {0 ^ n0 ^ n,n> = 0}。

对于PDA:Μ= {A,Q,H,δ,q0,h0,F}我们有:

A = {"0"}
H = {X, I}
Q = {S, T}
q0 = S
h0 = X
F = {T}

Then, the δ function is:
   ___________________________________________________________________
   |           X            |             I            |      -|     |
---+------------------------+--------------------------+-------------|
S  | read("0")=> push(I)    |   read("0")=> push(I)    |             |
   | keep=> move(T)         |   pop                    |             |
---+------------------------+--------------------------+-------------|
T  |                        |                          |   success   |
---------------------------------------------------------------------+

这是我的解决方案,但它有问题。自动机必须接受诸如的字符串 00,ε,0000而不是0或000.通常字符串的偶数为0。

让我们尝试两个例子:

->for string 00:
 MOVE    STACK    INPUT    STATE    DESCRIPTION_OF_MOVE
  1      X         '0'0      S        reading_of 0
  2      XI          '0'     S        reading_of 0
  3      XII        ε        S        pop
  4      XI         ε        S        pop
  5      X          ε        S        ε-transition
  6      X          ε        T        success

->for string 000:
 MOVE    STACK    INPUT    STATE    DESCRIPTION_OF_MOVE
  1      X        '0'00      S        reading_of 0
  2      XI        '0'0      S        reading_of 0
  3      XII         '0'     S        reading_of 0
  4      XIII       ε        S        pop
  5      XII        ε        S        pop
  6      XI         ε        S        pop
  7      X          ε        S        ε-transition
  8      X          ε        T        success

不应接受最后一个字符串。我无法弄清楚如何在识别字符串之前检查弹出的数量,以选择是否接受它。有没有人有任何想法,任何触发我的线索?

1 个答案:

答案 0 :(得分:0)

解决方案很简单。在这种情况下,PDA必须接受偶数个0,包括零数0。

为了实现这一点,一个简单的实现是每次满足0的偶数出现时从符号I弹出符号δ,所以 ___________________________________________________________________ | X | I | -| | ---+------------------------+--------------------------+-------------| S | read("0")=> push(I) | read("0")=> pop | | | keep=> move(T) | | | ---+------------------------+--------------------------+-------------| T | | | success | ---------------------------------------------------------------------+ 函数将是:

->for string 00:
 MOVE    STACK    INPUT    STATE    DESCRIPTION_OF_MOVE
  1      X         '0'0      S        read(0)=> push(I)
  2      XI          '0'     S        read(0)=> pop
  3      X          ε        S        ε-transition
  4      X          ε        T        success

->for string 000:
 MOVE    STACK    INPUT    STATE    DESCRIPTION_OF_MOVE
  1      X        '0'00      S        read(0)=> push(I)
  2      XI        '0'0      S        read(0)=> pop
  3      X           '0'     S        read(0)=> push(I)
  4      XI         ε        S        eoi=> failure

让我们尝试两个例子:

// graphical_editor.cpp : Defines the entry point for the console application.
//

    #include "stdafx.h"
    #include <iostream> //provides access to cout and cin 
    #include <string> //Always import <string> if piping std input to a string in .net 
    #include <vector>
    #include <fstream>

    using std::ofstream;
    using std::cin; 
    using std::cout; 
    using std::string;
    using std::vector;

    //This is where we store the pixels of the image
    static vector<vector <string>> image_array;
    ofstream myfile;
    //our definition of an X,Y coordinate pair. 
    typedef struct point {
        int x_coordinate, y_coordinate;
    };

    void initialise_image();
    void clear_image(); 
    void save_image(string file_name);
    int get_image_width();
    int get_image_height();
    void color_pixel(int x, int y, string color);
    void color_point(point p, string color);
    void color_vertical_line(int x, int y1, int y2, string color);
    void color_horizontal_line(int x1, int x2, int y, string color);
    void color_box(int x1, int x2, int y1, int y2, string color);
    void flood_fill(point p, string color);
    vector<point> get_matching_neighbours(point p, string color);

    int main()
    {
        string command; //first letter of a given line 
        myfile.open("example.txt");
        while (cin >> command) {
            //application terminates when command is X
            if (command.compare("X") == 0) {
                return 0;
            } else if (command.compare("I") == 0) {
                initialise_image();
            }
            else if (command.compare("S") == 0) {
                string file_name;
                cin >> file_name;
                save_image(file_name);
            }
            else if (command.compare("L") == 0) {
                string color;
                point p;
                cin >> p.x_coordinate >> p.y_coordinate >> color;
                color_point(p, color);
            }
            else if (command.compare("V") == 0) {
                string color;
                int x, y1, y2;
                cin >> x >> y1 >> y2 >> color;
                color_vertical_line(x, y1, y2, color);
            }
            else if (command.compare("H") == 0) {
                string color;
                int x1, x2, y;
                cin >> x1 >> x2 >> y >> color;
                color_horizontal_line(x1, x2, y, color);
            }
            else if (command.compare("K") == 0) {
                string color;
                int x1, x2, y1, y2;
                cin >> x1 >> x2 >> y1 >> y2 >> color;
                color_box(x1, x2, y1, y2, color);
            }
            else if (command.compare("F") == 0) {
                string color;
                point p;
                cin >> p.x_coordinate >> p.y_coordinate >> color;
                flood_fill(p, color);
            }
            else if (command.compare("C") == 0) {
                clear_image();
            }
        }

        return 0;
    }

    void initialise_image()
    {
        /*read parameters height and width*/
        int width, height; 
        cin >> width >> height;

        /*first we create a vector of vectors (numRows+1)x(numColumns matrix+1). */
        image_array.clear(); 
        for (int i = 0; i < width+ 1; i++) {
            image_array.push_back(vector<string>());
        }

        /*then we initialize each element of it one by one*/
        for (int colNo = 0; colNo < width + 1; colNo++) {
            for (int rowNo = 0; rowNo < height + 1; rowNo++) {
                image_array[colNo].push_back("O");
            }

        }
    }

    void clear_image() {
        /*we initialize each element of it one by one*/
        for (int y = 1; y < get_image_height()+1 ; y++) {
            for (int x = 1; x < get_image_width()+1; x++) {
                image_array[x][y] = "O";
            }
        }
    }

    void save_image(string file_name) {


        myfile << file_name << "\n";
        //cout << file_name << "\n";
        for (int y = 1; y < get_image_height()+1; y++) {
            for (int x = 1; x < get_image_width()+1; x++) {
                myfile << image_array[x][y];
                //cout << image_array[x][y];
            }
            myfile << "\n";
            //cout << "\n";
        }
        myfile.close();
    }

    int get_image_width() {
        return image_array.size()-1;

    }

    int get_image_height() {
        return image_array[0].size()-1;
    }

    void color_point(point p, string color) {
        color_pixel(p.x_coordinate,p.y_coordinate, color);
    }

    void color_pixel(int x, int y, string color) {
        image_array[x][y] = color;
    }


    void color_vertical_line(int x, int y1, int y2, string color) {
        for (int y = y1; y <= y2; y++) {
            color_pixel(x, y, color);
        }
    }

    void color_horizontal_line(int x1, int x2, int y, string color) {
        for (int x = x1; x <= x2; x++) {
            color_pixel(x, y, color);
        }
    }

    void color_box(int x1, int x2, int y1, int y2, string color) {
        for (int x = x1; x <= x2; x++) {
            for (int y = y1; y <= y2; y++) {
                color_pixel(x, y, color);
            }
        }
    }

    string get_point_color(point p) {
        return image_array[p.x_coordinate][p.y_coordinate];
    }

    void flood_fill(point p, string color) {
        vector <point> points_queue; 
        points_queue.push_back(p);
        string original_color = get_point_color(p);
        point current_point; 
        while (points_queue.size() > 0) {
            current_point = points_queue[0];

            //if the point shares a color with the original point then color it in the new color. 
            if (get_point_color(current_point).compare(original_color) == 0) {
                color_point(current_point, color);
            }

            // remove current point from the queue
            points_queue.erase(points_queue.begin());

            // add it's neighbours to the queue
            vector<point> matching_neighbours = get_matching_neighbours(current_point, original_color);
            for (int i = 0; i < matching_neighbours.size(); i++) {
                points_queue.push_back(matching_neighbours[i]);
            }


        }


    }

    bool is_valid_point(point p) {
        if (p.x_coordinate >= 1 && p.x_coordinate < get_image_width() + 1 && p.y_coordinate >= 1 && p.y_coordinate < get_image_height() + 1) {
            return true;
        }
        else {
            return false; 
        }
    }

    vector<point> get_matching_neighbours(point p, string color) {
        vector<point> neighbours;
        point left_neighbour, right_neighbour, upper_neighbour, lower_neighbour;
        left_neighbour.x_coordinate = p.x_coordinate - 1;
        left_neighbour.y_coordinate = p.y_coordinate;
        if (is_valid_point(left_neighbour) && get_point_color(left_neighbour).compare(color) == 0) {
            neighbours.push_back(left_neighbour);
        }


        right_neighbour.x_coordinate = p.x_coordinate + 1;
        right_neighbour.y_coordinate = p.y_coordinate;
        if (is_valid_point(right_neighbour) && get_point_color(right_neighbour).compare(color) == 0) {
            neighbours.push_back(right_neighbour);
        }

        upper_neighbour.x_coordinate = p.x_coordinate;
        upper_neighbour.y_coordinate = p.y_coordinate + 1;
        if (is_valid_point(upper_neighbour) && get_point_color(upper_neighbour).compare(color) == 0) {
            neighbours.push_back(upper_neighbour);
        }

        lower_neighbour.x_coordinate = p.x_coordinate;
        lower_neighbour.y_coordinate = p.y_coordinate - 1;

        if (is_valid_point(lower_neighbour) && get_point_color(lower_neighbour).compare(color) == 0) {
            neighbours.push_back(lower_neighbour);
        }
        return neighbours;
    }