Я хочу создать скрипт сравнения строк на C ++.
Функция сравнения файлов Total Commander очень хороша:
Как работает этот алгоритм?
Может ли кто-нибудь поделиться фрагментом этой функции?
Я хочу создать скрипт сравнения строк на C ++.
Функция сравнения файлов Total Commander очень хороша:
Как работает этот алгоритм?
Может ли кто-нибудь поделиться фрагментом этой функции?
Я не могу сказать Вам, чем занимается тотальный командир. Возможно, его можно было бы разобрать и попытаться проследить приемы.
Но общий алгоритм таков:
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
Алгоритм строкового поиска. Это, безусловно, полезно и для сравнения.
Также обратитесь к этому сообщению: алгоритм сравнения строк c ++
С наилучшими пожеланиями
ate
изменилось на eat
, а затем слово on
было удалено?
- person Alexey Frunze; 16.04.2013
Для такого сравнения вы можете использовать алгоритм diff или LCS.
Ниже приведена его простая реализация на языке C:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int lcs(const char* s1, const char* s2)
{
size_t l1 = strlen(s1), l2 = strlen(s2);
size_t sz = (l1 + 1) * (l2 + 1) * sizeof(size_t);
size_t w = l2 + 1;
size_t* dpt;
size_t i1, i2;
if (sz / (l1 + 1) / (l2 + 1) != sizeof(size_t) ||
(dpt = malloc(sz)) == NULL)
{
printf("Not enough memory\n");
return EXIT_FAILURE;
}
for (i1 = 0; i1 <= l1; i1++)
dpt[w * i1 + 0] = 0;
for (i2 = 0; i2 <= l2; i2++)
dpt[w * 0 + i2] = 0;
for (i1 = 1; i1 <= l1; i1++)
for (i2 = 1; i2 <= l2; i2++)
{
if (s1[l1 - i1] == s2[l2 - i2])
{
dpt[w * i1 + i2] = dpt[w * (i1 - 1) + (i2 - 1)] + 1;
}
else if (dpt[w * (i1 - 1) + i2] > dpt[w * i1 + (i2 - 1)])
{
dpt[w * i1 + i2] = dpt[w * (i1 - 1) + i2];
}
else
{
dpt[w * i1 + i2] = dpt[w * i1 + (i2 - 1)];
}
}
i1 = l1; i2 = l2;
for (;;)
{
if ((i1 > 0) && (i2 > 0) && (s1[l1 - i1] == s2[l2 - i2]))
{
printf("%c", s1[l1 - i1]);
i1--; i2--; continue;
}
else
{
if (i1 > 0 &&
(i2 == 0 || dpt[w * (i1 - 1) + i2] >= dpt[w * i1 + (i2 - 1)]))
{
printf("-%c", s1[l1 - i1]);
i1--; continue;
}
else if (i2 > 0 &&
(i1 == 0 || dpt[w * (i1 - 1) + i2] < dpt[w * i1 + (i2 - 1)]))
{
printf("+%c", s2[l2 - i2]);
i2--; continue;
}
}
break;
}
printf("\n");
free(dpt);
return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
const char *s1, *s2;
if (argc == 3)
{
s1 = argv[1]; s2 = argv[2];
}
else
{
printf("Usage:\n lcs-diff.exe <string1> <string2>\n\n");
s1 = "I ate apple on yesterday"; s2 = "I eat apple yesterday";
printf("Sample comparison:\n\n \"%s\" vs \"%s\":\n\n", s1, s2);
}
return lcs(s1, s2);
}
Вывод (ideone):
Usage:
lcs-diff.exe <string1> <string2>
Sample comparison:
"I ate apple on yesterday" vs "I eat apple yesterday":
I +eat-e apple -o-n- yesterday
С нуля я бы подошел к этой проблеме так (псевдокод):
String[] sarr1 = string1.split();
for (int i1 =0; i1<sarr1.length; i1++) {
if (!string2.contains(sarr[i1]) {
markWordRed(string1, sarr[i1]);
}
}
String[] sarr2 = string2.split();
for (int i2 =0; i2<sarr2.length; i2++) {
if (!string1.contains(sarr[i2]) {
markWordRed(string2, sarr[i2]);
}
}
Начиная с этого, дополнительно можно:
проверьте порядок слов, а не только то, существуют они или нет
проверить сходство каждого ненайденного слова со всеми ненайденными словами во второй строке и показать буквенные различия