Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
5 / 6 / 4
Регистрация: 18.11.2009
Сообщений: 661
1

Контейнер из неоднородных элементов

06.06.2011, 17:27. Показов 2058. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Хотел сначала написать в раздел С для экспертов, но выяснилось- прав не имею.
Есть такая задача (даже несколько разновидностей) дается в Бауманке на 1 или 2 курсе:
Моделировать очередь (руками), в качестве элементов которой могут использоваться числа и слова. Операции: добавление элемента, удаление элемента, печать элементов. Соз-дать класс - потомок, который содержит процедуру сортировки слов по алфавиту.
Я ее сделал немалой кровью правда.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 class TElement
{ public:
TElement *nxt;
TElement() { nxt=NULL;}
      virtual ~TElement() {cout<<"Delete TElement.";}
      virtual void Print()=0;
     };
class TQueue
{
public:
  TQuue();//конструктор
  ~TQueue();  //деструктор
  TElement *First(){return cur=first;}
  TElement *Last(){return cur=last;}
  TElement *Next(){return cur=cur->nxt;}
  void addEL(TElement *val);//добавление элемента
  void delEL(); //удаление 1 элем
   void print();
private:
 TElement *first,*last,*cur;
 };
   TQueue::TQuue() //конструктор
   {first=last=cur=NULL;}
 TQueue::~TQueue()  //деструктор
 {TElement *cur1;
  cur1=first;
     while (cur!=NULL) {
     cur=cur1->nxt;
     delete(cur1);
                        }
   }
  void TQueue::addEL(TElement *e)  //добавление элемента
 {
  if (first==NULL)
        { first=last=e; e->nxt=NULL;}
   else
   { e->nxt=first;first=e;}
 }
 
 void TQueue::delEL()
  {//удаление 1 элем
   first=first->nxt;
  }
 
 void TQueue::print()
  {
    cur=first;
      while (cur!=NULL)
      {cur->Print(); cur=cur->nxt;}
  }
 //--------------------------------------------
 class TNum:public TElement
 { 
 public:
 int num;
    TNum(int n):TElement(),num(n) {}
    virtual ~TNum() {cout<<"Delete TNum.";}
    virtual void Print() { printf("%d ",num); }
      };
//--------------------------------------------
 class TSlovo:public TElement
 { public:
       char s[20];
    TSlovo(char *S):TElement() {strcpy(s,S);}
    virtual ~TSlovo() {cout<<"Delete TChar.";}
    virtual void Print() { printf("%s ",s);}
 };
 
class TQueueS: public TQueue
{
 public:
 void sort(TElement * first);
};
void TQueueS::sort(TElement * first)
{ int i;
 TElement *a; TElement *b; char tmp[20];  TSlovo *A;TSlovo *B;
 a = first;
 while ((A =dynamic_cast<TSlovo *>(a))==0)
     a=a->nxt;//продвигаемся до 1-го элемента-строки
 while(a->nxt) // пока существует следующий элемент
 {
   b = a->nxt;
   while(b)  // для каждого элемента перебираем все оставшееся справа
      {
       while ((B=dynamic_cast<TSlovo *>(b))==0 )
          { b=b->nxt;   if (!b) return;}; //продвигаемся до 1-го элемента-строки
      if(strcmp(A->s,B->s)>0)//если порядок не тот - меняем
        { strcpy(tmp, A->s);strcpy(A->s,B->s); strcpy(B->s,tmp); }
        b = b->nxt;
      }
      while ((A =dynamic_cast<TSlovo *>(a))==0)
         a = a->nxt;  //продвигаемся до следующего элемента-строки
 }
}
Особенно напрягла процедура сортировки строк - ведь тут для перехода к следующему элементу мало
a = a->nxt; а надо делать цикл типа
C++
1
2
while ((A =dynamic_cast<TSlovo *>(a))==0)
         a = a->nxt;
Так что даже простой пузырек выглядит нетривиально
Хочу спросить опытных людей: а на хрена вообще вся эта конструкция - неоднородный контейнер любого вида? Где применяется?
напоминает чем то UNION в SQL - там UNION тоже редко используется
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.06.2011, 17:27
Ответы с готовыми решениями:

Заменить контейнер vector, использовавшийся для хранения текстовых строк (листинг 2.3), на контейнер list
Здравствуйте форумчане, может кто объяснить как делать это задание и что собственно мы тут вообще...

Решение неоднородных ДУ второго порядка
Друзья, уже биты час сижу и не могу понять,почему не выводится график? Само уравнение y&quot;+y'=3*x^2...

Система неоднородных дифф.уравнений.
Ребята, помогите пожалуйста решить пример. Очень надо.. Буду всем очень благодарен.. Вот задание:

Система неоднородных дифференциальных уравнений
Добрый день. Прошу помощи в решении линейной неоднородной системы дифференциальных уравнений:...

9
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.06.2011, 18:03 2
Цитата Сообщение от eugrita Посмотреть сообщение
Хочу спросить опытных людей: а на хрена вообще вся эта конструкция - неоднородный контейнер любого вида? Где применяется?
очевидно там где содержимое может быть разных типов

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <string>
#include <typeinfo>
#include <cassert>
#include <vector>
#include <iostream>
 
enum type{E_STRING, E_DOUBLE};
 
class Data
{
public:
   virtual type getType() const = 0;
protected:
   type m_type;
};
 
template <class T>
class Element : public Data
{
public:
   Element( const T& data ) : m_data( data )
   {
      if( typeid(double) == typeid(T) ) 
         m_type = E_DOUBLE; 
      else if ( typeid(std::string) == typeid(T) ) 
         m_type = E_STRING; 
      else
         assert(!"invalid type!");
   }
   virtual type getType() const
   {
      return m_type;
   }
   T getValue()
   {
      return m_data;
   }
private:
   T m_data;
};
 
int main()
{
   std::vector<Data*> v;
   for( int i=0;i<5;++i )
   {
      v.push_back( new Element<double>(3.14 * i) );
   }
 
   v.push_back( new Element<std::string>("hello") );
   v.push_back( new Element<std::string>("world") );
   
   typedef std::vector<Data*>::iterator VIt;
   
   for( VIt it = v.begin(); it != v.end(); ++it )
   {
      if( E_STRING == (*it)->getType() )
         std::cout << 
           dynamic_cast<Element<std::string>*>(*it)->getValue()
                   << " ";
      else 
          std::cout << 
           dynamic_cast<Element<double>*>(*it)->getValue()
                   << " ";
   }
}
http://liveworkspace.org/code/... f1d306621d
тут конечно ограничение ++'са, что возвращаемое значение должно быть известно на момент компиляции
0
5 / 6 / 4
Регистрация: 18.11.2009
Сообщений: 661
06.06.2011, 18:48  [ТС] 3
ну вот еще одна stl-ная реализация. А вопрос без ответа - в каких задачах это применяется?
Явно уважаемые программисты, не имеете опыта руководства дипломниками. Решена задача - а применение подобрать слабо?
Как говорится, дайте мне задачу и как Архимед с помощью этой программной опоры переверну мир
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.06.2011, 18:58 4
eugrita, в вашем чтоли тоже стл был?
пускай будет разбор токенов строки, где токены могу быть разного типа
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
06.06.2011, 19:03 5
eugrita, у тебя всё правильно, только нужно сделать список независимым от элементов, которые в него помещают, а сами элементы обобщить с помощью шаблонов, а именно не писать вручную каждого наследника базового класса, а написать один шаблонный класс.
Ну и для выведения использовать виртуальные функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
#include <list>
 
class basic_element
{
public:
    virtual ~basic_element () {}
    
    friend std::ostream & operator << (std::ostream & stream, const basic_element & e)
    {
        return e.print_to_stream(stream);
    }
    
private:    
    virtual std::ostream & print_to_stream (std::ostream & stream) const = 0;
};
 
template <typename Value>
class element : public basic_element
{
public:
    typedef Value value_type;
    
    element ()
    {
    }
    
    element (const Value & value):
        value(value)
    {
    }
   
private:
    virtual std::ostream & print_to_stream (std::ostream & stream) const
    {
        return stream << value;
    }
    
public:
    value_type value;
};
 
int main()
{
    typedef std::list<basic_element *> container_type;
    container_type elements;
    
    elements.push_back(new element<int>(17));
    elements.push_back(new element<std::string>("qwe"));
    
    for (container_type::iterator i = elements.begin(); i != elements.end(); ++i)
    {
        std::cout << **i << std::endl;
    }
    
    for (container_type::iterator i = elements.begin(); i != elements.end(); ++i)
    {
        delete *i;
    }
    
    return 0;
}
Зачем это нужно?
Например, для интерпретаторов, в частности, как выше заметили, для разбора строки.
1
5 / 6 / 4
Регистрация: 18.11.2009
Сообщений: 661
06.06.2011, 19:05  [ТС] 6
слава богу. Одно применение нашли.Правда разбор токенов - расплывчато. Вот разбор арифметического выражения (алгоритм Дейкстры) - конкретно, однако здесь - не катит.
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.06.2011, 19:13 7
Цитата Сообщение от volovzi Посмотреть сообщение
return e.print_to_stream(stream);
хорошее решение

Добавлено через 6 минут
Цитата Сообщение от eugrita Посмотреть сообщение
Хотел сначала написать в раздел С для экспертов, но выяснилось- прав не имею.
задача то для экспертов, да

Цитата Сообщение от eugrita Посмотреть сообщение
слава богу. Одно применение нашли.Правда разбор токенов - расплывчато. Вот разбор арифметического выражения (алгоритм Дейкстры) - конкретно, однако здесь - не катит.
что кому надо то? и да, разбор арифметических выражений - вершина достижений computer science
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
06.06.2011, 19:34 8
Цитата Сообщение от alex_x_x Посмотреть сообщение
хорошее решение
Называется "невиртуальный интерфейс" .

Цитата Сообщение от eugrita Посмотреть сообщение
слава богу. Одно применение нашли.Правда разбор токенов - расплывчато. Вот разбор арифметического выражения (алгоритм Дейкстры) - конкретно, однако здесь - не катит.
Ещё раз — это можно использовать в интерпретаторах языков, а значит, и в разборе арифметических выражений.
1
silent_1991
06.06.2011, 19:37
  #9

Не по теме:

Цитата Сообщение от volovzi Посмотреть сообщение
Называется "невиртуальный интерфейс"
Это что-то из разряда паттернов? Не скажете, где можно почитать про эти приёмы?

0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
06.06.2011, 19:41 10
Цитата Сообщение от silent_1991 Посмотреть сообщение

Не по теме:


Это что-то из разряда паттернов? Не скажете, где можно почитать про эти приёмы?

Вот тут хорошо описано:
http://www.insidecpp.ru/patter... interface/
Заодно советую сразу ещё и это прочитать:
http://www.insidecpp.ru/patter... e_pattern/
1
06.06.2011, 19:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.06.2011, 19:41
Помогаю со студенческими работами здесь

Система из 3 неоднородных дифференциальных уравнений
1. Возможно ли в Mathcad решить систему из трех неоднородных дифференциальных уравнений? 2. Какие...

Запись неоднородных данных (Record) в Stream
Здравствуйте, товарищи! Появились трудности с записью Record'а в файловый поток (TStream) Инфы в...

Решение системы неоднородных диф. уравнений
Добрый день! Есть система уравнений для U(x) и I(x), где x-расстояние (см. картинку 1). Эту...

Как в маткаде записать систему 2-х неоднородных ду
y'+5y-7x'-5=0 x''+2x'+3x-9y-10=0


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru