C # эквивалент C ++ std :: string find_first_not_of и find_last_not_of - PullRequest
8 голосов
/ 21 декабря 2010

IndexOf, IndexOfAny и LastIndexOf, LastIndexOfAny, кажется, не делают этого (или, возможно, они делают). Я ищу эквивалентные из std :: string's find_first_not_of и find_last_not_of. Я думаю о создании класса расширения, но я не уверен, что C # уже предоставляет эту функциональность.

Ответы [ 3 ]

11 голосов
/ 21 декабря 2010
string source = "the quick brown fox jumps over the lazy dog";
string chars = "ogd hte";

int? firstNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
                        .Where(x => chars.IndexOf(x.Val) == -1)
                        .Select(x => x.Idx)
                        .FirstOrDefault();

int? lastNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
                       .Where(x => chars.IndexOf(x.Val) == -1)
                       .Select(x => x.Idx)
                       .LastOrDefault();

Или, если вы предпочитаете некоторые методы расширения не LINQ.Они должны иметь чуть лучшую производительность, особенно для FindLastNotOf:

int? firstNotOf = source.FindFirstNotOf(chars);
int? lastNotof = source.FindLastNotOf(chars);

// ...

public static int? FindFirstNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return 0;

    for (int i = 0; i < source.Length; i++)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}

public static int? FindLastNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return source.Length - 1;

    for (int i = source.Length - 1; i >= 0; i--)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}

(вполне возможно, что может получить лучшую производительность - как в версиях LINQ, так и в версиях без LINQ -если вы конвертируете chars в HashSet<char>, или, может быть, даже в простой массив char[]. Вам нужно будет провести сравнительный анализ, чтобы выяснить это, хотя любая разница, вероятно, будет незначительной, если chars не станет довольно большим.)

4 голосов
/ 21 декабря 2010

Если использование LINQ приемлемо, вы можете вызвать методы First () и Last () с соответствующим предикатом.

Например, еслиВы хотите, чтобы первый и последний символы не были гласными:

string vowels = "aeiouy";
char first = yourString.First(ch => vowels.IndexOf(ch) < 0);
char last = yourString.Last(ch => vowels.IndexOf(ch) < 0);

РЕДАКТИРОВАТЬ: Выше будут возвращаться символы, а не их индексы.Чтобы сделать это, вы можете проецировать индексы, используя метод Select () , но все станет слишком сложно, поскольку нам нужно вернуть -1, если ни один символ не соответствует:

int firstIndex = (yourString.Select(
        (ch, i) => new { Character = ch, Index = i }
    ).First(obj => vowels.IndexOf(obj.Character) < 0)
    ?? new { Character = '\0', Index = -1 }).Index;

int lastIndex = (yourString.Select(
        (ch, i) => new { Character = ch, Index = i }
    ).Last(obj => vowels.IndexOf(obj.Character) < 0)
    ?? new { Character = '\0', Index = -1 }).Index;

Альтернативно, вот менее сложное решение, основанное на ответе @ abatishchev:

string vowels = "aeiouy";
int firstIndex = yourString.IndexOf(yourString.First(
    ch => vowels.IndexOf(ch) < 0));
int lastIndex = yourString.LastIndexOf(yourString.Last(
    ch => vowels.IndexOf(ch) < 0));
0 голосов
/ 21 декабря 2010

Вот решение Regex.

string testString = "oueytestie";
var matchFirstNotOf = Regex.Match(testString, @"[^aeiouy]");
int firstNotOf = matchFirstNotOf.Success ? matchFirstNotOf.Index : -1;
var matchLastNotOf = Regex.Match(testString, @"[^aeiouy]", RegexOptions.RightToLeft);
int lastNotOf = matchLastNotOf.Success ? matchLastNotOf.Index : -1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...