Сравнить массивы символов
Если бы у меня был массив символов, например:
A = [w, o, r, n, g, , w, o, r, d]
И еще один массив, например:
B = [c, o, r, r, e, c, t, , w, o, r, d, .]
Мне нужно сравнить слова в массиве A (которые разделены пробелом) с массивом B, и если любое из слов в первом массиве существует во втором массиве, то это слово должно быть напечатано. Так, например, поскольку "слово" существует в первом массиве и во втором массиве, то "слово" должно быть распечатано.
Как мне это сделать?
3 ответа
Посмотрим, как бы я это сделал:
Вам понадобится функция, которая, учитывая массив char
, разбивает его на массив слов (и помещает их в строки C, NUL прекращается, пожалуйста:-)). Я бы положил длину этого массива и массив в структуре
struct WordCollection
{
size_t NumWords;
char **Words;
}
Теперь... Как сделать эту функцию?
Допустим, мы немного "обманываем" и решаем, что наши массивы A
а также B
NUL прекращается (или если они .
завершается как B, затем вы заменяете .
с NUL). Теперь, так как это C, вы должны сначала посчитать количество пробелов в строке, выделить массив char*
(WordCollection::Words
) достаточно большой, чтобы вместить n + 1
char*
(и положить это n + 1
в WordCollection::NumWords
) и с помощью strtok "токенизируйте" строку и поместите слова в созданный вами массив.
Затем вы должны (могли) разделить массив A и B на слова, используя эту функцию. Вы получите два WordCollection
А1 и В1.
Чтобы сделать это быстрее, я бы qsort B1.
Затем для каждого слова в A1 вы вводите его в B1 (это не плохое слово... Это означает Бинарный поиск, и это быстрый метод поиска чего-либо в упорядоченном массиве)
Готово:-)
Я добавлю это, если вы впервые используете bsearch
а также qsort
Лучше вы посмотрите на образцы, которые вы можете найти вокруг. Их синтаксис может быть "хитрым".
Теперь... я знаю, что вы не будете смотреть на код:-), поэтому я положу его здесь
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct WordCollection
{
size_t NumWords;
char **Words;
};
void splitWord(char *str, struct WordCollection *wc)
{
char *c;
char **currentWord;
c = str;
wc->NumWords = 1;
while (*c != '.')
{
if (*c == ' ')
{
wc->NumWords++;
}
c++;
}
*c = '\0';
wc->Words = (char**)malloc(wc->NumWords * sizeof(char*));
c = strtok(str, " ");
currentWord = wc->Words;
while (c)
{
*currentWord = c;
currentWord++;
c = strtok(NULL, " ");
}
}
int myComp(const void *p1, const void *p2)
{
return strcmp(*(const char**)p1, *(const char**)p2);
}
int main(void)
{
char a[] = { 'w', 'o', 'r', 'n', 'g', ' ', 'w', 'o', 'r', 'd', '.' };
char b[] = { 'c', 'o', 'r', 'r', 'e', 'c', 't', ' ', 'w', 'o', 'r', 'd', '.' };
struct WordCollection a1, b1;
struct WordCollection *pSmaller, *pBigger;
size_t i;
splitWord(a, &a1);
splitWord(b, &b1);
if (a1.NumWords <= b1.NumWords)
{
pSmaller = &a1;
pBigger = &b1;
}
else
{
pSmaller = &b1;
pBigger = &a1;
}
qsort(pBigger->Words, pBigger->NumWords, sizeof(char*), myComp);
for (i = 0; i < pSmaller->NumWords; i++)
{
void *res = bsearch(&pSmaller->Words[i], pBigger->Words, pBigger->NumWords, sizeof(char*), myComp);
if (res)
{
printf("Found: %s", pSmaller->Words[i]);
}
}
free(a1.Words);
free(b1.Words);
return 0;
}
И на идеоне
В основном вам нужно как-то разделить слова, а затем перебирать комбинации. Есть сотни способов сделать это - это просто требует программирования.
Вы также можете сделать это так:
Вставьте все слова из набора A в набор C с суффиксом "A". Вы получите =>
worngA
wordA
Вставьте все слова из набора B в набор C с суффиксом "B". Вы получите =>
correctB
wordB
Запустите алгоритм сортировки на множестве C, например, qsort. Вы получите =>
correctB
wordA
wordB
worngA
Цикл в наборе С, пока он не станет размером 1. сравнить
word[i]
сword[i+1]
- если они совпадают, кроме последней буквы - вы нашли дубликат и можете распечатать его.
Я не знаю, насколько сложен этот алгоритм, но он явно должен быть быстрее, чем просто перебор всех комбинаций слов:-)