giúp em hàm tìm và thay thế ngẫu nhiên

Liên hệ QC
Status
Không mở trả lời sau này.
...
For i = 1 To LenStr
If Mid(MyStr, i, LenRep) = Rep Then
Randomize
...
Theo lẽ thường, tránh bỏ Randomize trong vòng lặp.
Không chỉ vì mất công, mà với máy chạy nhanh có thể nó bị trở lại số trước.
1. Randomize là dùng thời gian hiện tại để đặt hạt giống cho Random. Nếu máy chạy nhanh quá, lúc vòng lại, đồng hồ chưa kịp tick, thế là số Random bị lặp lại.
2. Randomize nhiều lần thật ra còn có thể làm cho cái sê ri của Random gián đoạn.
 
Theo lẽ thường, tránh bỏ Randomize trong vòng lặp.
...
Trước đây tôi hiểu là nếu không có Randomize, thì Random lần sau có thể sẽ bị trùng với random lần trước liền kề. Vừa rồi tôi thử cho Randomize ra ngoài vòng lặp và test vài chục lần thì thấy khả năng trùng cao hơn so với bỏ trong vòng lặp, không biết đúng không
1. Randomize là dùng thời gian hiện tại để đặt hạt giống cho Random. Nếu máy chạy nhanh quá, lúc vòng lại, đồng hồ chưa kịp tick, thế là số Random bị lặp lại.
May mắn là trong trường hợp này Randomize nằm trong 1 cái IF, chỉ True mới chạy, và False (chạy qua Else) nhiều hơn nên kéo dài được 1 miếng thời gian, anh xem giùm cái "may mắn" này có giúp được tí nào không?
Và trường hợp không "may mắn" thì phải xử lý thế nào?
2. Randomize nhiều lần thật ra còn có thể làm cho cái sê ri của Random gián đoạn.

Phiền anh giải thích giùm cái sê ri của Random là gì, và bị gián đoạn là sao, thực tình tôi chưa biết.
 
...Và trường hợp không "may mắn" thì phải xử lý thế nào?
1. VBA khá chậm, cho nên ít xảy ra "không may mắn".
2. Thường thì người ta đặt Randomize ở khoảng đầu hàm, trước khi làm các việc khác. Nếu hàm nhỏ thì người ta đặt thêm cái biến static cho biết đã Randomize chưa.

...Phiền anh giải thích giùm cái sê ri của Random là gì, và bị gián đoạn là sao, thực tình tôi chưa biết.
Random là một hàm chuỗi (đại khái như chuỗi Taylor), dựa vào cái hạt giống ban đầu để lấy trị đầu tiên. Và cứ dựa vào đó mà lấy trị kế tiếp. Vì vậy, với một hạt giống, bạn sẽ được một sê ri.
Khi bạn liên tục gọi Randomize tức là bạn đặt lại hạt giống. Và mỗi số random thực ra thuộc về một sê ri khác.

Chú thích: ở trên tôi nói là nguyên tắc lấy random bình thường. Trường hợp đặc biệt thì processor sẽ dùng tích entropy để làm thông số cho hàm chuỗi. Và cái đó dân chuyên nghiệp gọi là thực thụ random.
 
1. VBA khá chậm, cho nên ít xảy ra "không may mắn".
2. Thường thì người ta đặt Randomize ở khoảng đầu hàm, trước khi làm các việc khác. Nếu hàm nhỏ thì người ta đặt thêm cái biến static cho biết đã Randomize chưa.


Random là một hàm chuỗi (đại khái như chuỗi Taylor), dựa vào cái hạt giống ban đầu để lấy trị đầu tiên. Và cứ dựa vào đó mà lấy trị kế tiếp. Vì vậy, với một hạt giống, bạn sẽ được một sê ri.
Khi bạn liên tục gọi Randomize tức là bạn đặt lại hạt giống. Và mỗi số random thực ra thuộc về một sê ri khác.

Chú thích: ở trên tôi nói là nguyên tắc lấy random bình thường. Trường hợp đặc biệt thì processor sẽ dùng tích entropy để làm thông số cho hàm chuỗi. Và cái đó dân chuyên nghiệp gọi là thực thụ random.
Bác ah, kỹ tính quá, Randomize thì chấp nhận là phụ thuộc vào hộp đen của họ rồi (lõi code biên dịch VBA, lõi Processor như bác nói)
Túm lại là bài toán ở đây quá nhỏ thì chắc khỏi cần Randomize
Vì trùng thì trùng cũng là ngẫu nhiên (đôi khi không trùng mới là quá ép)
 
Nếu dữ liệu tính theo hàng, thì 1 lần chạy khoảng 50.000 hàng dữ liệu thì có ổn không ạ
Em muốn nó ngẫu nhiêu hạn chế trùng lặp ạ
 
Hàm viết lại: tham số Rep dài tuỳ ý
PHP:
Function ReplaceRnd(MyStr As String, Rep As String, Optional Replacement)
Application.Volatile True
Dim Tmp, LenStr As Long, i As Long, X As String
Dim LenRep As Long, LenCurrent As Long
If IsMissing(Replacement) Then Replacement = ".; ,;, ;.,;..; , "
    LenStr = Len(MyStr)
    LenRep = Len(Rep)
    LenCurrent = 0
    Tmp = Split(Replacement, ";")
    For i = 1 To LenStr
        If Mid(MyStr, i, LenRep) = Rep Then
            Randomize
            X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
            ReplaceRnd = Left(ReplaceRnd, LenCurrent) & X
            i = i + LenRep - 1
        Else
            ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
        End If
        LenCurrent = Len(ReplaceRnd)
    Next
End Function
Cũng trong bộ code này, nhờ anh viết dùm em thêm trường hơp ngẫu nhiên này với ạ
Vd tìm cụm kí tự "bnm" thay bằng cụm kí tự ngẫu nhiên khác, nhưng chỉ chọn 1 loại kí tự thay ngẫu nhiên đồng loạt vào 1 chuổi đó ạ, như trong vd4-2 em up file kèm mô tả ạ.
cảm ơn anh !
 

File đính kèm

  • vd4-2.xlsm
    15.3 KB · Đọc: 5
Mình xin có câu hỏi ngu/ngơ với chủ bài đăng: "Thứ" này dùng làm gì có ích cho XH không bạn?
 
Mình xin có câu hỏi ngu/ngơ với chủ bài đăng: "Thứ" này dùng làm gì có ích cho XH không bạn?
Bán hàng, và ngẫu nhiên chế ra 50.000 chuỗi ký tự. Cái này bạn tự đoán ra lợi ích của nó rồi. Khỏi cần hỏi.

Bạn còn bao nhiêu trường hợp thì liệt kê ra hết đi
Người ta làm xong một bước mới sáng kiến bước kế tiếp. Vì sáng kiến không mất tiền cho nên không bao giờ hết đâu.
Chỉ khi nào trò chơi chán rồi thì mới dừng.
 
Người ta làm xong một bước mới sáng kiến bước kế tiếp. Vì sáng kiến không mất tiền cho nên không bao giờ hết đâu.
Chỉ khi nào trò chơi chán rồi thì mới dừng.
Nếu bạn ấy liệt kê xong và tuyên bố đã hết, thì tôi làm, và không làm thêm bất kỳ trường hợp nào khác nữa. Tất nhiên nếu 1 trường hợp nào đó oái oăm quá thì không làm nổi và bó tay
 
Nếu bạn ấy liệt kê xong và tuyên bố đã hết, thì tôi làm, và không làm thêm bất kỳ trường hợp nào khác nữa. Tất nhiên nếu 1 trường hợp nào đó oái oăm quá thì không làm nổi và bó tay
Từ "rất cần" chỉ phải gõ có 11 ký tự (máy tôi gõ theo Telex) cho nên ai lên đây cũng thấy vấn đề của mình "rất cần".
Liệt kê rõ nhu cầu thì gõ tới hàng trăm ký tự. Liệt kê HẾT nhu cầu thì cần phải động não rất nhiều; vì phải hình dung ra được kết quả của từng bước liên tiếp. Vì vậy người ta chỉ hình dung bước một; xong bước này mới tính ra được bước kế.
 
Từ "rất cần" chỉ phải gõ có 11 ký tự (máy tôi gõ theo Telex) cho nên ai lên đây cũng thấy vấn đề của mình "rất cần".
Liệt kê rõ nhu cầu thì gõ tới hàng trăm ký tự. Liệt kê HẾT nhu cầu thì cần phải động não rất nhiều; vì phải hình dung ra được kết quả của từng bước liên tiếp. Vì vậy người ta chỉ hình dung bước một; xong bước này mới tính ra được bước kế.
Đó là việc của người "cần" đó anh, còn tôi không "cần" và tôi đủ kiên nhẫn để chờ :)
Nói thêm: nói RÕ cũng không phải dễ, vì như VD4, mô tả bằng lời không giống trong file
 
Lần chỉnh sửa cuối:
Đó là việc của người "cần" đó anh, còn tôi không "cần" và tôi đủ kiên nhẫn để chờ :)
Nói thêm: nói RÕ cũng không phải dễ, vì như VD4, mô tả bằng lời không giống trong file
Dạ với chủ đề "tìm và thay thế ngẫu nhiên" thì em xin thêm trường hợp ở #48 (vd4-2) ạ, nhờ anh viết thêm dùm em code ở trường hợp này nữa với ạ, cảm ơn anh nhiều !
 
Quan trọng là hết chưa, vì tôi sẽ làm lần cuối cho chủ đề này
 
Thêm tham số RepCase:
Only one random replacement use Repcase = 1
All replacements are random use RepCase = 2
Change random replacement for new line use RepCase = 3

PHP:
Function ReplaceRnd(MyStr As String, Rep As String, Replacement, RepCase As Integer) As String
'Only one random replacement use Repcase = 1'
'All  replacements are random use RepCase = 2'
'Change random replacement for new line use RepCase = 3'
Application.Volatile True
Dim Tmp, LenStr As Long, i As Long, X As String
Dim LenRep As Long, LenCurrent As Long
    LenStr = Len(MyStr)
    LenRep = Len(Rep)
    LenCurrent = 0
    Tmp = Split(Replacement, ";")
    If RepCase = 1 Then 'Only one random replacement'
        Randomize
        X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
        For i = 1 To LenStr
            If Mid(MyStr, i, LenRep) = Rep Then
                ReplaceRnd = ReplaceRnd & X
                i = i + LenRep - 1
            Else
                ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
            End If
        Next
    Else
        For i = 1 To LenStr
        Select Case RepCase
            Case 2 'All  replacements are random'
                If Mid(MyStr, i, LenRep) = Rep Then
                    Randomize
                    X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
                    ReplaceRnd = ReplaceRnd & X
                    i = i + LenRep - 1
                Else
                    ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
                End If
               
            Case 3 'Change random replacement for new line'
                If i = 1 Or Mid(MyStr, i, 1) = Chr(10) Then
                    Randomize
                    X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
                End If
                If Mid(MyStr, i, LenRep) = Rep Then
                    ReplaceRnd = ReplaceRnd & X
                    i = i + LenRep - 1
                Else
                    ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
                End If
        End Select
        'LenCurrent = Len(ReplaceRnd)
    Next
    End If
End Function
 

File đính kèm

  • vdFinal-Ptm.xlsm
    17.8 KB · Đọc: 11
Thêm tham số RepCase:
Only one random replacement use Repcase = 1
All replacements are random use RepCase = 2
Change random replacement for new line use RepCase = 3

PHP:
Function ReplaceRnd(MyStr As String, Rep As String, Replacement, RepCase As Integer) As String
'Only one random replacement use Repcase = 1'
'All  replacements are random use RepCase = 2'
'Change random replacement for new line use RepCase = 3'
Application.Volatile True
Dim Tmp, LenStr As Long, i As Long, X As String
Dim LenRep As Long, LenCurrent As Long
    LenStr = Len(MyStr)
    LenRep = Len(Rep)
    LenCurrent = 0
    Tmp = Split(Replacement, ";")
    If RepCase = 1 Then 'Only one random replacement'
        Randomize
        X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
        For i = 1 To LenStr
            If Mid(MyStr, i, LenRep) = Rep Then
                ReplaceRnd = ReplaceRnd & X
                i = i + LenRep - 1
            Else
                ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
            End If
        Next
    Else
        For i = 1 To LenStr
        Select Case RepCase
            Case 2 'All  replacements are random'
                If Mid(MyStr, i, LenRep) = Rep Then
                    Randomize
                    X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
                    ReplaceRnd = ReplaceRnd & X
                    i = i + LenRep - 1
                Else
                    ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
                End If
              
            Case 3 'Change random replacement for new line'
                If i = 1 Or Mid(MyStr, i, 1) = Chr(10) Then
                    Randomize
                    X = Tmp(Int(Rnd() * (UBound(Tmp) + 1)))
                End If
                If Mid(MyStr, i, LenRep) = Rep Then
                    ReplaceRnd = ReplaceRnd & X
                    i = i + LenRep - 1
                Else
                    ReplaceRnd = ReplaceRnd & Mid(MyStr, i, 1)
                End If
        End Select
        'LenCurrent = Len(ReplaceRnd)
    Next
    End If
End Function
Em chạy thử thì thấy có lỗi thêm cả "-ptmNo1" vào nữa anh
Em muốn thêm kí hiệu vào trong công thức luôn cho gọn đẹp ạ
Vd: kí hiệu số 1: là đảo ngẫu nhiên , kí kiệu số 2: là đảo ngẫu nhiên nhưng theo chuỗi
Cảm ơn anh !
 
Status
Không mở trả lời sau này.
Web KT
Back
Top Bottom