Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.04.2024, 18:22   #1
Veronika360
 
Регистрация: 06.04.2024
Сообщений: 5
По умолчанию Хеш Таблицы в Си

Код:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define HASH_SIZE 100

typedef struct {
    char first_name[50];
    char last_name[50];
    char bd[11]; 
    float balance;
} Person;

typedef struct {
    char key[112];
    Person* data;
    struct Entry* next;
} Entry;

typedef struct {
    Entry* table[HASH_SIZE];
} HashTable;

int strcmb(const char* a, const char* b) {
    int find = 0, i = 0;
    while (a[i] != '\0' && b[i] != '\0') {
        if (a[i] != b[i]) {
            find = 1;
            break;
        }
        i++;
    }
    if (find == 0) 
        return 0;
    else return 1;
}
int strl(char* str) {
    int i = 0;
    while (str[i++]);
    return i;
}
char* cut(const char* str1, const char* str2, const char* str3) {
    char* obj = (char*)malloc(strl(str1) + strl(str2) + strl(str3) + 1);
    if (obj == NULL) {
        return NULL;
    }
    sprintf(obj, "%s%s%s", str1, str2, str3);
    return obj;
}
unsigned long hash_function(char* str)
{
    unsigned long i = 0;

    for (int j = 0; str[j]; j++)
        i += str[j];

    return i % HASH_SIZE;
}

int insert(HashTable* hash_table, Person* person) {
    unsigned long index = hash_function(cut(person->first_name, person->last_name, person->bd));
    Entry* newNode = (Entry*)malloc(sizeof(Entry));
    if (newNode == NULL) {
        return 0;
    }

    char* keyPtr = newNode->key;
    const char* cutStr = cut(person->first_name, person->last_name, person->bd);
    while (*cutStr) {
        *keyPtr++ = *cutStr++;
    }
    *keyPtr = '\0';

    newNode->data = (Person*)malloc(sizeof(Person));
    if (newNode->data == NULL) {
        free(newNode);
        return 0;
    }

    *(newNode->data) = */person;
    hash_table->table[index] = newNode;
    return 1;
}
Person* search(HashTable* hash_table, char* name, char*surname, char* bd) {
    unsigned long index = hash_function(cut(name,surname,bd));
    Entry* entry = hash_table->table[index];
    while (entry != NULL) {
        if (strcmb(entry->data->first_name, name) == 0 && strcmb(entry->data->last_name, surname) == 0 && strcmb(entry->data->bd, bd) == 0) {

            return entry->data; // Return found person
        }
        entry = entry->next; // Move to the next entry in the linked list
    }

    return NULL; // Person not found
}
int update(HashTable* hash_table, char* name, char* surname, char* bd,float balance) {
    Entry* entry = search(hash_table, name, surname, bd);
    if (entry == NULL) {
        return 0;
    }
    if (balance < 0 && entry->data->balance + balance < 0) {
        return 0;
    }
    entry->data->balance += balance;
    return 1;
}
int delete(HashTable* hash_table, char* name, char* surname, char* bd) {
    unsigned long index = hash_function(cut(name, surname, bd));
    Entry* entry = hash_table->table[index];
    Entry* prev = NULL;
    while (entry != NULL) {
        if (strcmb(cut(entry->data->first_name, entry->data->last_name, entry->data->bd), cut(name, surname, bd)) == 0) {
            if (prev == NULL) {
                hash_table->table[index] = entry->next;
            }
            else {
                prev->next = entry->next;
            }
}
        free(entry);
        return 1;
    }
    return 0;
    
}
void freeHash(HashTable* hash_table) {
    for (int i = 0; i < HASH_SIZE; ++i) {
        Entry * entry = hash_table->table[i];
        while (entry != NULL) {
            Entry* temp = entry;
            entry = entry->next;
            free(temp);
        }
    }
}
float prevod_float(char* str) {
    char* ptr = str;
    while (*ptr != '\0') {
        if (*ptr == ',') {
            *ptr = '.';
        }
        ptr++;
    }
    return(float)strtod(str, NULL);
}

int main() {

    HashTable hash_table;
    for (int i = 0; i < HASH_SIZE; i++) {
        hash_table.table[i] = NULL;
    }
    char balance[10];
    char name[13];
    char surname[10];
    char bd[10];
    int isFirst = 0;
    char operation;
    while (scanf(" %c", &operation) != EOF) {
        switch (operation) {
        case 'i':
            Person* pers = (Person*) malloc(sizeof(Person));
            if (scanf("%12s %10s %10s %9s", pers->first_name, pers->last_name, pers->bd, balance) != 4) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("insert failed");
                continue;
            }
            pers->balance = parsetofloat(balance);
            if (!insert(&hash_table, pers)) {
                printf("insert failed\n");
            }

            break;

        case 's':
            if (scanf("%12s %10s %10s", name, surname, bd) != 3) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("search failed");
                continue;
            }

            Person* person = search(&hash_table, name, surname, bd);
            if (person == NULL) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("search failed");
            }
            else {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("%d,%02d", person->balance / 100, person->balance % 100);
            }
            break;
        case 'u':
            if (scanf("%12s %10s %10s %9s", name, surname, bd, balance) != 4) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("update failed");
                continue;
            }

            if (!update(&hash_table, name, surname, bd, parsetofloat(balance))) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("update failed");
            }
            break;
        case 'd': {
            if (scanf("%12s %10s %10s", name, surname, bd) != 3) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("delete failed");
                continue;
            }
            if (!delete(&hash_table, name, surname, bd)) {
                if (isFirst) { isFirst = 0; }
                else printf("\n");
                printf("delete failed");
            }
        }
        default:
            break;

        }
    }
}
есть такой от код, не могу понять что не так,нужна помощь

Последний раз редактировалось BDA; 06.04.2024 в 21:12. Причина: добавил тег код
Veronika360 вне форума Ответить с цитированием
Старый 06.04.2024, 20:55   #2
jura_k
gamer
Участник клуба
 
Аватар для jura_k
 
Регистрация: 09.05.2015
Сообщений: 1,529
По умолчанию

Вы разбираетесь в структурах? :0
И в указателях?
А на каком факультете вы учитесь? В каком институте?

Меня, блин, за это на второй год оставили...

Кстати, тот человек, который писал код - очень нехороший человек. Его бы любой преподаватель завалил. Просто за то, что он не оставил комментариев. Это же чуть ли не половина задачи... Где постановка задачи? Какой требуется результат?
Это будут первые вопросы, которые задаст преподаватель.
Такое только в космонавтике возможно, но никак не в программировании.

Что касается оформления кода, то код надо было заключить специальным тегом, чтобы было понятно на форуме.
Типа вот такого:
Код:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define HASH_SIZE 100

typedef struct {
char first_name[50];
char last_name[50];
char bd[11];
float balance;
} Person;
мой канал на Ютубе: youtube.com/@games-zz3ju/videos/
мой канал на Рутубе: rutube.ru/channel/31423139/videos/
В ожидании Кеши...

Последний раз редактировалось jura_k; 06.04.2024 в 21:01.
jura_k вне форума Ответить с цитированием
Старый 07.04.2024, 15:32   #3
Veronika360
 
Регистрация: 06.04.2024
Сообщений: 5
По умолчанию

Цитата:
Сообщение от jura_k Посмотреть сообщение
Вы разбираетесь в структурах? :0
И в указателях?
А на каком факультете вы учитесь? В каком институте?

Меня, блин, за это на второй год оставили...

Кстати, тот человек, который писал код - очень нехороший человек. Его бы любой преподаватель завалил. Просто за то, что он не оставил комментариев. Это же чуть ли не половина задачи... Где постановка задачи? Какой требуется результат?
Это будут первые вопросы, которые задаст преподаватель.
Такое только в космонавтике возможно, но никак не в программировании.

Что касается оформления кода, то код надо было заключить специальным тегом, чтобы было понятно на форуме.
Типа вот такого:
Код:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define HASH_SIZE 100

typedef struct {
char first_name[50];
char last_name[50];
char bd[11];
float balance;
} Person;
Your task is to implement the dynamic set abstract data type using a hash table. The following operations should be supported:
i - insert - inserting a new item into the table
s - search - search for an item by key
u - update - adjustment of the item (specifically the balance on the account) according to the key
d - delete - removing an item from the table by key

Items represent people, consisting of first name, last name, date of birth, and a number representing the financial balance in the person's account.
The key is the combination of full name and date of birth.
Each person has a unique key.

Each operation must also be treated for possible operation failure, in which case the text " failed" is printed on the output in a separate line.
A failure is, for example, when we try to look up a person who is not in the data structure, or when we try to insert a duplicate person into the data structure.

The input of the program is the individual operations for the hash table, where each operation is located in a separate line.
A line always begins with the letter specifying the operation (i.e., i, s, u, or d), followed by the data required for that operation.
The insert operation needs all the data to insert the given item, i.e. first name, last name, date of birth and initial account balance (positive number with precision of 2 digits, e.g. euros and cents).
The search operation only uses the key
The update operation needs a key, followed by a modification of the account balance (i.e. a number with a precision of 2 digits, e.g. euros and cents). In the case of a negative value, the update operation is valid only if it does not cause a negative balance on the account of the given person (i.e. the balance on the account must always be positive).
The delete operation only uses the key.

The output is the items found using the search operations and the failure report of the given operation.
Each item/message is on a separate line.

Do 08.04.2024, 09:00

Ukážkový vstup
i Thomas Sanford 1.1.2001 2017,81
i Nathan Flores 18.4.2002 6689,79
i Michelle Palmer 12.7.1999 7205,98
i Angelica Olsen 25.2.1991 6511,68
i Kevin Taylor 21.9.1969 7573,79
i Brian Hutchinson 5.9.1953 1531,69
i Joseph Hunter 15.5.1986 805,16
i Anthony White 6.5.1958 8013,22
i James Anderson 23.4.2002 7694,99
i Lori Mcknight 20.8.1976 1584,38
i Christopher Bryant 28.2.1962 229,57
i Kayla Jones 3.6.1962 9065,65
i Hannah West 2.2.1993 8237,84
i Jocelyn Frey 11.8.1954 3762,70
i Megan Collins 29.12.1988 7481,26
i Victoria Peck 6.9.1988 5301,50
i Jason Stafford 18.1.1974 2866,75
i Jean Johnson 27.3.1988 6950,36
i Grace Obrien 22.6.1981 2796,93
i Laura Ward 20.1.1999 7579,02
u Brian Hutchinson 5.9.1953 2073,09
u James Anderson 23.4.2002 -329,97
s Megan Collins 29.12.1988
u Kayla Jones 3.6.1962 2179,57
u Jocelyn Frey 11.8.1954 -985,99
u Hannah West 2.2.1993 457,97
u Angelica Olsen 25.2.1991 -1504,94
s Jason Stafford 18.1.1974
s Hannah West 2.2.1993
u Lori Mcknight 20.8.1976 1081,23
s Thomas Sanford 1.1.2001
u Thomas Sanford 1.1.2001 1514,85
u Angelica Olsen 25.2.1991 569,20
u Brian Hutchinson 5.9.1953 -2363,20
u Kayla Jones 3.6.1962 -206,37
u Nathan Flores 18.4.2002 -1100,55
d Grace Obrien 22.6.1981
u Laura Ward 20.1.1999 -1195,77
s James Anderson 23.4.2002
s Christopher Bryant 28.2.1962
s Brian Hutchinson 5.9.1953
i Christopher Powell 6.2.1966 91,21
u Christopher Bryant 28.2.1962 1511,66
u Jason Stafford 18.1.1974 246,09
u Kevin Taylor 21.9.1969 -2010,75
u Brian Hutchinson 5.9.1953 1384,48
u Jason Stafford 18.1.1974 -495,16
u Kayla Jones 3.6.1962 340,55
s Christopher Bryant 28.2.1962
u Brian Hutchinson 5.9.1953 -2387,11
u Michelle Palmer 12.7.1999 1737,77
s Megan Collins 29.12.1988
u Brian Hutchinson 5.9.1953 -2069,00
u Jason Stafford 18.1.1974 580,80
u Angelica Olsen 25.2.1991 1553,44
s Thomas Sanford 1.1.2001
u Nathan Flores 18.4.2002 589,51
u Kevin Taylor 21.9.1969 852,81
s James Anderson 23.4.2002
u Lori Mcknight 20.8.1976 -2189,98
u James Anderson 23.4.2002 -2448,33
u Kayla Jones 3.6.1962 650,09
u Laura Ward 20.1.1999 767,51
s Brian Hutchinson 5.9.1953
s Angelica Olsen 25.2.1991
s Kevin Taylor 21.9.1969
s Michelle Palmer 12.7.1999
u Jean Johnson 27.3.1988 716,98
u Angelica Olsen 25.2.1991 990,06
u Brian Hutchinson 5.9.1953 906,66
u Thomas Sanford 1.1.2001 -1269,26
s Thomas Sanford 1.1.2001
u Angelica Olsen 25.2.1991 -738,82
s Laura Ward 20.1.1999
s Joseph Hunter 15.5.1986
s Jean Johnson 27.3.1988
u Joseph Hunter 15.5.1986 -2400,21
d Hannah West 2.2.1993
s Michelle Palmer 12.7.1999
u Michelle Palmer 12.7.1999 -660,55
i Traci James 13.2.1991 39,89
u Victoria Peck 6.9.1988 1290,12
s Thomas Sanford 1.1.2001
u Thomas Sanford 1.1.2001 705,46
u Anthony White 6.5.1958 -1977,22
s Christopher Powell 6.2.1966
u Jason Stafford 18.1.1974 -1897,53
u Thomas Sanford 1.1.2001 -200,94
i Michael Jordan 20.3.1994 6683,23
s Megan Collins 29.12.1988
u Jean Johnson 27.3.1988 447,07
s Kevin Taylor 21.9.1969
u Joseph Hunter 15.5.1986 460,05
u Jean Johnson 27.3.1988 -2453,37
s Jean Johnson 27.3.1988
i Sean Wade 10.3.1985 7598,93
s Christopher Bryant 28.2.1962
i Zoe Meza 19.11.1995 5522,63
i Patricia Salinas 9.4.2000 7818,62
s Harry Potter 12.5.1995
s Laura Ward 20.1.1999

Ukážkový výstup
7481,26
2866,75
8695,81
2017,81
7365,02
229,57
1241,58
1741,23
7481,26
update failed
3532,66
7365,02
238,95
7129,38
6415,85
8943,75
2263,40
7150,76
805,16
7667,34
update failed
8943,75
2263,40
91,21
7481,26
6415,85
5661,04
1741,23
search failed
7150,76
Veronika360 вне форума Ответить с цитированием
Старый 08.04.2024, 06:44   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от Veronika360 Посмотреть сообщение
что не так
Как основа для решения - нормально. Но есть куча недочетов: код в текущем виде не компилируется; функция cut выделяет память, которую никто не очищает; в функции insert не хватает кода добавления в конец односвязного списка при коллизии хешей; стоит согласовать длины имени и фамилии в структуре Person и в main; функция search возвращает указатель на Person, но в функции update он используется как указатель на Entry; нужно поправить вывод баланса (или хранить баланс как целое число центов и печатать частное и остаток, как сейчас).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как выполнить подстановку данных в несколько столбцов таблицы из одной справочной таблицы? RuS_984 SQL, базы данных 3 20.12.2015 00:36
Данные из таблицы в список, если в ячейке таблицы стоит количество oleg_sh Microsoft Office Excel 4 08.10.2012 14:52
Макрос: заполнение таблицы данными из другой таблицы с автоматическим добавлением строк yevgeniy.demidov Microsoft Office Excel 6 06.09.2012 15:27
формирование таблицы из элементов другой таблицы с удалением повторяющихся значений Selicat Microsoft Office Excel 1 20.10.2011 22:36
Access ограничить значение поля таблицы значениями полей другой таблицы Сергей089 Microsoft Office Access 10 08.12.2010 02:22