Hàm tạo số tự nhiên có 2 chữ số từ các số cho trước (2 người xem)

Liên hệ QC

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

NguyenNgocSon

KEEP WALKING
Tham gia
4/4/08
Bài viết
280
Được thích
833
Nghề nghiệp
Ths. Cầu hầm
Minh có bài toán sau: "Liệt kê ra tất cả các số tự nhiên có 2 chữ số được tạo bởi n số (n=0 đến 9)
1.Ví dụ: các số có hai chữ số tạo bởi hai số 1,2
2.Ví dụ: các số có hai chữ số tạo bởi ba số 1,2,3
3.Ví dụ: các số có hai chữ số tạo bởi bốn số 8,9,0,4
Không chứa số lặp lại nghĩa là 11,22,33,...,99
.......
Cám ơn
 
Lần chỉnh sửa cuối:
Số các số có 2 chữ số được tạo ra từ n số là: (n!)/(n-2)!
Nhưng hiện tại mình chưa tìm ra cách xử lý hàm for theo chiều dài chuỗi ???
 
Upvote 0
Không biết làm chỗ nào? thuật toán hay là code?
Có 2 thuật toán:
Thuật xuôi: cứ tuần tự lấy n chữ số ra mà chặp số
Thuật ngược: xét từ 10 đến 99, cái nào không có trong n chữ số thì loại ra
 
Upvote 0
Thí dụ 2, 3, 4
Kết quả
22, 23, 24, 32, 33, 34, 42, 43, 44

Số lượng kết quả = n^2

PHP:
Function Num2Digs(Arr)
Dim RArr, SArr, NCnt As Long
SArr = Arr
NCnt = UBound(SArr)
s = 0
ReDim RArr(1 To NCnt ^ 2, 1 To 1)
For i = 1 To NCnt
    For j = 1 To NCnt
        If SArr(i, 1) * 10 + SArr(j, 1) > 9 Then
            s = s + 1
            RArr(s, 1) = SArr(i, 1) * 10 + SArr(j, 1)
        End If
    Next
Next
Num2Digs = RArr
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Thí dụ 2, 3, 4
Kết quả
22, 23, 24, 32, 33, 34, 42, 43, 44

Số lượng kết quả = n!

PHP:
Function Num2Digs(Arr)
Dim RArr, SArr, NCnt As Long
SArr = Arr
NCnt = UBound(SArr)
s = 0
ReDim RArr(1 To NCnt ^ 2, 1 To 1)
For i = 1 To NCnt
    For j = 1 To NCnt
        If SArr(i, 1) * 10 + SArr(j, 1) > 9 Then
            s = s + 1
            RArr(s, 1) = SArr(i, 1) * 10 + SArr(j, 1)
        End If
    Next
Next
Num2Digs = RArr
End Function
Cám ơn Bác. Em muốn kết quả không chứa số lặp lại ví dụ: 00,...,22,33,44,...99
 
Upvote 0
Do không nói rõ:
- Các số cho trước có trùng không
- Số kết quả có cho phép trùng không
- Hai chữ số của số kết quả có cho phép trùng không
- Số 2 chữ số dạng 09 có coi là 2 chữ số không

Nên làm vậy, không chịu thì thôi.
 
Upvote 0
Sửa
PHP:
If SArr(i, 1) * 10 + SArr(j, 1) > 9 Then
Thành
PHP:
If SArr(i, 1) * 10 + SArr(j, 1) > 9 And SArr(i, 1) <> SArr(j, 1) Then
 
Upvote 0
Do không nói rõ:
- Các số cho trước có trùng không
- Số kết quả có cho phép trùng không
- Hai chữ số của số kết quả có cho phép trùng không
- Số 2 chữ số dạng 09 có coi là 2 chữ số không

Nên làm vậy, không chịu thì thôi.

Thật xin lỗi quá ! :(
Kết quả như sau:
- Hai chữ số của số kết quả không cho phép trùng nhau
- Số 2 chữ số dạng 09 coi là 2 chữ số

Cám ơn !
 
Upvote 0
Sửa tiếp:

If SArr(i, 1) * 10 + SArr(j, 1) > 9 And SArr(i, 1) <> SArr(j, 1) Then

Thành

If SArr(i, 1) <> SArr(j, 1) Then



 
Upvote 0
Em muốn cú pháp hàm như sau: Num2Digs(Byval Arr as string) cho dễ nhập ? Vì nhập các số dạng mảng hơi lâu.
 
Upvote 0
Upvote 0
Ngoài ra em muốn sử dụng hàm này để dùng cho 1 module trong VBA để lập trình ?

Thế thì liệt kê hết những cái muốn ra đi nhóc, mai làm. Còn 2 câu chưa trả lời nữa:
- Các số cho trước có trùng không
- Số kết quả có cho phép trùng không
 
Upvote 0
Em muốn cú pháp hàm như sau: Num2Digs(Byval Arr as string) cho dễ nhập ? Vì nhập các số dạng mảng hơi lâu.

Vài chú ý:
1. Chuỗi chữ số phải có ít nhất 2 ký tự. Đơn giản vì ta liết kê số có 2 chữ số. Nếu chuỗi không thỏa thì không trả về kết quả. Kiểm tra mảng trả về thì IsEmpty = TRUE
2. code cho phép chuỗi nguồn có ký tự trùng vì nó có thể được lấy từ đâu đó. Nếu bắt người dùng lọc duy nhất trước khi gọi hàm thì dã man quá. Cũng cho phép chuỗi nguồn có ký tự không là chữ số. Tất nhiên code sẽ bỏ qua. Thân thiện với người dùng quá rồi còn gì.
5. Các số trả về khác nhau từng đôi một. Mỗi số có 2 chữ số khác nhau.
6. Do không biết tác giả định dùng mảng trả về như thế nào (mà dùng cả trong Module) nên hàm trả về mảng ngang một chiều. Nếu "đập" xuống sheet thì "đập" xuống dòng. Muốn "đập" xuống cột thì phải transpose.
--------------
Code. Bài toán thuộc loại liệt kê thì cứ liệt kê ra thôi chả cần nghĩ ngợi gì nhiều. Viết tới đâu nghĩ tới đó. Về thuật toán thì là thuật toán cho lớp mẫu giáo thôi, to tát gì đâu. Đơn giản là lấy từng ký tự dùng làm chữ số hàng chục và từng ký tự làm chữ số đơn vị. Tất nhiên có kiểm tra trùng do điểm 2 ở trên. Do phải viết code nên mới cần đến lớp "nhớn".
Code:

Cứ viết đại thế này

Mã:
Function Num2Digs(ByVal Arr As String)
Dim result, tmp() As String, a As Long, b As Long, count As Long, so As String, p As Long, n As Long, good As Boolean

    If Len(Arr) < 2 Then Exit Function
'    loai so trung, loai ky tu khong la chu so - ai thich thi dung dit to dit nho
    ReDim tmp(1 To 1)
    For p = 1 To Len(Arr) - 1
        so = Mid(Arr, p, 1)
        If IsNumeric(so) Then
            good = True
            For n = p + 1 To Len(Arr)
                If so = Mid(Arr, n, 1) Then
                    good = False
                    Exit For
                End If
            Next n
            If good Then
                count = count + 1
                ReDim Preserve tmp(1 To count)
                tmp(count) = so
            End If
        End If
    Next p

    count = count + 1
    ReDim Preserve tmp(1 To count)
    tmp(count) = Right(Arr, 1)
                
    If count < 2 Then Exit Function
    
    count = 0

'    phan chinh

    ReDim result(1 To 1)
    For a = 1 To UBound(tmp)
        For b = 1 To UBound(tmp)
            If a <> b Then
                count = count + 1
                ReDim Preserve result(1 To count)
                result(count) = tmp(a) & tmp(b)
            End If
        Next b
    Next a
    
    Num2Digs = result
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
HTML:
Public Function Ghep(ByVal Number As String)
Dim i, j, k, n As Integer
Dim l As Integer
l = Len(Number)
Dim Arr
n = 0
If l < 2 Then Exit Function
ReDim Arr(1 To 1)
    For i = 1 To l
        For j = 1 To l
         If i <> j Then
            n = n + 1
            ReDim Preserve Arr(1 To n)
            Arr(n) = Mid(Number, i, 1) & Mid(Number, j, 1)
         End If
        Next j
    Next i
Ghep=Arr
End Function
Đã fix ok. Cám ơn các bác
 
Lần chỉnh sửa cuối:
Upvote 0
Thực ra code bài 5 sửa hay không sửa cũng có thể sử dụng trong module, chỉ khác rằng kết quả là mảng 2 chiều. Mảng 2 chiều thì truy xuất kiểu mảng 2 chiều cũng được, nhưng không hay.

Bây giờ noi gương anh siwtom "thân thiện" và không "dã man", tức là chuỗi ban đầu có quyền trùng ký số trong chuỗi, đồng thời có cả ký tự không phải số. Và cũng không dùng "dit to dit nho", mà dùng replace. Và cho kết quả là mảng 1 chiều.
Tuy vậy mảng 1 chiều cũng truy xuất được trên sheet theo hàng dọc bằng hàm index.

Code không hẳn hay hơn hoặc nhanh hơn, nhưng thêm 1 cách không dùng "dit":

PHP:
Function Num2Digits(ByVal Arr)
Dim RArr, SArr, NCnt As Long, tmp As String
tmp = Arr
For i = 1 To Len(Arr)
    If Not IsNumeric(Mid(Arr, i, 1)) Then
        tmp = Replace(tmp, Mid(Arr, i, 1), "")
    Else
        If Len(tmp) - Len(Replace(tmp, Mid(Arr, i, 1), "")) > 1 Then
            tmp = Replace(tmp, Mid(Arr, i, 1), "", 1, 1)
        End If
    End If
Next
ReDim SArr(1 To 1)
ReDim RArr(1 To 1)
For i = 1 To Len(tmp)
    ReDim Preserve SArr(1 To i)
    SArr(i) = Mid(tmp, i, 1)
Next
NCnt = UBound(SArr)
For i = 1 To NCnt
    For j = 1 To NCnt
        If i <> j Then
            s = s + 1
            ReDim Preserve RArr(1 To s)
            RArr(s) = SArr(i) & SArr(j)
        End If
    Next
Next
Num2Digits = RArr
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Và cũng không dùng "dit to dit nho", mà dùng replace. Và cho kết quả là mảng 1 chiều.
Tuy vậy mảng 1 chiều cũng truy xuất được trên sheet theo hàng dọc bằng hàm index.

Code không hẳn hay hơn hoặc nhanh hơn, nhưng thêm 1 cách không dùng "dit":

Nhìn anh thao tác với string tmp cũng hay lắm. Cám ơn anh.

Không phải là tôi không mê "đít. Tùy chất lượng, kích cỡ thế nào, và có mặc đồ bó hay không thôi. He he.
 
Upvote 0
Nhìn anh thao tác với string tmp cũng hay lắm. Cám ơn anh.

Không phải là tôi không mê "đít. Tùy chất lượng, kích cỡ thế nào, và có mặc đồ bó hay không thôi. He he.

Cám ơn anh siwtom, code có 1 lỗi và tôi vừa sửa xong. Chỗ sửa là đoạn "thao tác với string tmp":

PHP:
    Else
        If Len(tmp) - Len(Replace(tmp, Mid(Arr, i, 1), "")) > 1 Then
            tmp = Replace(tmp, Mid(Arr, i, 1), "", 1, 1)
        End If
    End If

Thêm 2 tham số cho replace
 
Upvote 0
Web KT

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

Back
Top Bottom