Консультация № 185990
08.05.2012, 18:55
114.51 руб.
0 17 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Проблема в следующем, вот код который я прилогаю ниже (ОС -Win, система разработки - Microsoft Visual C++ 2010 Express edition, таблица просматриваемая)

Структуру каждого элемента таблицы можно увидеть в коде, предусматриваю следующие операции:
= включение нового элемента в таблицу при условии, что в таблице могут находиться несколько элементов с одинаковыми ключами и разными номерами версий(номер версии элемента формируется как порядковый номер элемента в последовательности элементов с одинаковыми ключами, определяемый при включении элемента в таблицу); с этим небольшая проблема понимания, а точнее переложения в код, опять же в коде она эта функция есть но она не так работает(добавляет корректно, некоретно версии изменяются).
=поиск в таблице я сделал!
=чистка таблицы сжатием - удаление из таблицы путем ее сжатия всех версий элементов, кроме последних; сделал но не понимаю как уже удалить этот элемент точнее поле или структуру, опять же в коде это представлено, но не доделано(
= ну и вывод я сделал
Сам код
Код:
#include "stdafx.h"
#include <iostream>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <conio.h>

using namespace std;
const int SIZE = 5;
struct item{
int key;
int release;
char info[256];
}itemi[SIZE];
int len = SIZE;
void enter(), init_list(), display(), proverka(),del();
void input(int i);
int menu();

void init_list() //инициализация
{
int t;
for(t=0;t<SIZE;t++) *itemi[t].info = '\0';
}
int menu()//менюшка
{
char ch;

cout << '\n';
do{
cout << "(E)nter\n";
cout << "(D)isplay\n";
cout << "(K)ey\n";
cout << "(R)elease\n";
cout << "(U)dalenie\n";
cout << "(Q)uit\n\n";
cout << "Viberite komandu: ";
cin >> ch;
}while(!strchr("edkruq", tolower(ch)));
return tolower(ch);
}

void enter()//ввод
{
int i;
for(i=0; i < SIZE; i++)
if(!*itemi[i].info) break;

if(i == SIZE)
{
cout << "Spisok polon.\n";
return;
}

input(i);
proverka();
}

void proverka()//проверка ключей
{

int i,j;
for(i=0; i < SIZE; i++)
if(itemi[i].key == itemi[i+1].key) itemi[i+1].release++;

if(i == SIZE)
return;
}

void input(int i)//продолжение ввода
{
cout << "Key: ";
cin >> itemi[i].key;



cout << "info: ";
cin >> itemi[i].info;
itemi[i].release=1;

}

void display()//вывод на екран
{
int t;

for(t=0; t < SIZE; t++)
{
if(*itemi[t].info)
{

cout << "Key: ";
cout << itemi[t].key << '\n';
cout << "Release: ";
cout << itemi[t].release << '\n';
cout << "info: ";
cout << itemi[t].info << '\n';
}
}
}

void key()//поиск по ключу
{
int i,n;
cout << "Key: ";
cin >> n;

for(i = 0; i < SIZE; i++)
{
if(itemi[i].key == n)
{
cout << "Key: ";
cout << itemi[i].key << '\n';
cout << "Release: ";
cout << itemi[i].release << '\n';
cout << "info: ";
cout << itemi[i].info << '\n';
}
}
}

void release()//поиск по ключу и версии
{
int i,n,r;
cout << "Key: ";
cin >> n;
cout << "Release: ";
cin >> r;

for(i = 0; i < SIZE; i++)
{
if(itemi[i].key == n && itemi[i].release == r)
{
cout << "Key: ";
cout << itemi[i].key << '\n';
cout << "Release: ";
cout << itemi[i].release << '\n';
cout << "info: ";
cout << itemi[i].info << '\n';
}
}
}
void del()//удаление элемента указываемого по ключу и версии
{
int i,k,r,j;
cout << "Key: ";
cin >> k;
cout << "Release: ";
cin >> r;
for(i = 0; i < SIZE; i++)
{
if(itemi[i].key == k && itemi[i].release == r)
{
itemi[i].key = itemi[i+1].key;
for(j = 0; j < SIZE; j++)
{
itemi[i].info[j] = itemi[i+1].info[j];
}
itemi[i].release = itemi[i+1].release;
}
}
}
int _tmain(int argc, _TCHAR* argv[]){

char choice;

init_list();

for(;;){
choice = menu();
switch(choice)
{
case 'e': enter();
break;
case 'd': display();
break;
case 'k': key();
break;
case 'r': release();
break;
case 'u': del();
break;
case 'q': return 0;
}
}
return 0;
}


помогите сделать корректное изменение версии ключа, то есть, если ключи 1 1 1 1 1, тогда версии, как я понял 1 2 3 4 5, или если 1 1 2 3 4, тогда версии 1 2 1 1 1
и помогите пожалуйсто сделать корректное удаление или уничтожение элемента как видите тут замещение сделано а как избавиться от поля или от элемента, так называемого, я не понял немного. Большое спасибо!
Нельзя использовать СТЛ, ООП. Все стандартно как написано у меня пожалуйсто

Обсуждение

Неизвестный
08.05.2012, 22:49
общий
Такая ситуация: есть ключ 1 с версией 1 и ключ 1 с версией 3, а мы добавляем ключ 1, какая должна быть версия?
давно
Посетитель
7438
7205
08.05.2012, 23:30
общий
Уточните, что надо удалять?
1) Элемент по ключу и версии
2) Все версии элементов с заданным ключом, кроме последнего. Если версия одна, то удаляем этот элемент?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.05.2012, 10:58
общий
Попробую ответить на два вопроса:
- 4 тоесть +1 к максимуму, тут как я понимаю добавили три ключа 1 1 1 и версии стали соответственно 1 2 3, значит ключ 1 с версией 2 удалили.
- смотрите в задании написано:
удаление из таблицы путем ее сжатия всех версий элементов кроме последних
Неизвестный
09.05.2012, 22:14
общий
удаление из таблицы путем ее сжатия всех версий элементов кроме последних

Туманная формулировка. Можно как-то расшифровать предложение разбив на простые составляющие.
Что значит сжатие? Перемещение всех нижних элементов вверх (как в коде) или восстановление порядка исчисления версий кроме последних (скольких?) ?
Неизвестный
09.05.2012, 23:39
общий
09.05.2012, 23:52
надо удалить все версии кроме последних тоесть допустим если отсчет версий идет с 1 то надо оставить версии 2 и более как я понимаю.
Причем насколько я понимаю если удаляется записи при добавлении следующем каждом должны добавляться в конец
привер видимо таков:
ключ 1
инфо йцук
версия 1
ключ 1
инфо фыв
версия 2

при выполнении удаления первого ключа с версией 1 остется ключ 1 и версия 2
при следующем выполнения ввода вводится будут уже и отображаться после поля ключ 1 версия 2
тоест получется можно оставить и такое удаления как тут в коде я его подкорректировал и удаление сжатием когда просто нажимаем условно y и идет процесс сжатия таблицы где удаляются не по выбору а по версиям

вобщем получается если несколько ключей одинаковых то надо удалить те у которых версия не последняя если ключ в поле 1 и нету больше такого то оставить
Пример
ключи
1 2 3 4 5
версии
1 1 1 1 1
остются элементы все
при обработке сжатием
пример где будут удаления
ключи 1 1 1 2 2
версии
1 2 3 1 2
после сжатия будет такая картина
по ключам остаются
1 2
по версиям
3 2

после этой функции элементы добавляются всякий раз в конец
Неизвестный
10.05.2012, 23:13
общий
12.05.2012, 17:28
это ответ
Здравствуйте, Посетитель - 392815!
Весь код не предоставляю, т.к. задача стояла в помощи написания функций. Их и обсудим.
Судя по Вашему коду - есть таблица фиксированного размера, где элемент таблицы признаётся пустой, если поле info пустое, т.е. первый байт имеет значение нуля. Поэтому удаление элемента выглядит просто:
Код:

void del_item(int index) //Удаление элемента с номером index
{
itemi[index].info[0]=0;
cout << "Element " << index <<" deleted" << '\n';
}

