Category Archives: 06. Các thư viện thường dùng

Bài 18- Xử lý chuỗi trong Kotlin


Trong tất cả các ngôn ngữ lập trình thì Xử lý chuỗi vô cùng quan trọng, hầu như các dự án ta đều phải liên quan tới xử lý chuỗi.

Toàn bộ thông tin chi tiết về chuỗi trong Kotlin được trình bày tại đây https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/, các bạn có thời gian thì vào đó xem. Trong bài học này Tui sẽ trình bày một số hàm thường dùng nhất trong chuỗi.

Để khai báo chuỗi trong Kotlin ta dùng:

var s:String=”Obama”

hoặc

var s:String?=”Putin”

Một chuỗi trong Kotlin sẽ có các thuộc tính và phương thức sau(rất rất nhiều phương thức hữu ích, nhưng Tui chỉ có thể liệt kê một số mà thôi):

Tên Thuộc tính/

phương thức

Mô tả
length thuộc tính trả về chiều dài của chuỗi
indexOf(chuỗi) Trả về vị trí đầu tiên tìm thấy, không tìm thấy trả về -1
lastIndexOf(chuỗi) lastIndexOf trả về vị trí cuối cùng tìm thấy
contains(chuỗi con) Contains Kiểm tra chuỗi con có nằm trong chuỗi s?
subString(vt) Trích lọc toàn bộ bên phải chuỗi từ vt
subString(startIndex,endIndex) Trích lọc giữa chuỗi nằm giữa start tới end index
replace(chuỗi cũ, chuỗi mới) Đổi toàn bộ chuỗi cũ thành chuỗi mới
replaceFirst(chuỗi cũ, chuỗi mới) Đổi chuỗi cũ thành chuỗi mới nhưng chỉ áp dụng cho chuỗi cũ đầu tiên
trimStart xóa khoảng trắng dư thừa bên trái
trimEnd xóa khoảng trắng dư thừa bên phải
trim xóa khoảng trắng dư thừa bên trái và phải
compareTo(chuỗi s2)
So sánh 2 chuỗi có phân biệt chữ HOA và chữ thường

=0 khi s1=s2

>0 khi s1>s2

<0 khi s1<s2

compareTo(s2, ignoreCase = true) So sánh 2 chuỗi KHÔNG phân biệt chữ HOA và chữ thường

=0 khi s1=s2

>0 khi s1>s2

<0 khi s1<s2

 plus(chuỗi x)  Nối chuỗi x vào chuỗi gốc
 split(chuỗi tách)  Tách chuỗi gốc thành List<String>
 toUpperCase  Chuyển chuỗi thành IN HOA
 toLowerCase  Chuyển chuỗi thàh in thường

Bây giờ Tui đi vào từng hàm để các bạn dễ dàng thực hành về xử lý chuỗi:

  • Hàm IndexOf – trả về vị trí đầu tiên tìm thấy, nếu không thấy trả về -1:

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s:String="Obama"
var i = 0
// Trả về i = 2
i = s.indexOf("a")
println(i)
}

Ta thấy rõ ràng ký tự/chuỗi a xuất hiện 2 lần, nhưng Kotlin chỉ quan tâm kết quả đầu tiên mà thôi, vì vậy kết quả =2 sẽ được xuất ra màn hình (vị trí bắt đầu tính từ 0).

  • lastIndexOf trả về vị trí cuối cùng tìm thấy, nếu không thấy trả về -1:

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s: String = "Hello everybody !";
var i = 0;
// Trả về i = 8
i = s.lastIndexOf("e");
println(i)
}

Ta thấy kết quả xuất ra =8 là vị trí cuối cùng của ký tự/chuỗi e

  • Contains kiểm tra chuỗi con có tồn tại trong chuỗi gốc hay không, có thì trả về true, còn không trả về false

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s :String  = "Hello everybody !"
var s2="body"
if(s.contains(s2))
{
println("Có tồn tại [$s2]")
}
else
{
println("Ko tồn tại [$s2]")
}
}

Kết quả chạy ta thấy xuất “Có tồn tại [body]”. Hàm contains được sử dụng rất nhiều để kiểm tra sự tồn tại của chuỗi con.

  • subString – trích lọc chuỗi

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
val s = "Xin chào Obama! Tui là Putin"
val s2 = s.substring(9)
println(s2)
val s3 = s.substring(9, 14)
println(s3)
}

Kết quả khi chạy ta thấy:

Obama! Tui là Putin
Obama

Muốn trích lọc bên phải chuỗi thì dùng substring với 1 đối số, muốn trích lọc giữa chuỗi thì dùng 2 đối số.

  • replace – đổi chuỗi cũ thành chuỗi mới

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s = "Xin chào Obama! Tui là Putin"
s = s.replace("Obama", "Kim Jong Un")
println(s)
}

Kết quả khi chạy ta thấy:

Xin chào Kim Jong Un! Tui là Putin
  • replaceFirst-Đổi chuỗi cũ thành chuỗi mới nhưng chỉ áp dụng cho chuỗi đầu tiên tìm thấy

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s = "Obama Xin chào Michelle Obama"
s = s.replaceFirst("Obama", "Putin")
println(s)
}

Kết quả khi chạy ta thấy:

Putin Xin chào Michelle Obama

Mặc dù chuỗi gốc ta có 2 chuỗi con Obama, nhưng chương trình chỉ áp dụng cho Obama đầu tiên

  • Các hàm xóa khoảng trắng: trim,trimEnd,trimStart

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s:String= "    Trần Duy Thanh      "
val s2=s.trimStart()
println(s2+"=>size="+s2.length)
val s3=s.trimEnd()
println(s3+"=>size="+s3.length)
val s4=s.trim()
println(s4+"=>size="+s4.length)

}

Kết quả khi chạy ta thấy:

Trần Duy Thanh      =>size=20
Trần Duy Thanh=>size=18
Trần Duy Thanh=>size=14
  • compareTo – so sánh chuỗi

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
val s1 = "Hạnh phúc"
val s2 = "Hạnh PHÚC"
val x = s1.compareTo(s2, ignoreCase = true)
println(x)
val y = s1.compareTo(s2, ignoreCase = false)
println(y)
}/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
val s1 = "Hạnh phúc"
val s2 = "Hạnh PHÚC"
val x = s1.compareTo(s2, ignoreCase = true)
println(x)
val y = s1.compareTo(s2, ignoreCase = false)
println(y)
}

Kết quả khi chạy ta thấy:

0
32

Ta thấy nếu so sánh không phân biệt chữ Hoa – thường(ignoreCase = true) thì kết quả =0, còn có phân biệt chữ HOA – thường(ignoreCase = false) thì kết quả >1 (32)

  • plus– nối chuỗi

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s:String="Obama"
s=s.plus(" ")
s=s.plus("Putin")
println(s)
}

Kết quả khi chạy ta thấy:

Obama Putin

Hàm plus ở trên nối chuỗi nhưng nó không làm thay đổi chuỗi gốc mà nó trả về 1 chuỗi mới do đó ta phải lưu lại địa chỉ mới này. Ta có thể dùng dấu + (nhưng không nên dùng khi nối chuỗi quá nhiều đặc biệt đọc từ file hay internet), Ngoài ra có thể dùng StringBuilder để xử lý nối chuỗi.

  • split– tách chuỗi theo tiêu chí bất kỳ, trả về một List<String>

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s:String="Trần Duy Thanh"
var arr:List = s.split(" ")
println("Số phần tử="+arr.size)
for(x in arr)
println(x)
}

Kết quả khi chạy ta thấy:

Số phần tử=3
Trần
Duy
Thanh

Hàm tách chuỗi rất quan trọng, vì hầu như ta đều gặp trong quá trình viết phần mềm. Input là 1 chuỗi có quy luật, và ta phải phân tích để tách chuỗi rồi mô hình hóa thành dữ liệu có cấu trúc(thường là OOP)

  • toUpperCase, toLowerCase để chuyển CHỮ HOA, chữ thường

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var s:String="Trần Duy Thanh"
var s2=s.toUpperCase()
println(s2)
var s3=s.toLowerCase()
println(s3)
}

Kết quả khi chạy ta thấy:

TRẦN DUY THANH
trần duy thanh

Bây giờ Tui thử làm một chương trình tối ưu chuỗi:

Cho một chuỗi bất kỳ, hãy tối ưu chuỗi theo mô tả: Chuỗi không có khoảng trắng dư thừa, các từ cách nhau bởi 1 khoảng trắng, ký tự đầu của các từ viết HOA

Ví dụ:

Input: “  TRẦN       duY       THAnh  ”

Output: “Trần Duy Thanh”


/**
* Created by cafe on 28/05/2017.
*/
fun toiUU(s: String): String {
var sToiTuu = s
sToiTuu = sToiTuu.trim()
val arrWord = sToiTuu.split(" ");
sToiTuu = ""
for (word in arrWord) {
var newWord = word.toLowerCase()
if (newWord.length > 0) {
newWord = newWord.replaceFirst((newWord[0] + ""), (newWord[0] + "").toUpperCase())
sToiTuu += newWord + " "
}
}
return sToiTuu.trim()
}
fun main(args: Array) {
var s = "   TRẦN         dUY     THanh   "
println(s)
var sToiUuu = toiUU(s)
println(sToiUuu)

s = "     NguyễN      VĂN  OBAMA   "
println(s)
sToiUuu = toiUU(s)
println(sToiUuu)
}

Kết quả khi chạy ta thấy:

   TRẦN         dUY     THanh
Trần Duy Thanh
NguyễN      VĂN  OBAMA
Nguyễn Văn Obama

Như vậy tới đây Tui đã hướng dẫn xong cách xử lý chuỗi trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Cần thành thạo các thư viện để có thể áp dụng tốt vào các dự án thực tế của mình.

Cần phải đọc nhiều ví dụ về cách xử lý chuỗi từ Kotlin, vì trong bài này Tui mới liệt kê được một số phương thức thường dùng mà thôi, nó còn vô vàn các phương thức khác rất hữu ích

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/v62acsqhh101jp8/XuLyChuoi.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

Bài 17-Các thư viện quan trọng thường dùng trong Kotlin


Ngôn ngữ nào cũng có tập các thư viện giúp ta giải quyết nhanh những công việc nào đó, và chắc chắn chúng ta phải sử dụng vì ta không thể tự viết ra được, ta phải biết cách sử dụng nó. Các thư viện này có thể nằm trong JVM hay KotlinJavaRuntime hay ở bất kỳ thư viện ngoài nào khác:

Trong bài này Tui sẽ trình bày một số thư viện thường dùng như:

  • Thư viện xử lý dữ liệu số
  • Thư viện xử lý ngày tháng
  • Thư viện xử lý toán học
  • Thư viện xử lý số ngẫu nhiên
  • Thư viện xử lý chuỗi

Và còn rất nhiều thư viện xử lý khác nữa, khi nào gặp ta lại ngâm cứu tiếp

Các thư viện này có thể được sử dụng từ JVM, Bây giờ Tui đi vào chi tiết từng thư viện xử lý

  • Thư viện xử lý dữ liệu số

Muốn định dạng chữ số thập phân cho số thực ta có thể dùng format sau:


fun main(args: Array) {
var d:Double=10.0/3.0
println(d)
println("%.2f".format(d))
}

Kết quả xuất ra màn hình khi chưa định dạng và đã định dạng thập phân:

3.3333333333333335
3.33

“%.2f” là cú pháp định số thập phân, ở trong Tui để số 2 tức là 2 số thập phân, bạn muốn bao nhiêu số thì tự thay thế.

Ta có thể sử dụng thư viện DecimalFormat nằm trong JVM để định dạng số, ví dụ dưới đây minh họa tạo ngăn cách phần nghìn:


import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.Locale

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var x:Int=986553823
var dcf=DecimalFormat("#,###")
var dcfs=DecimalFormatSymbols(Locale.getDefault())
dcfs.groupingSeparator=','
dcf.decimalFormatSymbols=dcfs
println(x)
println(dcf.format(x))
}

Kết quả khi chạy chương trình:

986553823
986,553,823

Chú ý những dòng lệnh import ở trên là IntelliJ IDEA tự import giùm, ta chỉ cần gõ Control +Space khi dùng các thư viện thì tự động nó xuất hiện. Kotlin giúp ta triệu gọi thư viện trong JVM một cách dễ dàng nhất giúp các lập trình viên Java dễ chuyển đổi ngôn ngữ

  • Thư viện xử lý ngày tháng

