Есть ли способ сравнить каждую строку в одном текстовом файле с одной строкой в другом текстовом файле в C?
Например, у меня есть индексный текстовый файл, содержащий более 400 английских слов, а затем у меня есть другой текстовый файл с расшифрованным текстом в каждой строке.
Я хочу проверить каждое английское слово в моем индексном файле с каждой строкой моего расшифрованного текстового файла (таким образом, проверяя соответствие 400+ английских слов на соответствие каждой строке дешифрованного текста)
Я думал об использовании strncmp(decryptedString, indexString, 10)
потому что я знаю, что strncmp завершается, если следующий символ NULL
,
Каждая строка моего расшифрованного текстового файла имеет длину 352 символа, и там хранится ~40 миллионов строк текста (каждая строка получается из разных выходных данных).
Это для расшифровки шифра playfair; Я знаю, что мой алгоритм расшифровки работает, потому что мой профессор дал нам пример для тестирования нашей программы, и он работал нормально.
Я работал над этим проектом шесть дней подряд, и это единственная часть, на которой я застрял. Я просто не могу заставить его работать. Я пытался использовать
while(getline(&line, &len, decryptedFile) != -1){
while(getline(&line2, &len2, indexFile) != -1){
if(strncmp(decryptedString, indexString, 10) == 0){
fprintf(potentialKey, "%s", key);
}
}
}
Но я никогда не получаю спичек. Я пытался хранить каждую строку в массивах и тестировать их по одному символу за раз, и это тоже не помогло мне, поскольку в нем все английские слова были бы перечислены в одной строке. Я просто потерян, поэтому любая помощь или указатели в правильном направлении будут высоко оценены. Заранее спасибо.
РЕДАКТИРОВАТЬ: Основываясь на совете Клиффорда в комментариях, вот пример того, что я пытаюсь сделать
Допустим, indexFile содержит:
HELLO
WORLD
PROGRAMMING
ENGLISH
И дешифрованный файл содержит
HEVWIABAKABWHWHVWC
HELLOHEGWVAHSBAKAP
DHVSHSBAJANAVSJSBF
WORLDHEEHHESBVWJWU
PROGRAMMINGENGLISH
Я пытаюсь сравнить каждое слово из indexFile с decryptedFile, по одному за раз. Таким образом, все четыре слова из indexFile будут сравниваться со строкой 1, строкой 2, строкой 3, строкой 4 и строкой 5 соответственно.
2 ответа
Если вы пытаетесь проверить, начинается ли строка ввода со слова, вы должны использовать:
strncmp(line, word, strlen(word));
Если вы знаете, что line
длиннее чем word
, ты можешь использовать
memcmp(line, word, strlen(word));
Если вы делаете это неоднократно с одним и тем же словом, вам лучше сохранить длину word
в той же структуре данных, что и word
Сам, чтобы избежать повторного вычисления каждый раз.
Это общий случай использования strncmp
, Обратите внимание, что ваше описание strncmp
немного неточно. Он остановится, когда достигнет значения NUL в любом из аргументов, но вернет значение равно, только если оба аргумента имеют значение NUL в одном и том же месте или если счет исчерпан без разницы.
strncmp
безопаснее, чем в зависимости от того, что line
длиннее чем word
, учитывая, что разница в скорости между memcmp
а также strncmp
очень маленький
Однако с таким большим количеством данных и таким количеством слов, которые нужно проверить, вы должны попробовать что-то, что уменьшит количество сравнений, которые вам нужно сделать. Вы можете поместить слова в Trie, например. Или, если это кажется слишком большой работой, вы можете по крайней мере классифицировать их по первой букве и использовать только те, чья первая буква соответствует первой букве строки, если таковые имеются.
Если вы ищете экземпляр слова (слов) где-либо в строке, то вам понадобится более сложная стратегия поиска. Есть много алгоритмов для этой проблемы; Aho-Corasick эффективен и прост, хотя есть и более быстрые.
Если строка дешифрованного текста имеет длину 352 символа, а каждое слово в индексе не имеет длину 352 символа, то строка дешифрованного текста никогда не будет соответствовать ни одному слову в индексе.
Исходя из этого, я думаю, что вы неправильно поняли требования и задали вопрос, основанный на недоразумении.
В частности, я подозреваю, что вы хотите сравнить каждое отдельное слово в расшифрованной строке (а не всю строку) с каждым каждым словом в вашем индексе, чтобы определить, являются ли все слова в расшифрованной строке приемлемыми. Для этого первым шагом будет разбить расшифрованную строку символов на отдельные слова - например, найти символы, которые разделяют слова (пробелы, символы табуляции, запятые?) В расшифрованном тексте, и заменить их нулевым терминатором (так, чтобы ты можешь использовать strcmp()
и не нужно беспокоиться о том, что "foobar" неправильно соответствует "foo" только потому, что совпадают первые буквы).
Обратите внимание, что, возможно, есть потенциальные оптимизации. Например, если вы знаете, что слово из расшифрованного текста содержит 8 символов (что вам нужно было бы знать, чтобы поместить нулевой терминатор в правильное место), и если ваш индекс разбит на "один список для каждой длины слова" (например, список индексных слов с 3 символами, список индексных слов с 4 символами и т. д.), тогда вы можете пропустить множество сравнений строк (и сравнивать только слова из расшифрованной строки со словами одинаковой длины). в указателе). В этом случае (когда вы знаете, что оба слова уже имеют одинаковую длину) вы также можете избежать изменения исходных 352 символов (вам не нужно будет вставлять нулевой терминатор после каждого слова).