Как найти сохраняющую порядок подпоследовательность в C #?

#c#

#c#

Вопрос:

Что я хочу сделать, так это найти подпоследовательности в заданной последовательности. Но я хочу, чтобы метод подпоследовательности был другим. А именно, первые цифры всегда должны быть первыми, вторые всегда вторыми и так далее. Итак, это должно быть сохранение порядка.

Например, учитывая три целых числа, X = 100, Y = 350, Z = 35, я хочу найти все числа между X и Y, такие, чтобы цифры чисел содержали последовательность Z цифр, а именно {3, 5} . Вывод в этом случае должен быть 8, а подпоследовательности: 135, 235, 305, 315, 325, 335, 345, 350.

 public List<int> split(int Z) {

    var digits = new List<int>();

    for (; Z > 0; Z /= 10) {
        digits.Add(Z % 10);
    }

    return digits;
}

private static int count(int X, int Y, int Z) {

    int count = 0;
    var splitZ = split(Z);

    for (int i = X; i <= Y; i  ) {
        var idigits = split(i); 
        var subseq = new LinkedList<int>();

        foreach (var digit in idigits) {
            subseq.AddLast(digit);

            if (subseq.Count == splitZ.Count) {
                if (subseq.SequenceEqual(splitZ)) {
                    Console.WriteLine(i);
                    count  ;
                }
            }
        }
    }

    return count;
}
  

У меня есть приведенный выше сегмент кода, но проблема в том, что он возвращает результат 3 вместо 8. Он просто считает, 135, 235, 335. Где последовательность 35 находится рядом друг с другом. Есть идеи, как изменить код и добиться того, чего я хочу?

Комментарии:

1. Вы смотрели на сортировку по основанию?

2. это напоминает мне логический семестр 1 — DFA и NFA

3. @DavidLively На самом деле нет.

Ответ №1:

Немного изменил вашу логику. Смотрите Комментарии в коде для объяснения.

 private static int count(int X, int Y, int Z)
{

    int count = 0;
    var splitZ = split(Z);

    if (splitZ.Count == 0)
    {
        return Y - X   1; // everything matches an empty Z sequence
    }

    for (int i = X; i <= Y; i  )
    {
        var idigits = split(i);
        int subIndex = 0;

        foreach (var digit in idigits)
        {
            if (splitZ[subIndex] == digit)
            {
                  subIndex; // matched digit
            }

            if (subIndex >= splitZ.Count)
            {
                  count;
                break; // matched whole sub-sequence
            }
        }
    }

    return count;
}
  

Комментарии:

1. Спасибо. Это имеет смысл.