В C строки - это массивы char
с нулевым терминатором, то есть байт со значением 0
, обычно представляемым как '\0'
.Вы не должны принимать какую-либо конкретную длину, такую как 100
.Действительно, размер массива в аргументах прототипа функции игнорируется компилятором.Вы можете определить длину, отсканировав нулевой терминатор, что эффективно делает strlen()
, или вы можете написать код таким образом, чтобы избежать многократных сканирований, останавливаясь на нулевом терминаторе.Вы должны убедиться, что ваши функции работают для пустой строки, которая является массивом с одним нулевым байтом.Вот проблемы в вашем коде:
В функции noSpaces
вы выполняете итерации за концом строки, изменяя память, потенциально принадлежащую следующей строке.Программа имеет неопределенное поведение.
Вы должны остановиться в конце строки.Также используйте 2 индексные переменные для выполнения в линейное время:
void noSpaces(char word[]) {
/*
This is a function to get rid of spaces in a word
It does this by scanning for a space and shifting the
array elements at indices > where the space is
down by 1 as long as there is still a space
there.
*/
int i, j;
for (i = j = 0; word[i] != '\0'; i++) {
if (word[i] != ' ') {
word[j++] = word[i];
}
}
word[j] = '\0';
}
Вы можете упростить compare
, чтобы использовать в третий раз столько тестов в среднем:
int compare(const char word1[], const char word2[]) {
/*
This is a function that accepts two sorted
char arrays (see 'sortWords' below) and
returns 1 if it finds a different character
at entry i in either array, or 0 if at no
index the arrays have a different character.
*/
for (int i = 0; word1[i] == word2[i]; i++) {
if (word1[i]) == '\0')
//printf("anagrams\n");
return 0;
}
}
// printf("not anagrams\n");
return 1;
}
sortWords
не определеноповедение для пустой строки, потому что вы читаете char
по индексу 1
за концом массива.Вот исправленная версия:
void sortWords(char word[]) {
/*
This is a function to sort the input char arrays
it's a simple bubble sort on the array elements.
'sortWords' function accepts a char array and returns void,
sorting the entries in alphabetical order
being careful about ignoring the 'special character'
'\0'.
*/
for (int j = 0; word[j] != '\0'; j++) {
for (int i = 1; i < j; i++) {
if (word[i - 1] > word[i]) {
char dummy = word[i - 1];
word[i - 1] = word[i];
word[i] = dummy;
}
}
}
}
Вы должны объявить функции перед использованием или поочередно определить их перед использованием.Ваш код компилируется, потому что компилятор принимает старый стиль C, где прототип для еще невидимых функций был выведен из аргументов, переданных на первом сайте вызова.Эта практика подвержена ошибкам и устарела.
Ваша функция сортировки имеет квадратичную сложность по времени, которая может быть очень медленной для очень длинных строк, но слова не должны быть слишком большими, поэтому это не проблема.
Было бы лучше не изменять строки аргументов.Вы можете выполнить тест с копией одной из строк с той же временной сложностью.
Вот прямой подход:
#include <stdio.h>
int check_anagrams(const char word1[], const char word2[]) {
/*
This function accepts two strings and returns 1 if they
are anagrams of one another, ignoring spaces.
The strings are not modified.
*/
int i, j, len1, letters1, letters2;
/* compute the length and number of letters of word1 */
for (len1 = letters1 = 0; word1[len1] != '\0'; len1++) {
if (word1[len1] != ' ')
letters1++;
}
/* create a copy of word1 in automatic storage */
char copy[len1]; /* this is an array, not a string */
for (i = 0; i < len1; i++)
copy[i] = word1[i];
for (j = letters2 = 0; word2[j] != '\0'; j++) {
char temp = word2[j];
if (temp != ' ') {
letters2++;
for (i = 0; i < len1; i++) {
if (copy[i] == temp) {
copy[i] = '\0';
break;
}
}
if (i == len1) {
/* letter was not found */
return 0;
}
}
}
if (letters1 != letters2)
return 0;
return 1;
}
int main(int argc, char *argv[]) {
const char *s1 = " listen";
const char *s2 = "silent ";
if (argc >= 3) {
s1 = argv[1];
s2 = argv[2];
}
int result = check_anagrams(s1, s2);
if (result == 0) {
printf("\"%s\" and \"%s\" are not anagrams\n", s1, s2);
} else {
printf("\"%s\" and \"%s\" are anagrams\n", s1, s2);
}
return result;
}