diff --git a/lab25/lab25/SortStringArray.c b/lab25/lab25/SortStringArray.c index d581d90..e3ec0f0 100644 --- a/lab25/lab25/SortStringArray.c +++ b/lab25/lab25/SortStringArray.c @@ -1,5 +1,14 @@ +#define _CRT_SECURE_NO_WARNINGS #include "SortStringArray.h" +// Слова, загруженные из файла +char words[MAX_WORDS][MAX_LEN_WORD]; +// Количество слов в массиве +int n = 0; +// Массив для сортировки +char a[MAX_WORDS][MAX_LEN_WORD]; + + int LoadWords(char* filename) { // открыть файл FILE* fin = fopen(filename, "r"); @@ -38,7 +47,6 @@ void CopyWordsToA() { for (int i = 0; i < n; i++) { strcpy(a[i], words[i]); } - } int ArraysAreEqual() { @@ -74,7 +82,7 @@ void swapWords(char a[], char b[]) { char tmp[MAX_LEN_WORD]; strcpy(tmp, a); strcpy(a, b); - strcpy(a, tmp); + strcpy(b, tmp); } int isSortedStringArray(char a[MAX_WORDS][MAX_LEN_WORD]) { @@ -162,70 +170,81 @@ void InsertionSortStrings() { } } -/** - * Сортирует массив, используя рекурсивную сортировку слиянием - * up - указатель на массив, который нужно сортировать - * down - указатель на массив с, как минимум, таким же размером как у 'up', используется как буфер - * left - левая граница массива, передайте 0, чтобы сортировать массив с начала - * right - правая граница массива, передайте длину массива - 1, чтобы сортировать массив до последнего элемента - * возвращает: указатель на отсортированный массив. Из-за особенностей работы данной реализации - * отсортированная версия массива может оказаться либо в 'up', либо в 'down' - **/ -char* MergeSortStrings(char* up, char* down, unsigned int left, unsigned int right) { +// Merges two subarrays of arr[]. +// First subarray is arr[l..m] +// Second subarray is arr[m+1..r] +void merge(char arr[MAX_WORDS][MAX_LEN_WORD], int l, int m, int r) +{ + int i, j, k; + int n1 = m - l + 1; + int n2 = r - m; - if (left == right) - { - strcpy(down[left], up[left]); - return down; + // Create temp arrays + char L[MAX_WORDS][MAX_LEN_WORD], R[MAX_WORDS][MAX_LEN_WORD]; + + // Copy data to temp arrays L[] and R[] + for (i = 0; i < n1; i++) { + strcpy(L[i], arr[l + i]); + } + for (j = 0; j < n2; j++) { + strcpy(R[i], arr[m + 1 + j]); } - unsigned int middle = left + (right - left) / 2; - - // разделяй и сортируй - char* l_buff = MergeSortStrings(up, down, left, middle); - char* r_buff = MergeSortStrings(up, down, middle + 1, right); - - // слияние двух отсортированных половин - char* target = (l_buff == up) ? down : up; - - unsigned int l_cur = left, r_cur = middle + 1; - for (unsigned int i = left; i <= right; i++) - { - if (l_cur <= middle && r_cur <= right) - { - if (strcmp(l_buff[l_cur], r_buff[r_cur]) < 0) - { - strcpy(target[i], l_buff[l_cur]); - l_cur++; - } - else - { - strcpy(target[i], r_buff[r_cur]); - r_cur++; - } + // Merge the temp arrays back into arr[l..r + i = 0; + j = 0; + k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + strcpy(arr[k], L[i]); + i++; } - else if (l_cur <= middle) - { - strcpy(target[i], l_buff[l_cur]); - l_cur++; - } - else - { - strcpy(target[i], r_buff[r_cur]); - r_cur++; + else { + strcpy(arr[k], R[j]); + j++; } + k++; + } + + // Copy the remaining elements of L[], + // if there are any + while (i < n1) { + strcpy(arr[k], L[i]); + i++; + k++; + } + + // Copy the remaining elements of R[], + // if there are any + while (j < n2) { + strcpy(arr[k], R[j]); + j++; + k++; } - return target; } -void ShellSort(char* array, int size) { - for (int s = size / 2; s > 0; s /= 2) { - for (int i = s; i < size; ++i) { - for (int j = i - s; j >= 0 && strcmp(array[j], array[j + s]) > 0; j -= s) { +// l is for left index and r is right index of the +// sub-array of arr to be sorted +void MergeSortStrings(char arr[MAX_WORDS][MAX_LEN_WORD], int l, int r){ + if (l < r) { + int m = l + (r - l) / 2; + + // Sort first and second halves + MergeSortStrings(arr, l, m); + MergeSortStrings(arr, m + 1, r); + + merge(arr, l, m, r); + } +} + +void ShellSort() { + for (int s = MAX_WORDS / 2; s > 0; s /= 2) { + for (int i = s; i < MAX_WORDS; ++i) { + for (int j = i - s; j >= 0 && strcmp(a[j], a[j + s]) > 0; j -= s) { char tmp[MAX_LEN_WORD]; - strcpy(tmp, array[j]); - strcpy(array[j], array[j + s]); - strcpy(array[j + s], tmp); + strcpy(tmp, a[j]); + strcpy(a[j], a[j + s]); + strcpy(a[j + s], tmp); } } } diff --git a/lab25/lab25/SortStringArray.h b/lab25/lab25/SortStringArray.h index 7f32406..ad843d2 100644 --- a/lab25/lab25/SortStringArray.h +++ b/lab25/lab25/SortStringArray.h @@ -9,13 +9,14 @@ // Максимальное количество слов #define MAX_WORDS 20000 +extern int n; // Слова, загруженные из файла extern char words[MAX_WORDS][MAX_LEN_WORD]; -// Количество слов в массиве -extern int n = 0; // Массив для сортировки extern char a[MAX_WORDS][MAX_LEN_WORD]; + + int LoadWords(char* filename); void CopyWordsToA(); int ArraysAreEqual(); @@ -26,8 +27,8 @@ void SelectionSortStrings(); void QuickSortStrings(); void BubbleSortStrings(); void InsertionSortStrings(); -char* MergeSortStrings(char* up, char* down, unsigned int left, unsigned int right); -void ShellSort(char* array, int size); +void MergeSortStrings(char arr[MAX_WORDS][MAX_LEN_WORD], int l, int r); +void ShellSort(); int LinearSearchStrings(char target[], char source[MAX_WORDS][MAX_LEN_WORD]); int BinarySearchStrings(char target[], char source[MAX_WORDS][MAX_LEN_WORD]); diff --git a/lab25/lab25/crystaldiskinfo.png b/lab25/lab25/crystaldiskinfo.png new file mode 100644 index 0000000..a23fb22 Binary files /dev/null and b/lab25/lab25/crystaldiskinfo.png differ diff --git a/lab25/lab25/crystaldiskmark.png b/lab25/lab25/crystaldiskmark.png new file mode 100644 index 0000000..4ec6125 Binary files /dev/null and b/lab25/lab25/crystaldiskmark.png differ diff --git a/lab25/lab25/dict0.txt b/lab25/lab25/dict0.txt new file mode 100644 index 0000000..e96d022 --- /dev/null +++ b/lab25/lab25/dict0.txt @@ -0,0 +1,13 @@ +Alice +to +of +by +on +the +and +or +into +but +it +no + diff --git a/lab25/lab25/main.c b/lab25/lab25/main.c index 7bd2460..950d003 100644 --- a/lab25/lab25/main.c +++ b/lab25/lab25/main.c @@ -5,20 +5,17 @@ #include "SortStringArray.h" int main() { - LoadWords("/TextMarkup/dict0.txt"); + LoadWords("TextMarkup/dict4.txt"); - - - for (int i = 0; i < 1; i++) { + int iter = 3; + clock_t start = clock(); + for (int i = 0; i < iter; i++) { CopyWordsToA(); + //memcpy(a, words, sizeof(words)); - clock_t start = clock(); - - SelectionSortStrings(); + //SelectionSortStrings(); //QuickSortStrings(); - - printf_s("time = %.3lf seconds", (double)(clock() - start) / (double)CLOCKS_PER_SEC); - + MergeSortStrings(a, 0, MAX_WORDS-1); if (!ArraysAreEqual()) { printf("Arrays are not equal!!!\n"); @@ -27,7 +24,9 @@ int main() { printf("Array is not sorted!!!\n"); } } + double runtime = (double)(clock() - start) / (double)CLOCKS_PER_SEC; + printf_s("full time = %.3lf seconds\n", runtime); + printf_s("single sort time = %.3lf seconds\n", runtime / iter); - return 0; } diff --git a/lab25/lab25/sort test.xlsx b/lab25/lab25/sort test.xlsx new file mode 100644 index 0000000..96cf62e Binary files /dev/null and b/lab25/lab25/sort test.xlsx differ