Проверьте, содержит ли строка символы в определенном порядке в C # r - PullRequest
0 голосов
/ 12 июня 2018

У меня есть код, который работает сейчас, но он не проверяет, в порядке ли символы, он только проверяет, есть ли они там.Как я могу изменить свой код, чтобы символы 'gaoaf' проверялись в указанном порядке в строке?

Console.WriteLine("5.feladat");
            StreamWriter sw = new StreamWriter("keres.txt");
            sw.WriteLine("gaoaf");
            string s = "";
            for (int i = 0; i < n; i++)
            {
                s = zadatok[i].nev+zadatok[i].cim;
                if (s.Contains("g") && s.Contains("a") && s.Contains("o") && s.Contains("a") && s.Contains("f") )
                {
                    sw.WriteLine(i);
                    sw.WriteLine(zadatok[i].nev + zadatok[i].cim);
                }

            }
            sw.Close();

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Вы можете преобразовать буквы в шаблон и использовать Regex:

var letters = "gaoaf";
var pattern = String.Join(".*",letters.AsEnumerable());

var hasletters = Regex.IsMatch(s, pattern, RegexOptions.IgnoreCase);

Для тех, кто без необходимости избегает .*, вы также можете решить эту проблему с помощью LINQ:

var ans = letters.Aggregate(0, (p, c) => p >= 0 ? s.IndexOf(c.ToString(), p, StringComparison.InvariantCultureIgnoreCase) : p) != -1;

Если возможно иметь повторяющиеся соседние буквы, вам нужно немного усложнить решение LINQ:

var ans = letters.Aggregate(0, (p, c) => {
        if (p >= 0) {
            var newp = s.IndexOf(c.ToString(), p, StringComparison.InvariantCultureIgnoreCase);
            return newp >= 0 ? newp+1 : newp;
        }
        else
            return p;
    }) != -1;

Учитывая (некрасивые) махинации, необходимые для в основном завершения Aggregate рано, и учитывая (некрасиво)и неэффективный) синтаксис, необходимый для использования встроенного вызова анонимного выражения, чтобы избавиться от временного newp, я создал несколько расширений, чтобы помочь, Aggregate, которые могут завершаться досрочно:

public static TAccum AggregateWhile<TAccum, T>(this IEnumerable<T> src, TAccum seed, Func<TAccum, T, TAccum> accumFn, Predicate<TAccum> whileFn) {
    using (var e = src.GetEnumerator()) {
        if (!e.MoveNext())
            throw new Exception("At least one element required by AggregateWhile");
        var ans = accumFn(seed, e.Current);
        while (whileFn(ans) && e.MoveNext())
            ans = accumFn(ans, e.Current);
        return ans;
    }
}

Теперь вы можетерешить проблему довольно легко:

var ans2 = letters.AggregateWhile(-1,
                                  (p, c) => s.IndexOf(c.ToString(), p+1, StringComparison.InvariantCultureIgnoreCase),
                                  p => p >= 0
                                 ) != -1;
0 голосов
/ 12 июня 2018

Почему бы не что-то подобное?

static bool CheckInOrder(string source, string charsToCheck)
{
    int index = -1;
    foreach (var c in charsToCheck)
    {
        index = source.IndexOf(c, index + 1);
        if (index == -1)
            return false;
    }
    return true;
}

Тогда вы можете использовать такую ​​функцию:

bool result = CheckInOrder("this is my source string", "gaoaf");

Это должно работать, потому что IndexOf возвращает -1, если строкане найден, и он только начинает сканирование ПОСЛЕ предыдущего совпадения.

...