скажем, у меня есть txt файл, содержащий:
пользователь вводит строку, например «омар», Я хочу, чтобы программа искала этот файл txt для строки «omar», если она не существует, просто отобразите «не существует».
Я попробовал функцию String.endsWith() или String.startsWith(), но, конечно, отображает «не существует» 3 раза.
Я начал java всего 3 недели назад, так что я полный новичок. пожалуйста, медведь со мной. спасибо.
Просто прочитайте этот текстовый файл и поместите каждое слово в List , и вы можете проверить, содержит ли это List ваше слово.
Вы можете использовать Scanner scanner=new Scanner(«FileNameWithPath»); для чтения файла, и вы можете попробовать сделать следующее, чтобы добавить слова в List .
Затем проверьте, есть ли ваше слово или нет
Кстати, вы можете искать непосредственно в файле.
используйте String.contains(your search String) вместо String.endsWith() или String.startsWith()
Вы можете пойти другим путем. Вместо того, чтобы печатать «не существует», печать «существует», если совпадение найдено при перемещении файла и break; Если весь файл перемещен и совпадение не найдено, только затем продолжайте и покажите ‘ не существует.
Кроме того, используйте String.contains() вместо str.startsWith() или str.endsWith() . Содержит проверку будет искать совпадение во всей строке, а не только в начале или в конце.
Надеюсь, что это имеет смысл.
И после этого просто используйте метод textData.contains(user_input); , где textData — это данные, считанные из файла, а user_input — это строка, которую пользователь ищет
UPDATE
Этот метод возвращает StringBuilder, созданный из данных, которые вы прочитали из текстового файла, указанного как параметр.
Вы можете видеть, находится ли строка ввода пользователя в файле следующим образом:
Я работаю на утомительные задания, но я застрял на части, что я думал, что было бы весьма simple..I нужно искать «имена» в текстовом файле. Имена указаны с дефисом до, так, например,
«Привет, это пример, если бы мы использовали -John, то Джон будет имя, которое я искал бы»
Мне нужно, чтобы «Джон» в этом случае и хранить его в список.
Я знаю, как читать строки, с функциями FileReader и ReadLine из java..but я не знаю, как искать символы в текстовом файле, как жгучие для дефиса, а затем создать короткую подстроку после дефиса и следующего пространства для указать название. Может кто-нибудь помочь мне с кодом псевдо или функции, что я не в курсе, что может сделать это проще? Я извиняюсь, если я звук ужасно запутанным!
Вы можете использовать регулярное выражение на линиях, чтобы найти имя в строке. Регулярное выражение выражение является то, которое используется, чтобы найти и сопоставить определенные характеристики в данной строке.
Так для примера, с помощью обратной косой черты, вы должны использовать следующий код:
«-«. представляет собой шаблон любого символа (ов), непосредственно после того, как «». Обратите внимание, что из-за «» является маскирующим, оно должно предшествовать другому «».
Если вы хотите, чтобы сделать его принимать только символы алфавита, вы можете использовать «- / ^ [Az] + $ /», который выглядит в основном только для дефисов непосредственно следуют символы алфавита.
Я рекомендую вам прочитать на регулярных выражений, а также различные выражения, которые он может предложить.
Я написал этот код для поиска строки в файле .txt . Возможно ли оптимизировать код так, чтобы он быстро искал строку? Предполагая, что текстовый файл будет большим (500 МБ-1 ГБ)
Я не хочу использовать регулярное выражение.
6 ответов
Fast приходит по цене . сложность кода и, возможно, читаемость.
Предполагая, что ваш код теперь дает правильные результаты . и это большое предположение, потому что:
- он ожидает, что слово находится в начале /конце строки или окружено пробелами (а не запятыми, пунктуацией и т. д.).
- он не ищет слово внутри другой строки, он будет соответствовать «есть», но не «голый».
Хорошо, гораздо быстрее (сохраняя его как Java), заключается в следующем:
- Преобразуйте строку поиска (‘are’) в байтовый массив в ту же кодировку, что и файл.
- Откройте байт-буфер с отображением памяти из Файл-канал в файле .
- Сканирование ByteBuffer, поиск совпадений с байтовым массивом поиска
- подсчитывайте символы перевода строк.
- закрыть ByteBuffer
Если файл больше, чем ваша память, вам придется иногда переставлять байтовый буфер. Я рекомендую использовать размер сопоставленного emopry размером около 4 МБ плюс размер строки поиска. Таким образом, вы можете выполнить поиск в окне 4MB, а затем запустить следующее окно на следующей границе 4mb.
Как только вы займетесь этим, это будет иметь смысл.
Эта система будет быстрой, потому что вам никогда не придется копировать данные файла в Java. На самом деле все будет происходить на родной стороне вещей.
Есть много, чтобы прочитать, чтобы заставить его работать.
Я бы начал с учебника .
, конечно, если вы хотите очень быстро, используйте grep.
Вот пример кода, который может вас запустить:
Если вы хотите перейти на производительность, вы можете попробовать другой алгоритм. Это то, что делает grep :
GNU grep использует известный алгоритм Бойера-Мура, который сначала ищет окончательную букву целевой строки, и использует таблицу поиска, чтобы рассказать ей, как далеко вперед она может пропустить во входном сигнале всякий раз, соответствующий символ.
из Почему GNU grep работает быстро (вы найдете на этом страница другие умные идеи).
Более подробную информацию можно найти на соответствующей странице Википедии .
Если вы хотите совместить «есть» с пробелами вокруг него, просто добавьте такие пробелы: «are» и посмотрите, содержит ли строка эту строку (принимая во внимание некоторые случаи краев).
Сделайте сначала наименее дорогостоящие проверки. Equals сначала проверит длину строки, так что это быстрая проверка, если линия не будет одинаково длинной для пространства поиска (не так часто). Функции startsWith и endsWith — это быстрые проверки, поскольку они не выполняют поиск; contains выполняется последним, потому что это самый дорогой.
Вышеизложенное позволяет избежать расщепления (которое может быть медленным) и итерации над списком слов. Вместо этого, чтобы API-интерфейс строки, который, скорее всего, реализован в собственном коде, выполняет вашу работу. Используемые строки должны быть построены до цикла, чтобы избежать повторных операций с строкой, хотя я думаю, что компилятор java оптимизирует это, я не уверен.
Хорошая реализация String.contains() будет использовать Boyer-Moore, но это не обязательно. Java не определяет, какой алгоритм он есть. Если вы хотите быть уверенным, см. Ссылку в ответе: https://codereview.stackexchange.com/a/44042/36120
Поскольку вы хотите найти номера строк, в которых совпадение будет успешным, я попытаюсь сделать улучшения на основе вашей текущей стратегии на основе BufferedReader.readLine() и прибегнуть к более экзотическим средствам, таким как NIO только при необходимости.
Две несколько дорогостоящие операции — это разделение строк и конкатенация строк.
Когда вы разделяете строку на слова, она должна выделять и копировать символы нового String для каждого слова, а также массив для хранения результатов. Вместо этого вы можете искать в строке и проверить, происходят ли начало и конец совпадения на границах слов.
Вероятно, вы должны рассматривать знаки препинания, а также пробелы как границы слов.
Другая неэффективность — это повторная конкатенация строк. Строки в Java неизменяемы. Всякий раз, когда вы пишете a + b для строк a и b , код фактически компилируется в new StringBuilder(a).append(b).toString() . Следовательно, lineNumber должен быть StringBuilder , поэтому вы можете эффективно добавлять к нему.
Обратите внимание, что FileNotFoundException является своего рода IOException . Вы можете использовать один блок catch для обработки обоих. Однако, если возникает IOException , вы, вероятно, не должны пытаться сообщать количество слов, которое, вероятно, будет недействительным. Для этого вы можете просто исключить все блоки try-catch из main() и объявить, что main(String[] args) throws IOException . Затем, в случае ошибки, он просто распечатает трассировку стека и выйдет.
Я не хочу использовать регулярное выражение.
Возможно, вам стоит.
Малоизвестный факт заключается в том, что Matcher не принимает String в качестве аргумента, а CharSequence . И String реализует этот интерфейс.
Поскольку вы имеете дело с большими текстовыми файлами, ну, у меня есть только библиотека для вас: крупный файл , Он реализует CharSequence в большом текстовом файле, что означает, что экземпляр LargeText можно использовать непосредственно с помощью Matcher :
Вы можете искать строку в виде байтового массива: проверить мою версию public static int search(byte[] input, byte[] searchedFor) на https://stackoverflow.com/questions/22234021/search-for- a-string-as-by-in-a-binary-stream /22236277 # 22236277
Конечно, делая байтовый поиск, вы должны поймать все символы «новой строки» и подсчитать их, чтобы дать пользователю номер строки, где были найдены совпадения.
Источник: