Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
1

Создать массив с n-ым количеством измерений

27.09.2016, 06:44. Показов 4176. Ответов 54
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет,

Задали мне в универе проект и я не могу никак с ним разобратся. Суть: задается в cin по шаблону (тип в скобках) имя массива (string) количество измерений dim (int) количество елементов в каждом измерении(лист intoв через комму) цифры которые нужно поместить в массив, через комму. Получается что-то такое А 2 2,3 1,2,3,4,5,6 - создает двухмерную матрицу 2 строки 3 столбца. B 3 3, 2, 3 ... - трехмерную матрицу 3 на 2 на 3. Если dim = 1 создается вектор, 0 - скаляр.

Проблема заключается в том,что моя программа должна работать для любого номера измерений. Тоесть при dim =4 должна получатся 4х-мерная матрица, при 5 - 5-мерная и так далее. Я мог бы написать код для каждого случая отдельно если б я знал что максимум измерений будет 5,например. Но я не знаю,сколько их будет. Собственно мой вопрос: возможно ли написать код который создаст n-размерную матрицу, в зависимости от значение которое пользователь введет? Я чувствую,что есть какой-то способ это сделать.. Но не могу додуматся какой)

Помогите пожалуйста.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.09.2016, 06:44
Ответы с готовыми решениями:

Создать массив с неизвестным количеством ячеек
Мне надо создать массив из неизвестного количества ячеек, а потом туда набрасывать разное...

Как создать массив с неизвестным количеством элементов
Товарищи, скажите пожалуйста можно ли как-то сделать массив (НЕ КОЛЛЕКЦИИ), с неизвестным...

Создать с помощью new динамический массив с указанным количеством элементов
Так как пока что я учусь самостоятельно у меня нету проверяющего, поэтому прошу вас посмотреть все...

Создать динамический массив с количеством элементов, которое вводит пользователь
Пользователь вводит размерность массива и его элементы. Создать динамический массив с количеством...

54
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
27.09.2016, 17:30  [ТС] 21
Author24 — интернет-сервис помощи студентам
Ну я понимаю, но в мейне у вас 3 цикла для 3хмерного массива, и я не понимаю как их адаптировать к любому количеству изменений
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
27.09.2016, 17:33 22
Цитата Сообщение от Invader0x7F Посмотреть сообщение
Мой вариант - это единственный правильный вариант решения данной задачи
А вот так не надо, пожалуйста. Такие слова надо обосновывать. А обосновать их ой как трудно!
Могу даже предположить, что понятие единственно правильного существует только в политике. И то только потому, что вся политика построена на лжи.
0
Helper C/C++
286 / 163 / 122
Регистрация: 22.09.2016
Сообщений: 518
27.09.2016, 17:35 23
На циклы внимания не обращать:

C++
1
2
3
4
5
6
7
8
int dimensions = 3;
ndspace<int, int> nds(dimensions);
    
const int val = 999;
 
std::vector<int> ix_args = { 3, 1, 7 };
 
ndspace[ix_args] = val;
Данный код присваивает элементу с индексами 3,1,7 n-мерного массива ndsspace значение val.

Это то же самое, что и m[3][1][7] = 999, если использовать возможности компилятора;

Так понятно ??
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
27.09.2016, 17:35 24
Цитата Сообщение от kozo Посмотреть сообщение
Байт, а можете показать как
Подождите чуток. Не хотел ввязываться, да задело.
Там тоже не все так просто.
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
27.09.2016, 18:14  [ТС] 25
Хорошо, буду ждать
0
Helper C/C++
286 / 163 / 122
Регистрация: 22.09.2016
Сообщений: 518
27.09.2016, 18:29 26
Слегка упростил код. Вот что получилось:

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
#include <stack>
#include <string>
#include <cstdlib>
#include <clocale>
#include <iostream>
 
using namespace std;
 
#include <map>
#include <string>
#include <iostream>
 
using std::map;
 
