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

循环减法下乱序valorInicial的减数识别算法开发求助

需求说明

现有字符串变量valorInicial,仅由0-9数字组成,长度为9至60字符。从该变量中选取3个数字,分别执行循环减法(结果小于0时从9接续,例如1-3=8、0-1=9),减数仅可为-1、-2、-3,得到变量valorRestado;随后valorInicial会被打乱顺序,与valorRestado的顺序无关联。

需要开发函数,识别出valorInicial中被选中的3个数字,以及每个数字对应的减数(-1/-2/-3)。

示例

valorInicial:988735928
对9减1得8,对2减2得0,对8减3得5,得到valorRestado:858735908
频率统计:9在valorInicial中出现2次、valorRestado中1次;8均为3次;7均为1次;5在valorInicial中1次、valorRestado中2次;2在valorInicial中1次、valorRestado中0次;0在valorInicial中0次、valorRestado中1次;其余数字出现次数一致。
打乱后的valorInicial:753982898

解题思路

  • 统计两个变量中各数字的出现频率
  • 频率减少的数字为被减数候选,频率增加的数字为减法结果候选
  • 结合仅有的三种减数,通过组合分析确定3组「被减数-减数-结果」的对应关系,需处理减法结果与原有数字重复的复杂情况

现有代码问题

提供的VBA代码仅做了基础的频率统计,缺乏深度逻辑分析,无法正确匹配每个被减数对应的具体减数(-1/-2/-3),也无法处理结果重复的复杂场景。

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim valorInicial As String = "982079171"
    Dim restado As String = "982979978"
    Dim resultadoFuncion As New List(Of String)

    resultadoFuncion = ReconstruirValorInicial(valorInicial, restado)

    ' Concatenar todos los elementos de la lista en una cadena
    Dim mensaje As String = String.Join(vbCrLf, resultadoFuncion)

    ' Mostrar la cadena en un MsgBox
    MsgBox(mensaje, MsgBoxStyle.OkOnly, "Valores de la lista")
End Sub

Function ReconstruirValorInicial(valorInicial As String, restado As String) As List(Of String)
    Dim frecuenciaInicial As New Dictionary(Of Char, Integer)
    Dim frecuenciaRestado As New Dictionary(Of Char, Integer)
    Dim resultados As New List(Of String)

    ' Contar frecuencia de cada dígito
    For i As Integer = 0 To valorInicial.Length - 1
        Dim c As Char = valorInicial.Substring(i, 1)
        If frecuenciaInicial.ContainsKey(c) Then
            frecuenciaInicial(c) += 1
        Else
            frecuenciaInicial(c) = 1
        End If
    Next
    For i As Integer = 0 To restado.Length - 1
        Dim c As Char = restado.Substring(i, 1)
        If frecuenciaRestado.ContainsKey(c) Then
            frecuenciaRestado(c) += 1
        Else
            frecuenciaRestado(c) = 1
        End If
    Next

    ' Identificar dígitos restados y determinar la cantidad a restar
    For i As Integer = 0 To valorInicial.Length - 1
        Dim c As Char = valorInicial.Substring(i, 1)
        Dim frecuenciaInicialDigito As Integer = frecuenciaInicial(c)
        Dim frecuenciaRestadoDigito As Integer = 0
        If frecuenciaRestado.ContainsKey(c) Then
            frecuenciaRestadoDigito = frecuenciaRestado(c)
        End If

        Dim cantidadARestar As Integer
        If frecuenciaRestadoDigito <= frecuenciaInicialDigito Then
            ' Se ha restado
            cantidadARestar = frecuenciaInicialDigito - frecuenciaRestadoDigito
        End If

        ' Almacenar resultados
        If cantidadARestar > 0 Then
            resultados.Add(c & " : " & cantidadARestar.ToString & " (Posición: " & (i + 1).ToString & ")")
        End If
    Next

    Return resultados
End Function

修正后的实现方案

以下是完善逻辑后的VBA函数,能够正确识别3组被减数与减数的对应关系:

Function IdentificarRestas(valorInicial As String, restado As String) As List(Of String)
    Dim freqIni As New Dictionary(Of Integer, Integer)
    Dim freqRest As New Dictionary(Of Integer, Integer)
    Dim resultados As New List(Of String)
    Dim cambios As New Dictionary(Of Integer, Integer) ' 数字: 频率变化量(restado - inicial)

    ' 初始化频率字典(0-9)
    For num As Integer = 0 To 9
        freqIni(num) = 0
        freqRest(num) = 0
    Next

    ' 统计初始字符串频率
    For Each c As Char In valorInicial
        freqIni(CInt(c.ToString)) += 1
    Next

    ' 统计restado字符串频率
    For Each c As Char In restado
        freqRest(CInt(c.ToString)) += 1
    Next

    ' 计算每个数字的频率变化
    For num As Integer = 0 To 9
        cambios(num) = freqRest(num) - freqIni(num)
    Next

    ' 收集候选:频率减少的是被减数(变化量为负,绝对值为1)
    Dim candidatosRestados As New List(Of Integer)
    ' 收集候选:频率增加的是结果(变化量为正,绝对值为1)
    Dim candidatosResultados As New List(Of Integer)

    For num As Integer = 0 To 9
        If cambios(num) = -1 Then
            candidatosRestados.Add(num)
        ElseIf cambios(num) = 1 Then
            candidatosResultados.Add(num)
        End If
    Next

    ' 遍历所有可能的减数组合(三个减数各用一次)
    Dim opcionesRestas As Integer() = {1, 2, 3}
    Dim permutaciones As New List(Of Integer())
    GeneratePermutations(opcionesRestas, 0, permutaciones)

    For Each perm As Integer() In permutaciones
        Dim valido As Boolean = True
        Dim parejas As New Dictionary(Of Integer, Integer) ' 被减数:减数
        For i As Integer = 0 To 2
            Dim numRestado As Integer = candidatosRestados(i)
            Dim resultadoEsperado As Integer = (numRestado - perm(i) + 10) Mod 10
            If Not candidatosResultados.Contains(resultadoEsperado) Then
                valido = False
                Exit For
            End If
            parejas(numRestado) = perm(i)
        Next

        ' 验证所有结果无重复
        If valido Then
            Dim resultadosUsados As New List(Of Integer)
            For Each kvp In parejas
                Dim res As Integer = (kvp.Key - kvp.Value + 10) Mod 10
                If resultadosUsados.Contains(res) Then
                    valido = False
                    Exit For
                End If
                resultadosUsados.Add(res)
            Next
            If valido AndAlso resultadosUsados.Count = 3 Then
                ' 输出匹配结果
                For Each kvp In parejas
                    resultados.Add($"被减数: {kvp.Key},减数: -{kvp.Value},结果: {(kvp.Key - kvp.Value + 10) Mod 10}")
                Next
                Return resultados
            End If
        End If
    Next

    resultados.Add("未找到有效匹配")
    Return resultados
End Function

' 辅助函数:生成数组的全排列
Sub GeneratePermutations(ByVal arr As Integer(), ByVal index As Integer, ByRef permutations As List(Of Integer()))
    If index = arr.Length - 1 Then
        permutations.Add(arr.Clone())
        Return
    End If

    For i As Integer = index To arr.Length - 1
        ' 交换元素
        Dim temp As Integer = arr(index)
        arr(index) = arr(i)
        arr(i) = temp

        GeneratePermutations(arr, index + 1, permutations)

        ' 回溯交换
        temp = arr(index)
        arr(index) = arr(i)
        arr(i) = temp
    Next
End Sub

' 测试调用示例
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim valorInicial As String = "753982898" ' 打乱后的初始值
    Dim restado As String = "858735908"
    Dim resultadoFuncion As New List(Of String)

    resultadoFuncion = IdentificarRestas(valorInicial, restado)

    Dim mensaje As String = String.Join(vbCrLf, resultadoFuncion)
    MsgBox(mensaje, MsgBoxStyle.OkOnly, "识别结果")
End Sub

代码说明

  • 频率统计与变化计算:先统计两个字符串中0-9每个数字的出现次数,计算频率变化量,筛选出频率减少1的被减数候选和频率增加1的结果候选
  • 全排列匹配:因为三个减数(1/2/3)各使用一次,生成所有可能的排列组合,逐一验证每个被减数减去对应减数后的循环结果是否在结果候选中
  • 有效性验证:确保每个结果只被匹配一次,避免重复匹配的情况
  • 循环减法处理:使用(num - resta + 10) Mod 10实现小于0时从9接续的逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:04:53