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

Классы, грфы, операции на них - C++

Восстановить пароль Регистрация
 
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
03.04.2013, 22:23     Классы, грфы, операции на них #1
Молю и помощи в написании перегруженного(или как так его правильно-то по-русски) оператора. Умные мужчины(а может и женщины), к вам обращаюсь
суть вот в чем:
есть класс граф, в котором есть подкласс пунктов(вершин), содержащий таблицу пунктов и их соединений(эта бинарная).
Функции типа удаления и добавления к этому всему на месте и работают исправно, а вот перегрузка оператора "+=" замерла, оператор должен добавить один граф ко второму при этом одинаковые вершины объединяются а те которых нет в каком-либо из них, дописываются (по принцыпу наложения одного графа на другой)
- ну не понимаю я как это написать чтоб заработало.
Помогите бабе.. пожалуйста!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2013, 22:23     Классы, грфы, операции на них
Посмотрите здесь:

C++ Классы
целое положительное К, за которым следуют К вещественных чисел. Определите, сколько из них отрицательных. Найдите наибольшее из них. C++
C++ целое положительное К, за которым следуют К вещественных чисел. Определите, сколько из них отрицательных. Найдите наибольшее из них
Задачка на классы (Создать методы, выполняющие поразрядные операции) C++
Битовые операции и операции смещения языка С C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
03.04.2013, 22:45     Классы, грфы, операции на них #2
Покажите код и опишите алгоритм (принцип) наложения графов друг на друга.
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
03.04.2013, 23:00  [ТС]     Классы, грфы, операции на них #3
хэдэр 1
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
#ifndef GRAPH_H_
#define GRAPH_H_
 
 
#include <iostream>
#include "Node.h"
 
using namespace std;
 
class Graf
{
private:
    Node* nodeList[NODENR];//List of verticies
    int size;//number of nodes
public:
    Graf();
    Graf operator+= (Graf& gr);
//------------------------------------------void getsize
    void getsize();
//------------------------------------------inline void addNode
inline void addNode(int nr, char info)
    {
        if (nodeList[nr]== NULL)
            nodeList[nr]=new Node(info);
    }
//-------------------------------------------void addEdge
void addEdge(int org, int dst, int info);
//-------------------------------------------inline bool existnode
inline bool existnote(int nr)
    {
        return nodeList[nr]!=NULL;
    }
//--------------------------------------------deleteNODE
inline void clear(int nr)
{
  if(nodeList[nr]!=NULL)
    delete nodeList[nr];
}
 
//-------------------------------------------destructor
    ~Graf();
 
};
#endif
функции к хэдэру 1
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
#include <iostream>
#include "Node.h"
#include "Graf.h"
 
using namespace std;
 
//---------------------------------------------------------------constuctor
Graf::Graf() : size(0)
{
    for (int i=0; i<NODENR; ++i)
        nodeList[i]=NULL;
}
//---------------------------------------------------------------void addEdge
void Graf::addEdge(int org, int dst, int info)
{
    if (!existnote(org))
        return;
    if (!existnote(dst))
        return;
    nodeList[org]->clear(dst);
    int *ed = new int(info);
    nodeList[org]->addEdge(dst,ed);
    nodeList[dst]->addEdge(org,ed);
}
 
//----------------------------------------------------------------void getsize
void Graf:: getsize()
{
   for (int i=0; i<NODENR; i++)
    if (nodeList[i]!=NULL)
    size++;
}
 
//-----------------------------------------------------------------destructor
Graf::~Graf()
{
    for(int i=0; i<NODENR; ++i)
    {
        if(nodeList[i] == NULL) continue;
        for(int j=i; j<NODENR; ++j)
        {
            if(nodeList[j] == NULL) continue;
            nodeList[i]->clear(j);
        }
        delete nodeList[i];
    }
}
//-------------------------------------------------------------------------------overloaded operator +=
    Graf Graf::operator+= (const Graf& other)
    {
        for (int i=0; i<NODENR; i++)
            if (this->nodeList[i]==other->nodeList[i])
                return *this;
            else if (this->nodeList[i]==NULL && other->nodeList[i]!==NULL)
                this->nodeList[i]=addNode();
 
    }
в конце тут начала, но как-то онон не очень хорошо пошло

хэдэр 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
#ifndef NODE_H_
#define NODE_H_
 
 
#include <iostream>
#define NODENR 200
 
using namespace std;
 
class Node
{
private:
    char info;
    int listsize;
    int* edges[NODENR];
 
public:
    int i;
//----------------------------------------------------constructor
    Node(char i);
 
//----------------------------------------------------inline void clear
    inline void clear(int nr)
    {
        if (edges[nr]!=NULL)
            delete edges[nr];
    }
 
//-----------------------------------------------------inline void addEdge
    inline void addEdge(int dst, char* info)
    {
        edges[dst] = info;
    }
//------------------------------------------------------destructor
    ~Node();
 
};
#endif
Добавлено через 8 минут
блин.. про сложение забыла
вот есть один граф с вершинами a,b,c,d и есть второй с вершинами a,c,d,e,f
все эти вершины могут быть раскиданы где не попадя в таблице, потому что номер ячейки сами вписываем и вот когда складываем эти графы должно остаться a,b,c,d,e,f т.е. те вершины что повторяются становятся одной а те что появляются один раз добавляются ко все куче
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
03.04.2013, 23:28     Классы, грфы, операции на них #4
Цитата Сообщение от MargaretK Посмотреть сообщение
те вершины что повторяются становятся одной а те что появляются один раз добавляются ко все куче
А ребра? А одинаковые ребра с разными весами?
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
03.04.2013, 23:32  [ТС]     Классы, грфы, операции на них #5
а рёбра.. блин.. не продумала.. хм.. да как проще.. только бы разделаться с этим всем... 3 недели убила
удалить наверное пока складываем, там же не указывается длина, просто они или есть или их нет
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.04.2013, 09:16     Классы, грфы, операции на них #6
Так, по сути, граф представляет из себя множество вершин и ребер.
Таким образом, слияние графов должно представлять из себя объединение множеств. Таким образом, в графе могут появиться параллельные ребра, если они одинаково направлены, имеют одинаковые вершины и разные веса.

Ниже представлен граф, представляющий собой множество ребер. Недостаток -- невозможно добавить вершину без ребер, но это легко обходится при фактической работе с таким графом.
Реализация множества на основе динамического массива и бинарного поиска по нему. Довольно простой концепт. Надеюсь вам это по зубам.
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <iostream>
#include <iomanip>
#include <istream>
#include <cmath>
#include <ctime>
#include <cstdlib>
 
struct Vertex {
  std::string name;
  Vertex() : name("") {}
  Vertex(const std::string &name) : name(name) {}
};
 
// сравнение вершин
bool operator<(const Vertex &a, const Vertex &b) {
  return a.name < b.name;
};
 
// для простоты, вывод вершины
std::ostream &operator<<(std::ostream &stream, const Vertex &v) {
  return stream << "Vertex{" <<
    "name='" << v.name << "'}";
};
 
struct Edge {
  Vertex begin, end;
  double weight;
  Edge() {}
  Edge(const Vertex &begin, const Vertex &end, double weight)
    : begin(begin), end(end), weight(weight) {}
};
 
// для простоты, вывод ребра
std::ostream &operator<<(std::ostream &stream, const Edge &e) {
  return stream << "Edge{" <<
    "begin=" << e.begin << "," <<
    "end=" << e.end << "," <<
    "weight=" << std::fixed << std::setprecision(3) << e.weight << "}";
};
 
// сравнение ребер
bool operator<(const Edge &a, const Edge &b) {
  if (a.begin < b.begin) {
    return true;
  } else if ((!(b.begin < a.begin)) && a.end < b.end) {
    return true;
  } else if ((!(b.begin < a.begin)) && (!(b.end < a.end))) {
    return a.weight < b.weight;
  } else {
    return false;
  }
};
 
// бинарным поиском находит первый элемент, не меньший заданного
template <class ForwardIterator, class T>
ForwardIterator lowerBound (ForwardIterator first, ForwardIterator last,
  const T& val) {
  size_t count = last - first;
  while (count > 0) {
    ForwardIterator it = first;
    size_t step = count / 2;
    it += step;
    if (*it<val) {
      first = ++it;
      count -= step + 1;
    }
    else count = step;
  }
  return first;
}
 
// собственно, граф, заданный ребрами
class EdgeListGraph {
 public:
  EdgeListGraph() : size(0), capacity(10), capacityIncrement(10),
    edges(new Edge[capacity]) {}
  virtual ~EdgeListGraph() {
    delete [] edges;
  }
  void addEdge(const Edge &edge) {
    makeSureCapacityIsEnough();
    Edge *position = lowerBound(edges, edges + size, edge);
    if (position >= edges + size || edge < *position) {
      for (Edge *i = edges + size; i > position; --i) {
        *i = *(i - 1);
      }
      *position = edge;
      ++size;
    }
  }
  void addBidirectionalEdge(const Edge &edge) {
    addEdge(edge);
    addEdge(Edge(edge.end, edge.begin, edge.weight));
  }
  void removeEdge(const Edge &edge) {
    Edge *position = lowerBound(edges, edges + size, edge);
    if (position >= edges + size || edge < *position) {
      // нет такого элемента
      // возможно, стоит кинуть ошибку?
    } else {
      for (Edge *i = position; i < edges + size; ++i) {
        *i = *(i + 1);
      }
      --size;
    }
  }
  const Edge *begin() const { return edges; }
  const Edge *end() const { return edges + size; }
  void clear() {
    delete [] edges;
    capacity = capacityIncrement;
    edges = new Edge[capacity];
    size = 0;
  }
  int getSize() const { return size; }
  void addEdges(const EdgeListGraph &g) {
    for (const Edge *i = g.begin(); i != g.end(); ++i) {
      addEdge(*i);
    }
  }
 protected:
  void makeSureCapacityIsEnough() {
    if (size - 1 >= capacity) {
      capacity += capacityIncrement;
      Edge *newEdges = new Edge[capacity];
      for (int i = 0; i < size; ++i) {
        newEdges[i] = edges[i];
      }
      delete [] edges;
      edges = newEdges;
    }
  }
 private:
  // запрет копирования:
  EdgeListGraph(const EdgeListGraph &); // конструктором копирования
  EdgeListGraph &operator=(const EdgeListGraph&); // присваиванием
  int size;
  int capacity;
  int capacityIncrement;
  Edge *edges;
};
 
std::ostream &operator<<(std::ostream &stream, const EdgeListGraph &g) {
  stream << "EdgeListGraph{size=" << g.getSize() << ",Edges=[";
  for (const Edge *i = g.begin(); i != g.end(); ++i) {
    stream << std::endl << "    " << *i;
  }
  return stream << "]}";
};
 
EdgeListGraph &operator+=(EdgeListGraph &a, const EdgeListGraph &b) {
  a.addEdges(b);
  return a;
}
 
int main(int argc, char *argv[]) {
  srand(time(0));
 
  EdgeListGraph a;
  a.addBidirectionalEdge(Edge(Vertex("a"), Vertex("b"), 1));
  a.addBidirectionalEdge(Edge(Vertex("a"), Vertex("c"), 1));
  a.addEdge(Edge(Vertex("b"), Vertex("d"), 0.5));
  a.addBidirectionalEdge(Edge(Vertex("c"), Vertex("d"), 1));
  std::cout << a << std::endl;
 
  EdgeListGraph b;
  b.addEdge(Edge(Vertex("a"), Vertex("b"), 1.3));
  b.addBidirectionalEdge(Edge(Vertex("a"), Vertex("c"), 1));
  b.addEdge(Edge(Vertex("b"), Vertex("c"), 0.5));
  std::cout << b << std::endl;
 
  EdgeListGraph c;
  c += a;
  c += b;
  std::cout << c << std::endl;
 
  std::cin.get();
  return 0;
}
Какая у вас вообще задача? Просто хранить графы?
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
04.04.2013, 09:46  [ТС]     Классы, грфы, операции на них #7
исходя из предыдущего кода можно сделать вывод что мне запрещено использовать стригни и прочие дополнительные библиотеки и да это запрещено
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
04.04.2013, 09:59     Классы, грфы, операции на них #8
MargaretK, Вам дали пример кода. Переписать его с учетом ограничений для вас не должно составить проблем.
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
04.04.2013, 10:21  [ТС]     Классы, грфы, операции на них #9
в то-то и проблема что состоявляет, не составило бы проблем - не написала бы сюда..
это первое что я пишу с ++ - такой вот нежданчик от препода
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.04.2013, 11:39     Классы, грфы, операции на них #10
Цитата Сообщение от MargaretK Посмотреть сообщение
это первое что я пишу с ++ - такой вот нежданчик от препода
Зачем вы пытаетесь ввести в заблуждение? Всем и так, заранее, пофигу, что вы забили на семестр-другой.

