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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.05.2017, 17:25   #11
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Не
Цитата:
Сообщение от Haric_110 Посмотреть сообщение
Если делать с кольцевым буфером, нужно два указателя — на начало очереди и на конец. Добавляются элементы в конец, удаляются из начала. В пустой очереди индекс начала равен индексу конца. При добавлении элемента в очередь индекс конца увеличивается, при удалении элемента из очереди увеличивается индекс начала. Если какой-нибудь индекс становится равным максимальному размеру очереди, он обнуляется (в этом и есть "закольцовывание"), а заполненность очереди определяет условие (индекс_начала < индекс_конца)
Ну и функции для добавления элемента и удаления писать нужно как в примере со стёком, только с учётом вышесказанного)
Ps: вернее, не меньше индекс начала должен быть, а "не равен" индексу конца при добавлении элемента (может быть равен только при удалении последнего элемента из очереди)
Не обязательно. Начало можеть быть - следущий после хвоста, при заполненом кольце. Вот пример урезаной сильно очереди, ее смысл найти среднее арифметическое последних N элементов (сильно урезано, потому что для ардуино)

https://github.com/alexzk1/startrack...wns/circular.h
alexzk вне форума Ответить с цитированием
Старый 09.05.2017, 17:44   #12
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

Сделал!
Правда подтверждений много требуется, но мне так спокойнее)))
Код:
#include<iostream>
#include<conio.h>
using namespace std;
class ochered
{
private:
	static const int MAX=10;
	int och[MAX];
	int ind1, ind2;
public:
	ochered(): ind1(0), ind2(1)
	{}
	void cikl()
	{
		for(int j=0; j<10; j++)
			och[j]=33;
	}
	void vvod()
	{
		int a;
		char ch='a';
		while(ind2<=MAX)
		{
			cout<<"Введите значение для помещения в очередь: ";
			cin>>a;
			if(ind2==MAX)
				ind2=0;
			if(ind2==ind1)
			{
				cout<<"Массив заполнен! \n"
					<<"Если желаете заменить значение существующее сейчас в массиве на вводимое,\n"
					<<"нажмите d.\n"
					<<"Если желаете сначала вывести значение, нажмите v.\n";
				cin>>ch;
				while(ch!='v' && ch!='d')
				{
					cout<<"Надо ввести v или d.";
					cin>>ch;
				}
			}
			if(ch=='v')
			{
				ind2=9;
				ch='a';
				break;
			}
			och[ind2++]=a;
			if(ch=='d')
				ind1++;
			ch='a';
			cout<<"Если желаете прервать ввод, нажмите n.\n"
				<<"Если желаете продолжить, нажмите любую клавишу.\n";
			cin>>ch;
			if(ch=='n')
			break;
		}
	}
	void vyvod()
	{
		char ch='a';
		cout<<"Вывод значений очереди.\n";
		while(ind1<=MAX)
		{
			if(ind1==MAX)
				ind1=0;
			if(ind1==ind2)
			{
				cout<<"Выводимое значение равно: "<<och[ind2]<<endl;
				if(ind2==9)
					ind2=0;
				else ind2++;
				cout<<"Очередь пуста!\n";
				ind1++;
				ind1=0;
				break;
			}
			cout<<"Выводимое значение равно: "<<och[ind1]<<endl;
			och[ind1]=0;
			ind1++;
			cout<<"Если желаете прервать вывод, нажмите n.\n"
				<<"Если желаете продолжить, нажмите любую клавишу.\n";
			cin>>ch;
			if(ch=='n')
			break;
		}
	}
};
int main()
{
	setlocale(LC_ALL,"rus");
	char ch='a';
	ochered o1;
	o1.cikl();
	cout<<"Программа имитирующая приём \"Очередь\".\n"
		<<"В данном случае очередь равна 10 ячейкам.\n";
	do
	{
	cout<<"Вы желаете внести в очередь или вынести из очереди? \n"
		<<"Если внести, то нажмите +, если вынести, то нажмите -.\n";
	cin>>ch;
	switch(ch)
	{
	case '+': o1.vvod();
		break;
	case '-': o1.vyvod();
		break;
	}
	cout<<"Желаете продолжить? Если да, нажмите любую клавишу. \n"
		<<"Если нет, нажмите n.\n";
	cin>>ch;
	}
	while(ch!='n');
	getch();
	return 0;
}
Работает с любого положения в любой ситуации))
Блин 33 в цикле инициации на ноль заменить надо и где-то предупреждение воткнуть о том, что там значение по умолчанию равно 0...))

