2016-12-15 3 views
1

방금이 코드를 온라인에서 찾았으며 입력을 어떻게 포맷해야하는지 이해하지 못했다. 동일한 프로그래머의 유사한 입력 예가 여기에 표시됩니다. Pushdown automaton implemented in CC에서 튜링 머신 구현의 입력을 이해할 수 없다

하지만 여전히 많은 도움이되지 않습니다. E01 :

입력 형식은 같다 : E0의 $ : 000111 : A : 광고 : aeeb의 $ : b0eb0 : b10ce : c10ce : 입력 드 CE $를 는 세미콜론으로 구분되어 여기의 말씀입니다 ":", 첫 번째 섹션은 "알파벳 입력", 초는 "스택 알파벳", "입력"그리고 마지막 전체 묶음은 전환 함수입니다.

누구든지 입력을 처리하는 방법에 대한 지침을 제공 할 수 있습니까? 나는 약 6 시간 동안 열심히 노력하고 있으며,이 코드에 대한 입력 형식을 어떻게 해석해야하는지에 대해 이해할 수는 없습니다.

gcc로 컴파일 한 후에는 "./executable"을 실행하고 Enter를 누르십시오. 그런 다음 위의 그림과 같이 샘플 입력 문자열을 붙여 넣습니다 (이 프로그램에서는 다른 입력이 필요함).

/* This C file implements a Turing Machine 
* author: Kevin Zhou 
* Computer Science and Electronics 
* University of Bristol 
* Date: 21st April 2010 
*/ 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

typedef struct tapes { 
    struct tapes *left; 
    struct tapes *right; 
    char content; 
} Tape; 

typedef enum { LEFT,RIGHT } Direction; 

typedef struct transition { 
    char current_state; 
    char tape_symbol; 
    char new_state; 
    char new_tape_symbol; 
    Direction dir; 
} Transition; 

typedef struct list { 
    Transition *content; 
    struct list *next; 
} List; 

typedef struct tm { 
    char *input_alpha; 
    char *input; 
    char *tape_alpha; 
    char start; 
    char accept; 
    char reject; 
    List *transition; 
} TM; 

Tape *insert_tape(Tape *t, Direction dir, char c) { 
    Tape *head = t; 
    Tape *new1 = calloc(1,sizeof(Tape));; 
    new1 -> content = c; 
    if(dir == LEFT) { 
     while(t->left != NULL) { 
      t = t->left; 
     } 
     new1->right = t; 
     new1->left = NULL; 
     t->left = new1; 
     return new1; 
    } 
    if(dir == RIGHT) { 
     while(t->right != NULL) { 
      t = t->right; 
     } 
     new1->left = t; 
     new1->right = NULL; 
     t->right = new1; 
    } 
    return head; 
} 

Tape *create_tape(char *input) { 
    int i=1; 
    Tape *t = calloc(1,sizeof(Tape)); 
    t->content = input[0]; 
    while(1) { 
     if(input[i] == '\0') break; 
     t = insert_tape(t,RIGHT,input[i]); 
     i++; 
    } 
    return t; 
} 

/* turn the input string into Transition fields */ 
Transition *get_transition(char *s) { 
    Transition *t = calloc(1,sizeof(Transition)); 
    Direction dir; 
    t->current_state = s[0]; 
    t->tape_symbol = s[1]; 
    t->new_state = s[2]; 
    t->new_tape_symbol = s[3]; 
    dir = (s[4]=='R')? RIGHT:LEFT; 
    t->dir = dir; 
    return t; 
} 

/* turn the string into transitions and add into list */ 
List *insert_list(List *l, char *elem) { 
    List *t = calloc(1,sizeof(List)); 
    List *head = l; 
    while(l->next!=NULL) 
     l = l->next; 
    t->content = get_transition(elem); 
    t->next = NULL; 
    l->next = t; 
    return head; 
} 

/* insert a transition into a list */ 
List *insert_list_transition(List *l, Transition *tr) { 
    List *t = calloc(1,sizeof(List)); 
    List *head = l; 
    while(l->next!=NULL) 
     l = l->next; 
    t->content = tr; 
    t->next = NULL; 
    l->next = t; 
    return head; 
} 

void print_tape(Tape *t,char blank) { 
    char c; 
    while(1) { 
     if(t->content != blank) break; 
     t= t->right; 
    } 
    while(1) { 
     if(t==NULL) break; 
     c = t->content; 
     if(t->content != blank) 
      putchar(c); 
     t= t->right; 
    } 
    putchar('\n'); 
} 

void print_transition (Transition *t) { 
    char s1[] = "Left"; 
    char s2[] = "Right"; 
    if(t==NULL) { 
     printf("NULL Transfer"); 
     return; 
    } 
    printf("current:%c tape:%c new state:%c new tape:%c direction %s\n",t->current_state,t->tape_symbol,t->new_state,t->new_tape_symbol,(t->dir == LEFT)?s1:s2); 
} 

/*test if the char c is in the string s */ 
int contains (char c, char *s) { 
    int i=0; 
    while(1) { 
     if(c== s[i]) return 1; 
     if(s[i] == '\0') return 0; 
     i++; 
    } 
} 

/* test if the input is a valid input */ 
int is_valid_input(char *input_alpha, char *input) { 
    int i=0; 
    char c; 
    while(1) { 
     c = input[i]; 
     if(c == '\0') break; 
     if(!contains(c,input_alpha)) return 0; 
     i++; 
    } 
    return 1; 
} 

TM *createTM (char *input) { 

    TM *m = calloc(1,sizeof(TM)); 
    List *tr = calloc(1,sizeof(List)); 
    char *buffer; 
    /*read input alphabet of PDA*/ 
    buffer = strtok(input,":"); 
    if(buffer == NULL) { 
     printf("Error in reading input alphabet!\n"); 
     exit(1); 
    } 
    m->input_alpha = buffer; 

    /*read tape alphabet*/ 
    buffer = strtok(NULL,":"); 

    if(buffer == NULL) { 
     printf("Error in reading tape alphabet!\n"); 
     exit(1); 
    } 
    m->tape_alpha = buffer; 

    /*read input sequence*/ 
    buffer = strtok(NULL,":"); 
    if(buffer == NULL) { 
     printf("Error in reading input sequence!\n"); 
     exit(1); 
    } 

    if(!is_valid_input(m->input_alpha,buffer)) { 
     printf("Error! Input contains some invalid characters that don't match the input alphabet!\n"); 
     exit(1); 
    } 

    m->input = buffer; 
    buffer = strtok(NULL,":"); 
    m->start = buffer[0]; 
    buffer = strtok(NULL,":"); 
    m->accept = buffer[0]; 
    buffer = strtok(NULL,":"); 
    m->reject = buffer[0]; 

    /*read tape transition*/ 
    while(1) { 
     buffer = strtok(NULL,":"); 
     if(buffer == NULL) break; 
     tr = insert_list(tr,buffer); 
    } 

    m->transition = tr->next; 
    return m; 
} 

Transition *find_transition(List * list,char state, char tape_symbol) { 
    Transition *t; 
    while(1) { 
     if(list==NULL) return NULL; 
     t = list -> content; 
     if(t->current_state == state && t->tape_symbol == tape_symbol) 
      return t; 
     list = list->next; 
    } 
} 

Tape *move(Tape *t,Direction dir, char blank) { 
    if(dir == LEFT) { 
     if(t->left==NULL) { 
      t = insert_tape(t,LEFT,blank); 
     } 
     return t->left; 
    } 
    if(dir == RIGHT) { 
     if(t->right==NULL) { 
      t = insert_tape(t,RIGHT,blank); 
     } 
     return t->right; 
    } 
    return NULL; 
} 

void simulate(TM *m) { 
    /* first symbol in input symbol used to represent the blank symbol */ 
    const char blank = m->tape_alpha[0]; 
    char current_state = m->start; 
    Tape *tape = create_tape(m->input); 
    Tape *current_tape = tape; 
    char current_tape_symbol; 
    Transition *current_transition; 
    while(1) { 
     if(current_state == m->accept) { 
      printf("Accept\n"); 
      print_tape(tape,blank); 
      break; 
     } 
     if(current_state == m->reject) { 
      printf("Reject\n"); 
      print_tape(tape,blank); 
      break; 
     } 
     current_tape_symbol = (current_tape==NULL||current_tape ->content == '\0')?blank:current_tape->content; 
     current_transition = find_transition(m->transition,current_state,current_tape_symbol); 
     current_state = current_transition -> new_state; 
     current_tape -> content = current_transition -> new_tape_symbol; 
     current_tape = move(current_tape, current_transition ->dir, blank); 
    } 
} 

int main(void) { 
    char s[300]; 
    TM *p; 
    scanf("%s",s); 
    p = createTM(s); 
    simulate(p); 
    return 0; 
} 
+0

왜 C++ 태그입니까? – saeleko

+0

방금 ​​그걸 고치고 단순화 된 질문 –

+0

튜링 기계에 대한 공식 정의는 위키피디아를보십시오. –

답변

3

라인 buffer = strtok(NULL,":")의 대량 사용은 입력 문자열이 있는지 확인한다 (등의 연결된 코드로) 결장 구분.

struct defintions는 입력을 리버스 엔지니어링하는 핵심 요소입니다.

주요 구조체이다

typedef struct tm { 
    char *input_alpha; 
    char *input; 
    char *tape_alpha; 
    char start; 
    char accept; 
    char reject; 
    List *transition; 
} TM; 

함수는 createTM():의 입력을 분리하고 튜링 기계로드 기능이다. struct tm에는 7 개의 필드가 있고 createTM()에는 7 개의 명확한 단계가 있습니다.

1) 첫 번째 부분은 입력 알파벳입니다. 아마도 이것은 1 개 이상의 문자로 된 문자열 일 것입니다. 01.

2) 두 번째 부분은 테이프 알파벳입니다. 나머지 코드에서 어떤 역할을하는 유일한 문자는 첫 번째 문자입니다. 주 시뮬레이션 기능의 const char blank = m->tape_alpha[0]; 행은 첫 번째 문자가 빈 문자 (테이프 정사각형이 비어 있음을 나타내는 문자)의 역할을한다는 것을 나타냅니다. 블랭크를 정사각형에 쓰면 튜링 기계가 정사각형의 데이터를 지울 수 있습니다. 어떤면에서 입력의이 부분은 순서가 맞지 않습니다. 구조체 정의의 세 번째 필드로 나열되지만 입력 문자열의 두 번째 필드입니다.

3) thirs 부분은 테이프의 초기 입력입니다. 첫 번째 부분에서 문자를 모두 가져온 문자열입니다. 함수 is_valid_input()은이 조건을 검사하는 데 사용됩니다.

4) 다음 부분은 단일 문자

5) 다음 부분은 다시 단일 문자 인 수락 상태 인 구성 시작 상태이다.따라서, TM이 모델에서 하나의 수용 상태

6) 다음 부분은 다시 문자열의 서열이다 다음 어떤 단일 문자

7)로 표시되는 거부 상태이다있다, 연결된 문자열 목록에 입력됩니다. 기능 get_transition()을주의 깊게 보면

typedef struct transition { 
    char current_state; 
    char tape_symbol; 
    char new_state; 
    char new_tape_symbol; 
    Direction dir; 
} Transition; 

는 전환에 의해 표현되는 것을 추론 할 수있다 : 어떻게 작동하는지 이해하는 핵심 기능은 이러한 전환 문자열 중 하나를 취하고 Transition 구조체로 변환 get_transition()이다, 선언 마지막 char가 R 또는 L 인 길이 5의 문자열. 예를 들어, "a 상태에있는 경우 0 기호를 스캔하고 상태 b으로 전환하고 1 기호로 작성하고 오른쪽으로 이동"과 같은 내용의 코드를 입력하면 a1b0R과 같이 표시됩니다.

01:_102:1001010101:$:a:r:$0b1R:b1b0L:a1b2R 

해당

01 _102 1001010101  $  a  r  $0b1R b1b0L a1b2R 
input tape  input  start accept reject   transitions 
| alphabets |     |  states  | 
(blank = '_')  
난 그냥 무작위로 일부 전환을했다

, 어느 쪽도 아니 알고도로 : 모두 함께 퍼팅

, 입력 문자열의 형태 뭔가 같은 것 이 입력으로 프로그램이 무엇을 할 것인지 신경 써라. 이것은 당신이 프로그램을 실험하기에 충분할 것입니다.