template<typename T1 = int>
class ndspace : public std::map<std::string, T1>
{
    private:
        std::map<std::string, T1>* m_pndmap;
 
    public:
        ndspace() { m_pndmap = this; };
        ~ndspace() { m_pndmap = nullptr; }
 
        void show()
        {
            for (auto it = m_pndmap->begin(); it != m_pndmap->end(); it++)
            {
                std::string indexes = it->first;
                std::cout << indexes;
 
                std::cout << " => " << it->second << std::endl;
            }
        }
 
    public:
        T1& operator[](const std::string& indexes)
        {
            m_pndmap->insert(std::make_pair(indexes, -1));
            return m_pndmap->at(indexes);
        }
};
 
const int N[] = { 3, 4, 5 };
 
int main()
{
    ndspace<int> nds;
 
    int n = 0;
    for (int i1 = 0; i1 < N[0]; i1++)
        for (int i2 = 0; i2 < N[1]; i2++)
            for (int i3 = 0; i3 < N[2]; i3++)
            {
                string s_key = "\0";
                s_key.append(std::to_string(i1) + ",");
                s_key.append(std::to_string(i2) + ",");
                s_key.append(std::to_string(i3));
 
                nds[s_key] = n++;
            }
 
    nds.show();
 
    std::cin.get();
    std::cin.get();
 
    return 0;
}
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
27.09.2016, 18:36  [ТС] 27
Сейчас еще более непонятно получилось.... А где dimensions теперь? И что n=0 в мейне делает?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
27.09.2016, 18:40 28
Цитата Сообщение от kozo Посмотреть сообщение
буду ждать
Ну вот, в спешке навалял кое-что. Возможны ошибки, и вообще это псевдокод и демонстрация идеи
Кликните здесь для просмотра всего текста

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
// Можно я без классов. По старинке...
#include <stdio.h>
#include <stdlib.h>
 
typedef struct {  // Описание массива
  int N;  // Кол-во измерений
  int *D;  // Размер по каждому
  double *M; // Значения элементов
} MAS;
 
MAS *Create(int n) // Создание
{int i;
   MAS *mas = (MAS *)malloc(sizeof(MAS));
   mas->N = n;
   mas->D = (int *)malloc(mas->N*sizeof(int));
   for(i=0; i<mas->N; i++) mas->D[i] = 0;
   mas->M = NULL;
   return mas;
}
void setD(MAS *mas, int k, int d) // Установка размера по k-ому измерению
{
   if (k<0 || k>= mas->N) return;
   mas->D[k] = d;
}
int CreatVal(MAS *mas)  // Создатие массива значений с обнулением
{ int i, X;
   for(i=0; i<mas->N; i++) if (mas->D[i]==NULL) return(-1); // Рано еще.
               // Не все размеры установлены
   for(X=1, i=0; i<mas->N; i++) X *= mas->D[i];  // Вычисление объема
   mas->M = (double *)malloc(X*sizeof(double));
   for(i=0; i<X; i++) mas->M[i] = 0;
   return X;
}
// Происходит вычисление pos - места в развернутом одномерном массиве M
// элемента с многомерным индексом [dd[0]][dd[1]] ...[[dd[N-1]]
// и присвоение ему значения val
// ...Тут мог и попутать в арифметике, но, надеюсь, идея понятна...
void setVal(MAS *mas, int *dd, double val)
{ int i, j, pos, x;
   for(i=0, pos=0; i<mas->N-1; i++) {
     for(j=0, x=1; j<=i; j++) x *= mas->D[j];
     pos += dd[i]*x;
   }
   pos += dd[mas->N-1];
   mas->M[pos] = val;
}
int main()
{ int i, j, dd[] = {2,3,2,4,2 };  // Размеры по измерениям
  MAS *ms[3]; int X[3];
 
 for (i=0; i<3; i++) { // создаем 3 массива (5-мерных)
   ms[i] = Create(5);
   for(j=0; j<5; j++) setD(ms[i], j, dd[j]);
   X[i] = CreatVal(ms[i]);
 }
 // Даем значения элементам массивов функцией setVal или просто заполняем
 // массивы ms[0]->M, ms[1]-M
 for(i=0; i<X[0]; i++) ms[2]->M[i] = ms[0]->M[i] + ms[1]->M[i]; // Это сложение
  // Другие действия (какие?, конечно, посложнее будут...
 return 0;
}

Сейчас меня ждут другие великие дела.
Буду рад услышать ваши замечания.
Повторяю - проект не закончен.
0
Helper C/C++
286 / 163 / 122
Регистрация: 22.09.2016
Сообщений: 518
27.09.2016, 18:43 29
n - это переменная счетчик, каждое значение которой присваивается элементу многомерного массива. Напр.: nds[2,3,1] = n;

Далее, в данному примере, количество измерений dimensions не принципиально. Вы просто формируете строку std::string а не массив std::vector. В строку записываются данные в следующем формате: string s_args = "2,3,1" - это эквивалентно nds[2][3][1] = n трехмерного массива созданного на уровне компилятора.

Добавлено через 1 минуту
Байт, в данном случае Вы как и я допускаете принципиальную ошибка усложняя код. (см. мой пример выше).
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
27.09.2016, 19:19  [ТС] 30
Спасибо за помощь. Приду домой - попробую оба варианта.

Байт, операции стандартные + - * / % а также max и min. Они будут сложнее?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
27.09.2016, 19:48 31
Цитата Сообщение от kozo Посмотреть сообщение
операции стандартные + - * / % а также max и min.
Умножение в каком смысле? Если поэлементное, то ничем не сложнее сложения. А если как матриц... Правда, я не знаю как умножаются матрицы размерности больше двух
Вообще все поэлементные операции так же просты, как и сложение.
Цитата Сообщение от Invader0x7F Посмотреть сообщение
Байт, в данном случае Вы как и я допускаете принципиальную ошибка усложняя код.
Возможно. Как я уже сказал, делал впопыхах. Уже вижу более простые, понятные и безопасные конструкции.
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
28.09.2016, 04:30  [ТС] 32
Цитата Сообщение от Байт Посмотреть сообщение
Умножение в каком смысле? Если поэлементное, то ничем не сложнее сложения. А если как матриц... Правда, я не знаю как умножаются матрицы размерности больше двух
Вообще все поэлементные операции так же просты, как и сложение.Возможно. Как я уже сказал, делал впопыхах. Уже вижу более простые, понятные и безопасные конструкции.
Invader: ваша программа не работает если изменить колличество dimensions либо N

Байт, до меня, вроде бы, доходит. Но можете подробнее свой код описать? Например у меня есть массив значений для двухмерной матрицы размерами 2х3: 1,2,3,4,5,6. Если я использую create(2) с вашего кода, то создам двухмерный массив, но как мне потом эти значения перевести в него на правильные места? Меня еще очень запутывает то, какая переменная у вас за что отвечает. Если вы б могли уточнить - был бы оочень благодарен
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2016, 06:38 33
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
///////////////////////////////////////////////////////////////////////////////
//3.
///////////////////////////////////////////////////////////////////////////////
//задается в cin по шаблону (тип в скобках) имя массива (string)
//количество измерений dim (int) количество елементов в каждом
//измерении(лист intoв через комму) цифры которые нужно поместить в массив,
//через комму. Получается что-то такое А 2 2,3 1,2,3,4,5,6 - создает
//двухмерную матрицу 2 строки 3 столбца.
//B 3 3, 2, 3 ... - трехмерную матрицу 3 на 2 на 3.
//Если dim = 1 создается вектор, 0 - скаляр.
///////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
typedef std::string                     T_str;
typedef std::vector     < size_t    >   T_dimensions;
typedef std::vector     < int       >   T_values;
///////////////////////////////////////////////////////////////////////////////
const   char    COMMA_SYMB  {','};
const   char    SPACE_SYMB  {' '};
///////////////////////////////////////////////////////////////////////////////
class   T_matr
{
    //-------------------------------------------------------------------------
    T_dimensions    dimensions_;
    T_values        values_;
    //-------------------------------------------------------------------------
public:
    //-------------------------------------------------------------------------
    T_matr
        (
            T_dimensions    const   &   dimensions,
            T_values        const   &   values
        )
        :
        dimensions_     ( dimensions    ),
        values_         ( values        )
    {}
    //-------------------------------------------------------------------------
    T_matr( T_str   s )
    {
        std::replace
            (
                s.begin     (),
                s.end       (),
                COMMA_SYMB,
                SPACE_SYMB
            );
 
        std::istringstream  istr(s);
        int     n{};
        istr    >>  n;
 
        dimensions_.resize      (n);
        int     values_count    {1};
 
        for( auto   &   dim     :   dimensions_ )
        {
            istr    >>  dim;
            values_count    *=  dim;
        }
 
        values_.resize( values_count );
        for( auto   &   val     :   values_ )
        {
            istr    >>  val;
        }
    }
    //-------------------------------------------------------------------------
    int     &   operator()
        (
            std::initializer_list< size_t >     indexes     =   {}
        )
    {
        if  (
                    indexes     .size   ()
                !=  dimensions_ .size   ()
            )
        {
            throw   std::invalid_argument
                        (
                                T_str(__FUNCTION__)
                            +   ": incorrect number of indexes in argument"
                        );
        }//if
 
        size_t  shift{};
 
        if  (
                indexes.size()
            )
        {
            auto    it_start    =   indexes.begin();
            shift               =   *it_start;
            ++it_start;
            size_t  dim_ind{1};
 
            for (
                    auto
                    indexes_it  =   it_start;
                    indexes_it  !=  indexes.end();
                    ++indexes_it, ++dim_ind
                )
            {
                shift   *=  dim( dim_ind );
                shift   +=  *indexes_it;
            }
        }//if
 
        return  values_.at( shift );
    }
    //-------------------------------------------------------------------------
    size_t  dim( size_t     ind )
    {
        return  dimensions_.at( ind );
    }
    //-------------------------------------------------------------------------
};
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_str   s;
    //getline( std::cin,  s );
 
    s   =   "3 2,3,4 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24";
 
    T_matr  matr(s);
 
    for( size_t  i{}; i < matr.dim(0); ++i )
    {
        for( size_t  j{}; j < matr.dim(1); ++j )
        {
            for( size_t  k{}; k < matr.dim(2); ++k )
            {
                std::cout   <<  matr({i, j, k})  <<  '\t';
            }
 
            std::cout   <<  std::endl;
        }//for
 
        std::cout   <<  std::endl;
    }//for
 
    matr({0, 0, 0})     =   1000;
    std::cout   <<  matr({0, 0, 0})     <<  std::endl;
 
 
    s   =   "0  15";
    T_matr  matr_scalar(s);
    std::cout   <<  matr_scalar()  <<  std::endl;
 
 
    s   =   "1  6   10,20,30,40,50,60";
    T_matr  matr_vect(s);
    for( size_t  i{}; i < matr_vect.dim(0); ++i )
    {
        std::cout   <<  matr_vect({i})  <<  '\t';
    }
    std::cout   <<  std::endl;
 
 
    std::cout   <<  "\n\nDemonstration of exceptions when wrong function calls:"  <<  std::endl;
    try
    {
        std::cout   <<  matr_scalar({10, 20, 30})  <<  std::endl;
    }
    catch( std::exception   &   e )
    {
        std::cout   <<  e.what()    <<  std::endl;
    }
 
 
    try
    {
        std::cout   <<  matr_vect({1000})  <<  '\t';
    }
    catch( std::exception   &   e )
    {
        std::cout   <<  e.what()    <<  std::endl;
    }
}
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
28.09.2016, 07:56  [ТС] 34
Mr.X Спасибо, попробую ваш код и отпишусь!

Байт можете еще рассказать как именно ваша функция setVal устанавливает значения в массиве? Например мне нужно создать 2хмерный 2х3 массив, и у меня есть 6 значений который должны в нем быть (1,2,3,4,5,6) - куда мои значения идут в вашей функции? И как мне потом получить индекс к каждому из элементов?

Напоследок хотел бы показать код, который я написал для 3х измерений максимум
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
#include <iostream>
#include <string>
#include <vector>
 
using namespace std;
 
class Array { //объект массива
    private: 
        unsigned int numDim;
        vector<int> dimSize;
        int D0; //для скаляра
        vector<int> D1; //для вектора
        vector<vector<int> > D2; //2хмерная матрица
        vector<vector<vector<int> > > D3; //3мерная
    public:
        Array(int Dnum, int value) { //конструктор для скаляра
            int D0 = value;
            numDim = Dnum;
        }
    //для всего остального
        Array(int Dnum, vector<int> Dsize, vector<int>  values) {
 
            numDim = Dnum;
            dimSize = Dsize;
            switch(Dnum) {
                case 1: //1мерный
                    D1 = values;
                    break;
                case 2: //2мерный
                    {
                    vector<int> newCol;
                    int count = 0;  
                    for (int i = 0; i<dimSize.at(0); i++) {
                        for (int j = 0; j<dimSize.at(1); j++) {
                                newCol.push_back(values.at(count));
                                count++;
                                }
                        D2.push_back(newCol);
                        newCol.clear();
                        }
                    break;
                    }
                case 3: //3мерный
                    {
                    vector<int> newCol1;
                    vector<vector<int> > newCol2;
                    int count = 0;
                    
                    for (int i=0; i<dimSize.at(0); i++) {
                        for (int j = 0; j<dimSize.at(1); j++) {
                            for (int k = 0; k<dimSize.at(2); k++) {
                                newCol1.push_back(values.at(count));
                                count++;
                            }
                        newCol2.push_back(newCol1);
                        newCol1.clear();
                        }
                        D3.push_back(newCol2);
                        newCol2.clear();
                    }
                    break;
                    }
            
 
 
 
 
            }
        }
 
        void Print() {
            for (int i = 0; i<dimSize.at(0); i++) {
                for(int j = 0; j<dimSize.at(1); j++) {
                    for(int k = 0; k<dimSize.at(2); k++) {
 
                    cout<<D3.at(i).at(j).at(k)<<endl;
                }
            }
        }
        }
};
            
 
int main() 
{
 
 
    Array a(Dn, siz, val);
    a.Print();
 
    return 0;
}
Как видите, мне нужно писать код для каждого измерения. Чем больше измерений, тем больше for циклов нужно писать. И я не могу понять как можно по другому это все сделать... Надеюсь один из тех вариантов что в этой теме показали мне помогут
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
28.09.2016, 10:40 35
Цитата Сообщение от kozo Посмотреть сообщение
Как видите, мне нужно писать код для каждого измерения. Чем больше измерений, тем больше for циклов нужно писать.
Это не дело, конечно. Мой подход как раз позволяет этого избежать. Я немного модифицировал свой код. Сделал его естественнее, что-ли. Может быть будет понятнее. Подожди немного...

Добавлено через 5 минут
Идея в том, чтобы "вытянуть" многомерный массив в одномерный. Собственно, так и поступает транслятор. Когда он видит mas[2][3] = { {1,2,3}, {4,5,6}} он его фактически заменяет на m[6] = { 1, 2, 3, 4, 5, 6 };
И вместо mas[i][j] берет m[3*i+j]

Добавлено через 10 минут
Кликните здесь для просмотра всего текста
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
// 28.09.2016
#include <stdio.h>
#include <stdlib.h>
 
typedef struct {  // Описание массива
  int N;  // Кол-во измерений
  int *D;  // Размер по каждому
  int *X;  // Произведения размеров
  double *M; // Значения элементов
} MAS;
 
MAS *Create(int n, int *d) // Создание (d - вектор размеров)
{int i, p, R;
   MAS *mas = (MAS *)malloc(sizeof(MAS));
   mas->N = n;
   mas->D = (int *)malloc(mas->N*sizeof(int));
   for(i=0, p=1; i<n; i++) {
     mas->D[i] = d[i];
     mas->X[n-i-1] = p;  // Размеры "слоев"
     p *= d[i];
   }
   R = mas->X[0];  // Полный размер массива
   mas->M = (double *)mallos(R*sizeof(double));
   for(i=0; i<R; i++) mas->M[i] = NULL;
   return mas;
}
// Происходит вычисление pos - места в развернутом одномерном массиве M
// элемента с многомерным индексом [dd[0]][dd[1]] ...[[dd[N-1]]
// и присвоение ему значения val
// ...Тут мог и попутать в арифметике, но, надеюсь, идея понятна...
void setVal(MAS *mas, int *dd, double val)
{ int i, pos;
   for(i=0, pos=0; i<mas->N; i++)
     pos += dd[i]*mas->X[i];
   mas->M[pos] = val;
}
int main()
{ int i, dd[] = {2,3,2,4,2 };  // Размеры по измерениям
  MAS *ms[3];
 
 for (i=0; i<3; i++) // создаем 3 массива (5-мерных)
   ms[i] = Create(5, dd);
 // Даем значения элементам массивов функцией setVal или просто заполняем
 // массивы ms[0]->M, ms[1]->M
 for(i=0; i<ms[0]->X[ms[0]->N-1]; i++) ms[2]->M[i] = ms[0]->M[i] + ms[1]->M[i]; // Это сложение
  // Другие поэлементные действия столь же просты
 return 0;
}


Добавлено через 54 секунды
Это для 5-мерного массива

Добавлено через 15 минут
А это для твоего примерчика 2 х 3
C++
1
2
3
4
5
6
7
8
9
10
11
int main()
{ int i, dd[] = {2,3};   // Размеры по измерениям
  int ii[2] = { 0, 0 };  // Массив индексов
  MAS *ms;
 
 ms = Create(2, dd); // создаем массив
 for(i=0; i<2*3; i++) ms->M[i] = i+1;  // "Простое" заполнение
 ii[0] = 1; ii[1] = 2;  // "Научное" Заполнение элемента [1][2]
 setVal(ms, ii, 6 );
 return 0;
}
Для полноты картины надо еще функцию double getVal(VFS *mas, int *ii) , но она совершенно аналогична setVal
Не проверял. Возможны ошибки. Буду благодарен за их обнаружение (а еще больше - за исправление)
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2016, 12:59 36
Реализовал функцию print:
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
///////////////////////////////////////////////////////////////////////////////
//4.
///////////////////////////////////////////////////////////////////////////////
//задается в cin по шаблону (тип в скобках) имя массива (string)
//количество измерений dim (int) количество елементов в каждом
//измерении(лист intoв через комму) цифры которые нужно поместить в массив,
//через комму. Получается что-то такое А 2 2,3 1,2,3,4,5,6 - создает
//двухмерную матрицу 2 строки 3 столбца.
//B 3 3, 2, 3 ... - трехмерную матрицу 3 на 2 на 3.
//Если dim = 1 создается вектор, 0 - скаляр.
///////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
typedef std::string                     T_str;
typedef std::vector     < size_t    >   T_dimensions;
typedef T_dimensions                    T_indexes;
typedef std::vector     < int       >   T_values;
///////////////////////////////////////////////////////////////////////////////
const   char    COMMA_SYMB  {','};
const   char    SPACE_SYMB  {' '};
///////////////////////////////////////////////////////////////////////////////
class   T_matr
{
    //-------------------------------------------------------------------------
    T_dimensions    dimensions_;
    T_values        values_;
    //-------------------------------------------------------------------------
public:
    //-------------------------------------------------------------------------
    T_matr
        (
            T_dimensions    const   &   dimensions,
            T_values        const   &   values
        )
        :
        dimensions_     ( dimensions    ),
        values_         ( values        )
    {}
    //-------------------------------------------------------------------------
    T_matr( T_str   s )
    {
        std::replace
            (
                s.begin     (),
                s.end       (),
                COMMA_SYMB,
                SPACE_SYMB
            );
 
        std::istringstream  istr(s);
        int     n{};
        istr    >>  n;
 
        dimensions_.resize      (n);
        int     values_count    {1};
 
        for( auto   &   dim     :   dimensions_ )
        {
            istr    >>  dim;
            values_count    *=  dim;
        }
 
        values_.resize( values_count );
        for( auto   &   val     :   values_ )
        {
            istr    >>  val;
        }
    }
    //-------------------------------------------------------------------------
    int     &   operator()
        (
            std::initializer_list< size_t >     indexes
        )
    {
        return  (*this)( T_indexes( indexes ) );
    }
    //-------------------------------------------------------------------------
    int     operator()
        (
            std::initializer_list< size_t >     indexes
        )                                                                   const
    {
        return  (*this)( T_indexes( indexes ) );
    }
    //-------------------------------------------------------------------------
    size_t  dim( size_t     ind )                                           const
    {
        return  dimensions_.at( ind );
    }
    //-------------------------------------------------------------------------
    void    print()                                                         const
    {
        for( size_t  i{}; i < values_.size(); ++i )
        {
            std::cout   <<  values_[i]  <<  '\t';
 
            if  (
                    i   ==  values_.size() - 1
                )
            {
                break;
            }
 
            size_t  mod_val{1};
 
            for (
                    auto
                    it  =   dimensions_.rbegin  ();
                    it  !=  dimensions_.rend    ();
                    ++it
                )
            {
                mod_val     *=  *it;
 
                if  (
                        (i + 1)     %   mod_val     ==      0
                    )
                {
                    std::cout   <<  std::endl;
                }
            }//for
        }//for
 
        std::cout   <<  std::endl
                    <<  std::endl
                    <<  std::endl;
    }
    //-------------------------------------------------------------------------
    int     &   operator()
        (
            T_indexes   const   &   indexes     =   {}
        )
    {
 
        return  values_.at  (
                                shift_for_indexes( indexes )
                            );
    }
    //-------------------------------------------------------------------------
    int     operator()
        (
            T_indexes   const   &   indexes     =   {}
        )                                                                   const
    {
 
        return  values_.at  (
                                shift_for_indexes( indexes )
                            );
    }
    //-------------------------------------------------------------------------
private:
    //-------------------------------------------------------------------------
    size_t  shift_for_indexes
        (
            T_indexes   const   &   indexes
        )                                                                   const
    {
        if  (
                    indexes     .size   ()
                !=  dimensions_ .size   ()
            )
        {
            throw   std::invalid_argument
                        (
                                T_str(__FUNCTION__)
                            +   ": incorrect number of indexes in argument"
                        );
        }//if
 
        size_t  shift{};
 
        if  (
                indexes.size()
            )
        {
            auto    it_start    =   indexes.begin();
            shift               =   *it_start;
            ++it_start;
            size_t  dim_ind{1};
 
            for (
                    auto
                    indexes_it  =   it_start;
                    indexes_it  !=  indexes.end();
                    ++indexes_it, ++dim_ind
                )
            {
                shift   *=  dim( dim_ind );
                shift   +=  *indexes_it;
            }
        }//if
 
        return  shift;
    }
    //-------------------------------------------------------------------------
};
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_str   s;
    //getline( std::cin,  s );
 
    s   =   "3 2,3,4 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24";
 
    T_matr  matr(s);
 
    for( size_t  i{}; i < matr.dim(0); ++i )
    {
        for( size_t  j{}; j < matr.dim(1); ++j )
        {
            for( size_t  k{}; k < matr.dim(2); ++k )
            {
                std::cout   <<  matr({i, j, k})  <<  '\t';
            }
 
            std::cout   <<  std::endl;
        }//for
 
        std::cout   <<  std::endl;
    }//for
 
    matr({0, 0, 0})     =   1000;
    std::cout   <<  matr({0, 0, 0})     <<  std::endl;
 
 
    s   =   "0  15";
    T_matr  matr_scalar(s);
    std::cout   <<  matr_scalar()  <<  std::endl;
    matr_scalar()   =   333333;
    std::cout   <<  matr_scalar()  <<  std::endl;
 
 
 
    s   =   "1  6   10,20,30,40,50,60";
    T_matr  matr_vect(s);
    for( size_t  i{}; i < matr_vect.dim(0); ++i )
    {
        std::cout   <<  matr_vect({i})  <<  '\t';
    }
    std::cout   <<  std::endl;
 
 
    std::cout   <<  "\n\nDemonstration of exceptions when wrong function calls:"  <<  std::endl;
    try
    {
        std::cout   <<  matr_scalar({10, 20, 30})  <<  std::endl;
    }
    catch( std::exception   &   e )
    {
        std::cout   <<  e.what()    <<  std::endl;
    }
 
 
    try
    {
        std::cout   <<  matr_vect({1000})  <<  '\t';
    }
    catch( std::exception   &   e )
    {
        std::cout   <<  e.what()    <<  std::endl;
    }
 
 
    std::cout   <<  "\n\nDemonstration of function 'print':"  <<  std::endl;
    matr        .print  ();
    matr_scalar .print  ();
    matr_vect   .print  ();
}
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
28.09.2016, 17:23  [ТС] 37
Mr.X а у Вас тоже для максимум 3 измерений? В мейне я вижу 3 цикла для 3хмерной структуры, 1 цикл для одномерной... Все как в моей.. или я что-то пропустил?

