Tìm số gần đúng (1 người xem)

Người dùng đang xem chủ đề này

lala_qn

Thành viên tiêu biểu
Tham gia
2/5/09
Bài viết
598
Được thích
17
Nghề nghiệp
chưa ổn định
giúp dùm em hàm tìm số gần đúng
vd
905123456
905122456
904123455
905113456
tìm các số gần đúng chỉ sai khác nhau 2 số trong dãy số, thanks a/c !
 
giúp dùm em hàm tìm số gần đúng
vd
905123456
905122456
904123455
905113456
tìm các số gần đúng chỉ sai khác nhau 2 số trong dãy số, thanks a/c !

Muốn giúp thì gởi cái file lên, kèm theo dữ liệu tương đối để có thể hiểu ý của bạn. Vui lòng cung cấp dữ liệu tạm nếu dò thủ công thì sẽ tìm được ông nào vì lý do gì... may ra thì có cơ hội nhé.
 
đã up file vd, nhờ a/c xem giúp em với
 

File đính kèm

đã up file vd, nhờ a/c xem giúp em với
Đã xem qua file của bạn và thấy khó nhai quá. Cố gắng chút thì cũng viêt code được nhưng chắc là hơi đuối. Hỏng biết có cao thủ nào chịu nổi bài toán này không.

PS: Bên trong file kết quả tạm của bạn không giống như yêu cầu bên ngoài. Kiểm tra lại đi nhé.
Thật ra bài toán này có cách giải nếu bạn cung cấp file đủ thông tin. Có vài dòng thì chả ăn thua gì cả.
 
Lần chỉnh sửa cuối:
Chắc chắn rằng tổng đài MobiFone sẽ giúp được bác
Không cần đợi tổng đài đâu bạn ạ. Theo mình thì ổ khóa nào cũng có chìa khóa. Cái chìa khóa đó những anh em trên diễn đàn đang giữ đấy.

Bạn hãy đợi xem sẽ có người chứng minh bài này giải được nếu chủ topic biết cách làm rõ thêm yêu cầu thêm 1 chút.
 
Đã xem qua file của bạn và thấy khó nhai quá. Cố gắng chút thì cũng viêt code được nhưng chắc là hơi đuối. Hỏng biết có cao thủ nào chịu nổi bài toán này không.

PS: Bên trong file kết quả tạm của bạn không giống như yêu cầu bên ngoài. Kiểm tra lại đi nhé.
Thật ra bài toán này có cách giải nếu bạn cung cấp file đủ thông tin. Có vài dòng thì chả ăn thua gì cả.

Điều đầu tiên mà tác giả cần làm là:
- Phải đưa ra được 1 tiêu chí chung về SỐ GẦN GIỐNG
- Khác bao nhiêu số (ở cùng vị trí) thì gọi là gần giống
vân vân...
Nói chung là không thể đoán mò được ---> Chả khác nào nhìn tên đoán giới tính
 
Điều đầu tiên mà tác giả cần làm là:
- Phải đưa ra được 1 tiêu chí chung về SỐ GẦN GIỐNG
- Khác bao nhiêu số (ở cùng vị trí) thì gọi là gần giống
vân vân...
Nói chung là không thể đoán mò được ---> Chả khác nào nhìn tên đoán giới tính
- Trong chuổi 9 số khác nhau 2 số (hoặc nhiều hơn có thể sữa hàm)
- Khác nhau ở bất kì vị trí nào
nhờ a/c giúp em, thanks !
 
- Trong chuổi 9 số khác nhau 2 số (hoặc nhiều hơn có thể sữa hàm)
- Khác nhau ở bất kì vị trí nào
nhờ a/c giúp em, thanks !

Tôi đã đưa ra một giải pháp ở bài #8 vậy mà bạn chẳng thèm xem qua. Không biết bạn có thật sự cần câu trả lời không.
Tôi nghĩ tất cả các bài trả lời cho topic của bạn có thể không phải là đáp án nhưng ít nhất bạn cũng phải đọc qua một lần xem người ta nói cái gì chứ.
 
Tôi đã đưa ra một giải pháp ở bài #8 vậy mà bạn chẳng thèm xem qua. Không biết bạn có thật sự cần câu trả lời không.
Tôi nghĩ tất cả các bài trả lời cho topic của bạn có thể không phải là đáp án nhưng ít nhất bạn cũng phải đọc qua một lần xem người ta nói cái gì chứ.
em xem wa nhưng em bấm chữ Run trong file thấy nó ko chạy, em ko biết sử dụng, xin lỗi anh, em muốn sử dụng hàm, thanks a !
 
Điều đầu tiên mà tác giả cần làm là:
- Phải đưa ra được 1 tiêu chí chung về SỐ GẦN GIỐNG
- Khác bao nhiêu số (ở cùng vị trí) thì gọi là gần giống
vân vân...
Nói chung là không thể đoán mò được ---> Chả khác nào nhìn tên đoán giới tính

Em có viết code này, nhưng không biết làm sao cho nó thành nhóm A, B, C, D,E.... theo thứ tự
PHP:
Sub so_gan_giong()
Dim i, ii, j, k, kk, x, kq(), dl()
Dim d As Object
Set d = CreateObject("scripting.dictionary")
dl = Range([A2], [A65536].End(3)).Value
ReDim kq(1 To UBound(dl), 1 To 2)
   For i = 1 To UBound(dl)
      For ii = 1 To UBound(dl)
         k = 0
         For j = 1 To 9
            If Mid(dl(i, 1), j, 1) = Mid(dl(ii, 1), j, 1) Then k = k + 1
         Next
         If k >= 6 Then
            If Not d.exists(dl(ii, 1)) Then
               x = x + 1
               d.Add dl(ii, 1), ""
               kq(x, 1) = dl(ii, 1): kq(x, 2) = ChrW(65 + kk)
            End If
         End If
      Next
      kk = kk + 1
   Next
[D2].Resize(x, 2) = kq
End Sub
To lala_qn
Khi nào muốn xài code thì thử code này nhé
 
Em có viết code này, nhưng không biết làm sao cho nó thành nhóm A, B, C, D,E.... theo thứ tự
PHP:
Sub so_gan_giong()
Dim i, ii, j, k, kk, x, kq(), dl()
Dim d As Object
Set d = CreateObject("scripting.dictionary")
dl = Range([A2], [A65536].End(3)).Value
ReDim kq(1 To UBound(dl), 1 To 2)
   For i = 1 To UBound(dl)
      For ii = 1 To UBound(dl)
         k = 0
         For j = 1 To 9
            If Mid(dl(i, 1), j, 1) = Mid(dl(ii, 1), j, 1) Then k = k + 1
         Next
         If k >= 6 Then
            If Not d.exists(dl(ii, 1)) Then
               x = x + 1
               d.Add dl(ii, 1), ""
               kq(x, 1) = dl(ii, 1): kq(x, 2) = ChrW(65 + kk)
            End If
         End If
      Next
      kk = kk + 1
   Next
[D2].Resize(x, 2) = kq
End Sub
To lala_qn
Khi nào muốn xài code thì thử code này nhé

Bài này không dễ xơi đâu. Cả code của tôi và của bạn đều chưa đúng. Bạn thử chạy code của bạn với 4 dòng dữ liệu sau:
904123455
174123768
174123498
174123455
Nếu code chạy đúng thì phải cùng một nhóm mới đúng.

Tuy nhiên do chủ topic không xài macro nên tôi không bàn tiếp.
 
Thí nghiệm code này xem
Mã:
Function DiffElements(ByVal Str1 As String, ByVal Str2 As String) As Long
  Dim i  As Long, n As Long
  If Len(Str1) = Len(Str2) Then
    For i = 1 To Len(Str1)
      If Mid(Str1, i, 1) <> Mid(Str2, i, 1) Then n = n + 1
    Next
  Else
    n = IIf(Len(Str1) > Len(Str2), Len(Str1), Len(Str2))
  End If
  DiffElements = n
End Function
Mã:
Function ClassElements(ByVal rng As Range, ByVal lDiff As Long)
  Dim i As Long, j As Long, lChk As Long, n As Long
  Dim aTmp, Arr()
  'rng là 1 vùng có 1 Column và nhieu Rows
  On Error Resume Next
  aTmp = rng.Value
  ReDim Arr(1 To UBound(aTmp), 1 To 1)
  For i = 1 To UBound(aTmp) - 1
    If Len(aTmp(i, 1)) Then
      For j = i + 1 To UBound(aTmp)
        If Len(aTmp(j, 1)) Then
          lChk = DiffElements(aTmp(i, 1), aTmp(j, 1))
          If lChk <= lDiff Then
            If Len(Arr(i, 1)) = 0 Then
              n = n + 1
              Arr(i, 1) = n
            End If
            Arr(j, 1) = Arr(i, 1)
          End If
        End If
      Next
    End If
  Next
  ClassElements = Arr
End Function
Và Sub Main
PHP:
Sub Main()
  Dim Arr
  With Range("A2:A1000")
    Arr = ClassElements(.Cells, 2)
    .Offset(, 1).Value = Arr
  End With
End Sub
Test thử nhé, cũng không chắc chính xác chưa nữa (già rồi, đầu óc tối thui)
Ẹc... Ẹc...
 

File đính kèm

Bài này không dễ xơi đâu. Cả code của tôi và của bạn đều chưa đúng. Bạn thử chạy code của bạn với 4 dòng dữ liệu sau:
904123455
174123768
174123498
174123455
Nếu code chạy đúng thì phải cùng một nhóm mới đúng.

Tuy nhiên do chủ topic không xài macro nên tôi không bàn tiếp.

Mình thử sort dữ liệu lại trước thì code chịu gom về 1 nhóm. Nhưng nghĩ mãi vẫn không hiểu tại sao.
 
Hic, hình như là code cũng đi hoang rồi anh ơi... sao lạ quá.

Đi hoang là đi thế nào? Hải thử nói xem
Code của tôi so sánh 2 String, nếu có từ 2 số (trở xuống) cùng vị trí nhưng khác nhau thì mới xem là gần giống
ClassElements(rng, lDiff) ---> Cái biến lDiff này ta tùy chỉnh (sub Main của tôi đang cho nó =2, tức có <=2 số cùng vị trí nhưng khác nhau)
 
Đi hoang là đi thế nào? Hải thử nói xem
Code của tôi so sánh 2 String, nếu có từ 2 số (trở xuống) cùng vị trí nhưng khác nhau thì mới xem là gần giống
ClassElements(rng, lDiff) ---> Cái biến lDiff này ta tùy chỉnh (sub Main của tôi đang cho nó =2, tức có <=2 số cùng vị trí nhưng khác nhau)
Anh thử test với 4 dòng dữ liệu em giả lập xem.
 
Đi hoang là đi thế nào? Hải thử nói xem
Code của tôi so sánh 2 String, nếu có từ 2 số (trở xuống) cùng vị trí nhưng khác nhau thì mới xem là gần giống
ClassElements(rng, lDiff) ---> Cái biến lDiff này ta tùy chỉnh (sub Main của tôi đang cho nó =2, tức có <=2 số cùng vị trí nhưng khác nhau)

Lạ hơn nữa là giờ test lại thì lại được. Đầu óc hôm nay sao rồi. Code của em cũng so sánh theo thuật toán như thế vậy mà nó chạy ra trật lất mới đau chứ.
 
Có chứ anh, dãy số đầu và dãy số cuối chỉ khác nhau 2 chữ số đầu tiên.

Tôi vẫn không thấy giữa 2 số:
904123455
174123768
Có điểm gì giống nhau để có thể cho vào 1 nhóm cả
Số có chiểu 9 chữ số, chỉ giống nhau 4 chữ số, còn 5 chữ số khác nhau chả lẽ cũng cho là GIỐNG à?
 
Lần chỉnh sửa cuối:
Em nói cặp dãy số 1 và dãy số 4 chức không phải cặp 1 - 2.

Vì 3 số dưới giống nhau nên chúng cùng 1 nhóm
Trong khi số đầu lại giống số thứ tư nhưng không giống 2 số còn lại. Nếu vì vậy mà cho chúng vào chung 1 nhóm thì.. kỳ cục quá (hóa ra 4 số giống nhau à?)
Ví dụ:
- a giống b
- b giống c
- c giống d
Vậy nếu cho a, b, c và d vào cùng 1 nhóm thì e rằng không đúng (trong trường hợp a và d khác nhau 1 trời 1 vực)
 
Lần chỉnh sửa cuối:
Vì 3 số dưới giống nhau nên chúng cùng 1 nhóm
Trong khi số đầu lại giống số thứ tư nhưng không giống 2 số còn lại. Nếu vì vậy mà cho chúng vào chung 1 nhóm thì.. kỳ cục quá (hóa ra 4 số giống nhau à?)
Ví dụ:
- a giống b
- b giống c
- c giống d
Vậy nếu cho a, b, c và d vào cùng 1 nhóm thì e rằng không đúng (trong trường hợp a và d khác nhau 1 trời 1 vực)

Ở đây em không bàn đến tính hợp lý trong yêu cầu của chủ topic. Vấn đề là mình làm như thế nào để đạt yêu cầu vì xét cho cùng thì cũng đâu có ai biết được chủ topic muốn phân nhóm để làm gì. Anh xem file của chủ topic sẽ biết chủ topic muốn gì.

Mặt khác, nếu anh suy luận như vậy thì code của anh lại mâu thuẫn với với suy luận của anh. Trong 4 dòng dữ liệu em đưa ra, code của anh gôm 3 dòng cuối là một nhóm trong khi dòng 2 và dòng 4 có ăn nhậu gì với nhau đâu. Cái này cũng rơi vào trường hợp a giống b, b giống c nhưng a khác c.

Hơn nữa nếu đã gọi là phân loại thì trật tự sắp xếp của dữ liệu sẽ không làm ảnh hưởng đến kết quả phân loại nhưng với code của anh khi thay đổi trật tự sắp xếp thì kết quả cũng thay đổi theo. Ví dụ anh đưa dòng 4 lên vị trí số 2 kết quả sẽ khác.

Làm chơi thôi chứ anh em mình ngồi tranh luận cũng chẳng được gì. Cái chủ topic đang cần là một giải pháp bằng công thức.
[GPECODE=vb]Private Sub CommandButton1_Click()
Dim Data, i As Long, j As Long, k As Long, l As Long, m As Long, Code
Set Dic = CreateObject("Scripting.Dictionary")
With Range([A2], [A65536].End(xlUp))
.Offset(, 1).ClearContents
Data = .Resize(, 2).Value
Code = .Offset(, 1).Value
For i = 1 To UBound(Data, 1) - 1
For j = i + 1 To UBound(Data, 1)
l = 0
For k = 1 To Len(Data(i, 1))
If Mid(Data(i, 1), k, 1) <> Mid(Data(j, 1), k, 1) Then l = l + 1
If l > 2 Then GoTo Next_j
Next
If Data(i, 2) = Data(j, 2) Then
If Data(i, 2) = "" Then
m = m + 1
Code(m, 1) = m
Data(i, 2) = m
Data(j, 2) = m
End If
Else
If Data(i, 2) = "" Then
Data(i, 2) = Data(j, 2)
ElseIf Data(j, 2) = "" Then
Data(j, 2) = Data(i, 2)
Else
Code(Data(i, 2), 1) = Code(Data(j, 2), 1)
End If
End If
Next_j:
Next
Next
j = 0
For i = 1 To UBound(Data, 1)
If Data(i, 2) <> "" Then
If Not Dic.Exists(Code(Data(i, 2), 1)) Then
j = j + 1
Dic.Add Code(Data(i, 2), 1), j
End If
Data(i, 2) = Dic.Item(Code(Data(i, 2), 1))
End If
Next
.Resize(, 2).Value = Data
End With
End Sub[/GPECODE]
 

File đính kèm

Các anh em cứ tiếp tục làm đi nhé. Mình cũng định làm bằng hàm, nhưng bực một nỗi cứ nhận được tin nhắn này vào máy làm phân tâm không làm được:
" Xin chào chủ nhân số máy 0909.125.073. Chúng tôi hiện có đang có các số 0909.125.074, 0908.125.073. Hãy gửi 200K cho chúng tôi để sở hữu 1 trong các số trên để làm quà cho người yêu của bạn để tạo nên một cặp đôi hoàn hảo"
Hic, kiểu này làm xong sẽ được nhận phần thưởng này miễn phí đó.
 
hic code em ko biết dùng, cảm ơn mấy anh đã nhiệt tình
em thấy có 1 hàm thế này
hàm này tìm 6 số cuối giống nhau
=SUMPRODUCT(1*(RIGHT($A$2:$A$67,6)=RIGHT($A2,6)))
anh xem thử có hướng nào sửa chữa theo đề bài này ko
hjc, thanks a !
 
giúp dùm em hàm tìm số gần đúng
vd
905123456
905122456
904123455
905113456
tìm các số gần đúng chỉ sai khác nhau 2 số trong dãy số, thanks a/c !

Trước tiên xét dãy số ví du:

905123456
904723456
905123126
905123236

Điều kiện xét của bạn là gì?

1. Là bắt buộc phải đi từ trên xuống, tức thứ tự số là thế không có chuyện sắp xếp trước khi dò tìm?
Vậy đi từ trên xuống thì ta có 2 số đầu

905123456
904723456

"giống nhau" vậy ta bắt buộc phải cho vào cùng nhóm 1. Khi đã có 2 số của nhóm 1 rồi thì 2 số cuối không thể cho vào nhóm 1 được nữa vì chúng không giống với số thứ hai. Ta nhận thấy 2 số cuối "giống nhau" vậy ta cho vào nhóm 2. Kết quả ta có 2 nhóm, mỗi nhóm 2 số.

2. Là không bắt buộc đi theo thứ tự? Thế thì tôi "bỏ" số thứ hai và nhẩy cóc xét luôn số thứ 3 và thấy nó "giống" số thứ 1 vậy tôi cho vào nhóm 1.

905123456
905123126

Tiếp theo tôi xét số thứ 4 và thấy nó giống cả với số 1 và số 2 trong nhóm 1 vậy tôi cho nó vào nhóm 1
905123456
905123126
905123236

Tới đây có vài vấn đề:

a. Tôi không biết bạn cần những số "giống nhau" để làm gì nhưng tôi liều đoán là làm theo cách 2 ta có kết quả "tối ưu" vì có nhóm có 3 số. Tức "tối ưu" = nhóm có độ dài lớn nhất.

b. Trong ví dụ dãy số ngắn này thì tôi "nhìn thấy" ngay là phải nhẩy cóc bỏ số thứ 2 tạm chưa xét. Trong dữ liệu thực và "nhìn" bằng code thì làm sao biết nhẩy cóc thế nào? Nếu muốn xét mọi trường hợp nhẩy cóc với dữ liệu n số thì có nghĩa là phải xét n! trường hợp. Lưu ý là với n = 10, 11, 12 thôi thì n! đã lớn tới mức mà việc dò tìm trở nên vô nghĩa.

c. Nếu tiêu chí là tối ưu theo như điểm a thì vẫn phải xét mọi đáp án rồi từ đó chọn ra đáp án tối ưu
Nhưng cứ cho là thế thì ...
Giả sử ta có 1 đáp án với các nhóm A, B, C, ...
Và đáp án khác có được do nhẩy cóc khác là A', B', C' ...
Thế nếu A > A' nhưng B < B' thì lấy đáp án nào?
Tôi chỉ nói A, A', B, B' nhưng có thể số nhóm đó rất nhiều và đáp án tiếp theo so với đáp án trước có 1 số nhóm có độ dài tăng nhưng 1 số nhóm khác có độ dài giảm thì lấy đáp án nào? Hay bạn đề ra một loạt tiêu chí cụ thể nào đó?

Cái chuyện "giống nhau" này không phải là bài toán hữu ích - giải 1 lần để dùng ngàn lần - nên tôi nghĩ chả nên mất công làm gì. Nó cũng chả thú vị để mà bỏ thời gian ra "thư giãn". Đây chỉ là ý kiến chủ quan của tôi thôi. Tôi không áp đặt cho ai đâu nhé.
 
ý của anh đúng rùi, nó sẽ gặp trường hợp trùng nhiều nhóm, như vậy theo em nó trùng nhóm nào thì xuất hiện nhóm đó luôn ko cần fai ưu tiên anh, anh viết dùm em hàm nhé, thanks a !
 
hic hic khó thật ..................
 
ý của anh đúng rùi, nó sẽ gặp trường hợp trùng nhiều nhóm, như vậy theo em nó trùng nhóm nào thì xuất hiện nhóm đó luôn ko cần fai ưu tiên anh, anh viết dùm em hàm nhé, thanks a !
Ý của anh siwtom cũng là viết code. Chắc bạn tưởng là công thức hả? Nếu vẫn còn nghĩ đến công thức thì hãy quên đi. Sẽ không bao giờ có công thức cho bài toán của bạn đâu. Các đại cao thủ viết code còn lắc đầu thì công thức nào chịu nổi.
 
Ý của anh siwtom cũng là viết code. Chắc bạn tưởng là công thức hả? Nếu vẫn còn nghĩ đến công thức thì hãy quên đi. Sẽ không bao giờ có công thức cho bài toán của bạn đâu. Các đại cao thủ viết code còn lắc đầu thì công thức nào chịu nổi.
a/c viết dùm em với ạ, thanks !
 
e gởi 1 file vd a nhé, thanks a !
 

File đính kèm

e gởi 1 file vd a nhé, thanks a !
Nhìn tới nhìn lui thì chả biết đường nào mà lần
Ví dụ khi chay code ra thê này là 1 nhóm, nhưng lấy mắt trần thịt mà nhìn vào thì chẳng ông nào giống ông nào cả mà cho vào 1 nhóm thì mắc cười quá. Thôi hỏng chơi với bài này nữa
907568486
902368486
907589486
907569486
907568126
907128486
907588486
907568456
907562386
901568486
907568487
905568489
908568426
907768986
 
hic ae có cách nào giúp em với
 
hic ae có cách nào giúp em với

Nếu bạn đưa ra tiêu chí rõ ràng thì chiều tối có thời gian tôi sẽ xem xét:
1. Bắt buộc phải đi từ trên xuống và xét các số LẦN LƯỢT?
2. Ta xét nhóm hiện hành - khi vào code thì là nhóm 1, có số đầu trong nó - khi vào code thì số đầu là số đầu của dãy dữ liệu. Ta xét lần lượt các số từ số TIẾP THEO cho tới số cuối của dãy? Nếu nó "giống" với TỪNG số trong nhóm hiện hành thì BẮT BUỘC phải cho nó vào nhóm hiện hành? Và sau khi cho số "giống" vào nhóm hiện hành thì ta lại xét từng số từ số TIẾP THEO sau "vị vừa thêm vào nhóm" cho tới số cuối, cứ thế cho tới khi xét số cuối cùng trong nhóm. Lúc đó ta có được nhóm hiện hành đầy đủ.
Tiếp theo ta xét nhóm hiện hành mới với dữ liệu bắt đầu là DÃY CON của dãy đã cho, tức đã loại bỏ các số có trong nhóm hoàn chỉnh vừa có?
Cứ như thế cho tới HẾT?
 
khi xét nếu nó thuộc nhóm A thì kí hiệu nhóm A, nếu xét tiếp nó thuộc nhóm B thì kí hiệu thêm nhóm B,....... cứ như vậy khi nhìn vào ta thấy đc nó thuộc trong những nhóm nào như vậy sẽ dễ chọn cho khách hàng ko anh
 
khi xét nếu nó thuộc nhóm A thì kí hiệu nhóm A, nếu xét tiếp nó thuộc nhóm B thì kí hiệu thêm nhóm B,....... cứ như vậy khi nhìn vào ta thấy đc nó thuộc trong những nhóm nào như vậy sẽ dễ chọn cho khách hàng ko anh

Cho dù xét như bạn nói thì với cách đó bạn cũng không liệt kê hết được các đáp án có thể. Để liệt kê mọi đáp án thì phải xét n! hoán vị các dòng với n là số dòng dữ liệu.
Khi xét nhóm mới thì phải chọn 1 dòng vào nó để nhóm mới có ít nhất 1 phần tử thì mới có cái để mà kiểm tra các dòng còn lại có thuộc nhóm hay không.
Với ý mới của bạn thì ta luôn có n nhóm, với n là số dòng. Và lúc đó cũng theo ý bạn thì:
1. Ta xét lần lượt nhóm 1, ..., nhóm n. Nhóm n có phần tử đầu tiên là dòng n của dữ liệu đầu vào.
2. Khi xét nhóm k, với 1 <= k <= n thì ta lại đi từ dòng đầu tiên cho tới dòng cuối cùng của dữ liệu đầu vào, tất nhiên bỏ dòng là phần tử đầu của nhóm (do "khi xét nếu nó thuộc nhóm A thì kí hiệu nhóm A, NẾU XÉT TIẾP NÓ THUỘC nhóm B thì kí hiệu thêm nhóm B")

Như thế thì ta cũng mới chỉ có n hoán vị - trong hoán vị thứ k thì dòng thứ k đứng đầu nhưng THỨ TỰ các dòng còn lại chỉ có 1, tức theo thứ tự của dữ liệu đầu vào - không phải là n!, tức có thể vẫn mất rất nhiều đáp án. Vậy thì bầy trò "giống nhau" để mà làm gì?

Được thôi, nếu bạn muốn thế thì ... Nhưng nếu bạn sửa lại CÁCH XÉT thì tôi sẽ không tham gia nữa.

