Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Различные структуры данных. Реализация / 25 сообщений из 422, страница 1 из 17
20.01.2015, 03:37
    #38858015
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Здравствуйте.
Сегодня проектировал стек LIFO, вот что получилось

stack.h

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#include <stdio.h>
#include <stdlib.h>

#define SEMPTY -1

struct Stack
{
	size_t max_size;
	size_t cur;//позиция для записи следующего элемента
	int (*push)(int el, struct Stack*);
	int (*pop)(struct Stack*);
	int* buffer;
};

struct Stack* createStack(size_t maxsize);




stack.c

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
#include "stack.h"

int push(int el, struct Stack* s)
{
	if (s->cur == s->max_size)
	{
		printf("stack is full.\n");
		return -1;
	}
	else
	{
		s->buffer[s->cur++] = s->cur;
		return 0;
	}
}

int pop(struct Stack* s)
{
	if (s->cur == 0)
	{
		printf("stack is empty.\n");
		return SEMPTY;
	}
	else
	{
		return *(s->buffer + --s->cur);
	}
}

struct Stack* createStack(size_t maxsize)
{
	struct Stack* s = (struct Stack*)malloc(sizeof(struct Stack));
	s->max_size = maxsize;
	s->cur = 0;
	s->push = push( );
	s->pop = pop(s);
        s->buffer = NULL;
	s->buffer = (int*)malloc(sizeof(int)*s->max_size);
	return s;
}



Подскажите пожалуйста, как правильно реализовать функцию createStack() ? Мне не нравится использование SEMPTY, но пока не придумал как от этого избавиться. Как бы вы поступили ?
...
Рейтинг: 0 / 0
20.01.2015, 10:54
    #38858211
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryМне не нравится использование SEMPTY, но пока не придумал как от этого избавиться. Как бы вы поступили ?
Код: plaintext
1.
bool pop(struct Stack* s, int* result)
...
Рейтинг: 0 / 0
20.01.2015, 11:27
    #38858261
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Еще лучше кидать исключение, но их нет в С.

Можно их имитировать через setjump/longjump.
...
Рейтинг: 0 / 0
20.01.2015, 12:53
    #38858381
Аноним123
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Считаю, что C-style стек должен выглядеть как-то так:

stack.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
#ifndef STACK_H
#define STACK_H

#include <stddef.h> // size_t

struct Stack;

/**
 * @brief StackCreate - создает новый стек
 * @param max_size - максимально возможное число элементов в стеке
 * @return указатель на созданный стек или NULL, в слечае неудачи
 */
struct Stack* StackCreate(size_t max_size);

/**
 * @brief StackPush - добавляет новый элемент в стек
 * @param s - валидный указатель на стек
 * @param val - новый элемент
 * @return число вставленных элементов
 */
int StackPush(struct Stack* s, int val);

/**
 * @brief StackPop - извлекает элемент из стека
 * @param s - валидный указатель на стек
 * @param result - результат
 * @return число извлеченных элементов
 */
int StackPop(struct Stack* s, int* result);

#endif




stack.c
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
#include "stack.h"

#include <assert.h>
#include <stdlib.h> // malloc

struct Stack
    {
    size_t max_size;
    size_t cur_size;
    int* buffer;
    };

struct Stack* StackCreate(size_t max_size)
    {
    struct Stack* s = (struct Stack*)malloc(sizeof(struct Stack));
    if (s != NULL)
        {
        s->max_size = max_size;
        s->cur_size = 0;
        s->buffer = (int*)malloc(sizeof(int) * max_size);
        if (s->buffer == NULL)
            {
            free(s);
            s = NULL;
            }
        }
    return s;
    }

int StackPush(struct Stack* s, int val)
    {
    assert(s != NULL);
    if (s->cur_size == s->max_size)
        {
        return 0;
        }
    s->buffer[s->cur_size] = val;
    ++s->cur_size;
    return 1;
    }

int StackPop(struct Stack* s, int* result)
    {
    assert(s != NULL);
    if (s->cur_size == 0)
        {
        return 0;
        }
    --s->cur_size;
    *result = s->buffer[s->cur_size];
    return 1;
    }
...
Рейтинг: 0 / 0
20.01.2015, 13:17
    #38858400
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryСегодня проектировал стек LIFO, вот что получилось
Если ты идёшь по пути чистого С, то один malloc лишний: гораздо удобнее работать со
структурой переменного размера, поскольку память не фрагментируется. Указывать
максимальный размер стека при создании, возможно, соответствует техзаданию, но тоже
абсолютно излишне.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
20.01.2015, 13:33
    #38858414
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Аноним123,
хочу реализовать стек как один объект
...
Рейтинг: 0 / 0
20.01.2015, 13:39
    #38858426
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Dimitry SibiryakovSashaMercuryСегодня проектировал стек LIFO, вот что получилось
Если ты идёшь по пути чистого С, то один malloc лишний: гораздо удобнее работать со
структурой переменного размера, поскольку память не фрагментируется. Указывать
максимальный размер стека при создании, возможно, соответствует техзаданию, но тоже
абсолютно излишне.


Вы предлагаете реаллоцировать при добавлении элемента? Если я вас правильно понял, то думаю что это спорный момент. Реаллоцирование тратит много времени. Максимальный размер стека необходим для безопасной работы программы
...
Рейтинг: 0 / 0
20.01.2015, 13:47
    #38858438
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryВы предлагаете реаллоцировать при добавлении элемента?
Нет, я предлагаю использовать связанный список буферов. Возможно, заранее
предопределённого размера.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
20.01.2015, 14:14
    #38858496
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Сейчас коллеги мы дойдем до формулы расчёта