Khi xử lý ngày tháng năm ta thường dùng 3 thư viện:

Date
Calendar
SimpleDateFormat

Các thư viện này nằm trong gói:

import java.util.Date
import java.util.Calendar
import java.text.SimpleDateFormat

  • Lấy ngày tháng năm hiện tại:

var cal=Calendar.getInstance()

  • Lấy từng tiêu chí

var year=cal.get(Calendar.YEAR)

var month=cal.get(Calendar.MONTH)

var day=cal.get(Calendar.DAY_OF_MONTH)

  • Thay đổi thông số ngày tháng năm:

cal.set(Calendar.YEAR, 1990);

cal.set(Calendar.MONTH,2)

cal.set(Calendar.DAY_OF_MONTH,20)

  • Lấy đối tượng ngày tháng năm:

var date=cal.time

  • Để định dạng ngày tháng năm dd/MM/YYYY

var date=cal.time
var sdf=SimpleDateFormat(“dd/MM/yyyy”);
println(sdf.format(date))

Ví dụ:


import java.util.Date
import java.util.Calendar
import java.text.SimpleDateFormat

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var cal=Calendar.getInstance()
var year=cal.get(Calendar.YEAR)
var month=cal.get(Calendar.MONTH)
var day=cal.get(Calendar.DAY_OF_MONTH)
println("Năm=$year")
println("Tháng=$month")
println("Ngày=$day")

var date=cal.time
var sdf=SimpleDateFormat("dd/MM/yyyy");
println(sdf.format(date))
var sdf2=SimpleDateFormat("dd/MM/yyyy hh:mm:ss aaa");
println(sdf2.format(date))
}

Kết quả khi chạy chương trình:

Năm=2017
Tháng=4
Ngày=28
28/05/2017
28/05/2017 07:26:33 AM

Chú ý tháng luôn chạy từ 0->11 nên khi ra số 4 chính là tháng 5 (ta có thể xem SimpleDateFormat xuất ra đúng tháng) .

hh:mm:ss aaa là định dạng giờ:phút:giây, aaa là AM hoặc PM . Muốn định dạng 24h thì thay hh thành HH

  • Thư viện xử lý toán học

Để xử lý toán học ta dùng thư viện Math nằm trong gói java.lang

Một số phương thức thường dùng của Math:

Tên phương thức Mô tả
PI Trả về giá trị PI
abs(a) Trả về trị tuyệt đối của a
max(a,b) Trả về giá trị lớn nhất giữa a và b
min(a,b) Trả về giá trị nhỏ nhất giữa a và b
sqrt(a) Trả về căn bậc 2 của a
pow(x,y) Tính lũy thừa xy
sin(radian) Tính sin, radian=Math.PI*góc/180
cos(radian) Tính cos
tan(radian) Tính tan

Ví dụ:


/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
println("Số PI="+Math.PI)
println("Giá trị tuyệt đối của -4="+Math.abs(-4))
println("số "+Math.max(9,2)+" là số lớn")
println("Căn bậc 2 của 25="+Math.sqrt(25.0))
println("3 mũ 4 ="+Math.pow(3.0,4.0))
var goc=45
var rad=Math.PI*goc/180
println("sin($goc)="+Math.sin(rad))
println("cos($goc)="+Math.cos(rad))
println("tan($goc)="+Math.tan(rad))
println("cotan($goc)="+Math.cos(rad)/Math.sin(rad))
}

Kết quả khi chạy chương trình:

Số PI=3.141592653589793
Giá trị tuyệt đối của -4=4
số 9 là số lớn
Căn bậc 2 của 25=5.0
3 mũ 4 =81.0
sin(45)=0.7071067811865475
cos(45)=0.7071067811865476
tan(45)=0.9999999999999999
cotan(45)=1.0000000000000002
  • Thư viện xử lý số ngẫu nhiên

Để xử lý số ngẫu nhiên ta dùng lớp Random nằm trong gói import java.util.Random

var rd=Random()

var x=rd.nextInt(n);

