Я делаю что-то, где я понял, что хочу посчитать, сколько /
я могу найти в строке, и потом меня поразило, что было несколько способов сделать это, но я не мог определиться с тем, что лучше (или проще) было ,
На данный момент я собираюсь с чем-то вроде:
string source = "/once/upon/a/time/";
int count = source.Length - source.Replace("/", "").Length;
Но мне это совсем не нравится, любители?
Я действительно не хочу выкапывать RegEx
это, не так ли?
Я знаю, что в моей строке будет искомый термин, поэтому вы можете предположить, что ...
Конечно , для строк , где длина> 1 ,
string haystack = "/once/upon/a/time";
string needle = "/";
int needleCount = ( haystack.Length - haystack.Replace(needle,"").Length ) / needle.Length;
LEN(ColumnToCheck) - LEN(REPLACE(ColumnToCheck,"N",""))
.Ответы:
Если вы используете .NET 3.5, вы можете сделать это в одну строку с LINQ:
Если вы не хотите использовать LINQ, вы можете сделать это с:
Вы можете быть удивлены, узнав, что ваша оригинальная техника кажется примерно на 30% быстрее, чем любой из них! Я только что сделал быстрый тест с "/ один раз / на / время /", и результаты следующие:
(Время для 50 000 000 итераций, поэтому вы вряд ли заметите большую разницу в реальном мире.)
источник
f == '\'
о символах в строке, а не в строкеДолжно быть быстрее, чем само
source.Replace()
по себе.источник
источник
RegexOptions.IgnoreCase
.Regex.Escape(...)
такnew System.Text.RegularExpressions.Regex(needle).Matches(haystack).Count;
Если вы хотите иметь возможность искать целые строки, а не только символы:
Читайте как «для каждого символа в строке, оставшуюся часть строки, начинающуюся с этого символа, в качестве подстроки; считайте, если она начинается с целевой строки».
источник
Я провел некоторое исследование и обнаружил, что решение Ричарда Уотсона является самым быстрым в большинстве случаев. Это таблица с результатами каждого решения в посте (кроме тех, которые используют Regex, потому что он генерирует исключения при разборе строки типа "test {test")
Вы можете видеть, что в случае нахождения количества вхождений коротких подстрок (1-5 символов) в короткую строку (10-50 символов) предпочтителен оригинальный алгоритм.
Также для подстроки с несколькими символами следует использовать следующий код (на основе решения Ричарда Уотсона )
источник
Regex.Escape(needle)
source="aaa" substring="aa"
я ожидал получить обратно 2, а не 1. Чтобы «исправить» это, изменитеn += substring.Length
наn++
overlapped
флаг, чтобы удовлетворить ваш случай, как это:overlapped=True;.... if(overlapped) {++n;} else {n += substring.Length;}
LINQ работает со всеми коллекциями, и так как строки - это просто коллекция символов, как насчет этой милой строчки:
Убедитесь, что у вас есть
using System.Linq;
верхняя часть файла кода, как.Count
и метод расширения из этого пространства имен.источник
int
все буквы находятся в домашних ключах, аvar
нет. эээ ... подожди, я использую ДворжакНа моем компьютере это примерно на 2 секунды быстрее, чем решение для каждого символа за 50 миллионов итераций.
Редакция 2013 года:
Измените строку на char [] и повторите это. Сокращает еще одну или две секунды от общего времени для итераций на 50 м!
Это еще быстрее:
Для правильной оценки, итерация от конца массива до 0 кажется самой быстрой, примерно на 5%.
Я задавался вопросом, почему это могло быть и гуглил вокруг (я помню кое-что об обратной итерации, которая была быстрее), и натолкнулся на этот SO вопрос, который досадно использует технику строки для char [] уже. Я думаю, что уловка разворота является новой в этом контексте, хотя.
Какой самый быстрый способ перебора отдельных символов в строке в C #?
источник
source.IndexOf('/', n + 1)
и потерятьn++
скобки и время while :) Кроме того,string word = "/"
вместо символа укажите переменную .источник
Оба они работают только для односимвольных поисковых терминов ...
может оказаться лучше для более длинных игл ...
Но должен быть более элегантный способ. :)
источник
Редактировать:
источник
source.Split(new[]{"//"}, StringSplitOptions.None).Count - 1
для многосимвольных разделителей.В C # хорошим счетчиком String SubString является этот неожиданно хитрый парень:
источник
источник
stringToMatch
потребности уходят, а неinput
.Поскольку оригинальное решение было самым быстрым для символов, я полагаю, что оно также будет для строк. Так вот мой вклад.
Для контекста: я искал слова типа «не удалось» и «успешно» в файле журнала.
Гр, Бен
источник
источник
Для тех, кто хочет использовать готовый метод расширения String,
вот что я использую, основываясь на лучших из опубликованных ответов:
источник
источник
Я думаю, что самый простой способ сделать это - использовать регулярные выражения. Таким образом, вы можете получить то же количество разделений, что и при использовании myVar.Split ('x'), но с несколькими символами.
источник
Это будет учитываться каждый раз, когда программа находит "/ s" точно (с учетом регистра), и число вхождений этого будет сохранено в переменной "вхождения"
источник
Я чувствовал, что нам не хватало определенных видов подсчета подстрок, таких как небезопасные побайтовые сравнения. Я собрал оригинальный метод плаката и любые методы, которые могли придумать.
Это расширения строк, которые я сделал.
Вслед за тестовым кодом ...
Результаты: CSX соответствует CountSubstrX, а CCX соответствует CountCharX. «chr» ищет строку для «_», «и» ищет строку для «and», а «mlw» ищет строку для «muchlongerword»
И, наконец, у меня был файл с 3,6 миллионами символов. Это был "derp adfderdserp dfaerpderp deasderp", повторенный 100 000 раз. Я искал "derp" внутри файла с помощью описанных выше методов 100 раз эти результаты.
Так что мой 4-й метод определенно является победителем, но на самом деле, если файл с 3,6 миллионами символов 100 раз потребовал всего 1586 мс как худший случай, то все это довольно незначительно.
Кстати, я также отсканировал символ 'd' в 3,6-миллионном символьном файле со 100-кратными методами CountSubstr и CountChar. Результаты...
Исходя из этого, оригинальный метод постеров очень плох для односимвольных игл в большом стоге сена.
Примечание. Все значения были обновлены до версии выпуска. Я случайно забыл использовать режим Release при первой публикации этого сообщения. Некоторые из моих заявлений были изменены.
источник
Универсальная функция для появления строк:
источник
Вариация ответа Ричарда Уотсона: немного быстрее с повышением эффективности, чем чаще встречается символ в строке, тем меньше кода!
Хотя я должен сказать, что без тщательного тестирования каждого сценария, я увидел очень значительное улучшение скорости с помощью:
источник
Нужно сделать что-то похожее на проверку условных операторов из строки.
Заменили то, что я искал, одним символом и посчитали экземпляры одного символа.
Очевидно, что используемый вами символ необходимо проверить, чтобы он не существовал в строке, прежде чем это произойдет, чтобы избежать неправильного подсчета.
источник
Строка в строке:
Найти "и т.д." в ".. JD JD JD JD и т. Д. И т. Д. JDJDJDJDJDJDJDJD и т. Д."
Проверьте работоспособность, прежде чем отбросить это как ненадежное / неуклюжее ...
источник
Мой начальный дубль дал мне что-то вроде:
Игла в подходе к стогу сена с использованием замены и деления дает 21+ секунд, тогда как это занимает около 15,2.
Отредактируйте после добавления немного, которое добавит
substring.Length - 1
к charIndex (как и должно быть), это на 11,6 секунды.Редактировать 2: я использовал строку, которая имела 26 двухсимвольных строк, вот времена, обновленные к тем же образцам текста:
Игла в стоге сена (версия ОП): 7,8 секунды
Предлагаемый механизм: 4,6 секунды.
Редактировать 3: добавив односимвольный угловой регистр, это заняло 1,2 секунды.
Изменить 4: Для контекста: было использовано 50 миллионов итераций.
источник
Думал, что я добавлю свой метод расширения в кольцо (см. Комментарии для получения дополнительной информации). Я не проводил никаких официальных тестов, но думаю, что для большинства сценариев это должно быть очень быстрым.
РЕДАКТИРОВАТЬ: ОК - так что этот SO вопрос заставил меня задуматься, как производительность нашей текущей реализации будет сочетаться с некоторыми решениями, представленными здесь. Я решил сделать небольшую оценку производительности и обнаружил, что наше решение очень соответствует производительности решения, предоставленного Ричардом Уотсоном. до тех пор, пока вы не начнете агрессивный поиск с большими строками (100 Кбайт +), большими подстроками (32 Кбайт +) ) и много встроенных повторений (10K +). На тот момент наше решение было примерно в 2-4 раза медленнее. Учитывая это и тот факт, что нам действительно нравится решение, представленное Ричардом Уотсоном, мы соответствующим образом реорганизовали наше решение. Я просто хотел сделать это доступным для всех, кто мог бы извлечь из этого пользу.
Наше оригинальное решение:
И вот наше исправленное решение:
источник
источник
Он просто проверяет каждый символ в строке, если символ является символом, который вы ищете, добавьте один для подсчета.
источник
Если вы загляните на эту веб-страницу , 15 различных способов сделать это будут сопоставлены, в том числе с использованием параллельных циклов.
Самый быстрый способ - использовать однопоточный цикл for (если у вас версия .Net <4.0) или параллельный цикл for (если вы используете .Net> 4.0 с тысячами проверок).
Предполагая, что "ss" - это ваша строка поиска, "ch" - это ваш массив символов (если у вас есть более одного символа, который вы ищете), вот основная суть кода, который имел быструю однопоточную скорость выполнения:
Исходный код теста также предоставляется, чтобы вы могли запускать свои собственные тесты.
источник
Это для подсчета появления персонажа. Для этого примера выводом будет «a4b4j3»
источник
Для случая строкового разделителя (не для случая символа, как говорит субъект):
string source = "@@@ Once @@@ at @@@ a @@@ time @@@";
int count = source.Split (new [] {"@@@"}, StringSplitOptions.RemoveEmptyEntries) .Length - 1;
Естественный разделитель исходного значения плаката ("/ Once / Upon / A / Time /") представляет собой символ '/', а ответы объясняют параметр source.Split (char []), хотя ...
источник
использование System.Linq;
int CountOf => "A :: BC :: D" .Split ("::"). Длина - 1;
источник