Код: plaintext
1.
2.
INITIAL_EXTENT=
NEXT_EXTENT=
...
Рейтинг: 0 / 0
20.01.2015, 14:52
    #38858542
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Dimitry SibiryakovSashaMercuryВы предлагаете реаллоцировать при добавлении элемента?
Нет, я предлагаю использовать связанный список буферов. Возможно, заранее
предопределённого размера.


Связанный список и надо использовать. Т.е. что значит -- надо ? Обычно так делают.

SashaMercury, у тебя это даже не совсем стек. Т.е. стек, но на базе массива.
А обычно делают стек на базе связного/двусвязного списка.
Хотя, конечно, и такой стек имеет право на существование, у обоих есть свои преимущества и недостатки.
...
Рейтинг: 0 / 0
20.01.2015, 15:37
    #38858596
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
MasterZivDimitry Sibiryakovпропущено...

Нет, я предлагаю использовать связанный список буферов. Возможно, заранее
предопределённого размера.


Связанный список и надо использовать. Т.е. что значит -- надо ? Обычно так делают.

SashaMercury, у тебя это даже не совсем стек. Т.е. стек, но на базе массива.
А обычно делают стек на базе связного/двусвязного списка.
Хотя, конечно, и такой стек имеет право на существование, у обоих есть свои преимущества и недостатки.

т.е. всё-таки это стек, конечно. Такой стек, и именно реализация на базе массива имеет право на существование в первую очередь.

PS
В каком году появился связный список, и в каком году Алан Тьюринг придумал стек ?
...
Рейтинг: 0 / 0
20.01.2015, 15:40
    #38858598
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercury,

SSВ каком году появился связный список, и в каком году Алан Тьюринг придумал стек ?
До середины 20 века появился стек. А ответ на первый вопрос я не знаю, ту книгу что вы мне рекомендовали(об истории IT), пока даже не прочитал
...
Рейтинг: 0 / 0
20.01.2015, 16:24
    #38858661
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryPS
В каком году появился связный список, и в каком году Алан Тьюринг придумал стек ?

Году в 50-55 стек придумали.
Это если аппаратно первая ЭВМ была без стека.
Если была -- ещё раньше, в 45.
...
Рейтинг: 0 / 0
21.01.2015, 01:40
    #38859093
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
MasterZivSashaMercuryPS
В каком году появился связный список, и в каком году Алан Тьюринг придумал стек ?

Году в 50-55 стек придумали.
Это если аппаратно первая ЭВМ была без стека.
Если была -- ещё раньше, в 45.

Так и предполагал.

Значит проблему с функцией push() в данном примере нельзя решить ?
...
Рейтинг: 0 / 0
21.01.2015, 03:16
    #38859118
wst
wst
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
можно и так:
return SEMPTY; ----> raise(SIGSEGV);
Вполне подходит по смыслу к попытке достать число из пустого стека.
...
Рейтинг: 0 / 0
21.01.2015, 06:01
    #38859132
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
wst,

если вы комментировали моё сообщение про push(), то я о другом спрашиваю . А вы говорите про функцию pop()
...
Рейтинг: 0 / 0
21.01.2015, 08:30
    #38859185
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Стек я бы делал, как выше писали, в виде связанного списка массивов.
Это минимизирует аллокации, не требует реаллокаций, и не требует при создании стека заранее задавать размер.

Задача контроля за чрезмерным выделением памяти не должна влиять на структуру данных. Никто вам не мешает контролировать это при любой реализации.
...
Рейтинг: 0 / 0
21.01.2015, 08:43
    #38859202
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Anatoly Moskovsky,
не очень понятно. Как он может не требовать реаллокации ? Только в том случае если мы выделили памяти сразу столько, сколько нужно
...
Рейтинг: 0 / 0
21.01.2015, 09:55
    #38859276
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercury,

Каждый вызов push() аллоцирует объём памяти, равный размеру данных плюс размер указателя на следующий элемент. Каждый pop() освобождает такой же объём; реаллокации нет.
...
Рейтинг: 0 / 0
21.01.2015, 09:58
    #38859278
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercury,

Все эти споры дают понять, почему в STL стек и очередь -- это адаптеры, реализованные над тремя базовыми структурами -- vector, deque и list.
...
Рейтинг: 0 / 0
21.01.2015, 10:28
    #38859317
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
RWolf,
теперь понятно

Ладно, с учётом того что сейчас это сделано так, как всё-таки решить проблему выделенную жёлтым цветом ? Возможно ли это в данной реализации ?


Anatoly Moskovsky,
как же контролировать объём данных ?
...
Рейтинг: 0 / 0
21.01.2015, 11:58
    #38859484
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryкак всё-таки решить проблему выделенную жёлтым цветом ?
Убрать скобки. И в следующей строке - тоже.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.01.2015, 12:25
    #38859538
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Елы-палы, я не заметил этот вопрос...
Да всё просто -- литерал с именем функции -- это переменная с типом "указатель на функцию с данной сигнатурой".
Так что -- да, достаточно в строке убрать скобки.
...
Рейтинг: 0 / 0
21.01.2015, 12:27
    #38859547
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
Следующая за жёлтой строка, кстати, неверна.
...
Рейтинг: 0 / 0
21.01.2015, 14:22
    #38859716
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различные структуры данных. Реализация
SashaMercuryЛадно, с учётом того что сейчас это сделано так, как всё-таки решить проблему выделенную жёлтым цветом ? Возможно ли это в данной реализации ?

Как исправить - уже сказали.
Но суть в том что указатели на функции в экземплярах объекта вообще не нужны - там нет никакого полиморфного поведения. Используйте обычные свободные функции.


SashaMercuryкак же контролировать объём данных ?
Хранить кол-во элементов и в push проверять достигнут ли предел.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Различные структуры данных. Реализация / 25 сообщений из 422, страница 1 из 17
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]