Если строка короткая, то зацикливание и тестирование могут быть самым простым и эффективным способом. Я имею в виду, что вы могли бы создать хэш-набор (на любой платформе, которую вы используете) и выполнить итерацию по символам, если произошел сбой, если символ уже есть в наборе, и добавить его в набор в противном случае, но это только чтобы обеспечить какую-либо выгоду, когда строки длиннее.
РЕДАКТИРОВАТЬ: Теперь, когда мы знаем, что это отсортировано, Ответ mquander является лучшим ИМО. Вот реализация:
public static bool IsSortedNoRepeats(string text)
{
if (text.Length == 0)
{
return true;
}
char current = text[0];
for (int i=1; i < text.Length; i++)
{
char next = text[i];
if (next <= current)
{
return false;
}
current = next;
}
return true;
}
Более короткая альтернатива, если вы не против повторить использование индексатора:
public static bool IsSortedNoRepeats(string text)
{
for (int i=1; i < text.Length; i++)
{
if (text[i] <= text[i-1])
{
return false;
}
}
return true;
}
РЕДАКТИРОВАТЬ: Хорошо, с "частотой", я немного переверну проблему. Я все еще собираюсь предположить, что строка отсортирована, поэтому мы хотим узнать длину самого длинного пробега. Если повторов нет, самая длинная длина цикла будет 0 (для пустой строки) или 1 (для непустой строки). В противном случае будет 2 или более.
Сначала специфичная для строки версия:
public static int LongestRun(string text)
{
if (text.Length == 0)
{
return 0;
}
char current = text[0];
int currentRun = 1;
int bestRun = 0;
for (int i=1; i < text.Length; i++)
{
if (current != text[i])
{
bestRun = Math.Max(currentRun, bestRun);
currentRun = 0;
current = text[i];
}
currentRun++;
}
// It's possible that the final run is the best one
return Math.Max(currentRun, bestRun);
}
Теперь мы можем сделать это как общий метод расширения для IEnumerable<T>
:
public static int LongestRun(this IEnumerable<T> source)
{
bool first = true;
T current = default(T);
int currentRun = 0;
int bestRun = 0;
foreach (T element in source)
{
if (first || !EqualityComparer<T>.Default(element, current))
{
first = false;
bestRun = Math.Max(currentRun, bestRun);
currentRun = 0;
current = element;
}
}
// It's possible that the final run is the best one
return Math.Max(currentRun, bestRun);
}
Тогда вы можете позвонить, например, "AABCD".LongestRun()
.