Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

1 массив для хранения 2 стеков

3.0K
16 июня 2006 года
ctraus
91 / / 16.06.2006
1 массив для хранения 2 стеков реализовать.
можн
struct{
int top;
int elenents[maxlenth];
};?
Если да то как изменяться методы?
P.s
если есть исходник буду благодарен
929
16 июня 2006 года
sp999
198 / / 31.01.2003
Для обоих стеков нужно будет хранить их длину.
Для первого стека верхушка самый первый элемент, для второго будет храниться в переменной.
Если вставляешь в первый стек, то увеличивается длина первого стека и верхушка второго. Перед вставкой все элементы сдвигаются.
Если вставляешь во второй, то увеличивается длина второго стека. Перед вставкой сдвигаются только элементы, начиная с верхушки второго стека.
При удалении - действия обратные.
8.8K
16 июня 2006 года
The_Ice
109 / / 04.04.2006
самый простой способ (не самый лучший):
есть у тебя массив на 80 целых чисел. Для того чтобы он хранил два стека тупо делишь этот массив на две части, т.е. в один стек у тебя "записывается" начиная с нуля и до 39, а во второй, уже начиная с 40 и до 79. Функции push могут иметь вид: void push(char number_of_stack,int value); или т.п. :)
8.8K
16 июня 2006 года
The_Ice
109 / / 04.04.2006
... и соответственно: int pop(char number_of_stack);
8.8K
16 июня 2006 года
The_Ice
109 / / 04.04.2006
[QUOTE=sp999]Для обоих стеков нужно будет хранить их длину.
Для первого стека верхушка самый первый элемент, для второго будет храниться в переменной.
Если вставляешь в первый стек, то увеличивается длина первого стека и верхушка второго. Перед вставкой все элементы сдвигаются.
Если вставляешь во второй, то увеличивается длина второго стека. Перед вставкой сдвигаются только элементы, начиная с верхушки второго стека.
При удалении - действия обратные.[/QUOTE]
тогда уж сразу надо пользоваться векторами, ведь сдвигать элементы статического массива очень неприятно, хотя бы по скорости. А с векторами куда проще: память выделяется автоматически - сколько надо чисел, чтолько и вставит, а потом и удалит :)
929
17 июня 2006 года
sp999
198 / / 31.01.2003
[QUOTE=The_Ice]тогда уж сразу надо пользоваться векторами, ведь сдвигать элементы статического массива очень неприятно, хотя бы по скорости. А с векторами куда проще: память выделяется автоматически - сколько надо чисел, чтолько и вставит, а потом и удалит :)[/QUOTE]
В задаче было сказано про массив.
Как видно, задача дана не для эффективности действий, а для тренировки ума и вывиха моска. :)
273
17 июня 2006 года
3A3-968M
1.2K / / 22.12.2005
[quote=sp999]В задаче было сказано про массив.
Как видно, задача дана не для эффективности действий, а для тренировки ума и вывиха моска. :)[/quote]
Я предлагаю так:
Один массив. Один стэк растёт сверху массива, другой снизу. Одна запись типа int будет хранить длину одного из стэка. Таким образом, тот стэк, которому память в массиве "нужнее" тот и будет её получать. А при делении массива просто на два факт вероятности заполнения обоих массивов не учитывается, таким образом память делится не эффективно. Можно реализовать массив таким образом, чтобы вообще при размещении данных в любой стэк массив не двигать:
Код:
[FONT=Courier New]typedef struct ArrayForStacks[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]  int busy1=0; //номер верхнего свободного элемента для 1 стэка[/FONT]
[FONT=Courier New]  int busy2=19; //номер верхнего свободного элемента для 2 стэка[/FONT]
[FONT=Courier New]  int elements[20];
} PackedStack;[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]void PushToFirstStack(PackedStack stack, int element)[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]   if(stack.busy1>=stack.busy2)[/FONT]
[FONT=Courier New]   {[/FONT]
[FONT=Courier New]     printf("Стэк 1 уже заполнен");[/FONT]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New]   else[/FONT]
[FONT=Courier New]   {[/FONT]
[FONT=Courier New]     stack.elements[stack.busy1++]=element;[/FONT]
[FONT=Courier New]   }
}[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]int PopFromFirstStack(PackedStack stack)[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]  return stack.elements[--stack.busy1];
}[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]void PushToSecondStack(PackedStack stack, int element)[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]  
[FONT=Courier New]   if(stack.busy2<=stack.busy1)[/FONT]
[FONT=Courier New]   {[/FONT]
[FONT=Courier New]     printf("Стэк 2 уже заполнен");[/FONT]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New]   else[/FONT]
[FONT=Courier New]   {[/FONT]
[FONT=Courier New]     stack.elements[stack.busy2--]=element;[/FONT]
[FONT=Courier New]   }[/FONT]
}[/FONT]

Вообщем, идея понятна думаю....
1.8K
17 июня 2006 года
k3Eahn
365 / / 19.12.2005
Можно использовать чётные элементы массива для первого стека, а нечётные для второго.
273
17 июня 2006 года
3A3-968M
1.2K / / 22.12.2005
[quote=k3Eahn]Можно использовать чётные элементы массива для первого стека, а нечётные для второго.[/quote]
Можно. Но это опять же разбиение массива пополам. Нет гарантии, что во время работы оба стэка будут эффективно использовать весь массив. Вариант, предложенный выше, учитывает динамику использования массива обоими стэками. Если одному стэку нужно памяти в массиве больше чем второму, он её получает.
Хотя это всё дело вкуса..............
9.4K
17 июня 2006 года
_nоrth_
99 / / 24.04.2006
С помощью typedef int StackItemType; задается тип элементов стека.
Код:
#include <exception>

const int MAX_STACK = 1024; // максимальный размер стека

typedef int StackItemType;

class StackException: public exception
{
public:
  StackException(const char *message="")
    : exception(message)  
  {};
};

class Stack
{
public:
  Stack()  // Конструктор по умолчанию
  {
    top1 = -1;  
    top2 = -1;  
    bottom1 = -1;  
    bottom2 = -1;  
    cnt1 = 0;    
    cnt2 = 0;    
  };

  // Проверяет пуст ли конкретный стек
  bool empty(int stackNo) throw(StackException);
  // Добавляет новый элемент на вершину стека stackNo
  void push(int stackNo, StackItemType &newItem) throw(StackException);
  // Удаляет вершину стека stackNo
  void pop(int stackNo, StackItemType *newItem = NULL) throw(StackException);
  // Возвращает число элементов стека stackNo
  int size(int stackNo) throw(StackException);
  // Удаляет все элементы стека stackNo
  void erase(int stackNo=0);
private:
  StackItemType items[MAX_STACK]; // массив элементов стека
  int top1;    // вершина стека No 1
  int top2;    // вершина стека No 2
  int bottom1; // дно стека No 1
  int bottom2; // дно стека No 2
  int cnt1;    // текущее число элементов стека No 1
  int cnt2;    // текущее число элементов стека No 2
};

bool Stack::empty(int stackNo)
{
  switch(stackNo)
  {
  case 1:
    return cnt1==0;
  case 2 :
    return cnt2==0;
  default:
    throw StackException("StackException : неправильный номер стека(empty)");
  }
}

int Stack::size(int stackNo)
{
  switch(stackNo)
  {
  case 1:
    return cnt1;
  case 2 :
    return cnt2;
  default:
    throw StackException("StackException : неправильный номер стека(size)");
  }
}

void Stack::pop(int stackNo, StackItemType *newItem)
{
  switch(stackNo)
  {
  case 1:
    if(cnt1>0)
    {
      if(newItem!=NULL)
        *newItem = items[top1];
      cnt1--;
      if(cnt1==0)
      {
        top1 = -1;
        bottom1 = -1;
      }
      else
      {
        top1++;
        if(top1==MAX_STACK)
          top1 = 0;
      }
    }
    else
    {
      throw StackException("StackException : стек 1 пуст(pop)");
    }
    break;
  case 2 :
    if(cnt2>0)
    {
      if(newItem!=NULL)
        *newItem = items[top2];
      cnt2--;
      if(cnt2==0)
      {
        top2 = -1;
        bottom2 = -1;
      }
      else
      {
        top2--;
        if(top2<0)
          top2 = MAX_STACK - 1;
      }
    }
    else
    {
      throw StackException("StackException : cтек 2 пуст(pop)");
    }
    break;
  default:
    throw StackException("StackException : неправильный номер стека(pop)");
  }
}

void Stack::push(int stackNo, StackItemType &newItem)
{
  if(cnt1+cnt2==MAX_STACK)
    throw StackException("StackException : стек переполнен");
  switch(stackNo)
  {
  case 1:
    cnt1++;
    if(cnt1==1)
    {
      if(cnt2==1)
      {
        bottom1 = MAX_STACK << 1;
        top1 = bottom1;
      }
      else
      {
        bottom1 = bottom2 - 1;
        if(bottom1 < 0)
          bottom1 = MAX_STACK -1;
        top1 = bottom1;
      }
    }
    else
    {
      top1--;
      if(top1 < 0)
        top1 = MAX_STACK - 1;
    }
    items[top1] = newItem;
    break;
  case 2 :
    cnt2++;
    if(cnt2==1)
    {
      if(cnt1==1)
      {
        bottom2 = MAX_STACK << 1;
        top2 = bottom2;
      }
      else
      {
        bottom1 = bottom2 + 1;
        if(bottom2 == MAX_STACK)
          bottom2 = 0;
        top2 = bottom2;
      }
    }
    else
    {
      top2++;
      if(top2 == MAX_STACK)
        top2 = 0;
    }
    items[top2] = newItem;
    break;
  default:
    throw StackException("StackException : неправильный номер стека(push)");
  }
}

void Stack::erase(int stackNo)
{
  switch(stackNo)
  {
  case 1:
    top1 = -1;  
    bottom1 = -1;  
    cnt1 = 0;    
    break;
  case 2:
    top2 = -1;  
    bottom2 = -1;  
    cnt2 = 0;    
    break;
  default:
    top1 = -1;  
    top2 = -1;  
    bottom1 = -1;  
    bottom2 = -1;  
    cnt1 = 0;    
    cnt2 = 0;    
  }
}


int main()
{
  Stack stack;
  // ...
  // ...
  // ...
    return 0;
}
350
28 июня 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=ctraus]1 массив для хранения 2 стеков реализовать.
можн
struct{
int top;
int elenents[maxlenth];
};?
Если да то как изменяться методы?
P.s
если есть исходник буду благодарен[/QUOTE]
Берешь некую середину массива, один стек "растет" кверху, другой книзу. Лучше, наверное, сделать два набора методов для каждого стека. Только какой смысл в этом - какая разница, два массива или один.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог