Консультация № 174438
22.11.2009, 14:16
0.00 руб.
0 10 1
Добрый день, уважаемые эксперты!
Прошу у вас помощи в написании программы.
определены следующие требования к программе:
В ходе работы для всех вариантов необходимо написать подпрограмму создания в оперативной памяти связанного однонаправленного списка содержащего данные согласно варианта задания. В программах всех вариантов должна быть подпрограмма вывода на экран всего списка по адресу его первого элемента. Используя эту подпрограмму необходимо вывести в наглядной форме исходный список (непосредственно после его создания) и список после модификации. Основное содержимое программы должно соответствовать варианту.
Примечание: В конце программы необходимо освободить всю захваченную память.
Задание заключается в следующем:
В элементе списка содержатся данные о ноутбуке-наименование,цена,тактовая частота,размер ОП.Удалить из списка элемент с максимальной ценой.
Я написал программу, но она выводит список не в том порядке, в каком я заносил данные.и не получается удалить требуемый элемент.ПОМОГИТЕ!



Приложение:
#include <conio.h>
#include <iostream.h>
#include <stdio.h>

struct nout
{
char nazv[20];
float price, proc;
int mem;
nout *next;
} *head=NULL ;


void makelist (int i)
{
nout *buf=new nout;
cout<<"\n Naimenovanie-";cin>>buf->nazv;
cout<<"\n Chastota processora-";cin>>buf->proc;
cout<<"\n Razmer pamyati-";cin>>buf->mem;
cout<<"\n Cena-";cin>>buf->price;
buf->next=head;
head=buf;
}

void showlist()
{
nout *elem=head;
while (elem)
{
cout<<"\nNaimenovanie- "<<elem->nazv;
cout<<"\nChastota processora- "<<elem->proc;
cout<<"\nRazmer pamyati- "<<elem->mem;
cout<<"\nCena: "<<elem->price<<endl;
elem=elem->next;
}
}

void editlist()
{
не знаю что делать.нужно удалить элемент с максимальной ценой ноутбука.
}


void main()
{
int n=0; //количество элементов списке
cout<<"\nskolko elementov v spiske? ";
cin>>n;
for (int i=0;i<n;i++)
makelist(i);
printf("\nVivod spiska:\n");
showlist();
getch();
printf("Ydalenie noutbuka s max cenoi");
editlist();
getch();
}

Обсуждение

Неизвестный
22.11.2009, 14:54
общий
Jekaiseburga:
В STL есть шаблон template list<> для списка. Я так понял Вам нельзя пользоваться STL, а надо самому сделать список?
Неизвестный
22.11.2009, 16:00
общий
Да, вы правы. мне нужно создавать все самому-и создание списка, и модификация, и вывод на экран. у меня всего два вопроса-почему список выводится наоборот?
и собственно модификация списка.
Неизвестный
22.11.2009, 18:38
общий
Jekaiseburga:
Список выводится наоборот потому, что Вы делаете вставку в голову списка, а не в хвост.
Неизвестный
22.11.2009, 19:00
общий
это ответ
Здравствуйте, Jekaiseburga.
Программа. C++. GCC.
Код:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <limits>

template<class Ty> class list;

// Узел списка
template<class Ty>
class node
{
private:
node(Ty item=Ty())
:_next(0)
,_data(item)
{}
Ty _data;
node* _next;
friend class list<Ty>;
public:
Ty data() const
{
return _data;
}
};

// Список
template<class Ty>
class list
{
public:
typedef node<Ty> node_type;
list()
:_root(0)
,_tail(0)
,_count(0)
{}
~list()
{
clear();
}
// Очистка списка
void clear()
{
while (_root)
{
remove_first();
}
}
// Удаляет первый элемент
void remove_first()
{
if (_root)
{
node_type* nodePtr=_root;
if (!(_root=_root->_next))
{
_tail=0;
}
delete nodePtr;
--_count;
}
}
// Удаляет элемент заданный узлом
void remove(const node_type* nodePtr)
{
if (_root==nodePtr)
{
_root=nodePtr->_next;
delete nodePtr;
--_count;
}
else
{
node_type* cur=_root;
while (cur && cur->_next!=nodePtr)
{
cur=cur->_next;
}
if (cur)
{
cur->_next=nodePtr->_next;
delete nodePtr;
--_count;
}
}
}
// Добавляет элемент в начало
void add_first(Ty item)
{
node_type* nodePtr=new node<Ty> (item);
nodePtr->_next=_root;
if (!_root)
{
_tail=nodePtr;
}
_root=nodePtr;
++_count;
}
// Добавляет элемент в конец
void add_last(Ty item)
{
node_type* nodePtr=new node<Ty>(item);
if (_root)
{
_tail->_next=nodePtr;
_tail=nodePtr;
}
else
{
_root=_tail=nodePtr;
}
++_count;
}
// Возвращает размер
size_t count() const
{
return _count;
}
// Возвращает указатель на начало
const node_type* const begin() const
{
return _root;
}
// Возвращает указатель на следующий элемент
const node_type* const next(const node_type* const n) const
{
return n?n->_next:0;
}
private:
node_type* _root;
node_type* _tail;
size_t _count;
};

// Класс ноутбук
class nout
{
public:
nout(std::string name,double price,double frequency,size_t memory)
:_name(name)
,_price(price)
,_frequency(frequency)
,_memory(memory)
{};
std::string name() const
{
return _name;
}
double price() const
{
return _price;
}
double frequency() const
{
return _frequency;
}
size_t memory() const
{
return _memory;
}
private:
std::string _name;
double _price,_frequency;
size_t _memory;
};

// Оператор вывода для class nout
template<class Elem,class Traits>
std::basic_ostream<Elem,Traits>& operator<<(std::basic_ostream<Elem,Traits>& stream,const nout& right)
{
stream<<"""<<right.name()<<""("<<right.price()<<"$,"<<right.frequency()<<"GHz,"<<right.memory()<<"Mb)";
return stream;
}

// Оператор вывода для template<> class list<Ty>
template<class Ty,class Elem,class Traits>
std::basic_ostream<Elem,Traits>& operator<<(std::basic_ostream<Elem,Traits>& stream,const list<Ty>& right)
{
const node<Ty>* nodePtr=right.begin();
while (nodePtr)
{
stream<<nodePtr->data()<<std::endl;
nodePtr=right.next(nodePtr);
}
return stream;
}

// Ф-я для ввода различных данных
template<class Ty>
Ty input(std::string message)
{
while (true)
{
std::cout<<message;
Ty result;
std::cin>>result;
if (std::cin.fail())
{
std::cout<<"Ошибочный ввод"<<std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
else
{
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
return result;
}
}
}

// Меню
int menu()
{
while (true)
{
std::cout<<"----------------------------------------------------"<<std::endl
<<"Сделайте выбор:"<<std::endl
<<"1-Ввод списка"<<std::endl
<<"2-Вывод списка на экран"<<std::endl
<<"3-Удаление элемента с максимальной ценой"<<std::endl
<<"0-Выход"<<std::endl
<<"Ваш выбор:";
char choice;
std::cin.get(choice);
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
switch (choice)
{
case '0':
case '1':
case '2':
case '3':
return choice-'0';
default:
std::cout<<"Будьте внимательней"<<std::endl;
}
}
}

typedef list<nout> noutList;

// Добавляет элементы в список
void addInList(noutList& lst)
{
while (true)
{
std::cout<<"Наименование модели(пустая строка для завершения):";
std::string name;
std::getline(std::cin,name);
if (name.empty())
{
return;
}
double price=input<double>("Цена:");
double freq=input<double>("Частота процессора(GHz):");
size_t mem=input<size_t>("Объем памяти:");
lst.add_last(nout(name,price,freq,mem));
}
}

// Выводит список
void printList(const noutList& lst)
{
std::cout<<"Наш список:"<<std::endl
<<lst;
}

// Удаляет элемент с максимальной ценой
void removeMaxPrice(noutList& lst)
{
if (lst.count())
{
const noutList::node_type* cur=lst.begin();
const noutList::node_type* max=cur;
while (cur)
{
if (max->data().price()<cur->data().price())
{
max=cur;
}
cur=lst.next(cur);
}
lst.remove(max);
}
else
{
std::cout<<"Список не содержит элементов"<<std::endl;
}
}

int main(int argc, char **argv)
{
noutList lst;
while (true)
{
switch (menu())
{
case 0:
return 0;
case 1:
addInList(lst);
break;
case 2:
printList(lst);
break;
case 3:
removeMaxPrice(lst);
break;
}
}
}

Пример вывода:
Код:
micren@localhost:~/projects/174438/build> ./174438                                                                       
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:1
Наименование модели(пустая строка для завершения):Acer Aspire One D250-0Bp
Цена:367
Частота процессора(GHz):1.6
Объем памяти:1024
Наименование модели(пустая строка для завершения):ASUS Eee PC 701 4G
Цена:244
Частота процессора(GHz):0.9
Объем памяти:512
Наименование модели(пустая строка для завершения):ASUS K50C
Цена:495
Частота процессора(GHz):1.2
Объем памяти:4096
Наименование модели(пустая строка для завершения):HP Presario CQ60-211
Цена:500
Частота процессора(GHz):2.167
Объем памяти:2048
Наименование модели(пустая строка для завершения):Lenovo IdeaPad S10 plus2
Цена:409
Частота процессора(GHz):1.66
Объем памяти:1024
Наименование модели(пустая строка для завершения):
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:2
Наш список:
"Acer Aspire One D250-0Bp"(367$,1.6GHz,1024Mb)
"ASUS Eee PC 701 4G"(244$,0.9GHz,512Mb)
"ASUS K50C"(495$,1.2GHz,4096Mb)
"HP Presario CQ60-211"(500$,2.167GHz,2048Mb)
"Lenovo IdeaPad S10 plus2"(409$,1.66GHz,1024Mb)
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:3
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:2
Наш список:
"Acer Aspire One D250-0Bp"(367$,1.6GHz,1024Mb)
"ASUS Eee PC 701 4G"(244$,0.9GHz,512Mb)
"ASUS K50C"(495$,1.2GHz,4096Mb)
"Lenovo IdeaPad S10 plus2"(409$,1.66GHz,1024Mb)
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:3
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:2
Наш список:
"Acer Aspire One D250-0Bp"(367$,1.6GHz,1024Mb)
"ASUS Eee PC 701 4G"(244$,0.9GHz,512Mb)
"Lenovo IdeaPad S10 plus2"(409$,1.66GHz,1024Mb)
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:3
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:2
Наш список:
"Acer Aspire One D250-0Bp"(367$,1.6GHz,1024Mb)
"ASUS Eee PC 701 4G"(244$,0.9GHz,512Mb)
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:3
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:2
Наш список:
"ASUS Eee PC 701 4G"(244$,0.9GHz,512Mb)
----------------------------------------------------
Сделайте выбор:
1-Ввод списка
2-Вывод списка на экран
3-Удаление элемента с максимальной ценой
0-Выход
Ваш выбор:0
micren@localhost:~/projects/174438/build>
5
Просто на отлично!Не ожидал, что так быстро ответ будет.
Неизвестный
22.11.2009, 19:25
общий
Micren, скажите пожалуйста, а без создания собственного класса данную задачу решить нельзя?у меня просто проблемы с классами+это все надо объяснить преподавателю.К сожалению у меня объяснить не получится,да и видно, что не пой подчерк в программировании.Нельзя ли каким-либо образом модернизировать мой исходник.естественно не за бесплатно.
Неизвестный
22.11.2009, 21:21
общий
Jekaiseburga:
Код:
#include <iostream>
#include <cstdio>

using namespace std;

struct nout
{
char nazv[20];
float price, proc;
int mem;
nout *next;
} *head=NULL,*tail=NULL ;


void makelist (int i)
{
nout *buf=new nout;
cout<<"\n Naimenovanie-";cin>>buf->nazv;
cout<<"\n Chastota processora-";cin>>buf->proc;
cout<<"\n Razmer pamyati-";cin>>buf->mem;
cout<<"\n Cena-";cin>>buf->price;
if(head)
{
buf->next=NULL;
tail->next=buf;
tail=buf;
}
else
{
head=tail=buf;
}
}

void showlist()
{
nout *elem=head;
while (elem)
{
cout<<"\nNaimenovanie- "<<elem->nazv;
cout<<"\nChastota processora- "<<elem->proc;
cout<<"\nRazmer pamyati- "<<elem->mem;
cout<<"\nCena: "<<elem->price<<endl;
elem=elem->next;
}
}

void editlist()
{
if(head)
{
nout* cur=head,*max=head,*prev=0;
while(cur->next)
{
if(cur->next->price>max->price)
{
max=cur->next;
prev=cur;
}
cur=cur->next;
}
if(prev)
{
prev->next=prev->next->next;
}
else
{
head=head->next;
}
if(!head)
{
tail=0;
}
delete max;
}
}

void dellist()
{
while(head)
{
nout* tmp=head;
head=head->next;
delete tmp;
}
tail=0;
}

int main()
{
int n=0; //количество элементов списке
cout<<"\nskolko elementov v spiske? ";
cin>>n;
for (int i=0;i<n;i++)
makelist(i);
printf("\nVivod spiska:\n");
showlist();
getchar();
printf("Ydalenie noutbuka s max cenoi");
editlist();
showlist ();
getchar();
dellist();
return 0;
}
Неизвестный
22.11.2009, 21:40
общий
Micren:
Micren,огромное спасибо!за мной не заржавеет!!!
Неизвестный
24.11.2009, 11:30
общий
Micren:
Поясните пожалуйста следующие строчки кода,а то до меня не доходит,как это работает(мне необходимо будет нарисовать блок-схему программы в отчете).
void makelist (int i)
{
nout *buf=new nout;
cout<<"\n Naimenovanie-";cin>>buf->nazv;
cout<<"\n Chastota processora-";cin>>buf->proc;
cout<<"\n Razmer pamyati-";cin>>buf->mem;
cout<<"\n Cena-";cin>>buf->price;
if(head)
{
buf->next=NULL;
tail->next=buf;
tail=buf;
}
else
{
head=tail=buf;
}


и еще :
if(prev)
{
prev->next=prev->next->next;\\что означает данная запись, как ее понять?
}
Неизвестный
24.11.2009, 19:03
общий
Jekaiseburga:
Прокомментировал свои строки кода
Код:
void makelist (int i)
{
nout *buf=new nout;
cout<<"\n Naimenovanie-";cin>>buf->nazv;
cout<<"\n Chastota processora-";cin>>buf->proc;
cout<<"\n Razmer pamyati-";cin>>buf->mem;
cout<<"\n Cena-";cin>>buf->price;

// если список уже существует
if(head)
{
// Вставляем в хвост и поэтому обнулим указатель(признак конца списка)
buf->next=NULL;
// tail - хвост списка. Сюда и вставляем
tail->next=buf;
// Теперь надо, чтоб tail указывал на последний добавленный элемент
tail=buf;
}
else
{
// если списка нет, то инициализируем head(голова) и tail(хвост) значением единственного элемента
head=tail=buf;
}
}

Код:
		if(prev)
{
// Это выражение можно записать так
prev->next=(prev->next)->next; // prev->next будет указывать не на следующий элемент, а на следующий после следующего.:)
// (prev->next) это такой же указатель nout* и он тоже ссылается на nout у которого есть поле next
}
Неизвестный
24.11.2009, 21:26
общий
Огромное спасибо!
Форма ответа