Chào anh chị, em nhờ anh chị làm cho em một hàm lọc như sau ạ:
- Em muốn lọc những số, là số có 10 chữ số, số có dạng 093xxxxxxx , số thỏa mãn điều kiện là các số không trùng nhau. tức là các số không lặp lại nhau, từ 0 đến 9, không bắt buộc theo thứ tự ạ
- Vì đặc thù là file số , nên số đầu tiên lúc nào cũng là số 0, nên có thể loại 0 ra, số có dạng 93abcdefg, ngoài 93 ra thì abcdefg có thể là 1 hoặc 2 hoặc 4 hoặc 5 hoặc 6 hoặc 7 hoặc 8 , abcdefg không trùng nhau.
- Ví dụ 938246157
- Em đính kèm 1 file số kèm, anh chị làm giúp em ạ. Em cảm ơn anh/ chị nhiều !!!!
Bạn nên viết cho chính xác.
Không thể là: "số thỏa mãn điều kiện là các số không trùng nhau"
Đã là "số" tức 1 "số" thì "các số" là cái gì?
Khi bạn có 1 số thì các "phần tử" nhỏ nhất của nó là "các chữ số". Người ta nói: "Cho một số có bốn chữ số" chứ không ai nói: "Cho một số có bốn số" cả.
Có thể bạn cho là tôi "bới bèo ra bọ" nhưng nếu bạn nói không chính xác thì nhiều người có thói quen đọc thoáng qua sẽ hiểu lầm ý bạn.
Bằng chứng? Nếu tôi không lầm thì trong chủ đề này đã có bạn hiểu sai ý của bạn rồi đấy.
Bạn viết: "số có dạng 093xxxxxxx", nhưng trong tập tin đính kèm còn có các số có dạng 090x...x
Vậy ý bạn muốn gì? Chỉ lấy các các số dạng 093xxxxxxx (trong file thì là dạng 93xxxxxxx) với đk là các chữ số khác nhau từng đôi một?
Và nên thay tiêu đề "Nhờ anh chị lọc ra những số không trùng nhau" bằng "Nhờ anh chị lọc ra những số có các chữ số không trùng nhau". Tôi nghĩ tiêu đề của bạn làm
be09 hiểu lầm.
-------------
Tôi mổ xẻ code của
quanghai chút.
1. Code của
quanghai lấy cả số dạng 90x...x, tôi cho là không hiểu được ý của chủ topic, không tính lỗi này.
2. Code của
quanghai xét các chữ số từ 3 tới 9 (For x = 3 To 9) nên sai. Vd. số 935129468 được code chọn vì 7 chữ số cuối (5129468) khác nhau từng đôi một. Nhưng rõ ràng số 935129468 không thỏa đk vì có chữ số 9 lặp lại.
3. Code của
quanghai không tối ưu.
[GPECODE=vb]
For x = 3 To 9
dk = Mid(dl(i, 1), x, 1)
If Not .exists(dk) Then
.Add dk, ""
Else
k = k + 1
End If
Next
[/GPECODE]
Ta thấy vòng lặp FOR luôn thực hiện 7 lần, bất kể các chữ số có lặp lại hay không. Trong khi đó nếu gặp trường hợp chữ số nào đó lặp lại thì điều đó có nghĩa là số đang xét chắc chắn "không tốt", vậy ra khỏi ngay vòng lặp cho khỏi tốn điện nước.
Vd. xét số 931145678 --> FOR được thực hiện 7 lần trong khi có thể ra khỏi FOR khi thực hiện vòng lặp thứ 2.
Vậy tôi đề nghị code như sau, có sửa cận dưới của FOR và tối ưu, và bổ sung để chỉ lấy số dạng 93x...x trong đó x cũng phải <> 0, nhưng vẫn giữ ý tưởng của
quanghai - dùng "đít to đít nhỏ"
Tôi đề nghị thôi chứ không áp đặt đâu nhé. Mà ở đây ta góp ý cho nhau cũng là để học hỏi thêm một cái gì đó thôi. Đúng sai là chuyện thường, con người mà chứ có phải máy đâu.
[GPECODE=vb]
Sub loc()
Dim dl(), i, x, k, dk, kq(), j, so, bad As Boolean
dl = Range([A1], [a65536].End(3)).Value
ReDim kq(1 To UBound(dl), 1 To 1)
With CreateObject("scripting.dictionary")
For i = 1 To UBound(dl)
so = dl(i, 1)
If Left(so, 2) = "93" Then
.Add "0", ""
.Add "9", ""
.Add "3", ""
bad = False
For x = 3 To 9
dk = Mid(so, x, 1)
If Not .exists(dk) Then
.Add dk, ""
Else
bad = True
Exit For
End If
Next
If Not bad Then
j = j + 1
kq(j, 1) = so
End If
.RemoveAll
End If
Next
End With
[B1].Resize(j) = kq
End Sub
[/GPECODE]
Nếu tôi viết thì có lẽ tôi sẽ dùng code sau:
[GPECODE=vb]
Sub loc()
Dim dl(), i, x, dk, kq(), j, so, bad As Boolean
dl = Range([A1], [a65536].End(3)).Value
ReDim kq(1 To UBound(dl), 1 To 1)
For i = 1 To UBound(dl)
so = dl(i, 1) & "0"
If Left(so, 2) = "93" Then
bad = False
For x = 1 To 9
dk = Mid(so, x, 1)
If InStr(x + 1, so, dk) > 0 Then
bad = True
Exit For
End If
Next
If Not bad Then
j = j + 1
kq(j, 1) = dl(i, 1)
End If
End If
Next
[C1].Resize(j) = kq
End Sub
[/GPECODE]