Добавлено через 11 минут
Байт а ваша setVal назначает каждому элементу значение Val? Его можно переписать чтобы каждый элемент соответвующие значение получал? Как в моем 2х3 = [ [1,2,3] [4,5,6]]. И потом, если я хочу добавить каждый элемент, то я делаю Val[0][1] + Val[0][2] и тд.. но если у меня все в одном массиве, как в вашем примере, и мне нужно получить доступ к элементу val[0][2], как мне знать где он находится в одномерном массиве a[X]?
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2016, 17:40 38
Цитата Сообщение от kozo Посмотреть сообщение
Mr.X а у Вас тоже для максимум 3 измерений? В мейне я вижу 3 цикла для 3хмерной структуры, 1 цикл для одномерной... Все как в моей.. или я что-то пропустил?
Не, у меня для любого количества измерений. А эти циклы исключительно для демонстрации доступа к элементам матрицы по индексам, которые задаются списком в фигурных скобках.
Печать матрицы производится функцией print, которую надо еще доработать чуть-чуть.
0
0 / 0 / 0
Регистрация: 27.09.2016
Сообщений: 52
28.09.2016, 17:44  [ТС] 39
Mr.X

А как можно получить доступ если я задам 4 измерений, например к элементу [0][2][2][1]?
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2016, 17:53 40
Цитата Сообщение от kozo Посмотреть сообщение
А как можно получить доступ если я задам 4 измерений, например к элементу [0][2][2][1]?
matr({0, 2, 2, 1})
0
28.09.2016, 17:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.09.2016, 17:53
Помогаю со студенческими работами здесь

Создать и заполнить одномерный массив случайным количеством случайных элементов
функция должна создавать и заполнять одномерный массив случайным количеством случайных элементов....

Как правильно создать массив с заданным в ручную количеством элементов в массиве
В наличии имеется такой код #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;clocale&gt; using...

Необходимо создать двумерный массив с количеством строк равным количеству полученных узлов xml документа.
Необходимо создать двумерный массив с количеством строк равным количеству полученных узлов xml...

создать сценарий который формирует массив степеней числа два с ключами равными соответствующим показателям степени с количеством элементов меньше пере
создать сценарий который формирует массив степеней числа два с ключами равными соответствующим...


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

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