假设我们有无上下文语言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
不应接受最后一个字符串。我无法弄清楚如何在识别字符串之前检查弹出的数量,以选择是否接受它。有没有人有任何想法,任何触发我的线索?
答案 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;
}