Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Академик
Рейтинг: 10411
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Академик
Рейтинг: 3938
∙ повысить рейтинг »
CradleA
Статус: Бакалавр
Рейтинг: 2502
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1735
Дата выхода:26.04.2012, 14:00
Администратор рассылки:Киселёва Алёна aka Verena (Академик)
Подписчиков / экспертов:144 / 96
Вопросов / ответов:1 / 1

Консультация # 185860: Здравствуйте! У меня возникли сложности с таким вопросом: Microsoft Visual C++ 2010 Express с++ Нужна программа для работы с перемешанной таблицей, использующей перемешивание сцеплением, по запросам оператора. Перемешанная таблица имеет структуру: structn Item { int key //ключ элемента int release //номер версии элемента c...


Консультация # 185860:

Здравствуйте! У меня возникли сложности с таким вопросом:
Microsoft Visual C++ 2010 Express
с++

Нужна программа для работы с перемешанной таблицей, использующей перемешивание сцеплением, по запросам оператора. Перемешанная таблица имеет структуру:
structn Item {
int key //ключ элемента
int release //номер версии элемента
char *info //указатель на информацию
Item *next указатель на след. элемент
}
размер массива const int SIZE = ...;
-необходимо ввод нового элемента, при условии что в таблице могут находиться несколько элементов с одинаковыми ключами и разными номерами версий (номер версии как порядковый номер элемента в послед-и элементов с одинаковыми ключами)
-поиск в таблице всех версий элемента, заданного ключом, или конкретной версии элемента, также заданного своим ключом
-вывод содержимого на экран
-удаление из таблицы всех версий элемента, заданного ключом или версией элемента заданного своим ключом

вся табли ца и информация относящиеся к элементу таблицы храниться в основной памяти.

И самое важное необходимы комментарии к коду.
Спасибо.

