Сортировка строки без библиотечных строковых функций - C (СИ)
Формулировка задачи:
Помогите, пожалуйста.
Напишите часть кода(сортировку).
Вводим строку.
Нужно отсортировать слова в алфавитном порядке без использования библиотечных строковых функций.
Решение задачи: «Сортировка строки без библиотечных строковых функций»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
size_t strspn(const char* const str, const char* const accept)
{
size_t count = 0;
const char* s = str;
const char* a = NULL;
while (*s != '\0')
{
a = accept;
while ((*a != '\0') && (*s != *a))
{
a++;
}
if (*a == '\0')
{
return count;
}
else
{
count++;
}
s++;
}
return count;
}
char* strpbrk(const char* const str, const char* const accept)
{
int found = 0;
const char* s = str;
const char* a = NULL;
while ((*s != '\0') && !found)
{
a = accept;
while ((*a != '\0') && !found)
{
if (*a == *s)
{
found = 1;
}
a++;
}
if (!found)
{
s++;
}
}
if (found)
{
return (char*) s;
}
else
{
return NULL;
}
}
void* memscan(const void* const memory, const int chr)
{
const unsigned char* memoryIterator = memory;
unsigned char c = (unsigned char) chr;
while (*memoryIterator != c)
{
memoryIterator++;
}
return (void*) memoryIterator;
}
char* strtok(char* s, const char* const delim)
{
char* token = NULL;
static char* old;
if (s == NULL)
{
s = old;
}
s = s + strspn(s, delim);
if (*s == '\0')
{
old = s;
return NULL;
}
token = s;
s = strpbrk(token, delim);
if (s == NULL)
{
old = memscan(token, '\0');
}
else
{
(*s) = '\0';
old = s + 1;
}
return token;
}
void* memcpy(void* const dest, const void* const src, const size_t len)
{
unsigned char* destIterator = dest;
unsigned char* srcIterator = src;
size_t i = 0;
for (i = 0; i < len; i++)
{
(*destIterator) = (*srcIterator);
destIterator++;
srcIterator++;
}
return dest;
}
size_t strlen(const char* const str)
{
size_t length = 0;
const char* iterator = str;
while (*iterator != '\0')
{
length++;
iterator++;
}
return length;
}
char* strcpy(char* const dest, const char* const src)
{
return memcpy(dest, src, strlen(src) + 1);
}
char* strcat(char* const dest, const char* const src)
{
strcpy(dest + strlen(dest), src);
return dest;
}
int tolower(const int c)
{
if ((c >= 65) && (c <= 90))
{
return c + 32;
}
else
{
return c;
}
}
int strcasecmp(const char* const s1, const char* const s2)
{
int result = 0;
const unsigned char* p1 = (const unsigned char*) s1;
const unsigned char* p2 = (const unsigned char*) s2;
if (p1 != p2)
{
while ((result == 0) && (*p1 != '\0'))
{
result = tolower(*p1) - tolower(*p2);
p1++;
p2++;
}
}
return result;
}
void AnalyzeString(const char* const str, size_t* const wordsCountPtr, size_t* const maxWordLengthPtr)
{
const char* iterator = str;
size_t wordCount = 0;
size_t maxLength = 0;
size_t length = 0;
while (*iterator != '\0')
{
if (*iterator != ' ')
{
length++;
}
else if (*iterator == ' ')
{
if (length > maxLength)
{
maxLength = length;
}
length = 0;
wordCount++;
}
if (*(iterator + 1) == '\0')
{
if (length > maxLength)
{
maxLength = length;
}
length = 0;
wordCount++;
}
iterator++;
}
(*wordsCountPtr) = wordCount;
(*maxWordLengthPtr) = maxLength;
}
void TokenizeString(char* const str, char** const tokensArray)
{
size_t i = 0;
char* token = strtok(str, " ");
while (token != NULL)
{
strcpy(tokensArray[i], token);
i++;
token = strtok(NULL, " ");
}
}
void FreeAndNullTokens(char*** const tokensArrayPtr, const size_t tokensCount)
{
char** temp = *tokensArrayPtr;
size_t i = 0;
if (temp != NULL)
{
for (i = 0; i < tokensCount; i++)
{
free(temp[i]);
temp[i] = NULL;
}
free(temp);
temp = NULL;
}
}
char** AllocateTokensArray(const size_t tokensCount, const size_t tokenLength)
{
char** tokensArray = NULL;
size_t i = 0;
int allocSuccessful = 0;
tokensArray = malloc(tokensCount * sizeof(*tokensArray));
if (tokensArray != NULL)
{
allocSuccessful = 1;
i = 0;
while ((i < tokensCount) && allocSuccessful)
{
tokensArray[i] = malloc((tokenLength + 1) * sizeof(**tokensArray));
if (tokensArray[i] == NULL)
{
allocSuccessful = 0;
}
i++;
}
if (!allocSuccessful)
{
FreeAndNullTokens(&tokensArray, tokensCount);
}
}
return tokensArray;
}
int SortTokens(char** tokensArray, const size_t N, const size_t itemLength)
{
char* tempToken = NULL;
size_t i = 0;
size_t j = 0;
tempToken = malloc((itemLength + 1) * sizeof(*tempToken));
if (tempToken == NULL)
{
return 0;
}
for (j = 0; j < N - 1; j++)
{
for (i = 0; i < N - 1; i++)
{
if (strcasecmp(tokensArray[i], tokensArray[i + 1]) > 0)
{
strcpy(tempToken, tokensArray[i]);
strcpy(tokensArray[i], tokensArray[i + 1]);
strcpy(tokensArray[i + 1], tempToken);
}
}
}
free(tempToken);
return 1;
}
void ImplodeTokens(const char** const tokensArray, const size_t tokensCount, char separator, char* const str)
{
size_t i = 0;
str[0] = '\0';
for (i = 0; i < tokensCount - 1; i++)
{
strcat(str, tokensArray[i]);
str[strlen(str) + 1] = '\0';
str[strlen(str)] = separator;
}
strcat(str, tokensArray[tokensCount - 1]);
}
void SortWordsInString(char* const str)
{
size_t wordsCount = 0;
size_t maxWordLength = 0;
char** tokensArray = NULL;
AnalyzeString(str, &wordsCount, &maxWordLength);
tokensArray = AllocateTokensArray(wordsCount, maxWordLength);
TokenizeString(str, tokensArray);
if (SortTokens(tokensArray, wordsCount, maxWordLength))
{
ImplodeTokens(tokensArray, wordsCount, ' ', str);
}
FreeAndNullTokens(&tokensArray, wordsCount);
}
int main(void)
{
char s[] = "This is a test string for strtok!";
printf("'%s'\n --> \n", s);
SortWordsInString(s);
printf("'%s'\n", s);
return 0;
}
Объяснение кода листинга программы
- В данной реализации функции
strspnиспользуется для определения количества пробежных символов в строке. - Функция
strpbrkиспользуется для поиска первого символа, не являющегося пробелом, в строке. - Функция
memscanиспользуется для поиска первого вхождения символа в строке. - Функция
strtokиспользуется для разделения строки на токены. - Функция
memcpyиспользуется для копирования строки. - Функция
strlenиспользуется для определения длины строки. - Функция
strcpyиспользуется для копирования строки. - Функция
strcatиспользуется для добавления строки к другой строке. - Функция
tolowerиспользуется для преобразования символа в нижний регистр. - Функция
strcasecmpиспользуется для сравнения строк без учета регистра. - В функции
AnalyzeStringанализируется входная строка, определяются количество слов и максимальная длина слова. - В функции
TokenizeStringстрока разделяется на слова, которые сохраняются в массиве указателей на строки. - В функции
FreeAndNullTokensосвобождается память, выделенная под массив указателей на строки, и обнуляется указатель на этот массив. - В функции
AllocateTokensArrayвыделяется память под массив указателей на строки и сами строки. - В функции
SortTokensсортируются слова в массиве указателей на строки. - В функции
ImplodeTokensмассив указателей на строки объединяется в одну строку с использованием указанного разделителя. - В функции
SortWordsInStringсортируются слова в входной строке. - В функции
mainпроводится тестирование функцииSortWordsInString.