#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. Спасибо. Это имеет смысл.