Дата отправки: 18.04.2012, 13:35
Вопрос задал: Сергей С. (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Сергей С.!
Вот Вам программа. Надеюсь, Вы в курсе, что такое перемешивание сцеплением smile

Код :
#include <locale>
#include <iostream>

using namespace std;
                                                                                                                                                                                      
void AddElement(void);
void SearchAllRelease(void);
void SearchOneRelease(void);
void DelAllRelease(void);
void DelOneRelease(void);
void OutTable(void);
void Exit(void);
int GetNum(void);

const int	SIZE = 10;

typedef struct Item
{
	int		key;		//ключ элемента
	int		release;	//номер версии элемента
	char	*info;		//указатель на информацию 
	Item	*next;		//указатель на след. элемент
}ITEM;

char *mesMain[] =		//сообщения меню
{
	"Включить новый элемент",
	"Найти элемент всех версий",
	"Найти элемент одной версии",
	"Удалить элемент всех версий",
	"Удалить элемент одной версии",
	"Вывести таблицу",
	"Выход"
};
//количество пунктов меню
int MesMainCount = sizeof( mesMain ) / sizeof( mesMain[0] );
//функции отработки пунктов меню
void ( *funcMain[] )()={AddElement, 
						SearchAllRelease,
						SearchOneRelease,
						DelAllRelease,
						DelOneRelease,
						OutTable,
						Exit};

ITEM	*table[SIZE];	//таблица-вектор

//добавление элемента в таблицу
void AddElement()
{
	int		i;
	int		num;		//индекс нового элемента
	int		iRelease=-1;//версия нового элемента
	char	str[80];
	ITEM	*pItem;		//указатель на текущий элемент
	ITEM	*pItemPrev;	//указатель на предыдущий элемент

	cout << "Введите ключ элемента: ";
	num = GetNum();		//вводим ключ
	i = num%SIZE;		//функция расстановки - остаток от деления на SIZE=10
						//результат - производный ключ
	
	//найдем, есть ли уже заданный ключ и последнюю его версию
	//pItemPrev в итоге будет указывать на предыдущий последний элемент, 
	//после которого мы вставим новый
	for (pItemPrev=NULL,pItem=table[i]; pItem; pItemPrev=pItem,pItem=pItem->next)
	{
		//ищем последнюю версию искомого ключа
		if (pItem->key == num)
			iRelease = pItem->release;
	}
	
	pItem = new ITEM;				//создаем новый элемент
	//заполняем поля
	pItem->key = num;				//ключ
	pItem->release = iRelease+1;	//версия на 1 больше, чем последняя найденная
	pItem->next = NULL;				//признак последнего элемента в цепочке
	cout << "Введите строку: ";
	cin.ignore();
	cin.getline(str, 80);
	pItem->info = new char[strlen(str)+1];
	strcpy(pItem->info, str);		//добавляем строку

	//определимся со ссылкой на наш элемент
	if (pItemPrev != NULL)			//если вставляется не в начало цепочки
		pItemPrev->next = pItem;	//то предыдущий будет на него ссылаться
	else
		table[i] = pItem;			//если первый элемент, то запоминаем ссылку в массиве table
	cout << "Элемент добавлен" << endl;
}

//поиск элемента всех версий
void SearchAllRelease()
{
	int		i, count, num;
	ITEM	*pItem;

	cout << "Введите ключ элемента: ";
	num = GetNum();			//вводим ключ
	i = num%SIZE;		//функция расстановки - остаток от деления на SIZE=10
						//результат - производный ключ
	
	count = 0;			//посчитаем, чтобы определить нашли или нет
	//по всем элементам цепочки для производного ключа
	for (pItem = table[i]; pItem; pItem=pItem->next)
	{
		if (pItem->key == num)		//ключ равен?
		{							//выводим
			cout << "key = " << pItem->key				//ключ
				 << ", release = " << pItem->release	//версия
				 << ", info = " << pItem->info			//строка
				 << endl;
			count++;									//считаем
		}
	}
	if (0==count)					//выведем сообщение, если не нашли
		cout << "Элемент не найден" << endl;
}

//поиск элемента заданной версии
void SearchOneRelease()
{
	int		i, num, release;
	ITEM	*pItem;

	cout << "Введите ключ элемента: ";
	num = GetNum();		//вводим ключ
	i = num%SIZE;		//функция расстановки - остаток от деления на SIZE=10
						//результат - производный ключ

	cout << "Введите версию элемента: ";
	release = GetNum();	//вводим версию
	
	//по всем элементам цепочки для производного ключа
	for (pItem = table[i]; pItem; pItem=pItem->next)
	{
		//сравниваем и ключ, и версию
		if ((pItem->key == num) && (pItem->release == release))
		{
			cout << "key = " << pItem->key 
				 << ", release = " << pItem->release 
				 << ", info = " << pItem->info
				 << endl;
			return;				//нашли, сразу выходим
		}
	}
	cout << "Элемент не найден" << endl;	//не нашли
}

//удаление элементов с ключем всех версий
void DelAllRelease()
{
	int		i, count, num;
	ITEM	*pItemPrev,*pItem, *pItemNext;

	cout << "Введите ключ элемента: ";
	num = GetNum();		//вводим ключ
	i = num%SIZE;		//функция расстановки - остаток от деления на SIZE=10
						//результат - производный ключ
	count = 0;			//считаем число удаленных версий
	//по всем элементам цепочки для производного ключа
	for (pItemPrev=NULL,pItem=table[i]; pItem; pItem=pItemNext)
	{
		pItemNext = pItem->next;		//указатель на следующего
		if (pItem->key == num)			//ключ равен заданному?
		{								//выкинем элемент из цепочки указателей
			if (pItemPrev == NULL)		//первый элемент в цепочке?
				table[i] = pItemNext;	//пишем в массив table адрес следующего
			else						//иначе, предыдущий ссылается
				pItemPrev->next = pItemNext;	//на следующего
			delete [] pItem->info;		//удаляем строку
			delete pItem;				//и сам элемент
			count++;					//считаем
		}								//при удалении предыдущий должен остаться тем же!
		else							//если ключ не наш
			pItemPrev=pItem;			//то предыдущего делаем равным текущему
	}
	if (count)
		cout << "Удалено " << count << " версий элемента" << endl;
	else
		cout << "Элемент не найден" << endl;
}

//удаление ключа одной заданной версии
void DelOneRelease()
{
	int		i, num, release;
	ITEM	*pItemPrev, *pItem, *pItemNext;

	cout << "Введите ключ элемента: ";
	num = GetNum();		//вводим ключ
	i = num%SIZE;		//функция расстановки - остаток от деления на SIZE=10
						//результат - производный ключ

	cout << "Введите версию элемента: ";
	release = GetNum();	//вводим версию
	
	//по всем элементам цепочки для производного ключа
	for (pItemPrev=NULL,pItem=table[i]; pItem; pItem=pItemNext)
	{
		pItemNext = pItem->next;		//указатель на следующего
		//сравниваем и ключ, и версию
		if ((pItem->key == num) && (pItem->release == release))
		{								//выкинем элемент из цепочки указателей
			if (pItemPrev == NULL)		//первый элемент в цепочке?
				table[i] = pItemNext;	//пишем в массив table адрес следующего
			else						//иначе, предыдущий ссылается
				pItemPrev->next = pItemNext;	//на следующего
			delete [] pItem->info;		//удаляем строку
			delete pItem;				//и сам элемент
			cout << "Элемент удален" << endl;
			return;						//все, других больше нет - выходим
		}
		pItemPrev=pItem;				//сдвигаем указатель на предыдущий элемент
	}
	//прошли всю цепочку, значит не нашли
	cout << "Элемент не найден" << endl;
}

//вывод всей таблицы
void OutTable()
{
	int		i, count = 0;	//посчитаем число элементов
	ITEM	*pItem;

	for(i=0; i<SIZE; i++)	//по всем элементам таблицы
	{
		//по всем элементам цепочек
		for (pItem = table[i]; pItem; pItem=pItem->next)
		{
			cout << "key = " << pItem->key 
				 << ", release = " << pItem->release 
				 << ", info = " << pItem->info
				 << endl;
			count++;
		}
	}
	if (0 == count)			//сообщение для пустой таблицы
		cout << "Таблица пуста" << endl;
}

//выход, удалим все элементы
void Exit()
{
	ITEM	*pItem, *pItemNext;
	for (int i=0; i<SIZE; i++)
	{
		for (pItem=table[i]; pItem; pItem=pItemNext)
		{
			pItemNext = pItem->next;		//запомним уазатель на следующего
			delete [] pItem->info;			//удаляем текущего
			delete pItem;
		}
	}
}

//ввод числа
int GetNum()
{
	int		a;
	cin >> a;
	while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
	{
		cout << "Введите число! " << endl;
		cin.clear();
		cin.ignore();
		cin >> a;
	}
	return a;
}

//показ меню с вводом номера строки
int ViewMenu(char** mes, int max)
{
	int ret;
	do
	{
		//меню
		for ( int i = 0; i < max; i++ )
			cout << i+1 << ". " << mes[i] << endl;
		cout << "Ваш выбор: ";
		//вводим число
		ret = GetNum();
	}
	//проверим на допустимость
	while ( ret < 1 || ret > max );
	//вернем номер строки
	return ret;
}

int main()
{
	int ret;
	system("chcp 1251 >> nul");
//    locale::global(locale("Russian_Russia.866")); //чтобы писалось по-русски
	do
	{
		ret = ViewMenu(mesMain, MesMainCount);	//выводим меню, вводим номер строки
		funcMain[ret-1]();						//отрабатываем пункт меню
		cout << "--------------------------------" << endl;
		if (ret == MesMainCount)				//последняя - выход
			break;
	}
	while ( ret );
	return 0;
}

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 23.04.2012, 01:20
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное