You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求无相邻重复字符的重复排列计数及逆排列算法

求开发带限制的重复排列算法(优先Visual Basic)

恳请社区协助开发算法(任意编程语言均可,优先适配Visual Basic)解决以下两个相关问题:

  1. 计算重复排列数:要求相同字符不可互换,且排列中无相邻相同字符;
  2. 实现逆排列:给定排列序号,返回符合「无相邻相同字符」限制的对应排列。

示例字符串:"00000000000000000000000000001111111111111111111111111111122222222222222222222222222222222222233333333333333333333333333333333"

具体需求

  • 统计满足「无相邻相同字符」(如不存在连续的"00""11"等子串)的重复排列总数;
  • 给定排列序号与基础字符串,生成符合上述限制的对应排列。

现有Visual Basic代码可实现无限制的重复排列计数及逆排列,代码如下:

Function PermToFreq(perm As String) As Dictionary(Of Char, Integer)
    Dim freq As New Dictionary(Of Char, Integer)()
    For Each x As Char In perm
        If freq.ContainsKey(x) Then
            freq(x) += 1
        Else
            freq(x) = 1
        End If
    Next
    Return freq
End Function

Function RankPerm(targetPerm As String) As BigInteger
    Dim freq As Dictionary(Of Char, Integer) = PermToFreq(targetPerm)
    Dim alphabet As List(Of Char) = freq.Keys.ToList()
    Dim rank As BigInteger = 0

    For i As Integer = 0 To targetPerm.Length - 1
        For Each x As Char In alphabet
            If freq(x) > 0 AndAlso x < targetPerm(i) Then
                freq(x) -= 1
                rank = BigInteger.Add(rank, Multichoose(freq))
                freq(x) += 1
            End If
        Next
        freq(targetPerm(i)) -= 1
    Next

    Return rank + 1 ' Add 1 because rank starts from 1, not 0
End Function

Function Multichoose(freq As Dictionary(Of Char, Integer)) As BigInteger
    Dim answer As BigInteger = 1
    Dim prevCount As Integer = 0

    For Each count As Integer In freq.Values
        For i As Integer = 1 To count
            answer = BigInteger.Multiply(answer, (i + prevCount))
            answer = BigInteger.Divide(answer, i)
        Next
        prevCount += count
    Next

    Return answer
End Function

Function UnrankPerm(perm As String, rank As BigInteger) As String
    Dim freq As Dictionary(Of Char, Integer) = PermToFreq(perm)
    Dim alphabet As List(Of Char) = freq.Keys.ToList()
    Dim answer As New List(Of Char)()

    For i As Integer = 0 To perm.Length - 1
        For Each x As Char In alphabet
            If freq(x) > 0 Then
                freq(x) -= 1
                Dim count As BigInteger = Multichoose(freq)
                If count < rank Then
                    rank -= count
                    freq(x) += 1
                Else
                    answer.Add(x)
                    Exit For
                End If
            End If
        Next
    Next

    Return New String(answer.ToArray())
End Function

感谢您的时间与建议!

内容的提问来源于stack exchange,提问作者Mencey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:33:14