diff --git a/11_Toolkits/CMakeLists.txt b/11_Toolkits/CMakeLists.txt new file mode 100644 index 0000000..28edf5b --- /dev/null +++ b/11_Toolkits/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10) + +project(11_Toolkits) + +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED glib-2.0) + +include_directories(${GLIB_INCLUDE_DIRS}) +link_directories(${GLIB_LIBRARY_DIRS}) + +add_executable(main main.c) + +add_definitions(${GLIB_CFLAGS_OTHER}) +target_link_libraries(main ${GLIB_LIBRARIES}) + diff --git a/11_Toolkits/main.c b/11_Toolkits/main.c new file mode 100644 index 0000000..271c4a3 --- /dev/null +++ b/11_Toolkits/main.c @@ -0,0 +1,82 @@ +#include + +#include + +const int BUF_SIZE = 90; + +gboolean process_new_line(GHashTable* counts) { + gchar buf[BUF_SIZE]; + char* p = fgets(buf, BUF_SIZE - 1, stdin); + if (p == NULL) + return FALSE; + g_strchomp(buf); + + gchar** words = g_strsplit(buf, " ", -1); + for (int word_ind = 0; words[word_ind] != NULL; ++word_ind) { + gchar* cur_word = words[word_ind]; + g_strchomp(cur_word); + if (cur_word[0] == '\0') { + // removing empty strings + continue; + } + gpointer value_pointer = g_hash_table_lookup(counts, cur_word); + int* new_value = g_malloc(sizeof(int)); + if (value_pointer != NULL) { + *new_value = *((int*)value_pointer) + 1; + } else { + *new_value = 1; + } + g_hash_table_replace(counts, g_strdup(cur_word), (gpointer)new_value); + } + g_strfreev(words); + return TRUE; +} + +gint array_comparator(gconstpointer a, gconstpointer b, gpointer word_counts) { + // negative value if a < b ; zero if a = b ; positive value if a > b + int first = *(int*)g_hash_table_lookup(word_counts, *(char**)a); + int second = *(int*)g_hash_table_lookup(word_counts, *(char**)b); + gint res; + if (first < second) + res = 1; + else if (first == second) + res = 0; + else + res = -1; + return res; +} + +void hash_table_destroyer(gpointer data) { + g_free(data); +} + +int main(int argc, char** argv) { + GHashTable* word_counts = g_hash_table_new_full( + g_str_hash, g_str_equal, hash_table_destroyer, hash_table_destroyer); + while (1) { + if (!process_new_line(word_counts)) { + break; + } + } + GArray* words_array = g_array_new(TRUE, FALSE, sizeof(char*)); + GList* keys_list = g_hash_table_get_keys(word_counts); + while (keys_list != NULL) { + int* value = g_hash_table_lookup(word_counts, keys_list->data); + g_array_append_val(words_array, keys_list->data); + keys_list = keys_list->next; + } + + g_array_sort_with_data(words_array, array_comparator, word_counts); + + g_printf("Total %d words\n", words_array->len); + for (int i = 0; i < words_array->len; ++i) { + char* cur_str = g_array_index(words_array, char*, i); + int* value = g_hash_table_lookup(word_counts, cur_str); + g_printf("%s -> %d\n", cur_str, *(int*)value); + } + + g_list_free(keys_list); + g_hash_table_destroy(word_counts); + g_array_free(words_array, TRUE); + return 0; +} \ No newline at end of file diff --git a/11_Toolkits/test_data.txt b/11_Toolkits/test_data.txt new file mode 100644 index 0000000..2d50bab --- /dev/null +++ b/11_Toolkits/test_data.txt @@ -0,0 +1,7 @@ +hello world +hello world +hello here +here +here +allow +