void del()//удаление элемента указываемого по ключу и версии
{
int i,k,r,j;
cout << "Key: ";
cin >> k;
cout << "Release: ";
cin >> r;
for(i = 0; i < SIZE; i++) //Пробежимся по всем элементам в поисках указанного
if(itemi[i].key == k && itemi[i].release == r) del_item(i); //При совпадении удалить
}
Заметьте, тут добавлена функция стирания элемента по индексу: del_item(int index). Она ещё понадобится.

Заполняется таблица в первый найденный свободный элемент с пустым info, сортировка не предусмотрена. Проверка на совпадение ключа и увеличение версии происходит так:
Код:

void proverka(int i)//проверка ключей
{
int j,k;
int MaxRelease=0;
for(j=0; j < SIZE; j++) //Сравним со всеми ключами
if((i!=j && *itemi[j].info && itemi[i].key == itemi[j].key && itemi[j].release>MaxRelease))
MaxRelease=itemi[j].release; //Если ключи совпали и версия выше, то запомним версию
itemi[i].release=MaxRelease+1; //Новая версия ключа
}
Изменилось объявление функции. Появился аргумент - индекс добавленного элемента. Вызов функции, надеюсь, сами сможете поправить.

Теперь новая функция, отсутствующая в Вашем коде, но я счёл необходимым её присутствие. Это сжатие (компрессия) как я её понял. Её работа заключается в удалении всех ключей с меньшими версиями:
Код:

void compress() //Сжатие версий (удаление всех версий кроме последней)
{
cout << "Compress" << '\n';
int i,j;
for(i=0; i<SIZE; i++) { //Пробежимся в таблице по ключам
if (*itemi[i].info) { //Если элемент не пуст
int MaxRelease=i; //Номер ключа с максимальной версией
for(j=i+1; j<SIZE; j++) { //Пробежимся по таблице в поиске таких же ключей
if (*itemi[j].info && itemi[MaxRelease].key==itemi[j].key) { //Совпадение ключей
if (itemi[MaxRelease].release<itemi[j].release) { //Попался ключ с большей версией
del_item(MaxRelease); //Удалим меньшую версию
MaxRelease=j; //Запомним бОльшую версию
} else {
del_item(j); //Удалим меньшую версию
}
}
}
}
}
}


Дополнительные комментарии присутствуют в коде.
Если Вы нуждаетесь и модераторы и другие эксперты сочтут необходимым выложить весь код, то выложу минифоруме. Но если код, размещённый в вопросе Вы писали сами, то Вам не составит труда интегрировать мои исправления в него.
Неизвестный
11.05.2012, 00:34
общий
пока вы делали я сделал так)

Код:
void proverka(int i)
{

int j;
for(j=0; j < SIZE; j++)
{
if(j == i) continue;
if(itemi[i].key == itemi[j].key) itemi[i].release++;
}
if(j == SIZE)
return;
}



Код:
void zip()
{
int k,r,n,e,p;
for(int i = 0; i < SIZE; i++)
{
for(int j = 0; j < SIZE; j++)
{
if(itemi[i].key == itemi[j].key && itemi[i].release != itemi[j].release)
{
k=itemi[i].key;
r=itemi[i].release;
for(e = 0; e < SIZE; e++)
{
if(itemi[e].key == k && itemi[e].release == r)
{

for(p=e;p < SIZE; p++)
{
itemi[p].key= itemi[p+1].key;
itemi[p].release= itemi[p+1].release;
for(n=0;n<256;n++)
itemi[p].info[n] = itemi[p+1].info[n];
}
}
}
}
}
}
}
Неизвестный
11.05.2012, 00:35
общий
Всем спасибо))))))
Неизвестный
11.05.2012, 09:31
общий
Для Вашей функции proverka(int i) промоделируйте ситуацию:
заполните таблицу элементами с ключом 1 (5 элементов при SIZE=5), получится 1 1, 1 2, 1 3, 1 4, 1 5;
удалите первый элемент 1 1, получится 1 2, 1 3, 1 4, 1 5;
добавьте элемент с ключом 1, должен появиться элемент 1 6, а получится два элемента 1 5.

Функция zip() предполагает, что версии одного ключа отсортированы по возрастающей в таблице. Есть ли в этом необходимость в задании не сказано. В моей функции compress() отсортированность не требуется.
В функции содержатся три ошибки:
1. Не учитываются пустые элементы. Фактически обрабатываются удалённые элементы.
2. Обращение itemi[p+1] в определённом случае указывает на элемент за пределами массива.
3. При сжатии не удаляется последний элемент, т.е. появляется копия последнего элемента.
давно
Старший Модератор
31795
6196
11.05.2012, 19:50
общий
11.05.2012, 20:00
Цитата: 363736
void del(int index) //Удаление элемента с номером index
{
itemi[index].info[0]=0;
cout << "Element " << i <<" deleted" << '\n';
}

void del()//удаление элемента указываемого по ключу и версии
{
int i,k,r,j;
cout << "Key: ";
cin >> k;
cout << "Release: ";
cin >> r;
for(i = 0; i < SIZE; i++) //Пробежимся по всем элементам в поисках указанного
if(itemi[i].key == k && itemi[i].release == r) del(i); //При совпадении удалить
}

Две функции DEL.
INDEX != I
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
11.05.2012, 20:46
общий
Адресаты:
Цитата: Зенченко Константин Николаевич
Две функции DEL.
INDEX != I

Да, действительно, с index я недоглядел.Конечно же должно быть index вместо i.
А вот две функции del вполне законно, перегрузкой функций называется. В зависимости от передаваемых параметров компилятор сам подставляет нужную функцию. Я хотел дать другое имя, но подумал, что начинающим программистам полезно было бы познакомиться с такой вещью.
Кстати, помогал мне компилятор gcc.
давно
Старший Модератор
31795
6196
11.05.2012, 20:56
общий
11.05.2012, 21:02
Цитата: Перегрузка_операторов
Перегрузка операторов — в программировании — один из способов реализации полиморфизма, заключающийся в возможности одновременного существования в одной области видимости нескольких различных вариантов применения оператора, имеющих одно и то же имя, но различающихся типами параметров, к которым они применяются.


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


Теперь внимательно читаем задание:
Цитата: 392815
Нельзя использовать СТЛ, ООП. Все стандартно как написано у меня пожалуйсто

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
11.05.2012, 21:56
общий
Адресаты:
Цитата: Зенченко Константин Николаевич
Теперь внимательно читаем задание:
© Цитата: Посетитель - 392815
Нельзя использовать СТЛ, ООП. Все стандартно как написано у меня пожалуйсто


Проморгал
давно
Старший Модератор
31795
6196
11.05.2012, 21:59
общий
11.05.2012, 22:00
Цитата: 363736
Проморгал

Бывает.

Компиляторы иногда играют с программистами злые шутки если не вводить ограничения на используемые возможности.

я исправляю: INDEX и добавляю DEL_ITEM в Вашем ответе.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
12.05.2012, 12:00
общий
Адресаты:
Цитата: Зенченко Константин Николаевич
я исправляю: INDEX и добавляю DEL_ITEM в Вашем ответе.

Согласен. Тогда ещё в функции compress() поправьте, там 2 вызова del.
Неизвестный
12.05.2012, 16:52
общий
Код:
void proverka(int i)
{

int j;
for(j=0; j < SIZE; j++)
{
if(j == i) break; \\тут было continue
if(itemi[i].key == itemi[j].key) itemi[i].release++;
}
if(j == SIZE)
return;
}



Код:
void zip()
{
int k,r,n,e,p;
for(int i = 0; i < SIZE; i++)
{
for(int j = 0; j < SIZE; j++)
{
if(itemi[i].key == itemi[j].key && itemi[i].release < itemi[j].release) \\тут поменял было !=
{
k=itemi[i].key;
r=itemi[i].release;
for(e = 0; e < SIZE; e++)
{
if(itemi[e].key == k && itemi[e].release == r)
{

for(p=e;p < SIZE; p++)
{
itemi[p].key= itemi[p+1].key;
itemi[p].release= itemi[p+1].release;
for(n=0;n<256;n++)
itemi[p].info[n] = itemi[p+1].info[n];
}
}
}
}
}
}
}


Вчера сдал с такими изменения в программе!
Неизвестный
12.05.2012, 17:38
общий
Посмотрел еще раз как работает программа переделал как вы показали, работает!
Форма ответа