arrays — Необязательная логика при передаче структур в Stack Overflow

Я тоже новичок в программировании и пытаюсь передать массив структур и «опцию» в функцию. Затем я хочу, чтобы функция могла манипулировать данными в массиве структуры.

struct coordinates{
int x;
int y;
int z;
}COORD;

Параметр option является целым числом, которое указывает, какой частью структуры манипулировать.

  1. Манипулировать x — option = 0
  2. Манипулировать y — option = 1
  3. Манипулировать z — option = 2

Пример этого показан ниже. Функция берет массив структур и составляет 3-х точечную скользящую среднюю от указанной точки данных. У меня проблема в том, что программа, которую я пытаюсь построить, имеет более 50 членов в каждой структуре, поэтому выписывать каждый оператор if на самом деле утомительно. Я спрашиваю, есть ли более элегантное решение ???

#include <iostream>

struct coordinates{
int x;
int y;
int z;
}COORD;

int main() {
COORD points[10];

// Initialising points
for(int i = 0, i < 10, i++){
points[i].x = 1;
points[i].y = 2;
points[i].z = 3;
}
//(struct,startpoint,option)
std::cout << movingaverage(&points,3,1); // Output
}

int movingaverage(COORD *data, int start_point, int option){

if(option == 0) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->x;
sum = sum + data[start_point - 1]->x;
sum = sum + data[start_point + 1]->x;
}

else if(option == 1) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->y;
sum = sum + data[start_point - 1]->y;
sum = sum + data[start_point + 1]->y;
}
else if(option == 2) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->z;
sum = sum + data[start_point - 1]->z;
sum = sum + data[start_point + 1]->z;
}
sum = sum / n;
return sum; //Sum is the moving average
}

1

Решение

Также указатель на членов является возможным решением; в сочетании с функцией шаблона элементы могут быть различного типа. Но да, синтаксис это что-то странное:

#include <iostream>
#include <vector>
using namespace std;

/// calculate the sum of a given structure member in a vector:
template <typename T, typename M>
M membersum(vector<T> array, M (T::*mptr)) {
M sum = 0;
for (int i=0; i<array.size(); i++) {
sum += (array[i].*mptr);
}
return sum;
}

struct Point {
Point(int x, int y, float z): x(x), y(y), z(z) {}
int x;
int y;
float z;
};

int main() {
vector<Point> points;
points.push_back(Point(1,2,3.8));
points.push_back(Point(1,2,4.5));
points.push_back(Point(1,2,1.7));
// your code goes here
cout << "sum x: " << membersum(points, &Point::x) << endl;
cout << "sum y: " << membersum(points, &Point::y) << endl;
cout << "sum z: " << membersum(points, &Point::z) << endl;
return 0;
}

Этот пример, который я создал на ideone.com.

1

Другие решения

C ++ не поддерживает рефлексию, и поэтому вы не можете перебирать элементы структуры. Я бы сделал это с помощью функции получения.

template<class Getter>
int movingaverage(COORD *data, int start_point, const Getter &get){
auto sum = get(data[start_point]);
sum = sum + get(data[start_point - 1]);
sum = sum + get(data[start_point + 1]);
return sum;
}

std::cout << "x: " << movingaverage(&points, 3, [](const COORD &coord){return coord.x;}) << '\n';
std::cout << "y: " << movingaverage(&points, 3, [](const COORD &coord){return coord.y;}) << '\n';
std::cout << "z: " << movingaverage(&points, 3, [](const COORD &coord){return coord.z;}) << '\n';

Если вы или ваш компилятор запутались в лямбда-части, вы можете просто написать обычную функцию и передать ее взамен.

1

Я бы предложил использовать простой функтор.

Class MovingAvg
{
MovingAvg(std::vector<Coordinate> *pSet);
void SetPointSet(std::vector<Coordinate> *p);

double operator()(int startPoint, int option)
{
//calculation here.
double sum = 0;
for(int i = -1; i <= 1; ++i)
{
switch(option)
case 0:
sum += pointSet[startPoint + i].x; //check for bounday conditions.
.................

}
return sum / 3;
}

private:
//container
std::vector<Coordinate> *pointSet;
}

Используйте это как.

MovAvg mvG(pointSet);
double sum = mvG(startP, option);

// изменить закрытый член, если необходимо изменить набор точек.

Функторы очень удобны в подобных случаях.

0

Вы можете попробовать что-то вроде

class coordinates{
private:
int xyz[3]; //implementation detail(!)

public:
int x() const { return xyz[0]; }
int y() const { return xyz[1]; }
int z() const { return xyz[2]; }

//some relevant setters go here

static int movingaverage(COORD *data, int start_point, int option){

sum = data[start_point]->xyz[option];
sum = sum + data[start_point - 1]->xyz[option];
sum = sum + data[start_point + 1]->xyz[option];
}
};
0
По вопросам рекламы [email protected]