Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Palindrome.cpp: определяет точку входа для консольного приложения.
- //
- #include "stdafx.h"
- #include "string.h"
- #include "stdio.h"
- #include "stdlib.h"
- #define SPACE 1 /*пробел не должен участвовать в сравнении*/
- enum State{ NO_CONCUR, PARTIALLY, OVERLAP, ERR};/*нет совпадений, частичное совпадение, полное*/
- struct Word{ /*структура содержит информацию о "нужности" слова и указатель на само слово*/
- State state;
- char* word1;
- char* word2;
- };
- char** Load(); /*Функция читает файл и возвращает массив строк, заканчивающийся NULL*/
- State Rev_comp(char* word1, char* word2); /*Функция сравнивает два слова и выносит вердикт о соответствии*/
- char* Compilation(int len,Word* arr); /*Функция создет палиндром*/
- char* Search(Word word, Word* arr, int len); /*Функция поиска подходящих слов для палиндрома*/
- char* Remove_Space(char*); /*Функция просто удаляет из слов пробелы*/
- char* Remove_Space(char* word){
- int i = 0;
- while(word[i++] != ' ');
- word[i - 1] = '\0';
- return word;
- }
- char* Search(Word word, Word* arr,int len){
- char buffer4straight[32] = { 0 }; /*буфер слова, для которого ищется пара*/
- char buffer4compare[32] = { 0 }; /*буфер слова, с которым в итоге будет сравниваться*/
- char buffer4reverse[64] = { 0 }; /*буфер соединения и разворачивания слов, хранящихся в buffer4straight и temp_bufer*/
- char temp_bufer[32] = { 0 }; /*буфер для хранения слова, которое будет подставляться к передаваемому*/
- char* complete_string = NULL; /*в конце этот указатель укажет на готовую, подобранную строку*/
- for (int i = 0; i < len; i++){
- if (arr[i].state == PARTIALLY){
- /*удаляем пробелы из слова, для которого ищется пара*/
- strcpy(buffer4straight, word.word1);
- Remove_Space(buffer4straight);
- /*удаляем пробелы из слова, с которым мы будем сравнивать*/
- strcpy(buffer4compare, word.word2);
- Remove_Space(buffer4compare);
- /*разворачиваем слово, для которого ищется пара*/
- strrev(buffer4straight);
- for (int j = 0; j < len && arr[j].word1 != NULL; j++){ /*получили после цикла либо составленную часть палиндрома, либо ничего*/
- /*даже не рассматриваем слова, для которых есть идеальная пара*/
- if (arr[i].state == OVERLAP)
- continue;
- /*копируем в temp_buffer тестовое слово, убирая из него пробел*/
- strcpy(temp_bufer, arr[j].word1);
- Remove_Space(temp_bufer);
- /*копируем в буфер для соединения слов тестовое слово, и для которого ищем пару*/
- strcpy(buffer4reverse, temp_bufer);
- strcat(buffer4reverse, buffer4straight);
- /*если строки совпали, то формируем нормальное словосочетание и возвращаем его из функции*/
- if (strcmp(buffer4reverse, buffer4compare) == 0){
- complete_string = (char*)calloc(strlen(buffer4reverse + SPACE), sizeof(char));
- strcpy(complete_string, arr[j].word1);
- strcat(complete_string,word.word1);
- return complete_string;
- }
- }
- }
- }
- return complete_string;
- }
- char* Compilation(int len, Word* arr){
- char** palindrome = (char**)calloc(len + 1,sizeof(char*)); /*+1 для обозначения конца списка*/
- char buffer[256] = { 0 }; /*занулит весь буфер*/
- int i, j, save_i; /*будем знать, на какой позиции закончились чистые палиндромы*/
- for (i = 0, j = 0; i < len; i++, j--){
- /*располагаем идеальные слова с концов палиндрома*/
- if (arr[i].state == OVERLAP){
- palindrome[i] = arr[i].word1;
- palindrome[j] = arr[i].word2;
- save_i = i;
- }
- }
- /*я чувствую, что какая-то хрень с этим save_i, но уже не соображаю)))*/
- /*по идее тут в каждую следующую ячейку палиндрома записывается найденное, сформированное словосочетание*/
- for (i = save_i; i < len; i++){
- if (arr[i].state == PARTIALLY){
- palindrome[i] = Search(arr[i],arr,len);
- }
- }
- /*ну это просто с запасом, короче писать, чем маллок*/
- static char output[1024];
- output[0] = ' ';
- for (i = 0; i < len; i++)
- /*конкатинируем все непустые ячейки*/
- if (palindrome[i] != NULL)
- strcat(output,palindrome[i]);
- /*возвращаем результат*/
- return output;
- }
- State Rev_comp(char* word1, char* word2){
- if (word1 == NULL || word2 == NULL)
- return ERR;
- int size1 = strlen(word1), \
- size2 = strlen(word2);
- char* matching_place = NULL;
- /*так как пробел всегда в конце слова, то его место заменит \0*/
- /*приходится вычитать SPACE, strlen считает не от 0, а от 1*/
- char* word1_wio_space = (char*)malloc((size1)*sizeof(char));
- char* word2_wio_space = (char*)malloc((size2)*sizeof(char));
- strcpy(word1_wio_space, word1);
- word1_wio_space[size1 - SPACE] = '\0';
- strcpy(word2_wio_space, word2);
- word2_wio_space[size2 - SPACE] = '\0';
- /*ищем в большей строке перевернутую меньшую*/
- /*strstr ищет подстроку, strrev - переворачивает строку. STRREV не стандартная функция!*/
- if (size1 < size2){
- strrev(word1_wio_space);
- matching_place = strstr(word2_wio_space, word1_wio_space);
- }
- else{
- strrev(word2_wio_space);
- matching_place = strstr(word1_wio_space, word2_wio_space);
- }
- if (matching_place == NULL)
- return NO_CONCUR;
- /*если размер строк совпадает и указатель на одну из строк совпадает с поисковым, то слова являются полными палиндромами*/
- else if (matching_place == word1_wio_space || matching_place == word2_wio_space && size1 - size2 == 0)
- return OVERLAP;
- /*иначе совпадают частично*/
- else return PARTIALLY;
- }
- char** Load(){
- /*Функция читает файл и возвращает массив строк, заканчивающийся NULL*/
- FILE* file = fopen("1.txt", "r");
- if (file == NULL){
- printf("\nError occured while reading\n");
- return NULL;
- }
- fseek(file, 0, SEEK_END);
- int FileSize = ftell(file); //узнаем размер файла
- fseek(file, 0, SEEK_SET);
- char* txt = (char*)malloc(sizeof(char)*FileSize + 1);
- FileSize = fread(txt, sizeof(char), FileSize, file); //Присваиваем FileSize количество реально прочитанных байт
- txt[FileSize] = '\0';
- void* search_ptr = txt;
- char** strings = (char**)calloc(1000, sizeof(char*)); //выделим побольше памяти, потом ее урежем realloc'ом
- int cnt = 0;
- do{ //считаем количество формул
- int length = 0;
- if (memchr(search_ptr, '\n', FileSize*sizeof(char)) != NULL) //длина формулы
- length = (intptr_t)memchr(search_ptr, '\n', FileSize*sizeof(char)) - (intptr_t)search_ptr + 1;
- else
- length = strlen((char*)search_ptr) + 1;
- strings[cnt] = (char*)calloc(length, sizeof(char));
- memcpy(strings[cnt], search_ptr, length - 1); //копируем -1 символ, чтобы сохранить \0 в конце строки
- cnt++;
- //+ (intptr_t)sizeof(char) отвечает за пропуск \n, а != (void*)1 за обрыв цикла, когда memchr выдал NULL (\n не найден)
- } while ((search_ptr = (void*)((intptr_t)memchr(search_ptr, '\n', FileSize*sizeof(char)) + (intptr_t)sizeof(char))) != (void*)1);
- strings = (char**)realloc(strings, (cnt + 1)*sizeof(char*));
- fclose(file);
- return strings;
- }
- void main()
- {
- int len;
- int real_len = 0;
- char** strings = Load();
- for (len = 0; strings[len] != NULL; len++); /*считаем количество слов из файла*/
- Word* check_arr = (Word*)calloc(len*len, sizeof(Word)); /*массив, из которого выкинем ненужные слова*/
- State state;
- for (int i = 0,k = 0; i < len; i++){
- for (int j = 0; j < len; j++){
- if (strings[i] == strings[j]) /*одно и то же слово*/
- continue;
- state = Rev_comp(strings[i], strings[j]);
- if (state == OVERLAP || state == PARTIALLY){
- /*если слова удовлетворяют требованиям, то заносим их в check_arr
- и больше не проверяем*/
- check_arr[k].state = state;
- check_arr[k].word1 = strings[i];
- check_arr[k].state = state;
- check_arr[k].word2 = strings[j];
- k++;
- }
- }
- }
- while (check_arr[real_len++].word1 != NULL);
- char* out = Compilation(len, check_arr);
- while (1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement