Tải bản đầy đủ (.pdf) (24 trang)

Bài giảng Cấu trúc dữ liệu và giải thuật – Bài 10: Ứng dụng của ngăn xếp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (732.33 KB, 24 trang )

Cấu trúc dữ liệu và giải thuật
Bài 10: Ứng dụng của ngăn xếp
Giảng viên: TS. Ngo Huu Phuc
Tel:
0438 326 077
Mob: 098 5696 580
Email:

1

PhD. Ngo Huu Phuc, Le Quy Don Technical University


Bài 10. Một vài ứng dụng của Stack
Nội dung:
10.1. Đảo mảng (3)
10.2. Đảo chuỗi (4)
10.3. Chuyển đổi hệ số (9)
10.4. Bracket Matching (5)
10.5. Balancing Act (4)

Tham khảo:

2

1.

Data structures and Algorithms Stacks.htm

2.


Kyle Loudon Mastering Algorithms, Chapter 6 Stacks and Queues

3.

Elliz Horowitz – Fundamentals of Data Structures, Chapter 3 Stacks and
Queues

4.

Deshpande Kakle – C and Data Structures, Chapter 19. Stacks and
Queues

5.

Bài giảng TS Nguyễn Nam Hồng
PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.1. Đảo mảng (1/3)
 Cho một mảng gồm một dãy các giá trị.
 Để đảo thứ tự các phần tử trong mảng, sử dụng

nguyên lý Last-In-First-Out của Stack.
 Ví dụ về hoạt động của đảo mảng:

3

17

18


134

216

23

25

47

55

25

23

55

47

18

17

216

134

PhD. Ngo Huu Phuc, Le Quy Don Technical University



10.1. Đảo mảng (2/3)
Ý tưởng thực hiện giải thuật:
1.

Khởi tạo một Stack rỗng, có kiểu số.

2.

Với n phần tử của mảng, lần lượt đưa vào Stack
thông qua hàm Push:
Push a[i] in to Stack.

3.

Lần lượt lấy ra từ Stack n phần tử và đưa vào trở
lại mảng ban đầu:
Pop a item from nStack in to a[i].

4.
4

Kết thúc giải thuật.
PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.1. Đảo mảng (3/3)
Ví dụ về đảo mảng:
void revArray(int a[],int n,int stack[])

{
makeEmpty(stack);
for(int i=0;ipush(stack,a[i]);
for(int i=0;ia[i]=pop(stack);
}
5

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.2. Đảo chuỗi (1/4)
 Cho một chuỗi gồm nhiều từ.
 Đảo chuỗi thực hiện việc đảo các từ trong chuỗi, sử

dụng ý tưởng Last-In-First-Out của Stack.
 Ví dụ về đảo chuỗi:

6

Tôi

Tập

Chăm

Giỏi

Làm


Bài

Học

Thì

Bài

Làm

Thì

Học

Tập

Tôi

Giỏi

Chăm

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.2. Đảo chuỗi (2/4)
Ý tưởng xây dựng chương trình:
1.


Tạo một wStack rỗng.

2.

Với mỗi từ mWord đọc được từ string, đưa từ đó
vào Stack:
Push mWord into wStack.

3.

Đọc từ wStack cho đến hết, thực hiện:
Pop a word from wStack into mWord.
Concate mWord to the end of outp string.

4.

Dừng giải thuật.

Chú ý: cần xây dựng hàm tách word từ string.
7

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.2. Đảo chuỗi (3/4)
#include <stdio.h>

for(int i=1; i
#include <stdlib.h>


{

#include <conio.h>

mWord = strtok(NULL," ");

#include "string.h"

if(mWord) push(stack,mWord,&top);

#define MAXSIZE 100

}

#define MAX 100

char *p=pop(stack,&top);

void push(char* stack[], char* value, int* top);

while(top>=0)

char* pop(char* stack[], int* top);

{

void main() {
char* stack[MAXSIZE];


p=strcat(p," ");

int top=-1;

p=strcat(p,pop(stack,&top));

char mString[MAX];

}

char* mWord;

printf("Chuoi ket qua \n");

printf("Nhap vao mot chuoi: ");

puts(p);

gets(mString);
mWord = strtok(mString," ");
push(stack,mWord,&top);

8

getch();
}

PhD. Ngo Huu Phuc, Le Quy Don Technical University



10.2. Đảo chuỗi (4/4)
void push(char* stack[], char* value, int* top)

char* pop(char* stack[], int* top)

{

{

char* value;
if(*top < MAXSIZE)

if(*top>=0)

{

{
*top=*top+1;

value=(char*)malloc(strlen(stack[*top]));

stack[*top]=(char*)malloc(strlen(value));

strcpy(value,stack[*top]);

strcpy(stack[*top],value);

*top=*top-1;

}


}

else

else

{

{

printf("Khong the them vao STACK\n");

value = NULL;

getch();

return value;

}
}

printf("STACK rong\n");

}
void makeEmpty(int* top)
*top=-1;
}

9


PhD. Ngo Huu Phuc, Le Quy Don Technical University

{

}


10.3. Chuyển đổi hệ số (1/9)
 Các hệ số hay sử dụng: hệ thập phân (Decimal), hệ

nhị phân (Binary), hệ 16 (Hexadecimal).
 Con người thường sử dụng hệ thập phân.
 Đối với máy tính, thường sử dụng hệ nhị phân.
 Hệ 16 là hệ trung gian giữa hệ thập phân và hệ nhị

phân.
 Ví dụ: 111 = (01101111)B = (6F)H

10

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.3. Chuyển đổi hệ số (2/9)
Việc chuyển đổi giữa các hệ số thường xét:
1.

Chuyển đổi từ hệ thập phân sang hệ nhị phân.


2.

Chuyển đổi từ hệ nhị phân sang hệ thập phân.

3.

Chuyển đổi từ hệ thập phân sang hệ 16.

4.

Chuyển đổi từ hệ 16 sang hệ thập phân.

11

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.3. Chuyển đổi hệ số (3/9)
Ý tưởng chuyển đổi từ hệ thập phân sang hệ nhị
phân sử dụng Stack:
 Khởi tạo một Stack rỗng.
 Chuyển đổi số từ dạng thập phân sang nhị phân bằng

phép div và mod cho 2.
 Kết quả của phép mod được đưa vào Stack.
 Đọc từ Stack cho đến hết, kết quả được nối với nhau để

tạo thành chuỗi.
 Kết thúc giải thuật.
12


PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.3. Chuyển đổi hệ số (4/9)
Các hàm chính Dec to Binary:

void push(char stack[], char value)

char* DecToBin(int a, char stack[]) {

{

if(stack[0] < MAXSIZE)

makeEmpty(stack);

stack[0]++;

int n=0;

stack[stack[0]]= value; }

while(a>0)

{

else

push(stack,a%2+'0');


{
printf("Khong the them vao STACK\n");

a=a/2;

getch();

n++;
}

char pop(char stack[])

char* mString;

{

mString = (char*) malloc(n);

}

if(stack[0]>0) {
value=stack[stack[0]];

while(stack[0]>0)

stack[0]--;

mString[i]=pop(stack);
i++;


}

mString[i]='\0';
return mString;

}

else

}

{
printf("STACK rong\n");
value = -1;
return value;

}
PhD. Ngo Huu Phuc, Le Quy Don Technical University

}

char value;

int i=0;
{

13

{


}


10.3. Chuyển đổi hệ số (3/9)
Ý tưởng chuyển đổi từ hệ thập phân sang hệ 16 sử
dụng Stack:
 Khởi tạo một Stack rỗng.
 Chuyển đổi số từ dạng thập phân sang nhị phân bằng

phép div và mod cho 16.
 Kết quả của phép mod được đưa vào Stack.
 Đọc từ Stack cho đến hết, kết quả được nối với nhau để

tạo thành chuỗi.
 Kết thúc giải thuật.
14

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.3. Chuyển đổi hệ số (4/9)
Các hàm chính Dec to Hex:

char* mString;

char* DecToHex(int a, char stack[])

mString = (char*) malloc(n);


{

int i=0;
makeEmpty(stack);

while(stack[0]>0)

int n=0;

{

while(a>0)

mString[i]=pop(stack);

{

i++;

int t = a%16;
}

if(t>=0 && t<=9)

mString[i]='\0';

push(stack,t+'0');

return mString;


else
push(stack,t-10+'A');

}

a=a/16;
n++;
}

15

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (1/6)
 Một biểu thức sử dụng dấu ngoặc (Bracket) đúng

nếu:
• với mỗi dấu ngoặc trái sẽ có 1 dấu ngoặc phải gần nhất

khớp với nó.
• với mỗi dấu ngoặc phải sẽ có 1 dấu ngoặc trái gần nhất

(bên trái) khớp với nó.
• một đoạn biểu thức nằm giữa một cặp dấu ngoặc trái,

phải được gọi là sử dụng đúng dấu ngoặc.

16


PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (2/6)
 Ví dụ về sử dụng dấu ngoặc trong biểu thức toán

học:

17

s * (s – a) * (s – b) * (s – c)



Well

(– b + (b2 – 4*a*c)^0.5) / 2*a



Well

s * (s – a) * (s – b * (s – c)



???

s * (s – a) * s – b) * (s – c)




???

(– b + (b^2 – 4*a*c)^(0.5/ 2*a))



???

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (3/6)
Giải thuật kiểm tra sử dụng dấu ngoặc:
1.

Tạo một bStack rỗng (Stack chứa dấu ngoặc).

2. Với mỗi ký hiệu sym trong đoạn (từ trái sang phải) :

2.1. Nếu sym là dấu ngoặc trái:
2.1.1. Đưa sym vào bStack.
2.2. Nếu sym là dấu ngoặc phải:
2.2.1. Nếu bStack rỗng, return false.
2.2.2. Lấy dấu ngoặc ở bStack, đưa vào biến left.
2.2.3. Nếu left và sym không khớp được với nhau,
return false.

3. Dừng giải thuật, trả về True nếu bStack rỗng, hoặc


False với các trường hợp khác.

18

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (4/6)
#include <stdio.h>

gets(a);

#include <stdlib.h>

if(bracketMatching(a,bStack,&top))

#include <conio.h>
#include "string.h"

printf("Bieu thuc su dung DUNG dau
ngoac\n");

#define MAXSIZE 100
#define MAX 100
void push(char bStack[], char value, int *top);

else
printf("Bieu thuc su dung KHONG
DUNG dau ngoac\n");


char pop(char bStack[], int *top);
int isEmpty(char bStack[],int top);

getch();
}

int isFull(char bStack[], int top);
void makeEmpty(int bStack[],int* top);
int bracketMatching(char* a,char bStack[], int *top);
void main()
{
char bStack[MAXSIZE];
char a[MAX];
int top=-1;
printf("Doc vao mot bieu thuc: ");
19

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (5/6)
int bracketMatching(char* a,char bStack[],int *top)

void push(char bStack[], char value, int *top)

{

{


int kt=1;
for(int i=0;i
if(*top
{

{
if(a[i]=='(')

*top = *top + 1;
push(bStack,a[i],top);

bStack[*top] = value;

if(a[i]==')')
}

{

else

if(isEmpty(bStack,*top))

{

kt=0;
else

printf("Khong the them vao STACK\n");


char ch=pop(bStack,top);

getch();

}
}

}
}

if(!isEmpty(bStack,*top))
kt=0;
return kt;
}
20

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.4. Bracket Matching (6/6)
char pop(char bStack[], int *top)

int isEmpty(char bStack[],int top)

{

{
char value;


if(top==-1)

if(*top>=0)

return 1;

{

else
value = bStack[*top];

return 0;

*top = *top - 1;
}

}

int isFull(char bStack[],int top)

else

{

{

if(top==MAXSIZE-1)

printf("STACK rong\n");
value = 0;


return 1;

}

else

return value;
}

return 0;
}
void makeEmpty(char bStack[], int *top)
{

21

PhD. Ngo Huu Phuc, Le Quy Don Technical University

*top=-1;

}


10.5. Balancing Act (1/4)
 Với phương pháp trước mới chỉ đảm bảo được khớp

dấu ngoặc ‘(‘ và ‘)’.
 Trong thực tế, còn có nhiều dấu ngoặc khác cần


khớp như: ‘(‘ và ‘)’; ‘[‘ và ‘]’; ‘{‘ và ‘}’.
 Như vậy, trong giải thuật trên, cần lưu ý thêm quá

trình push và pop vào bStack:
 Nếu quá trình push vào bStack có dạng: (, [, {.
 Quá trình pop từ bStack cần đúng thứ tự: }, ], ).
 Nếu đã duyệt xong biểu thức và bStack rỗng → return

True, ngược lại, return False.
22

PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.5. Balancing Act (2/4)
void main()

int balancingAct(char* a,char bStack[],int *top)

{

{
char bStack[MAXSIZE];

int kt=1;
for(int i=0;i
char a[MAX];

{


if(a[i]=='(' || a[i]=='[' || a[i] == '{')

int top=-1;

push(bStack,a[i],top);

printf("Doc vao mot bieu thuc: ");

if(a[i]==')' || a[i]=='}' || a[i]==']')

gets(a);

{

if(balancingAct(a,bStack,&top))

if(isEmpty(bStack,*top))

printf("Bieu thuc su dung DUNG dau
ngoac\n");

kt=0;

else

else

printf("Bieu thuc su dung KHONG DUNG dau
ngoac\n");


{

char ch=pop(bStack,top);
if(!matching(ch,a[i])) kt=0; }

getch();
}

}
}

if(!isEmpty(bStack,*top)) kt=0;
return kt;
23

}
PhD. Ngo Huu Phuc, Le Quy Don Technical University


10.5. Balancing Act (3/4)
int matching(char a, char b)
{
int kt=0;
if(a=='(' && b==')') kt=1;
if(a=='[' && b==']') kt=1;
if(a=='{' && b=='}') kt=1;
return kt;
}


24/24

PhD. Ngo Huu Phuc, Le Quy Don Technical University



×