Последний раз редактировалось KAMLS; 09.05.2017 в 17:48. Причина: опечатка
KAMLS вне форума Ответить с цитированием
Старый 09.05.2017, 18:52   #13
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Я б такого студня на пересдачу сразу отправил...
p51x вне форума Ответить с цитированием
Старый 09.05.2017, 19:06   #14
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

Тю! И за шо?
KAMLS вне форума Ответить с цитированием
Старый 09.05.2017, 19:15   #15
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Чот та же фигня, которую всю первую страницу обсуждали.

Еще имена почти всех переменных, функций и прочих сущностей плохие. Лафоре ж не так делает )
https://ru.hexlet.io/blog/posts/naming-in-programming

Цитата:
Сообщение от KAMLS Посмотреть сообщение
стандартными средствами (push, pop, ...) пользоваться нельзя
Причем тут средства? В данном случае это просто нормальные имена функций (естественно если они отражают суть происходящего внутри), которые вы и должны реализовать.
Между ними и STL контейнерами нет никакой связи кроме того что в интерфейсе их классов есть похожие функции.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 09.05.2017 в 19:20.
Alex11223 вне форума Ответить с цитированием
Старый 09.05.2017, 19:40   #16
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

KAMLS, давайте я вам по простому объясню:
очередь - это коробка (такая большая бумажная) с простешими функциями положить что-то в нее, достать что-то из нее, посмотреть пустая ли она, ...
а у вас получается - привез папа на машине апельсины коробка одна, принесла мама пешком из магазина тортик коробку переделываем, приехали вы на велосипеде - коробку переделываем.

Не использовать стандартные средства - значит не юзать стандартные контейнеры, а студентов, которые уродуют интерфейс стандартных контейнеров, надо отправлять на пересдачи пока не поумнеют.

Последний раз редактировалось Alex11223; 09.05.2017 в 19:47.
p51x вне форума Ответить с цитированием
Старый 09.05.2017, 21:15   #17
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Оставлю здесь простецкий стек:
Код:
#include <iostream>
 
 
template<typename T>
class Stack
{
public:
    Stack() : mTop(0) {}//В конструкторе инициализируем указатель нулем
    
    void push(const T &value) //Запинать в стек
    {
        //Создаем новый узел, при этом у него next делаем равным mTop,
        //т.е. текущая вершина стека станет следующим 
        //узлом для вновь созданного узла.
        //Ну и новый узел делаем вершиной стека.
        mTop = new StackNode(value, mTop);
    }
    
    bool pop()//Вышвырнуть из стека
    {
        if (mTop) {//Если в стеке есть элементы, то
            StackNode *d = mTop;//сохраняем указатель на вершину в d
            mTop = mTop->next;//следующий узел делаем верхним
            delete d;//удаляем прошлую верхушку
        }
        return mTop != 0;//вернет true, если в стеке имеются еще элементы
    }
    
    T *top() const //Заглянуть в щелку
    {
        if (mTop) {//Если в стеке есть элементы, то
            return &(mTop->value);//возвращаем указатель на значение, сохраненное в верхнем узле
        }
        return 0;//иначе возвращаем 0
        
    }
    
    ~Stack()
    {
        //Харакири для всех узлов
        while (pop()) {//удаляем элементы, пока они есть
        }
    }
private:
    struct StackNode {//узел стека
        StackNode (const T &value_, StackNode *next_) : value(value_), next(next_){}
        T value;//Значение, хранимое в узле
        StackNode *next;//Указатель на следующий узел
    };
    StackNode *mTop;//Указатель на верхний узел стека
};
 
 
int main()
{
    Stack<int> stack;
    stack.push(10);
    stack.push(12);
    stack.push(13);
    while (stack.top()) {
        std::cout << *stack.top() << ", ";
        stack.pop();
    }
}
Думаю, переделать в очередь не трудно.
Croessmah вне форума Ответить с цитированием
Старый 10.05.2017, 01:51   #18
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
Не обязательно. Начало можеть быть - следущий после хвоста, при заполненом кольце.
Я и не отрицаю этого нигде) то есть, я исправился, сказал, что главное, чтобы хвост не перешёл в голову при добавлении элемента в очередь.
Haric_110 вне форума Ответить с цитированием
Старый 10.05.2017, 02:34   #19
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Код:
if(ind2==ind1)
{
	cout<<"Массив заполнен! \n"
		<<"Если желаете заменить значение существующее сейчас в массиве на вводимое,\n"
		<<"нажмите d.\n"
		<<"Если желаете сначала вывести значение, нажмите v.\n";
	cin>>ch;
	while(ch!='v' && ch!='d')
	{
		cout<<"Надо ввести v или d.";
		cin>>ch;
	}
}
if(ch=='v')
{
	ind2=9;
	ch='a';
	break;
}
och[ind2++]=a;
//...
Что происходит, если нажимается 'v'? Изначально ind1==ind2, он может быть равен любому числу от 0 до MAX, но вы присваиваете ему значение 9... и зачем? где выводится значение замещаемого элемента, как это обещается? Или вывести в смысле извлечь из очереди?
Неправильно понята суть очереди. Нужно написать функции ввода (void push(int)) и вывода (int pop()) без лишних выкрутасов. push() добавляет один элемент, который в аргументе, pop() удаляет 1 элемент из конца очереди и возвращает его значение. Можно оставить сообщения "Очередь пуста" и "Очередь заполнена" там, где надо. Предложения заменить элемент, обработки ввода с клавиатуры можно написать в main, но не в интерфейсе очереди.
Хотите "заменить первый элемент заполненной очереди на добавленный"?
Код:
queue.pop();
queue.push(number);
И ничего придумывать не надо.
Если вам нравится такой диалог с пользователем, это без проблем можно оформить в том блоке, где вызываются функции очереди push() и pop(), и реализовать всё только функциями push() и pop(). Задача в том, чтобы их правильно написать...

Последний раз редактировалось Haric_110; 10.05.2017 в 02:58.
Haric_110 вне форума Ответить с цитированием
Старый 10.05.2017, 07:00   #20
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

У меня это работает так.
Запуск очереди. Значение инд1=0 инд2=1. Это чтобы сразу не сработало совпадение значений инд1 и инд2 и не высветилось "Массив заполнен!" При вводе или "Очередь пуста!" в методе вывода.
Все элементы массива уже инициализированы циклом, значения 33 или 0.
Предполагается что сначала используется ввод.
Значения вводятся вводятся и вот значение инд2 (работающего на ввод) приближается к концу очереди, т.е. к значению инд2=9.
Там есть не рабочий закуток, временный инд2=10, чтобы у алгоритма было время и возможность сориентироваться.
Т.е. если инд2=10 он сразу становится инд2=0, т.е. есть переходит в начало очереди. Если там остался инд1, т.е. никто ничего пока не выводил, происходит сосбщение "Массив заполнен!" и инд2 возвращается на позицию 9 (или как вариант, (там есть вариант) на инд2-1 если совпадение индов произошло где-то в районе ячеек 5-6 и т.п.)
Там то и нужен подтвердитель v. Если вы жмете d то будет происходить запись поверх значения инд1, а инд1 будет отодвигаться на одну ячейку дальше, стало быть опять при следующем вводе то же самое выбирать поверх записывать или сначала вывести значение.
Когда вывод инд1 догоняет ввод инд2, происходит сдвижка инд2 чтобы не зависало на "Очередь пуста!".
то есть организована работа по кругу с учетом вариантов столкновений индикаторов инд1 и инд2. При выводе значение ячеек делается равным 0.
Я гонял по кругу, всё работает. С вариациями.
Понимаю, что написано коряво, нет блин никаких то там контейнеров, указателей и т.п.
Дак я про них еще и не знаю вообще)))))

Последний раз редактировалось KAMLS; 10.05.2017 в 07:01. Причина: опечатка
KAMLS вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вводим 15 элементов в очередь, затем выводим на экран эту очередь и добавил в очередь еще один элемент. Потом удаляем любой элемен Xumera C++ Builder 2 07.12.2013 13:56
Очередь sys*.12 Паскаль, Turbo Pascal, PascalABC.NET 1 05.12.2012 04:43
Очередь fenix0093 Помощь студентам 1 30.11.2012 16:15
Очередь Си svetikzo Помощь студентам 0 23.01.2010 10:03
Очередь C++ svetikzo Помощь студентам 2 23.01.2010 09:53