發現離散數學的小作用
阿新 • • 發佈:2022-04-02
迷宮程式
點選檢視迷宮程式程式碼
#include<stdio.h> #include <stdlib.h> /* 迷宮求解 */ struct Node { int x; int y; struct Node* prior; struct Node* next; }; struct Stack{ Node* bottom; Node* top; int stacksize; }; // 初始化棧 Stack* init(); // 入棧 void push(Stack* s, int x, int y); // 出棧 void pop(Stack* s); // 顯示棧中資料 void showStack(Stack* stack); int x,y; int map[10][10] = { {1,1,1,1,1,1,1,1,1,1}, {1,2,1,0,0,0,0,0,1,1}, {1,0,1,1,1,1,1,0,1,1}, {1,0,0,0,1,0,1,0,0,1}, {1,0,1,0,1,0,0,0,0,1}, {1,0,1,0,1,1,1,1,1,1}, {1,1,1,0,1,0,0,0,1,1}, {1,0,0,0,1,0,1,0,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; Stack* stack; int right(); int left(); int up(); int down(); int main() { x = 1; y = 1; stack = init(); //x != 8 && y != 8 錯誤 // x != 8 || y != 8 正確 // x == 8 && y == 8 正確 int flag = 1; while (flag) { printf("\n"); if (right()) { printf("右走\n"); } else if (left()) { printf("左走\n"); }else if (up()) { printf("上走\n"); }else if (down()) { printf("下走\n"); }else { printf("出棧\n"); pop(stack); } for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { int n = map[i][j]; printf(" %d ", n); } printf("\n"); } if (x == 8 && y == 8) { flag = 0; } // if (right() || left() // || up() || down()) { // printf("下一步\n"); // } else { // printf("出棧\n"); // pop(stack); // } } return 0; } int right() { if (map[x][y + 1] != 1 && map[x][y + 1] != 2) { y += 1; map[x][y] = 2; push(stack, x, y); return 1; } return 0; } int left() { if (map[x][y - 1] != 1 && map[x][y - 1] != 2) { y -= 1; map[x][y] = 2; push(stack, x, y); return 1; } return 0; } int up() { if (map[x - 1][y] != 1 && map[x - 1][y] != 2) { x -= 1; map[x][y] = 2; push(stack, x, y); return 1; } return 0; } int down(){ if (map[x + 1][y]!= 1 && map[x + 1][y] != 2) { x += 1; map[x][y] = 2; printf("下一步地址;%d", map[x][y]); push(stack, x, y); return 1; } return 0; } // 初始化棧 Stack* init() { Stack* stack = (Stack*)malloc(sizeof(Stack)); stack->stacksize = 100; Node* head = (Node*)malloc(sizeof(Node)); head->next = head; head->prior = head; stack->bottom = head; stack->top = head; for (int i = 0; i < stack->stacksize; i++ ) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->next = head->next; head->next->prior = newNode; newNode->prior = head; head->next = newNode; } return stack; } // 入棧 void push(Stack* stack, int x, int y) { if (stack->top->next != stack->bottom) { stack->top = stack->top->next; stack->top->x = x; stack->top->y = y; } else { printf("棧滿!\n"); } } // 出棧 void pop(Stack* stack) { if (stack->top != stack->bottom) { stack->top = stack->top->prior; x = stack->top->x; y = stack->top->y; } else { printf("棧空!\n"); } } // 顯示棧中資料 void showStack(Stack* stack) { if (stack->bottom == stack->top) { printf("棧為空!"); } else { Node* p = stack->bottom->next; printf("當前棧資料為:"); while (p != stack->top->next) { printf("%d ", p->x); printf("%d ", p->y); p = p->next; } } printf("\n"); printf("\n"); }
判斷是否到達終點時發生錯誤
為真:沒到達終點
為假:到達終點
x != 8 && y != 8 錯誤
x != 8 || y != 8 正確
!(x == 8 && y == 8) 正確
如果是第一個條件,則當x為8或y為8的時候都沒到達終點。第九行和第九列都無法到達。
如果是第二個條件或第三個條件,意思是:當x和y都為8的時候到達終點
發現的技巧
x != 8 && y != 8
的意思直接理解起來可能會理解錯誤,或者不好理解
這時候我們可以使用離散數學中的數理邏輯進行等價轉換
設A:x等於8 設B:y等於8
x != 8 && y != 8 符號化為:┐A ∧ ┐B <=> ┐(A ∨ B) 意思為:x等於8或y等於8為假時,到達終點 代表第九行和第九列都是終點,而不是(8,8)這個位置是終點 !(x == 8 && y == 8) 這個就比較好理解 意思為:x等於8並且y等於8為假,到達終點 可以等價於:┐(A ∧ B) <=> ┐A ∨ ┐B 意思為:x不等於8或者y不等於8為真
總結
可以使用等價代換去檢查判斷條件是否正確,通過不同的表達方式去理解判斷條件的意思。從而檢查我們是否理解錯誤判斷條件的意思。