Ý mình là: làm sao tìm được cụm từ chung ở đây là cụm từ "Việt Nam" từ 4 cells như ví dụ bạn àTheo mình Bạn cần nêu rõ khái niệm ký tự trong cách bạn hiểu ở bài này bạn nhé.
Ý mình nếu coi 4 cells mỗi cells gồm tập hợp các ký tự, giao của 4 tập hợp này sẽ là "Việt Nam"Thế nào là "cụm từ"? Phải đúng là "Việt Nam", hay chỉ "Việt" và "Nam"
"Bảo Hiểm Xã Hội" là một cụm từ, hay "Bảo Hiểm" là một cụm và "Xã Hội" là một cụm nữa?
Ý bạn chả rõ gì cả.Ý mình nếu coi 4 cells mỗi cells gồm tập hợp các ký tự, giao của 4 tập hợp này sẽ là "Việt Nam"
Ở Việt Nam lập hội không xin phép là vi phạm pháp luật, tội khá nghiêm trọngÝ bạn chả rõ gì cả.
Nếu 4 cells có:
BHX Hội Việt Nam
BH Xã Hội Việt Nam
Xã Hội Việt Nam Bảo Hiểm
Bảo Hiểm Xã Hội Việt Nam
Thì theo lô gic toán, giao là "Hội Việt Nam". Có phải vậy không?
Option Compare Text
Function IntersectWords(ByVal aText As Variant) As String
Dim i As Long, j As Long, k As Long, lLength As Long, lMinLength As Long, sMainText As String, aMainWords As Variant, sTmp As String, oReg As Object
aText = aText
sMainText = aText(1, 1)
lMinLength = CountWords(aText(1, 1))
For i = 1 To UBound(aText, 1)
aText(i, 1) = Application.Trim(aText(i, 1))
lLength = CountWords(aText(i, 1))
If lLength < lMinLength Then
sMainText = aText(i, 1)
lMinLength = lLength
End If
Next
If lMinLength = 0 Then Exit Function
aMainWords = Split(sMainText, " ")
For j = LBound(aMainWords, 1) To UBound(aMainWords, 1)
For i = 1 To UBound(aText, 1)
If Not CheckInStr(aText(i, 1), aMainWords(j)) Then
aMainWords(j) = ""
Exit For
End If
Next
Next
k = UBound(aMainWords, 1)
For i = LBound(aMainWords, 1) To k
If aMainWords(i) <> "" Then
sTmp = aMainWords(i)
For j = i + 1 To k
If aMainWords(j) <> "" Then
sTmp = sTmp & vbBack & aMainWords(j)
ReDim Preserve aMainWords(LBound(aMainWords, 1) To UBound(aMainWords, 1) + 1)
aMainWords(UBound(aMainWords, 1)) = sTmp
Else
Exit For
End If
Next
End If
Next
sMainText = Application.Trim(Join(aMainWords, " "))
sMainText = Replace(Replace(sMainText, " ", vbTab), vbBack, " ")
aMainWords = Split(sMainText, vbTab)
SortLengthZA aMainWords
For j = LBound(aMainWords, 1) To UBound(aMainWords, 1)
For i = 1 To UBound(aText, 1)
If Not CheckInStr(aText(i, 1), aMainWords(j)) Then GoTo NotFound
Next
IntersectWords = aMainWords(j)
Exit Function
NotFound:
Next
End Function
Private Function CountWords(ByVal sStr As String) As Long
If sStr <> "" Then CountWords = Len(sStr) - Len(Replace(sStr, " ", "")) + 1
End Function
Private Function CheckInStr(ByVal sStr As String, ByVal sChildStr As String) As Boolean
CheckInStr = InStr(" " & sStr & " ", " " & sChildStr & " ")
End Function
Private Sub SortLengthZA(ByRef Arr As Variant)
Dim i As Long, j As Long, sTmp As String
For i = LBound(Arr, 1) To UBound(Arr, 1) - 1
For j = i + 1 To UBound(Arr, 1)
If CountWords(Arr(j)) > CountWords(Arr(i)) Then
sTmp = Arr(i): Arr(i) = Arr(j): Arr(j) = sTmp
End If
Next
Next
End Sub
Sub TimNhomTu()
Dim Nguon
Dim Mang
Dim Chuoi
Dim Kq
Dim rws
Dim i, j, k, x, y, z, t
Nguon = Sheet1.Range("A1").CurrentRegion
rws = UBound(Nguon)
For i = 1 To rws
Nguon(i, 1) = Application.Trim(Nguon(i, 1))
If k < Len(Nguon(i, 1)) Then
t = i
k = Len(Nguon(i, 1))
End If
Next i
Mang = Split(Nguon(t, 1))
k = UBound(Mang)
With CreateObject("Scripting.Dictionary")
For j = 0 To k
For y = 0 To k - j
Chuoi = ""
For z = y To y + j
Chuoi = Chuoi & " " & Mang(z)
Next z
.Item(.Count) = Trim(Chuoi)
Next y
Next j
ReDim Kq(1 To .Count, 1 To 2)
k = 0
For i = 0 To .Count - 1
t = .Items()(i)
Kq(i + 1, 1) = t
For x = 1 To rws
If InStr(1, Nguon(x, 1), t, 1) Then Kq(i + 1, 2) = Kq(i + 1, 2) + 1
Next x
If k < Kq(i + 1, 2) Then k = Kq(i + 1, 2)
Next i
End With
If k < rws Then MsgBox "Khong co cum tu chung": Exit Sub
With Sheet1
.Columns(3).Clear
x = 0
For i = UBound(Kq) To 1 Step -1
If Kq(i, 2) = k Then
x = x + 1
.Range("C" & x) = Kq(i, 1)
.Range("D" & x) = Kq(i, 2)
Else
If .Range("C1") <> "" Then Exit For
End If
Next i
.UsedRange.Columns.AutoFit
End With
End Sub
Cái này phải chờ xem ý chủ thớt thế nào đã anh. Ưu tiên từ/ cụm từ xuất hiện trước hay có số lượng ký tự nhiều hơn hay thế nào đó thì mình tính tiếp.Với dữ liệu
Giới ăn chơi Hà Thành
Thanh niên Hà Thành ăn chơi trác táng
Thanh niên Hà Thành không ăn chơi bằng thanh niên Sài Thành
Thanh niên Hà Thành nói không với ăn chơi
thì code của huuthang_bd và CHAOQUAY trả vể "ăn chơi". Tại sao không là "Hà Thành"? Thậm chí "Hà Thành" dài hơn. Đếm ký tự bằng mắt hay bằng LEN đều dài hơn.
Nếu thế thì với dữ liệuTheo như mô tả thuật toán trong code của em thì chỉ lấy từ/ cụm từ có số lượng từ nhiều nhất tìm thấy đầu tiên, chưa xét đến các điều kiện khác.
Chắc anh hiểu nhầm ý em. Code của em tìm thấy đầu tiên không phải là xuất hiện trước trong chuỗi do thứ tự bị thay đổi khi sử dụng thuật toán bubble sort.Nếu thế thì với dữ liệu
Giới ăn chơi Hà Thành - bắc Việt Nam
Thanh niên Hà Thành ăn chơi trác táng
Thanh niên Hà Thành không ăn chơi bằng thanh niên Sài Thành
Thanh niên Hà Thành nói không với ăn chơi
kết quả cũng phải là "ăn chơi". Nhưng code trả về "Hà Thành".
Nếu chỉ là Giới ăn chơi Hà Thành - Việt Nam thì lại trả về "ăn chơi".
---
Nguyên nhân là do code lấy chuỗi ngắn nhất trong các chuỗi C4, C5, ... làm "điểm xuất phát"? Nếu có nhiều chuỗi cùng ngắn nhất thì lấy chuỗi cuối cùng?
Trường hợp Giới ăn chơi Hà Thành và Giới ăn chơi Hà Thành - Việt Nam thì lấy chuỗi C4 (ngắn nhất) làm "điểm xuất phát", còn với Giới ăn chơi Hà Thành - bắc Việt Nam thì lấy C5 (C4 và C5 cùng độ dài LEN) làm "điểm xuất phát"?
Option Compare Text
Sub TuTrung()
Dim sArr(), tmp(), S, iStr$, Res$
Dim sRow&, K&, i&, j&, n&, c&
sArr = Range("B3:B6").Value
sRow = UBound(sArr)
S = Split(Application.Trim(sArr(1, 1)), " ")
K = UBound(S)
ReDim tmp(1 To 2, 0 To K)
For j = 0 To K
tmp(1, j) = S(j): tmp(2, j) = K - j
Next j
For i = 2 To sRow
S = Split(Application.Trim(sArr(i, 1)), " ")
For j = 0 To K
If Len(tmp(1, j)) > 0 Then
iStr = tmp(1, j)
For n = 0 To UBound(S)
If iStr = S(n) Then Exit For
Next n
If n = UBound(S) + 1 Then
tmp(1, j) = Empty
ElseIf tmp(2, j) > 0 Then
For c = 1 To tmp(2, j)
If n + c <= UBound(S) Then
If tmp(1, j + c) <> S(n + c) Then
tmp(2, j) = c - 1: Exit For
End If
Else
tmp(2, j) = c - 1: Exit For
End If
Next c
End If
End If
Next j
Next i
For j = 0 To K
If Len(tmp(1, j)) > 0 Then
If Len(Res) = 0 Then Res = tmp(1, j) Else Res = Res & "; " & tmp(1, j)
For c = 1 To tmp(2, j)
Res = Res & " " & tmp(1, j + c)
Next c
j = j + tmp(2, j)
End If
Next j
[B1] = Res
End Sub
Có lẽ không phải do chuỗi ngắn nhất vì nếu chuỗi ngắn nhất không đạt yêu cầu thì coi như cả mảng dữ liệu đều không đạt.Nếu thế thì với dữ liệu
Giới ăn chơi Hà Thành - bắc Việt Nam
Thanh niên Hà Thành ăn chơi trác táng
Thanh niên Hà Thành không ăn chơi bằng thanh niên Sài Thành
Thanh niên Hà Thành nói không với ăn chơi
kết quả cũng phải là "ăn chơi". Nhưng code trả về "Hà Thành".
Nếu chỉ là Giới ăn chơi Hà Thành - Việt Nam thì lại trả về "ăn chơi".
---
Nguyên nhân là do code lấy chuỗi ngắn nhất trong các chuỗi C4, C5, ... làm "điểm xuất phát"? Nếu có nhiều chuỗi cùng ngắn nhất thì lấy chuỗi cuối cùng?
Trường hợp Giới ăn chơi Hà Thành và Giới ăn chơi Hà Thành - Việt Nam thì lấy chuỗi C4 (ngắn nhất) làm "điểm xuất phát", còn với Giới ăn chơi Hà Thành - bắc Việt Nam thì lấy C5 (C4 và C5 cùng độ dài LEN) làm "điểm xuất phát"?
À đấy là đoán mò thôi chứ tôi ngại dò code quá.Có lẽ không phải do chuỗi ngắn nhất vì nếu chuỗi ngắn nhất không đạt yêu cầu thì coi như cả mảng dữ liệu đều không đạt.
Chắc lỗi là do lúc xuất kết quả, không biết ý đầu bài là xuất hết hay là 1 kết quả rồi thôi nên mới bị vậy bác.
DIỄN ĐÀN GIẢI PHÁP EXCEL Group 1
DIỄN ĐÀN GIẢI PHÁP EXCEL Group 2