Thêm 1 bài toán tách chuổi (câu hỏi từ ddth.com)

Liên hệ QC

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,905
Tôi gặp 1 bài toán từ dtth.com, thấy hay nên post lên cho mọi người tham khảo... Nguyên văn như sau:
Em có một vấn đề nhỏ xíu không biết giải, đưa lên đây mong anh em chỉ giáo thêm...
trong 1 cell có 2 loại chữ như thế này: "马来西亚Malaysia吉隆坡Kuala Lumpur" bây giờ dùng hàm như thế nào để tách chữ Trung Quốc ra 1 cell khác và chữ LaTinh ra 1 cell khác.
Em học dzở excel mong mấy anh đừng chê cười...
Tôi đang định dùng vòng lập quét qua chuổi với điều kiên ký tự nào có code = 65~90 hoặc 97~122 thì lấy, ngược lại ký tự nào có hàm code trả về giá trị ko nằm trong 2 khoảng này thì bỏ qua!
Giã định rằng ký tự Latin là các ký tự thông thường ko chứa ký tự đặc biệt, và giã định thêm mỗi chuổi có cấu trúc tổng quát như sau: Trung quốc Latin Trung quốc Latin
Các cao thủ khác góp ý xem thử ta giãi quyết bài này như thế nào?
ANH TUẤN
 
Tôi gặp 1 bài toán từ dtth.com, thấy hay nên post lên cho mọi người tham khảo... Nguyên văn như sau:

Tôi đang định dùng vòng lập quét qua chuổi với điều kiên ký tự nào có code = 65~90 hoặc 97~122 thì lấy, ngược lại ký tự nào có hàm code trả về giá trị ko nằm trong 2 khoảng này thì bỏ qua!
Giã định rằng ký tự Latin là các ký tự thông thường ko chứa ký tự đặc biệt, và giã định thêm mỗi chuổi có cấu trúc tổng quát như sau: Trung quốc Latin Trung quốc Latin
Các cao thủ khác góp ý xem thử ta giãi quyết bài này như thế nào?
ANH TUẤN

Vấn đề nhỏ xíu mà chẳng nhỏ tí nào. Em thử lấy code() của mấy ký tự tiếng Hoa, nó toàn ra số 63 cả. Còn trong VB thì không ra được.
 
Vấn đề nhỏ xíu mà chẳng nhỏ tí nào. Em thử lấy code() của mấy ký tự tiếng Hoa, nó toàn ra số 63 cả. Còn trong VB thì không ra được.
Kết quả 63 đâu có sao đâu! Như tôi đã nói, chỉ cần lưu ý giá trị hàm code nào thuộc khoảng từ 65~90 hoặc từ 97~122 thì lấy... những cái ko thuộc khoảng này thì bỏ qua là dc rồi... Như vậy ta sẽ tách dc các ký tự Latin ra riêng, phần ký tự TQ có lẻ dùng các hàm cắt chuổi tương tự như SUBSTITUTE: mang chuổi gốc ra thay thế các ký tự Latin vừa tách ra = ký tự rỗng...
Bạn nghĩ sao?
ANH TUẤN
 
Các cao thủ cho hỏi! Tôi đang làm bài này bằng VBA nhưng bị vướng ở hàm CODE
Cho hỏi trong VBA cái gì thay thế hàm CODE vậy? Tôi dùng Application.WorksheetFunction.Code nó ko chịu... thậm chí dùng đến tuyệt chiêu:
Temp1 = Evaluate("=Code(.............)") giống như ta vẫn làm với hàm SUMPRODUCT trong VBA cũng ko ăn thua
Phải làm sao đây? Xin dc trợ giúp!
ANH TUẤN
 
Trong VBA ta dùng hàm Asc, Ví dụ : Asc("A") cho giá trị 65.
 
Tôi gặp 1 bài toán từ dtth.com, thấy hay nên post lên cho mọi người tham khảo... Nguyên văn như sau:

Tôi đang định dùng vòng lập quét qua chuổi với điều kiên ký tự nào có code = 65~90 hoặc 97~122 thì lấy, ngược lại ký tự nào có hàm code trả về giá trị ko nằm trong 2 khoảng này thì bỏ qua!
Giã định rằng ký tự Latin là các ký tự thông thường ko chứa ký tự đặc biệt, và giã định thêm mỗi chuổi có cấu trúc tổng quát như sau: Trung quốc Latin Trung quốc Latin
Các cao thủ khác góp ý xem thử ta giãi quyết bài này như thế nào?
ANH TUẤN

Hình như hum trước trên diễn đàn GPE đã có bài tương tự cũng về chữ Trung Quôc (chinnese), không biết giải quyết chưa nhỉ
ah, tìm thấy đây rùi: http://www.giaiphapexcel.com/forum/showthread.php?p=67884#post67884

Hướng giải quyết thế là được, Nhưng có vẻ hơi chậm (vì chúng ta phải dò từng ký tự, -> rồi nhặt từng ký tự)
 
Tôi thấy bài toán với dử liệu tôi đưa lên là hoàn toàn khả thi ấy chứ... Tôi làm bằng công thức tách ra dc tuốt, đáng tiếc là ko hợp lại dc theo kiểu như VBA:
Temp1 = Temp1 & Temp2
Chắn chắn VBA giãi quyết việc này trong tầm tay, nhưng tôi làm file bằng VBA cãm thấy vất vả quá! Các cao thủ giúp 1 tay với!
ANH TUẤN
 
Tôi thấy bài toán với dử liệu tôi đưa lên là hoàn toàn khả thi ấy chứ... Tôi làm bằng công thức tách ra dc tuốt, đáng tiếc là ko hợp lại dc theo kiểu như VBA:
Temp1 = Temp1 & Temp2
Chắn chắn VBA giãi quyết việc này trong tầm tay, nhưng tôi làm file bằng VBA cãm thấy vất vả quá! Các cao thủ giúp 1 tay với!
ANH TUẤN

Anh ANHTUANxem thử giải pháp của em xem. Có gì cho em ý kiến nhé!
Vui lòng xem file đính kèm
 

File đính kèm

  • TachChu.xls
    39 KB · Đọc: 79
Lần chỉnh sửa cuối:
OK... vậy là tuyệt lắm rồi... Từ đây nếu ai muốn tách chi tiết nữa thì hoàn toàn có thể dùng các hàm cắt chuổi thông thường...
Cảm ơn bạn!
ANH TUẤN
 
Nếu muốn tách riêng nhóm từ thứ n thì dùng hàm này: =ToLatin(chuỗi gốc, STT nhóm từ)
Code cũng đơn giản, và ngắn gọn.
 

File đính kèm

  • ToLatin.xls
    25 KB · Đọc: 26
Nếu muốn tách riêng nhóm từ thứ n thì dùng hàm này: =ToLatin(chuỗi gốc, STT nhóm từ)
Code cũng đơn giản, và ngắn gọn.
Cách này hay lắm... nhưng giá sư phụ cố gắng hoàn thiện thêm nhát nữa bằng cách thêm 1 option cho phép chọn LOẠI cần lấy ra là Latin hay TQ thì càng tuyệt hơn!
Cảm ơn sư phụ trước!
ANH TUẤN
 
Nó nè!
Cấu trúc: ExtrStr(chuỗi, STT nhóm từ, loại)
Loại = 1 : Lấy Latin
Loại = 2 : Lấy thứ khác

To Anhtuan: Làm biếng quá đi, sửa có 1 xíu!
 

File đính kèm

  • ExtractString.xls
    29.5 KB · Đọc: 14
Nó nè!
Cấu trúc: ExtrStr(chuỗi, STT nhóm từ, loại)
Loại = 1 : Lấy Latin
Loại = 2 : Lấy thứ khác

To Anhtuan: Làm biếng quá đi, sửa có 1 xíu!
Gọi là làm tùy theo sức của mình... Phân công rõ ràng, ai sở trường gì thì làm nấy mà sư phụ.. he... he...
Vậy là OK, đệ sẽ chỉ đường link cho các đồng chí bên ddth.com qua đây xem sư phụ biểu diển...
ANH TUẤN
 
lâu quá không post nên post đại vài câu!
Đừng post đại chứ, lâu không post thì làm thiệt đi!
1.- Dồn 3 cái thành 1
2.- Thay Select case thành If then

Câu 2 dễ, câu 1 Thunghi làm được mà ngắn, đơn giản, dễ hiểu như vậy mới tài!
Đùa tí, nhưng quan điểm mình là làm vậy nó rõ ràng, dễ hiểu hơn, dù mình làm chưa phải tối ưu.
 
Gộp "3 TRONG 1" cho VUI

Đừng post đại chứ, lâu không post thì làm thiệt đi!
1.- Dồn 3 cái thành 1
2.- Thay Select case thành If then

Câu 2 dễ, câu 1 Thunghi làm được mà ngắn, đơn giản, dễ hiểu như vậy mới tài!
Đùa tí, nhưng quan điểm mình là làm vậy nó rõ ràng, dễ hiểu hơn, dù mình làm chưa phải tối ưu.

Gộp "3 TRONG 1" cho VUI

PHP:
Function ExtrStr2(Mystr As String, sttchuoi As Byte, Loai As Byte) As String
Dim Kqtam As String, kQ As String, Lenst As Byte, newStr2 As String
newStr2 = Mystr
For j = 1 To sttchuoi
  If Len(newStr2) = 0 Then
        ExtrStr2 = "": Exit Function
  Else
  Kqtam = ""
  Lenst = Len(newStr2)
  For i = 1 To Lenst
    tam = Mid(newStr2, i, 1)
    If Loai = 1 Then
      Select Case Asc(tam)
        Case 32, 65 To 90, 97 To 122
            Kqtam = Kqtam & tam
            If i <= Lenst - 1 Then
                tam2 = Mid(newStr2, i + 1, 1)
                If Asc(tam2) = 63 Then
                    newStr2 = Right(newStr2, Len(newStr2) - i): Exit For
                End If
            Else: newStr2 = "": End If
       End Select
    Else
      If Asc(tam) = 63 Then
            Kqtam = Kqtam & tam
            If i <= Lenst - 1 Then
                tam2 = Mid(newStr2, i + 1, 1)
                If Asc(tam2) <> 63 Then
                    newStr2 = Right(newStr2, Len(newStr2) - i): Exit For
                End If
            Else: newStr2 = "": End If
       End If
    End If
  Next i
  kQ = Kqtam
  End If
Next j
ExtrStr2 = kQ
End Function
Như thế này cho hấp dẫn hơn a ptm0412 ah, Nhìn cho rõ thuật toán hơn hix hix@#!^%
Thử sức tí cho vui đó mà,
Đúng là thuật toán chưa tối ưu vì mất công dò tìm từ đầu đến cuối chuỗi (và lại còn dò từ ký tự nữa) - TUY vậy chuỗi bất kỳ kiểu này chắc k có ít cách nào hay hơn
 
Lần chỉnh sửa cuối:
Gọi là làm tùy theo sức của mình... Phân công rõ ràng, ai sở trường gì thì làm nấy mà sư phụ.. he... he...
Vậy là OK, đệ sẽ chỉ đường link cho các đồng chí bên ddth.com qua đây xem sư phụ biểu diển...
ANH TUẤN

Hồi này a tuấn định sang đá sân khách ah,

kẻo này không đá - lại kéo về sân Nhà đá đây....
.
 
Vui thật!
Nhưng TigerTiger chỉ đổi 1 Select case thành if thôi à? Cái kia để nguyên dễ hơn à?
Sao không:
Select Case Asc(tam)
Case 32, 65 To 90, 97 To 122

đổi thành:

If Asc(tam) <> 63

Ban đầu mình sợ Asc() trả về các giá trị khác nhau cho các ký tự Miên khác nhau (>255) nên mới làm thế. Sau biết rằng mọi ký tự Miên đều cho giá trị 63, thì làm biếng sửa thành if. :)
 
Ver3 (ExtrStr3) cho hoành tráng lun

Vui thật!
Nhưng TigerTiger chỉ đổi 1 Select case thành if thôi à? Cái kia để nguyên dễ hơn à?
Sao không:
Select Case Asc(tam)
Case 32, 65 To 90, 97 To 122

đổi thành:

If Asc(tam) <> 63

Ban đầu mình sợ Asc() trả về các giá trị khác nhau cho các ký tự Miên khác nhau (>255) nên mới làm thế. Sau biết rằng mọi ký tự Miên đều cho giá trị 63, thì làm biếng sửa thành if. :)

Oh, thế thì k để ý a ptm ah,
Sửa lun thành Ver3 (ExtrStr3) cho hoành tráng lun thế này

PHP:
Function ExtrStr3(Mystr As String, sttchuoi As Byte, Loai As Byte) As String
Dim Kqtam As String, kQ As String, Lenst As Byte, newStr2 As String
newStr2 = Mystr
For j = 1 To sttchuoi
  If Len(newStr2) = 0 Then
        ExtrStr3 = "": Exit Function
  Else
  Kqtam = ""
  Lenst = Len(newStr2)
  For i = 1 To Lenst
    tam = Mid(newStr2, i, 1)
    If Loai = 1 And Asc(tam) <> 63 Then
            Kqtam = Kqtam & tam
            If i <= Lenst - 1 Then
                tam2 = Mid(newStr2, i + 1, 1)
                If Asc(tam2) = 63 Then
                    newStr2 = Right(newStr2, Len(newStr2) - i): Exit For
                End If
            Else: newStr2 = "": End If
    End If
    
    If Loai <> 1 And Asc(tam) = 63 Then
            Kqtam = Kqtam & tam
            If i <= Lenst - 1 Then
                tam2 = Mid(newStr2, i + 1, 1)
                If Asc(tam2) <> 63 Then
                    newStr2 = Right(newStr2, Len(newStr2) - i): Exit For
                End If
            Else: newStr2 = "": End If
    End If
  Next i
  kQ = Kqtam
  End If
Next j
ExtrStr3 = kQ
End Function
 
Lần chỉnh sửa cuối:
TUY vậy chuỗi bất kỳ kiểu này chắc k có ít cách nào hay hơn
Hic! Không có ít cách hay hơn, tức là nhiều cách hay hơn!
Nhưng an ủi 1 điều:
Đúng là thuật toán chưa tối ưu vì mất công dò tìm từ đầu đến cuối chuỗi (và lại còn dò từ ký tự nữa)
Có 1 cái Exit for, nên không tìm đến cuối chuỗi, trừ khi tách nhóm từ cuối cùng.
Dù gì len(MyStr) chắc cũng không quá 100, For chạy tối đa 100 lần, chắc tối đa 1/100 giây :)

PS: Nếu từ đầu nhìn code Ver 3.0 chắc mù tịt, vì những if là if 4, 5 cái lồng nhau. Và lồng đôi!
Mình vẫn chịu cách để rời 3 cái hơn.
 
Web KT
Back
Top Bottom