MỤC LỤC
LỜI NÓI ĐẦU............................................................................................................... 3
CHƯƠNG 1: TÌM HIỂU KÝ PHÁP BA LAN..............................................................4
1.1.
Giới thiệu ký pháp Ba Lan...............................................................................4
1.2.
Ý tưởng của bài toán........................................................................................5
1.3.
Thuật toán chuyển đổi từ trung tố sang hậu tố..................................................5
1.3.1.
Độ ưu tiên của toán tử................................................................................5
1.3.2.
Kiểm tra toán tử và toán hạng....................................................................6
1.3.3.
Chuẩn hóa biểu thức Infix..........................................................................6
1.3.4.
Chuyển biểu thức Infix sang Postfix..........................................................7
1.3.5.
Thuật toán tính giá trị của biểu thức tiền tố...............................................9
1.3.6.
Thuật toán tính giá trị của biểu thức hậu tố..............................................10
CHƯƠNG 2: TÌM HIỂU VỀ ANDROID....................................................................13
2.1. Giới thiệu về Anroid..........................................................................................13
2.2. Ưu và nhược điểm hệ điều hành Android..........................................................13
2.3. Các thành phần trong ứng dụng Android...........................................................14
2.4. Các thành phần giao diện trong Android...........................................................14
2.3.1. View............................................................................................................14
2.3.2. ViewGroup..................................................................................................15
2.5. Các control trong Android.................................................................................16
2.6. Cách tạo ra ứng dụng Android...........................................................................17
CHƯƠNG 3: XÂY DỰNG ỨNG DỤNG ANDROID.................................................20
3.1. Ý tưởng xây dựng ứng dụng “Calculator”.........................................................20
3.2. Công cụ.............................................................................................................20
3.3. Giao diện chương trình......................................................................................21
3.4. Source code.......................................................................................................23
KẾT LUẬN.................................................................................................................. 29
TÀI LIỆU THAM KHẢO............................................................................................30
LỜI NÓI ĐẦU
Mạng điện thoại di động xuất hiện tại Việt Nam từ đầu những năm 1990 và theo
thời gian số lượng các thuê bao cũng như các nhà cung cấp dịch vụ đi động tại Việt
Nam ngày càng tăng. Do nhu cầu trao đổi thông tin ngày càng tăng và nhu cầu sử dụng
sản phẩm công nghệ cao nhiều tính năng, cấu hình cao, chất lượng tốt, kiểu dáng mẫu
mà đẹp, phong phú nên nhà cung cấp phải luôn luôn cải thiện, nâng cao những sản
phẩm của mình. Do đó việc xây dựng các ứng dụng cho điện thoại di động đang là một
ngành công nghiệp mới đầy tiềm năng và hứa hẹn nhiều sự phát triển vượt bậc của
ngành khoa học kĩ thuật. Cùng với sự phát triển của thị trường điện thoại di động là sự
phát triển mạnh mẽ của xu hướng lập trình phần mềm ứng dụng cho các thiết bị di
động. Phần mềm, ứng dụng cho điện thoại di động hiện nay rất đa dạng và phong phú
trên các hệ điều hành di động cũng phát triển mạnh mẽ và đang thay đổi từ ngày. Các
hệ điều hành J2ME, Android, IOS, Hybrid, Web based Mobile Application đã có rất
phát triển trên thị trường truyền thông di động. Trong vài năm trở lại đây, hệ điều hành
Android ra đời với sự kế thừa những ưu việt của các hệ điều hành ra đời trước và sự
kết hợp của nhiều công nghệ tiên tiến nhất hiện nay, đã được nhà phát triển công nghệ
rất nổi tiếng hiện nay là Google. Android đã nhanh chóng là đối thủ cạnh tranh mạnh
mẽ với các hệ điều hành trước đó và đang là hệ điều hành di động của tương lai và
được nhiều người ưa chuộng nhất. Ngày nay, với sự phát triển nhanh chóng của xã hội,
những tiện ích smartphone và nhu cầu tình toán, vì vậy em đã chọn đề tài “Tìm hiểu
ký pháp Ba Lan và xây dựng ứng dụng Calculator” với mục đích nghiên cứu,tìm hiểu
về ký pháp Ba Lan và xây dựng ứng dụng Calculator để có thể đáp ứng được nhu cầu
tính toán một cách nhanh chóng và tiện lợi.
CHƯƠNG 1: TÌM HIỂU KÝ PHÁP BA LAN
1.1.
Giới thiệu ký pháp Ba Lan
Ký pháp Ba Lan do nhà logic toán Jan Łukasiewicz đề xuất khoảng năm 1920. Jan
Łukasiewicz là một nhà toán học người Ba Lan. Ông sinh ra ở Lwów, Galicia (nay là
Lviv, Ukraina). Lĩnh vực nghiên cứu chính của ông là logic toán.
Các biểu thức đại số được sử dụng hằng ngày đều được biểu diễn dưới dạng trung
tố (Infix). Cách biểu diễn này rất dễ hiểu với con người vì hầu hết các toán tử (+, -,
*, /) đều là toán tử hai ngôi và chúng phân cách giữa hai toán hạng với nhau. Tuy
nhiên đối với máy tính, để tính được giá trị của một biểu thức đại số theo dạng này
không đơn giản như ta vẫn làm. Để khắc phục điều đó, máy tính cần chuyển cách biểu
diễn các biểu thức đại số từ trung tố sang một dạng khác là tiền tố hoặc hậu tố.
Thế nào là biểu thức tiền tố, trung tố và hậu tố ?
Biểu thức tiền tố (Prefix)
-
Biểu thức tiền tố được biểu diễn bằng cách đặt toán tử lên trước các toán hạng.
Cách biểu diễn này còn được biết đến với tên gọi “ký pháp Ba Lan” do nhà toán
học Ba Lan Jan Łukasiewicz phát minh năm 1920. Với cách biểu diễn này, thay
vì viết x+y như dạng trung tố, ta sẽ viết +xy. Tùy theo độ ưu tiên của toán tử mà
chúng sẽ được sắp xếp khác nhau, bạn có thể xem một số ví dụ ở phía sau phần
giới thiệu này.
Biểu thức hậu tố (Posfix)
-
Ngược lại với cách Prefix, tức là các toán tử sẽ được đặt sau các toán hạng.
Cách biểu diễn này được gọi là “ký pháp nghịch đảo Ba Lan” hoặc được viết tắt
là RPN (Reverse Polish notation), được phát minh vào khoảng giữa thập kỷ
1950 bởi một triết học gia và nhà khoa học máy tính Charles Hamblin người
Úc.
Một số ví dụ:
Infix
a+b
a+b–c
a+b*c
a + (b – c)
1.2.
Prefix
+ab
-+abc
+a*bc
+x-yz
Ý tưởng của bài toán
Posfix
ab+
ab+cabc*+
abc-+
-
Đọc biểu thức từ trái sang phải, nếu gặp môt toán hạng (con số hoặc biến) thì
lush toá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 toán:
-
Nếu gặp một toá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 toán tử (01) thực hiện 2 bước sau:
Nếu có toá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 toá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 toá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 toán tử hai ngôi
và thường dùng bao gồm: multiply (+),subtract (-), multiply (*), divide (/). Theo đó
các toá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 toá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à toán tử hoặc toá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.
Ngoà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 toá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.
Ngoà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 toán chuyển sang postfix trước vì thuật toá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à toán tử đó có độ ưu tiên lớn hơn hoặc
bằng toán tử hiện tại thì lấy toá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<String> S = new Stack<String>();
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 toá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à toán tử đó có độ ưu tiên lớn hơn
-
toán tử hiện tại thì lấy toá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 toá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 toá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
toá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
toá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<String> S = new Stack<String>();
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 soá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 quá nhiều dẫn đến khó kiểm soá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 luôn đượ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.
Frame layout
FrameLayout được dùng để bố trí các đối tượng theo kiểu giống như làcác Layer
trong Photoshop. Những đối tượng nào thuộc Layer bên dưới thì sẽ bị che khuất bởi
các đối tượng thuộc Layer nằm trên. FrameLayer thường được sử dụng khi muốn
tạo ra các đối tượng có khung hình bên ngoài chẳng hạn như contact image button.
Table layout
Layout này được sử dụng khi cần thiết kế một table chứa dữ liệu hoặc cần bố trí các
widget theo các row và column. Chẳng hạn như, giao diện của một chiếc máy tính
đơn giản hoặc một danh sách dữ liệu.
AbsoluteLayout
Layout này được sử dụng để bố trí các widget vào một vị trí bất kì trong layout dựa
vào 2 thuộc tính toạ độ x, y. Tuy nhiên, kiểu layout này rất ít khi được dùng bởi vì
toạ độ của các đối tượng luôn cố định và sẽ không tự điều chỉnh được tỷ lệ khoảng
cách giữa các đối tượng. Khi chuyển ứng dụng sang một màn hình có kích thước
với màn hình thiết kế ban đầu thì vị trí của các đối tượng sẽ không còn được chính xác
như ban đầu.
RelativeLayout
Layout này cho phép bố trí các widget theo một trục đối xứng ngang hoặc dọc. Để
đặt được đúng vị trí thì các widget cần được xác định một mối ràng buộc nào đó
với các widget khác. Các ràng buộc này là các ràng buộc trái, phải, trên, dưới so với
một widget hoặc so với layout parent. Dựa vào những mối ràng buộc đó mà
RetaliveLayout cũng không phụ thuộc vào kích thước của screen thiết bị. Ngoài ra, nó
còn có ưu điểm là giúp tiết kiệm layout sử dụng nhằm mục đích giảm lượng tài
nguyên sử dụng khi load đồng thời đẩy nhanh quá trình xử lý.
2.5. Các control trong Android
Button
Button là một Push-Button mà có thể được nhấn, hoặc được click, bởi người dùng
để thực hiện một hành động.
Button là 1 control có kế thừa textView, dùng để thiết lập các sự kiện khi người
dùng thao tác với nó.
EditText
Là một loại thành phần trên giao diện mà người dùng cuối có thể nhập dữ liệu ở
dạng văn bản vào.
TextView
Là một đối tượng để hiển thị một dòng chữ, một thông báo, một đề nghị,… dưới
dạng văn bản. Nội dung văn bản của đối tượng này thường do người lập trình ứng
dụng Android thiết lập trước.
ImageView
Là đối tượng dùng để hiển thị hình ảnh do lập trình viên Android chỉ định.
CheckBox
Đối tượng thường dùng để thể hiện trạng thái bật/tắt. Lập trình viên Android
thường sử dụng checkbox để cho phép người dùng check (chọn) làm gì đó hay không.
RadioButton
Là loại đối tượng cho phép biểu thị 1 trong 2 trạng thái là đang được chọn hoặc
đang không được chọn. Loại đối tượng này thường được sử dụng theo nhóm từ 2
RadioButton trở lên để hỗ trợ việc chỉ được chọn 1 trong 1 tập hợp các RadioButton
của cùng 1 nhóm.
RadioGroup
Là đối tượng quản lý nhiều RadioButton, cho phép chỉ chọn 1 RadioButton trong
nhóm. Lập trình viên Android thường sử dụng loại điều khiến này để cho người dùng
chọn một trong số các tùy chọn xác định nào đó.
ToggelButton
Là loại nút thể hiện 2 trạng thái là ấn hoặc không ấn (on/off).
ProgressBar
Là đối tượng dùng để biểu diễn tiến độ của một công việc nào đó (Tính theo tỉ lệ
%).
EditText là một tấm bìa trải qua TextView mà cấu hình chính nó để có thể chỉnh sửa.
Nó là một lớp phụ của TextView mà bao gồm các khả năng chỉnh sửa đa dạng.
ContextMenu
ContextMenu được sử dụng để hiển thị các tuỳ chọn khi người dùng nhấn dài
vào một Button trên màn hình.
2.6. Cách tạo ra ứng dụng Android
Để tạo ra một ứng dụng android thì hiện nay có rất nhiều IDE hỗ trợ cho phép tạo ra
project Android như: Eclipse, Netbean...
Android Studio có nhiều phiên bản khác nhau, ở trong ảnh là version 3.0.1
Nhấn vào strat new Android Project sẽ ra một cửa sổ để tạo Project mới.
Đặt tên Application Name, Company domain và nơi lưu project.
Nhấn next để tiếp tục
Chọn phiên bản SDK minium là phiên bản Android có thể chạy được ứng dụng.
Và chọn lựa chọn cho Wear, TV...
Nhấn next để tiếp tục
Nhấn next để cấu hình Activy Name
Chọn finish và chờ Android Studio tạo ra 1 project mới.
CHƯƠNG 3: XÂY DỰNG ỨNG DỤNG ANDROID
3.1. Ý tưởng xây dựng ứng dụng “Calculator”.
Sử dụng ký pháp Ba Lan ngược và sử dụng công cụ Android Studio để tạo ra ứng dụng
Calculator.
Tại sao chúng ta nên dùng thuật toán Ba Lan ngược để biểu diễn biểu thức khi muốn
tính giá trị biểu thức bằng lập trình máy tính?
Khi lập trình, việc để cho máy tính tính giá trị một biểu thức toán học là điều quá đỗi
bình thường, nhưng để trình bày làm sao cho máy tính có thể đọc và hiểu được quy
trình tính toán đó không phải là điều đơn giản. Trong nhiều ứng dụng (như chương
trình vẽ đồ thị hàm số chẳng hạn, trong đó chương trình cho phép người dùng nhập
vào hàm số), ta cần phải tính giá trị của một biểu thức được nhập vào từ bàn phím dưới
dạng một chuỗi. Với các biểu thức toán học đơn giản (như a+b) thì bạn có thể tự làm
bằng các phương pháp tách chuỗi “thủ công”. Nhưng để “giải quyết” các biểu thức có
dấu ngoặc, ví dụ như (a+b)*c + (d+e)*f , thì các phương pháp tách chuỗi đơn giản đều
không khả thi. Trong tình huống này, ta phải dùng đến Ký Pháp Nghịch Đảo Ba Lan
(Reserve Polish Notation – RPN), một thuật toán “kinh điển” trong lĩnh vực trình biên
dịch.
Tại sao phương pháp nghịch đảo Ba Lan lại giúp cho máy tính hiểu được biểu thức?
Máy tính cũng chỉ là một cái máy, quá trình lập trình ta sẽ cần trừu tượng quá quy trình
xử lý một cách rõ ràng (trong khi con người đã có thể bỏ qua bước này, giống như bạn
có thể đọc 1 biểu thức 1 lần là có thể biết được cặp số hạng nào cần tính trước cái nào
phải tính sau. Nhưng máy tính muốn biết được điều đó ta phải trừu tượng quá trình đó
bằng sự kết hợp giữa ngăn xếp và hàng đợi). Chính sự kết hợp 1 cách khéo léo của lập
trình viên trong việc sử dụng thuật toán nghịch đảo Ba Lan, kiến thức tính biểu thức,
kĩ năng thao tác với hàng đợi và ngăn xếp, là điều mà sẽ giúp cho máy tính hiểu được
nó phải làm gì với biểu thức.
3.2. Công cụ.
Để xây dựng ứng dụng “Calculator” em có sử dụng công cụ Android Studio. Lý do em
chọn công cụ này vì: Android Studio là một môi trường phát triển tích hợp (IDE Integrated Development Environment) , được dựa trên một tên tuổi nổi tiếng IntelliJ
IDE. Android Studio là một môi trường thiết kế và phát triển ứng dụng cho nền tảng
Android. Môi trường phát triển này rất dễ cài đặt, thiết lập và có thể tạo ra một dự án
(project) mới chỉ sau vài giây.
Với Android Studio thì có nhiều ưu điểm hơn nhờ các yếu tố sau:
-
Giao diện chỉnh sửa WYSIWYG Editor hỗ trợ Live-layout có thể dựng ứng
-
dụng và xem trước theo thời gian thực.
Có tùy chọn để xem trước giao diện với nhiều thiết lập trên nhiều màn hình khi
-
viết ứng dụng.
Cho phép tạo ra file cài đặt APK (file cài đặt ứng dụng Android) hàng loạt.
Hỗ trợ công cụ Lint để kiểm tra tính tương thích, hiệu năng ứng dụng và khả
-
năng hoạt động trên nhiều phiên bản Android...
Hỗ trợ phát triển ứng dụng cho Android Wear, Android TV và Android Auto.
Có thể tích hợp với nền tảng đám mây Google Cloud Platform (App Engine và
Google Cloud Messaging)
3.3. Giao diện chương trình
Giao diện khi chạy ứng dụng Calculator sử dụng LineLayout, Button và TextView để
thiết kế. Giao diện gồm Button số từ 0 – 9, dấu ngoặc (), dấu bằng, dấu chấm và các
toán tử tính toán.
Giao diện ứng dụng sau tính 1 biểu thức.
3.4. Source code
Source file InfixToPostfix
package ictu.ttcs.tuanictu97.calplus;
import java.util.Arrays;
import java.util.Stack;
public class InfixToPostfix {
public int priority(char c) {
tu uu tien
if (c == '+' || c == '-') {
// thiet lap thu
return 1;
} else if (c == '*' || c == '/') {
return 2;
}
else {
return 0;
}
}
public boolean isSoAm(char c){
boolean check = false;
try {
Float num =
Float.parseFloat(String.valueOf(c));
if (num < 0){
check = true;
}else
check = false;
}catch (Exception e){
System.out.println("Lỗi");
}
return check;
}
public boolean isOperator(char c) {
// kiem tra
xem co phai toan tu
char operator[] = {'+', '-', '*', '/', ')', '(',
'~'};
Arrays.sort(operator);
if (Arrays.binarySearch(operator, c) > -1) {
return true;
} else {
return false;
}
}
public String[] processString(String sMath) { // xu
ly bieu thuc nhap vao thanh cac phan tu
String s1 = "", elementMath[] = null;
InfixToPostfix IFP = new InfixToPostfix();
sMath = sMath.trim();
sMath = sMath.replaceAll("\\s+", " "); //
chuan hoa sMath
for (int i = 0; i < sMath.length(); i++) {
char c =
sMath.charAt(i);//sMath.substring(i,1);
if (!IFP.isOperator(c)) {
s1 = s1 + c;
} else {
s1 = s1 + " " + c + " ";
}
}
s1 = s1.trim();
s1 = s1.replaceAll("\\s+", " "); //
chuan hoa
s1
elementMath = s1.split(" "); //tach s1 thanh cac
phan tu
//System.out.println(s1);
return elementMath;
}
public String reverseArrayString(String[] elementMath)
{
String string = "";
for (int i = elementMath.length; i
string += elementMath[i];
}
return string;
}
public String[] postfix(String[] elementMath) {
String s1 = "", E[];
Stack<String> S = new Stack<String>();
for (int i = 0; i < elementMath.length; i++) {
// duyet cac phan tu
char c = elementMath[i].charAt(0);
//
c la ky tu dau tien cua moi phan tu
if (!isOperator(c)) // neu c khong la toan tu
{
s1 = s1 + elementMath[i] + " ";
//
xuat elem vao s1
} else {
// c la toan tu
if (c == '(') {
S.push(elementMath[i]);
// c la
"(" -> day phan tu vao Stack
} else {
if (c == ')') {
// c la ")"
char c1;
//duyet lai cac phan tu trong Stack
do {
c1 = S.peek().charAt(0);
// c1 la ky tu dau tien cua phan tu
if (c1 != '(') {
s1 = s1 + S.peek() + " ";
// trong khi c1 != "("
}
S.pop();
} while (c1 != '(');
} else {
while (!S.isEmpty() &&
priority(S.peek().charAt(0)) >= priority(c)) {
// Stack khong rong va trong
khi phan tu trong Stack co do uu tien >= phan tu hien tai
s1 = s1 + S.peek() + " ";
// xuat phan tu trong Stack ra s1
S.pop();
}
S.push(elementMath[i]); //
dua phan tu hien tai vao Stack
}
}
}
}
while (!S.isEmpty()) {
// Neu Stack con phan
tu thi day het vao s1
s1 = s1 + S.peek() + " ";
S.pop();
}
E = s1.split(" ");
//
tach s1 thanh cac
phan tu
return E;
}
public String valueMath(String[] elementMath) {
Stack<String> S = new Stack<String>();
for (int i = 0; i < elementMath.length; i++) {
char c = elementMath[i].charAt(0);
if (!isOperator(c)) {