Более эффективный способ получить все индексы символа в строке
Вместо того, чтобы прокручивать каждый символ, чтобы увидеть, хочет ли он тот, который вы хотите, добавив индекс в список, например:
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
{
if (myStr[i] == 'a')
foundIndexes.Add(i);
}
Ответы
Ответ 1
Вы можете использовать string.indexof, см. пример
string s = "abcabcabcabcabc";
var foundIndexes = new List<int>();
long t1 = DateTime.Now.Ticks;
for (int i = s.IndexOf('a'); i > -1; i = s.IndexOf('a', i + 1))
{
// for loop end when i=-1 ('a' not found)
foundIndexes.Add(i);
}
long t2 = DateTime.Now.Ticks - t1; // read this value to see the run time
Ответ 2
Я использую следующий метод расширения для yield
всех результатов:
public static IEnumerable<int> AllIndexesOf(this string str, string searchstring)
{
int minIndex = str.IndexOf(searchstring);
while (minIndex != -1)
{
yield return minIndex;
minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length);
}
}
использование:
IEnumerable<int> result = "foobar".AllIndexesOf("o"); // [1,2]
Ответ 3
Как насчет
string xx = "The quick brown fox jumps over the lazy dog";
char search = 'f';
var result = xx.Select((b, i) => b.Equals(search) ? i : -1).Where(i => i != -1);
Ответ 4
Исходная итерация всегда лучше и наиболее оптимизирована.
Если это не сложная задача, вам действительно не нужно искать лучшее оптимизированное решение...
Поэтому я предлагаю продолжить:
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
if (myStr[i] == 'a') foundIndexes.Add(i);
Ответ 5
Если строка короткая, может быть более эффективным поиск строки один раз и подсчет количества раз, когда появляется символ, затем выделите массив этого размера и повторите поиск строки во второй раз, записав индексы в массив. Это пропустит перераспределение списка.
В чем дело, насколько длинна строка и сколько раз появляется символ. Если строка длинна, а символ появляется несколько раз, поиск ее один раз и добавление указателей на List<int>
будет быстрее. Если символ появляется много раз, то поиск строки дважды (один раз для подсчета и один раз для заполнения массива) может быть быстрее. Именно там, где точка перелома зависит от многих факторов, которые не могут быть выведены из вашего вопроса.
Если вам нужно найти строку для нескольких разных символов и получить список индексов для этих символов отдельно, быстрее выполнить поиск по строке один раз и построить Dictionary<char, List<int>>
(или a List<List<int>>
с использованием смещений символов от \0
в качестве указателей во внешнем массиве).
В конечном счете, вы должны проверить свое приложение на наличие узких мест. Часто код, который, как мы думаем, будет выполняться медленно, на самом деле очень быстро, и мы тратим большую часть нашего времени на ввод/вывод или ввод пользователя.