Trả về số ngẫu nhiên từ [0…n-1]

Ví dụ:

[0….100]=>rd.nextInt(101)

[-100 …100]=>-100+rd.nextInt(201)

[-100 … -50]=>-100+rd.nextInt(51)

rd.nextDouble() trả về số ngẫu nhiên [0…1)

Ví dụ viết Game đoán số theo mô tả:

Máy tính sẽ ra 1 số ngẫu nhiên [0..100], yêu cầu người chơi đoán số này, cho phép đoán sai 7 lần (quá 7 lần thì Game Over). Nếu đoán sai thì phải cho người chơi biết là số Người chơi đoán nhỏ hơn hay lớn hơn số của máy.

=>Sau khi kết thúc game (WIN or LOST)=>hỏi xem Người chơi có muốn chơi nữa không.

import java.util.Random

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {

while (true) {
choi()
println("Chơi nữa không thím?(c/k):")
val tl = readLine()
if (tl.equals("k", ignoreCase = true))
break
}
println("Tạm biệt Thím!")

}
fun choi()
{
val rd = Random()
val soMay = rd.nextInt(101)
println("Máy đã ra 1 số [0...100] mời Thím đoán!")
var soNguoi: Int=0
var soLanDoan = 0
do {
println("Bạn đoán số gì?:")
var s=readLine()
if(s!=null)
soNguoi = s.toInt()
soLanDoan++
println("Thím đoán lần thứ " + soLanDoan)
if (soNguoi == soMay) {
println("Chúc mừng Thím! Thím đoán đúng, số máy =" + soMay)
break
}
if (soNguoi  số thím")
} else {
println("Thím đoán sai! số máy <số thím")
}
if (soLanDoan == 7) {
println("Thím đã Cáo Phó, vì đoán 7 lần mà ko trúng!")
break
}
} while (soLanDoan <= 7)
}

Kết quả khi chạy chương trình:

Máy đã ra 1 số [0…100] mời Thím đoán!
Bạn đoán số gì?:
50
Thím đoán lần thứ 1
Thím đoán sai! số máy > số thím
Bạn đoán số gì?:
75
Thím đoán lần thứ 2
Thím đoán sai! số máy <số thím
Bạn đoán số gì?:
62
Thím đoán lần thứ 3
Chúc mừng Thím! Thím đoán đúng, số máy =62
Chơi nữa không thím?(c/k):
k
Tạm biệt Thím!
  • Thư viện xử lý Chuỗi

Ta thường sử dụng lớp StringBuilder (nằm trong kotlin.text) để xử lý chuỗi

  • StringBuilder(): Mặc định tạo ra một đối tượng StringBuilder có thể lưu giữ được 16 ký tự
  • StringBuilder(int capacity): Tạo ra một đối tượng StringBuilder có thể lưu giữ được capacity ký tự
  • StringBuilder(String s): Tạo một đối tượng StringBuilder lấy thông tin từ chuỗi s

Các phương thức thường sử dụng:

  • append() – nối chuỗi
  • insert() – chèn chuỗi
  • delete() – xóa chuỗi
  • reverse() – đảo ngược chuỗi

Ví dụ:


fun main(args: Array) {
var sb= StringBuilder("Obama Putin")
println(sb.toString())
sb.insert(5,"Kim Jong Un")
println(sb.toString())
sb.append(" Donald Trump")
println(sb.toString())
sb.reverse()
println(sb.toString())
}

Kết quả khi chạy chương trình:

Obama Putin
ObamaKim Jong Un Putin
ObamaKim Jong Un Putin Donald Trump
pmurT dlanoD nituP nU gnoJ miKamabO

Đặc biệt khi nối chuỗi như đọc từ File, đọc từ internet với nội dung dài thì ta nên dùng StringBuilder để nối (append) thay vì dùng dấu +. Vì khi dùng dấu + tốc độ xử lý sẽ rất chậm.

Như vậy tới đây Tui đã hướng dẫn xong một số thư viện quan trọng thường dùng trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Cần thành thạo các thư viện để có thể áp dụng tốt vào các dự án thực tế của mình.

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/hkqhv8emwnrep4v/HocThuVienThuongDung.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

%d bloggers like this: