Алгоритм поиска возможностей цепочек слов с их n-го места в алфавите с использованием VBA - PullRequest
0 голосов
/ 05 апреля 2019

В Интернете я наткнулся на вопрос, который был следующим:

11216812520 - для алфавита, а 183624911413 - для ____________

Первое число - это просто номер каждой буквы в алфавите;

1.12.16.8.1.2.5.20 = ALPHABET

При попытке решить другое число, хотя и не слишком сложно, бывают случаи, когда оно может быть 1 = A или 11 = K и т. Д.

Я хотел написать алгоритм на VBA, который мог бы перечислять все возможные комбинации слов.

Мой код:

Sub routine()

Dim num As String
Dim word As String
Dim arr() As String
Dim c As Collection

Set c = New Collection
c.Add "A", "1"
c.Add "B", "2"
c.Add "C", "3"
c.Add "D", "4"
c.Add "E", "5"
c.Add "F", "6"
c.Add "G", "7"
c.Add "H", "8"
c.Add "I", "9"
c.Add "J", "10"
c.Add "K", "11"
c.Add "L", "12"
c.Add "M", "13"
c.Add "N", "14"
c.Add "O", "15"
c.Add "P", "16"
c.Add "Q", "17"
c.Add "R", "18"
c.Add "S", "19"
c.Add "T", "20"
c.Add "U", "21"
c.Add "V", "22"
c.Add "W", "23"
c.Add "X", "24"
c.Add "Y", "25"
c.Add "Z", "26"

word = ""
num = Cells(1, 5).Value
j = 1

For i = 1 To Len(num)

        If Mid(num, i + 1, 1) = 0 Then

            arr(j) = Mid(num, i, 1) & Mid(num, i + 1, 1)
            j = j + 1

        ElseIf Mid(num, i + 1, 1) <= 6 And Mid(num, i, 1) <= 2 Then

            arr(j) = Mid(num, i, 1)
            arr(j + 1) = arr(j) & Mid(num, i + 1, 1)
            j = j + 1

        Else

            arr(j) = Mid(num, i + 1, 1)

        End If

Next i

Cells(1, 6).Value = word

End Sub

Я собрал все буквы и их буквы.n место в алфавите.Я изо всех сил пытаюсь понять, как будут генерироваться слова.

Если мы посмотрим на вторую строку чисел в загадке выше [183624911413], алгоритм может увидеть, что 1 и 18 могут быть буквамиA и R соответственно, тогда новый цикл начнется со 2-го символа для A и увидит, что это 8, поэтому будет H, так как 83 слишком велико, а 3-й символ для R, который будет C, как 36, слишком велик.

Поскольку это продолжается, алгоритм должен будет посмотреть на текущие строки, т. Е. AH, и обработать их n-е место 1,8, увидеть, что длина строки равна 2, и снова начать с 3-й цифры в оригинале.число [3].

Я не могу найти хороший способ сделать это без целой связки операторов If, которые не будут полезны для неопределенных длин чисел.

Ответы [ 3 ]

3 голосов
/ 05 апреля 2019

Простой ответ: рекурсия .

  • Я предполагаю, что c - это глобальная коллекция (вы не хотите продолжать определять ее каждый раз, когда вы повторяете).
  • Ввод - это строка, выход - этострока.
  • Цифры в строке являются просто символами, а не числами.
  • Конечной точкой любой строки рекурсии является пустая строка (это легко проверить)
  • Сначала я буду жадным, потому что любая отдельная цифра будет действительным символом.

Псевдокод:

Function ConvertToCharacter(inputString, existingAnswer)
    IF inputString is empty THEN 
        output existingAnswer
        END recursion line
    IF length inputString > 2 THEN
        IF first2char are valid char then ConvertToCharacter(inputString less first two char, existingAnswer plus valid char)
    ConvertToCharacter(inputString less first char, existingAnswer plus other valid char)

Каждый отдельный рекурсивный вызов может переходить в два вызова.Однако, если один из вызовов приводит к бессмысленной паре цифр (например, «83»), он молча завершится ошибкой (следовательно, не даст результата).

Этот подход предоставит несколько ответов для одной строки.

2 голосов
/ 06 апреля 2019

Здесь решение в C # работает рекурсивно, когда объединенные цифры <= 26, оно создает дополнительный путь. </p>

class Program
{
    public static void Main(string[] args)
    {
        List<string> Activewords = new List<string>();

        string guessWord = "183624911413";

        AddedWord(Activewords, guessWord, 0, "");
    }

    public static void AddedWord(List<string> Words, string searchWord, int Position, string curWord)
    {
        if (Position == searchWord.Length)
        {
            Words.Add(curWord);
            return;
        }

        char oneChar = searchWord[Position];
        int i = oneChar - 48;

        AddedWord(Words, searchWord, ++Position, curWord + (char)(i + 64));
        if (Position < searchWord.Length)
        {
            int j = i * 10 + searchWord[Position] - 48;

            if (j <= 26) //Alphabet has 26 letters
            {
                AddedWord(Words, searchWord, ++Position, curWord + (char)(j + 64));
            }
        }
         return ;
    }
}
0 голосов
/ 08 апреля 2019

Мне удалось решить эту проблему благодаря @AJD, который разместил псевдокод. Я включил код ниже, который будет перечислять все возможные комбинации букв на основе числа.

Public iRow As Integer

Function ConvertToCharacter(inputString, existingAnswer)
    Dim c As Collection

    Set c = New Collection
    c.Add "A", "1"
    c.Add "B", "2"
    c.Add "C", "3"
    c.Add "D", "4"
    c.Add "E", "5"
    c.Add "F", "6"
    c.Add "G", "7"
    c.Add "H", "8"
    c.Add "I", "9"
    c.Add "J", "10"
    c.Add "K", "11"
    c.Add "L", "12"
    c.Add "M", "13"
    c.Add "N", "14"
    c.Add "O", "15"
    c.Add "P", "16"
    c.Add "Q", "17"
    c.Add "R", "18"
    c.Add "S", "19"
    c.Add "T", "20"
    c.Add "U", "21"
    c.Add "V", "22"
    c.Add "W", "23"
    c.Add "X", "24"
    c.Add "Y", "25"
    c.Add "Z", "26"
    c.Add " ", "27"

    If inputString = "" Then
        Cells(iRow, 1).Value = existingAnswer
        iRow = iRow + 1
        Exit Function
    ElseIf Len(inputString) >= 2 Then
        If Int(Left(inputString, 2)) <= 27 And Int(Left(inputString, 1)) <> "0" Then Call ConvertToCharacter(Right(inputString, Len(inputString) - 2), existingAnswer & c.Item(Left(inputString, 2)))
    End If
    If inputString <> "0" And Left(inputString, 1) <> "0" Then
        Call ConvertToCharacter(Right(inputString, Len(inputString) - 1), existingAnswer & c.Item(Left(inputString, 1)))
    End If


End Function

Sub ListPossibleWords()
Range(Cells(5, 1), Cells(20000, 1)).ClearContents
iRow = 5
Call ConvertToCharacter(Cells(2, 2), "")
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...