Цитата Сообщение от MargaretK Посмотреть сообщение
исходя из предыдущего кода можно сделать вывод что мне запрещено использовать стригни и прочие дополнительные библиотеки и да это запрещено
Такое обращение как минимум не вежливо. Вы не удосужились сформулировать даже задачу, а теперь выкатываете какие-то нелепые предъявы.

Какое мне дело, что вам запрещено носить трусы с веревочками и посещать библиотеки?! Мне абсолютно наплевать. Я вам дал пример кода. Не можете подогнать под требование сами -- либо вежливо попросите, либо посещайте исправно предмет.
MargaretK
0 / 0 / 0
Регистрация: 28.12.2012
Сообщений: 6
04.04.2013, 11:49  [ТС]     Классы, грфы, операции на них #11
Цитата Сообщение от lemegeton Посмотреть сообщение
Зачем вы пытаетесь ввести в заблуждение? Всем и так, заранее, пофигу, что вы забили на семестр-другой.
я на первом семетре и далеко не информатики, а физики и вот есть у нас пердмет в программе которого четко сказанно - язык С - препод по лабораториям*(я не знаю как еще назвать эти уроки по-русски) решил сразу дать с++. Я никогда не программировала ни в одном языке раньше и мне дико тяжело адаптироваться к этому всему. И мне дико стыдно, что я не понимаю как написать это всё. Никакой грубости выражать я не собиралась и прошу прощения если кому-то так показалось. Ниодной пары я еще не пропустила, но на лекциях нам продолжают рассказывать о великолепном языке с. К тому же сегодня адский день с тремя контрольными и конечным сроком отдачи этого проекта дурацкого. Поэтому я очень прошу о помощи!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2013, 13:08     Классы, грфы, операции на них
Еще ссылки по теме:

C++ Классы
C++ Классы: перегрузка операции "Бинарный +"
Битовые операции. Где о них можно почитать? C++

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

Или воспользуйтесь поиском по форуму:
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.04.2013, 13:08     Классы, грфы, операции на них #12
Какие у вас ограничения? С сишными строками подойдет?
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <iostream>
#include <iomanip> // это для форматирования вывода
#include <cstring>  // это для работы с сишными строками
 
class Vertex {
 public:
  Vertex() : name(new char[1]) { name[0] = '\0'; }
  Vertex(const char *name) : name(0) { setName(name); }
  Vertex(const Vertex &other) : name(0) { setName(other.getName()); }
  virtual ~Vertex() { delete [] name; }
  Vertex &operator=(const Vertex &other) {
    if (this != &other) {
      setName(other.getName());
    }
    return *this;
  }
  const char *getName() const { return name; }
  void setName(const char *name) {
    delete [] this->name;
    this->name = strcpy(new char[strlen(name) + 1], name);
  }
 private:
  char *name;
};
 
// сравнение вершин
bool operator<(const Vertex &a, const Vertex &b) {
  return strcmp(a.getName(), b.getName()) < 0;
};
 
// для простоты, вывод вершины
std::ostream &operator<<(std::ostream &stream, const Vertex &v) {
  return stream << "Vertex{" <<
    "name='" << v.getName() << "'}";
};
 
struct Edge {
  Vertex begin, end;
  double weight;
  Edge() {}
  Edge(const Vertex &begin, const Vertex &end, double weight)
    : begin(begin), end(end), weight(weight) {}
};
 
// для простоты, вывод ребра
std::ostream &operator<<(std::ostream &stream, const Edge &e) {
  return stream << "Edge{" <<
    "begin=" << e.begin << "," <<
    "end=" << e.end << "," <<
    "weight=" << std::fixed << std::setprecision(3) << e.weight << "}";
};
 
// сравнение ребер
bool operator<(const Edge &a, const Edge &b) {
  if (a.begin < b.begin) {
    return true;
  } else if ((!(b.begin < a.begin)) && a.end < b.end) {
    return true;
  } else if ((!(b.begin < a.begin)) && (!(b.end < a.end))) {
    return a.weight < b.weight;
  } else {
    return false;
  }
};
 
// бинарным поиском находит первый элемент, не меньший заданного
Edge *lowerBound (Edge *first, Edge *last, const Edge &val) {
  size_t count = last - first;
  while (count > 0) {
    Edge *it = first;
    size_t step = count / 2;
    it += step;
    if (*it<val) {
      first = ++it;
      count -= step + 1;
    }
    else count = step;
  }
  return first;
}
 
// собственно, граф, заданный ребрами
class EdgeListGraph {
 public:
  EdgeListGraph() : size(0), capacity(10), capacityIncrement(10),
    edges(new Edge[capacity]) {}
  virtual ~EdgeListGraph() {
    delete [] edges;
  }
  void addEdge(const Edge &edge) {
    makeSureCapacityIsEnough();
    Edge *position = lowerBound(edges, edges + size, edge);
    if (position >= edges + size || edge < *position) {
      for (Edge *i = edges + size; i > position; --i) {
        *i = *(i - 1);
      }
      *position = edge;
      ++size;
    }
  }
  void addBidirectionalEdge(const Edge &edge) {
    addEdge(edge);
    addEdge(Edge(edge.end, edge.begin, edge.weight));
  }
  void removeEdge(const Edge &edge) {
    Edge *position = lowerBound(edges, edges + size, edge);
    if (position >= edges + size || edge < *position) {
      // нет такого элемента
      // возможно, стоит кинуть ошибку?
    } else {
      for (Edge *i = position; i < edges + size; ++i) {
        *i = *(i + 1);
      }
      --size;
    }
  }
  const Edge *begin() const { return edges; }
  const Edge *end() const { return edges + size; }
  void clear() {
    delete [] edges;
    capacity = capacityIncrement;
    edges = new Edge[capacity];
    size = 0;
  }
  int getSize() const { return size; }
  void addEdges(const EdgeListGraph &g) {
    for (const Edge *i = g.begin(); i != g.end(); ++i) {
      addEdge(*i);
    }
  }
 protected:
  void makeSureCapacityIsEnough() {
    if (size - 1 >= capacity) {
      capacity += capacityIncrement;
      Edge *newEdges = new Edge[capacity];
      for (int i = 0; i < size; ++i) {
        newEdges[i] = edges[i];
      }
      delete [] edges;
      edges = newEdges;
    }
  }
 private:
  // запрет копирования:
  EdgeListGraph(const EdgeListGraph &); // конструктором копирования
  EdgeListGraph &operator=(const EdgeListGraph&); // присваиванием
  int size;
  int capacity;
  int capacityIncrement;
  Edge *edges;
};
 
std::ostream &operator<<(std::ostream &stream, const EdgeListGraph &g) {
  stream << "EdgeListGraph{size=" << g.getSize() << ",Edges=[";
  for (const Edge *i = g.begin(); i != g.end(); ++i) {
    stream << std::endl << "    " << *i;
  }
  return stream << "]}";
};
 
EdgeListGraph &operator+=(EdgeListGraph &a, const EdgeListGraph &b) {
  a.addEdges(b);
  return a;
}
 
int main(int argc, char *argv[]) {
  EdgeListGraph a;
  a.addBidirectionalEdge(Edge(Vertex("a"), Vertex("b"), 1));
  a.addBidirectionalEdge(Edge(Vertex("a"), Vertex("c"), 1));
  a.addEdge(Edge(Vertex("b"), Vertex("d"), 0.5));
  a.addBidirectionalEdge(Edge(Vertex("c"), Vertex("d"), 1));
  std::cout << a << std::endl;
 
  EdgeListGraph b;
  b.addEdge(Edge(Vertex("a"), Vertex("b"), 1.3));
  b.addBidirectionalEdge(Edge(Vertex("a"), Vertex("c"), 1));
  b.addEdge(Edge(Vertex("b"), Vertex("c"), 0.5));
  std::cout << b << std::endl;
 
  EdgeListGraph c;
  c += a;
  c += b;
  std::cout << c << std::endl;
 
  std::cin.get();
  return 0;
}
Yandex
Объявления
04.04.2013, 13:08     Классы, грфы, операции на них
Ответ Создать тему
Опции темы

Текущее время: 18:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru