Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 437
#1

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

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

Хотел сначала написать в раздел С для экспертов, но выяснилось- прав не имею.
Есть такая задача (даже несколько разновидностей) дается в Бауманке на 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 тоже редко используется
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.06.2011, 17:27
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Контейнер из неоднородных элементов (C++):

STL контейнер set, вставка элементов - C++
Уважаемые админы.Снова прошу о помощи. Необходимо в множество bred,начиная с позиции n, вставить элементы из множества new_bred. ...

Отсортировать контейнер map по значению элементов - C++
Есть заполненный контейнер unordered_map (ну или просто map) Нужно отсортировать его по значению или сделать сортированный по значению...

Решить систему алгебраических линейных неоднородных уравнени - C++
У меня есть система линейных уравнений. В ней 4000 уравнений. Киньте плиз код для её решения. Желательно, чтобы он был максимально...

Контейнер map с сохранением порядка вставки элементов - C++
Можно ли в контейнере расположить ключи так, чтобы они не были отсортированы в порядке убывания или возрастания. Например я ложу в...

Контейнер map. Осуществить ввод элементов и поиск по ключу - C++
Поиск работает, но как сделать чтобы чтобы можно было вводить элементы с клавиатуры и искать по ключу вводом с клавиатуры? #include...

Сохранить порядок следования элементов используя лишь контейнер <set> - C++
Здравствуйте! Знаю, что при помощи множеств можно исключить повторные вхождения элементов (массива, файла и т.д.), но можно ли сохранить их...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 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/ce305f...2c7af1d306621d
тут конечно ограничение ++'са, что возвращаемое значение должно быть известно на момент компиляции
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 437
06.06.2011, 18:48  [ТС] #3
ну вот еще одна stl-ная реализация. А вопрос без ответа - в каких задачах это применяется?
Явно уважаемые программисты, не имеете опыта руководства дипломниками. Решена задача - а применение подобрать слабо?
Как говорится, дайте мне задачу и как Архимед с помощью этой программной опоры переверну мир
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
06.06.2011, 18:58 #4
eugrita, в вашем чтоли тоже стл был?
пускай будет разбор токенов строки, где токены могу быть разного типа
volovzi
267 / 169 / 8
Регистрация: 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;
}
Зачем это нужно?
Например, для интерпретаторов, в частности, как выше заметили, для разбора строки.
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 437
06.06.2011, 19:05  [ТС] #6
слава богу. Одно применение нашли.Правда разбор токенов - расплывчато. Вот разбор арифметического выражения (алгоритм Дейкстры) - конкретно, однако здесь - не катит.
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
06.06.2011, 19:13 #7
Цитата Сообщение от volovzi Посмотреть сообщение
return e.print_to_stream(stream);
хорошее решение

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

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

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

Не по теме:

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

volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.06.2011, 19:41 #10
Цитата Сообщение от silent_1991 Посмотреть сообщение

Не по теме:


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

Вот тут хорошо описано:
http://www.insidecpp.ru/patterns/nonvirtual_interface/
Заодно советую сразу ещё и это прочитать:
http://www.insidecpp.ru/patterns/cur...plate_pattern/
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2011, 19:41
Привет! Вот еще темы с ответами:

Какой контейнер выбрать (Нужен массив, с возможностью добавления и удаления элементов)? - C++
Привет, народ! Посоветуйте, что лучше использовать. В моей задаче нужен массив, с возможностью добавления и удаления элементов, при...

Динамический контейнер позволяющий хранить произвольное число элементов одного типа - C++
Динамический контейнер позволяющий хранить произвольное число элементов одного типа (например тесовых строк).

В одномерном массиве посчитать сумму элементов до максимального.Оформить через контейнер Vector. - C++
В одномерном массиве посчитать сумму элементов до максимального.Оформить через контейнер Vector Вот код:исправьте пожалуйста а то я...

В одномерном массиве посчитать сумму элементов до последнего нулевого значения. Использовать контейнер - List - C++
не могу сделать...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.06.2011, 19:41
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru