Tải bản đầy đủ - 0 (trang)
CHƯƠNG 1: TÌM HIỂU KÝ PHÁP BA LAN

CHƯƠNG 1: TÌM HIỂU KÝ PHÁP BA LAN

Tải bản đầy đủ - 0trang

-



Đọc biểu thức từ trái sang phải, nếu gặp môt tốn hạng (con số hoặc biến) thì

lush tốn hạng vào ngăn xếp, nếu gặp toán tử, lấy hai toán hạng ra khỏi ngăn



-



xếp (stack), tính kết quả. Đẩy kết quả trở lại ngăn xếp.

Khi quá trình kết thúc con số cuối cùng còn lại trong ngăn xếp chính là giá trị

của biểu thức đó.



Thuật tốn:

-



Nếu gặp một tốn hạng (con số hoặc biến) thì ghi nó vào chuỗi kết quả (chuỗi



-



kết quả là biểu thức trung tố).

Nếu gặp dấu mở ngoặc, đưa nó vào Stack.

Nếu gặp một tốn tử (01) thực hiện 2 bước sau:

 Nếu có tốn tử 02 ở đỉnh ngăn xếp và độ ưu tiên của 01 nhỏ hơn hoặc



-



bằng độ ưu tiên của 02 thì lấy 02 ra khỏi ngăn xếp và ghi vào kết quả.

 Push 01 vào ngăn xếp.

Nếu gặp dấu đóng ngoặc thì lấy các toán tử trong ngăn xếp ra và ghi kết quả



-



đến khi lấy được dấu mở ngoặc ra khỏi ngăn xếp.

Khi đã duyệt biểu thức trung tố, lấy lần lượt tất cả các tốn hạng (nếu có) từ



ngăn xếp và ghi vào chuỗi kết quả.

1.3. Thuật toán chuyển đổi từ trung tố sang hậu tố

1.3.1. Độ ưu tiên của toán tử

Một trong những điều quan trọng trước khi bắt đầu là phải tính tốn được độ ưu tiên

của các toán tử trong biểu thức nhập vào. Để đơn giản ta chỉ xét các tốn tử hai ngơi

và thường dùng bao gồm: multiply (+),subtract (-), multiply (*), divide (/). Theo đó

các tốn tử “*, /” có cùng độ ưu tiên và cao hơn hai toán tử “+, -”.

public int priority(char c) {

if (c == '+' || c == '-') {

return 1;

} else if (c == '*' || c == '/') {

return 2;

}

else {

return 0;

}

}

1.3.2. Kiểm tra toán tử và toán hạng



Trong thuật tốn chuyển đổi này ta cần có các phương thức kiểm tra xem một thành

phần của chuỗi có phải là tốn tử hoặc tốn hạng khơng. Thay vì sử dụng các cấu trúc

if hoặc switch dài dòng và bất tiện khi phát triển, ta sẽ dùng Regex để kiểm tra.

Ngồi ra vì chuỗi nhập vào là một biểu thức đại số, nên các toán hạng ta sẽ xét khơng

chỉ là các chữ số mà còn có chữ cái từ a-z và A-Z.

Có một quy tắc nữa là khi dùng chữ cái thì chỉ cho phép duy nhất một chữ cái đại diện

cho một tốn hạng, còn khi dùng chữ số thì có thể nhiều chữ số ghép thành một toán

hạng.

public boolean isOperator(char c) {

char operator[] = {'+', '-', '*', '/', ')', '(', '~'};

Arrays.sort(operator);

if (Arrays.binarySearch(operator, c) > -1) {

return true;

} else {

return false;

}

}

1.3.3. Chuẩn hóa biểu thức Infix

Các biểu thức Infix khi nhập vào có thể dư thừa các khoảng trắng, các kí tự khơng phù

hợp hoặc viết sai cú pháp.

Ngồi ra các bạn còn phải ghép các chữ số liền nhau thành số (toán hạng), tách các

toán tử, phân cách với nhau bằng một khoảng trắng. Các phần tử này sẽ gọi là một

token.

public String[] processString(String sMath) {

String s1 = "", elementMath[] = null;

InfixToPostfix IFP = new InfixToPostfix();

sMath = sMath.trim();

sMath = sMath.replaceAll("\\s+", " ");

for (int i = 0; i < sMath.length(); i++) {

char c = sMath.charAt(i);

if (!IFP.isOperator(c)) {



s1 = s1 + c;

} else {

s1 = s1 + " " + c + " ";

}

}

s1 = s1.trim();

s1 = s1.replaceAll("\\s+", " ");

elementMath = s1.split(" ");

return elementMath;

}

1.3.4. Chuyển biểu thức Infix sang Postfix

Lý do em trình bày thuật tốn chuyển sang postfix trước vì thuật tốn này phổ biến và

dễ cài đặt hơn dạng prefix.

Thuật toán để chuyển một biểu thức Infix sang dạn Prefix:

Đọc từng token trong biểu thức infix từ trái qua phải, với mỗi token ta thực hiện các

bước sau:

-



Nếu là toán hạng: cho ra output.

Nếu là dấu mở ngoặc “(“: cho vào stack

Nếu là dấu đóng ngoặc “)”: lấy các toán tử trong stack ra và cho vào output cho

đến khi gặp dấu mở ngoặc “(“. (Dấu mở ngoặc cũng phải được đưa ra khỏi



-



stack)

Nếu là toán tử:

 Chừng nào ở đỉnh stack là toán tử và tốn tử đó có độ ưu tiên lớn hơn hoặc

bằng tốn tử hiện tại thì lấy tốn tử đó ra khỏi stack và cho ra output.

 Đưa toán tử hiện tại vào stack



Sau khi duyệt hết biểu thức infix, nếu trong stack còn phần tử thì lấy các token trong

đó ra và cho lần lượt vào output.

Ví dụ: Chuyển biểu thức A*B+C*((D-E)+F)/G từ dạng Infix sang dạng Postfix

Tocken

A

*

B

+

C



Stack

{Empty}

*

*

+

+



Output

A

A

AB

AB*

AB*C



*

(

)

D

E

)

+

F

)

/

G



+*

AB*C

+*(

AB*C

+*((

AB*C

+*((

AB*CD

+*((AB*CD

+*((AB*CDE

+*(

AB*CDE+*(+

AB*CDE+*(+

AB*CDEF-F

+*

AB*CDE-F+

+/

AB*CDE-F+*

+/

AB*CDE-F+*G

{Empty}

AB*CDE-F+*G/+

Dựa theo thuật toán trên, ta cài đặt một phương thức tương ứng trên Java.

public String[] postfix(String[] elementMath) {

String s1 = "", E[];

Stack S = new Stack();

for (int i = 0; i < elementMath.length; i++) {

char c = elementMath[i].charAt(0);

if (!isOperator(c))

{

s1 = s1 + elementMath[i] + " ";

} else {

if (c == '(') {

S.push(elementMath[i]);

} else {

if (c == ')') {

char c1;

do {

c1 = S.peek().charAt(0);

if (c1 != '(') {

s1 = s1 + S.peek() + " ";

}

S.pop();



} while (c1 != '(');

} else {

while (!S.isEmpty() &&

priority(S.peek().charAt(0)) >= priority(c)) {

s1 = s1 + S.peek() + " ";

S.pop();

}

S.push(elementMath[i]);

}

}

}

}

while (!S.isEmpty()) {

s1 = s1 + S.peek() + " ";

S.pop();

}

E = s1.split(" ");

return E;

}

1.3.5. Thuật tốn tính giá trị của biểu thức tiền tố.

Khơng có nhiều sự khác biệt giữa việc chuyển từ Infix sang Prefix với Infix sang

Postfix, chủ yếu là sự thay đổi thứ tự duyệt từ phải sang trái thay vì từ trái sang phải.

Và thay vì duyệt theo hướng ngược lại, có thể thực hiện một chuyển đổi nhỏ để đảo

ngược biểu thức nhập vào.

Sử dụng “đảo ngược biểu thức” thay vì ”đảo ngược chuỗi”, việc đảo ngược này phải

giữ nguyên được giá trị của các toán hạng, ví dụ bạn khơng thể đảo ngược 12 thành 21

được. Hơn nữa vì chuỗi đã đảo ngược nên các dấu ngoặc đơn cũng phải được hiểu

ngược lại.

Ví dụ: Chuyển biểu thức Infix A*B+C*((D-E)+F)/G sang dạng Prefix

Đầu tiên ta đảo ngược biểu thức trên thành G/)F+)E-D((*C+B*A, sau đó ta thực hiện

các bước trong thuật toán sau:



Đọc từng token trong biểu thức infix từ trái qua phải, với mỗi token ta thực hiện các

bước sau:

-



Nếu là toán hạng: cho ra output.

Nếu là dấu đóng ngoặc “)“: cho vào stack

Nếu là dấu mở ngoặc “(”: lấy các toán tử trong stack ra và cho vào output cho

đến khi gặp dấu đóng ngoặc “)“. (Dấu đóng ngoặc cũng phải được đưa ra khỏi

stack)

Nếu là toán tử:

 Chừng nào ở đỉnh stack là toán tử và tốn tử đó có độ ưu tiên lớn hơn



-



tốn tử hiện tại thì lấy tốn tử đó ra khỏi stack và cho ra output.

 Đưa toán tử hiện tại vào stack.

Sau khi duyệt hết biểu thức infix, nếu trong stack còn phần tử thì lấy các token trong

đó ra và cho lần lượt vào output. Cuối cùng là đảo ngược biểu thức một lần nữa và ta

sẽ thu được kết quả.

1.3.6. Thuật tốn tính giá trị của biểu thức hậu tố.

Việc tính giá trị của một biểu thức tốn học ở dạng trung tố trong máy tính thơng

thường sẽ được chuyển sang dạng ký pháp nghịch đảo Ba Lan (hậu tố) để việc tính

tốn được dễ dàng. Trong phương pháp tính giá trị của một biểu thức hậu tố bằng

Stack.

Lặp qua các token của của biểu thức postfix từ trái qua phải:

– Nếu là toán hạng: push vào stack

– Nếu là toán tử: pop hai toán hạng trong stack ra và tính giá trị của chúng dựa vào

tốn tử này. Push kết quả đó lại vào stack.

Phần tử còn sót lại trong stack sau vòng lặp chính là kết quả của biểu thức.

Với elementMath là mảng các phần tử của biểu thức hậu tố.

public String valueMath(String[] elementMath) {

Stack S = new Stack();

for (int i = 0; i < elementMath.length; i++) {

char c = elementMath[i].charAt(0);

if (!isOperator(c)) {

S.push(elementMath[i]);

} else {

double num = 0f;



double num1 = Float.parseFloat(S.pop());

double num2 = Float.parseFloat(S.pop());

switch (c) {

case '~' :

num = -num1;

break;

case '+':

num = num2 + num1;

break;

case '-':

num = num2 - num1;

break;

case '*':

num = num2 * num1;

break;

case '/':

num = num2 / num1;

break;

default:

break;

}

S.push(Double.toString(num));

}

}

return S.pop();

}



CHƯƠNG 2: TÌM HIỂU VỀ ANDROID

2.1. Giới thiệu về Anroid

Android là một hệ điều hành có mã nguồn mở dựa trên nền tảng Linux được thiết kế

dành cho các thiết bị di động có màn hình cảm ứng như điện thoại thơng minh và máy

tính bảng.

Ban đầu, Android được phát triển bởi Tổng công ty Android, với sự hỗ trợ tài chính từ

Google, sau này được chính Google mua lại vào năm 2005 và hệ điều hành Android đã

ra mắt vào năm 2007. Chiếc điện thoại đầu tiên chạy Android là HTC Dream được bán

vào ngày 22 tháng 10 năm 2008.

2.2. Ưu và nhược điểm hệ điều hành Android

Ưu điểm:

-



Là hệ điều hành có mã nguồn mở nên khả năng tuỳ biến cao, có thể tùy ý chỉnh



-



sửa mà khơng có sự can thiệp hay cấm cản từ Google.

Đa dạng sản phẩm, rất nhiều hãng điện thoại, thiết bị công nghệ đã ưu ái chọn



-



Android cho thiết bị của họ, giá cả thì hợp lý từ bình dân đến cao cấp.

Kho ứng dụng Google Play Store đồ sộ.

Thân thiện và dễ sử dụng.

Khả năng đa nhiệm, chạy cùng lúc nhiều ứng dụng cao.



Nhược điểm:

-



Dễ nhiễm phần mềm độc hại và virus. Do tính chất mã nguồn mở, nhiều phần

mềm khơng được kiểm sốt có chất lượng không tốt hoặc lỗi bảo mật vẫn được



-



sử dụng.

Kho ứng dụng q nhiều dẫn đến khó kiểm sốt chất lượng, thiếu các ứng dụng



-



thật sự tốt.

Sự phân mảnh lớn. Trong khi một số thiết bị Android xuất sắc đã trình làng như

Galaxy S5, Galaxy Note 4, Xperia Z3…, vẫn còn rất nhiều sản phẩm giá rẻ bình



-



thường khác.

Cập nhật khơng tự động với tất cả thiết bị. Khi một phiên bản hệ điều hành mới

ra mắt, không phải tất cả sản phẩm đều được cập nhật, thậm chí nếu muốn trải

nghiệm bạn thường xuyên phải mua mới thiết bị.



2.3. Các thành phần trong ứng dụng Android

Có 4 kiểu thành phần trong ứng dụng của Android bao gồm:

-



Activities.

Services.



-



Content providers.

Broadcast receivers.



Mỗi thành phần này được sử dụng cho mỗi mục đích khác nhau và có một vòng đời

khác nhau:

 Activity (Android.app.Activity): đây là lớp khởi tạo giao diện ứng dụng nội

bộ trên Android tương tư như MIDlet trong J2ME.

 Service (Android.app.Service): cung cấp các dịch vụ liên quan đến

client/service. Một Service sẽ chạy ngầm bên dưới, sau đó các client (Activity)

sẽ kết nối và truy xuất các hàm trên dịch thông qua Interface class.

 Broadcast receiver (Android.content.BroadcastReceiver): đây là một ứng dụng

chạy ngầm dùng để đọc và cập nhật thông tin trên UI, ví dụ như cập nhật sự

thay đỗi giờ, pin...

 Content Provider: cung cấp chức năng truy vấn dữ liệu giữa các ứng dụng của

Android.

 Intent: nền tảng để truyền tải các thông báo. Intent được sử dụng để gửi các

thông báo đi nhằm khởi tạo 1 Activity hay Service để thực hiện công việc mà

chúng ta mong muốn.

2.4. Các thành phần giao diện trong Android

2.3.1. View

Trong Android giao diện người dùng được xây dựng từ các đối tượng View. Trong

Android Platform, các screen ln được bố trí theo một kiểu cấu trúc phân cấp như

hình trên. Một screen là một tập hợp các Layout và các widget được bố trí có thứ tự.

Để thể hiện một screen thì trong hàm onCreate của mỗi Activity cần phải được gọi

một hàm là setContentView (R.layout.main); hàm này sẽ load giao diện từ file

MAIN.XML lên để phân tích thành mã bytecode.

2.3.2. ViewGroup

ViewGroup là sự mở rộng của class View hay nói cách khác ViewGroup chính là

các WidgetLayout được dùng để bố trí các đối tượng khác trong một screen.Có các

loại ViewGroup như sau:

 Linear Layout

LinearLayout được dùng để bố trí các thành phần giao diện theo chiều ngang hoặc

chiều dọc nhưng trên một line duy nhất mà khơng có xuống dòng.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

CHƯƠNG 1: TÌM HIỂU KÝ PHÁP BA LAN

Tải bản đầy đủ ngay(0 tr)

×