[GPECODE=vb]
Function ApproxNumbers(Arr)
Dim count As Long, i As Long, r As Long, cIndex As Long, badCount As Long
Dim k As Long, total As Long, text As String, s As String, badItem As Boolean
Dim currArr, tmp, resArr
If Not IsArray(Arr) Then
ReDim currArr(1 To 1, 1 To 2)
currArr(1, 1) = Arr
currArr(1, 2) = "Nhom 1"
GoTo end_
End If
' tmp là mảng dữ liệu vào
tmp = Arr
' resArr là mảng kết quả có kích thước ban đầu hơi dư
ReDim resArr(1 To UBound(tmp) ^ 2, 1 To 2)

For r = LBound(tmp) To UBound(tmp)
count = 1
ReDim currArr(1 To count)
' ban đầu mảng chỉ có 1 phần tử là phần tử thứ r trong mảng tmp
currArr(count) = tmp(r, 1)
' ta xét từng dòng từ dòng đầu cho tới dòng cuối của tmp
For i = LBound(tmp) To UBound(tmp)
' nếu dòng đang xét không phải là dòng đầu tiên trong nhóm thì đi tiếp
If i <> r Then
' dữ liệu dòng hiện hành
text = tmp(i, 1)
badItem = False
' trong vòng lặp ta so sánh dòng hiện hành với từng dòng của mảng hiện hành currArr
For k = 1 To count
' đọc từng dòng của mảng hiện hành currArr
s = currArr(k)
badCount = 0
For cIndex = 1 To Len(text)
' nếu 2 ký tự ở cùng vị trí khác nhau thì tăng số lượng "sai" badCount thêm 1
If Mid(text, cIndex, 1) <> Mid(s, cIndex, 1) Then
badCount = badCount + 1
End If
' nếu số lượng "sai" badCount vượt quá 2 thì dòng hiện hành không giống - không xét tiếp các ký tự ở sau
If badCount > 2 Then
badItem = True
Exit For
End If
Next cIndex
' dòng hiện hành không giống nên không so sánh với các phần tử tiếp theo của currArr
If badItem Then Exit For
Next k
' nếu dòng hiện hành giống với từng phần tử của mảng hiên hành currArr thì ta thêm vào
If Not badItem Then
count = count + 1
ReDim Preserve currArr(1 To count)
currArr(count) = text
End If
End If
Next i
' ta sao nhóm - mảng hiện hành sang mảng kêt quả
For k = 1 To count
resArr(total + k, 1) = currArr(k)
resArr(total + k, 2) = "Nhom " & r
Next k
total = total + count
Next r
ReDim currArr(1 To total, 1 To 2)
For i = 1 To total
currArr(i, 1) = resArr(i, 1)
currArr(i, 2) = resArr(i, 2)
Next i
end_:
ApproxNumbers = currArr
End Function

Sub Main()
Dim rng As Range, Arr
Set rng = Range([A2], [A65536].End(xlUp))
Arr = ApproxNumbers(rng)
Range("B2").Resize(UBound(Arr), 2).Value = Arr
End Sub
[/GPECODE]

1. Muốn chạy được thì phải bật macro.
2. Tôi mới test ở mức thấy ra kết quả, không có lỗi. Tôi không kiểm tra kết quả vì tôi không có kiên nhẫn để xem kết quả trả về có đúng không. Bạn tự kiểm tra
3. Tôi không kiểm tra dữ liệu đầu vào, ví dụ có dòng trống, hoặc các số không có cùng độ dài (kiện nay là 9 ký tự)
 

File đính kèm

Nói chuyện về xếp nhóm thì phải có quy định đại số.

Định nghĩa một nhóm trong Đại Số là tập hợp một số phần tử có cùng một số đặc tính nào đó.

Đặc tính ở đây là gì? Chỉ khác nhau hai ký tự tức là sao?
1. Tức là mọi phần tử trong nhóm chỉ được phép khác từng phần tử khác trong nhóm tối đa 2 ký tự?
2. Hay là ta có 1 phần tử mốc mà mọi phần tử khác trong nhóm chỉ được phép khác phần tử này tối đa 2 ký tự? (dĩ nhiên phần tử mốc này cũng thuộc về nhóm vì nó đạt điều kiện)

@siwtom:
Hình như yêu cầu của đề bài là 2 ký tự "hoặc nhiều hơn nếu cần".
Vì vậy ta nên đặt hàm thêm một tham có mặc định

Function ApproxNumbers(Arr, Optional mxCount=2)


Bên trong hàm:

If badCount > mxCount Then
 
Nói chuyện về xếp nhóm thì phải có quy định đại số.

Định nghĩa một nhóm trong Đại Số là tập hợp một số phần tử có cùng một số đặc tính nào đó.

Đặc tính ở đây là gì? Chỉ khác nhau hai ký tự tức là sao?
1. Tức là mọi phần tử trong nhóm chỉ được phép khác từng phần tử khác trong nhóm tối đa 2 ký tự?
2. Hay là ta có 1 phần tử mốc mà mọi phần tử khác trong nhóm chỉ được phép khác phần tử này tối đa 2 ký tự? (dĩ nhiên phần tử mốc này cũng thuộc về nhóm vì nó đạt điều kiện)

@siwtom:
Hình như yêu cầu của đề bài là 2 ký tự "hoặc nhiều hơn nếu cần".
Vì vậy ta nên đặt hàm thêm một tham có mặc định

Function ApproxNumbers(Arr, Optional mxCount=2)


Bên trong hàm:

If badCount > mxCount Then

Chủ topic viết: "tìm các số gần đúng chỉ sai khác nhau 2 số trong dãy số"
Còn "hoặc nhiều hơn nếu cần" là ý nói là có thể trong tương lai sẽ không phải là 2 mà có thể là 3, 4 nhưng cho dù là bao nhiêu thì cũng là số cụ thể. Tức bài 1: khác nhau 2 số, bài 2: khác nhau 3 số, bài 3: khác nhau 4 số. Còn nếu là bài tổng quát mà số chữ số khác nhau thay đổi theo nhu cầu thì dĩ nhiên là thay 2 bằng biến rồi.

Mà tôi có cảm giác là chủ topic viết không đúng ý của mình.
Theo tôi ý không phải là "tìm các số gần đúng chỉ sai khác nhau ĐÚNG 2 số trong dãy số" mà ý là: "tìm các số gần đúng chỉ sai khác nhau NHIỀU NHẤT 2 số trong dãy số". Bởi theo tư duy của tôi thì hai cô gái khác nhau MŨI và TÓC coi như là "giống nhau" thì chả lý gì hai cô gái chỉ khác nhau MŨI lại không "giống nhau".

Tất nhiên tôi hiểu là thế, tôi không áp đặt cho ai cả.
-------------
Bạn có để ý là cho tới tận giờ, khi vài ngày đã trôi qua và chủ đề có vài chục bài mà chủ topic vẫn chưa đưa ra đầy đủ và chính xác: khái niệm "giống nhau", cách xét các dòng dữ liệu?

Chính vì thế khi đưa code tôi nói rất rõ tôi đã giả thiết như thế nào: cách xét các nhóm, lấy gì vào làm phần tử đầu của nhóm (vì làm sao có thể xét dòng nào đó có thuộc nhóm hay không khi nó rỗng), và sau khi có phần tử rồi thì lần lượt xét những dòng nào, "đi" từ đâu tới đâu v...v
 
Bạn có để ý là cho tới tận giờ, khi vài ngày đã trôi qua và chủ đề có vài chục bài mà chủ topic vẫn chưa đưa ra đầy đủ và chính xác: khái niệm "giống nhau", cách xét các dòng dữ liệu?

Chính vì thế khi đưa code tôi nói rất rõ tôi đã giả thiết như thế nào: cách xét các nhóm, lấy gì vào làm phần tử đầu của nhóm (vì làm sao có thể xét dòng nào đó có thuộc nhóm hay không khi nó rỗng), và sau khi có phần tử rồi thì lần lượt xét những dòng nào, "đi" từ đâu tới đâu v...v

Tức là vầy anh ơi: Nhìn và cảm thấy... giống giống chứ ai biết được là nó giống thế nào
Em nói từ đầu rồi: Cũng giống như nhìn cái TÊN và cảm thấy nó là TÊN CON GÁI (chứ nào có ai cấm cái tên đó không được đặt cho con trai)
Ẹc... Ẹc...
 
Tức là vầy anh ơi: Nhìn và cảm thấy... giống giống chứ ai biết được là nó giống thế nào
Em nói từ đầu rồi: Cũng giống như nhìn cái TÊN và cảm thấy nó là TÊN CON GÁI (chứ nào có ai cấm cái tên đó không được đặt cho con trai)
Ẹc... Ẹc...

Chính xác. Bản thân chủ topic cũng chả biết thế nào là cùng nhóm mà.
 

Bài viết mới nhất

Back
Top Bottom