Задача. Дано 3 числа : a, b, c и одномерный массив. Заполнить его следующим образом: a, b, c, a, b, c, a, b, c ...
Решение
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
for (int i = 0; i < cnt; i+=3) {
arr[i] = a;
arr[i + 1] = b;
arr[i + 2] = c;
}
}
В моем решении есть выход за границы массива. Как это исправить? Заранее спасибо.
Вариантов масса.
От
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
for (int i = 0; i < cnt; i+=3) {
arr[i] = a;
if (i+1 < cnt) arr[i + 1] = b;
if (i+2 < cnt) arr[i + 2] = c;
}
}
до
for (int i = 0; i < cnt; ++i)
{
arr[i] == (i%3==0) ? a : (i%3 == 1) b : c;
}
P.S. Ага, раз пошла такая пьянка, пора достать алгебраический огурец:
void fillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
double aa = (c+a)/2-b, bb = 2*b-(3*a+c)/2, cc = a;
for (int i = 0; i < cnt; i++)
{
int j = i%3;
arr[i] = (aa*j+bb)*j+cc;
}
}
Вариантов можно несколько сделать, я бы сделал так:
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
double mas[] = {a, b, c};
for (int i = 0; i < cnt; i++)
{
arr[i] = mas[i % 3];
}
}
Ну как же тут не вспомнить нетленную классику? (Подразумевая cnt > 0)
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
int n = (cnt + 2) / 3;
arr += cnt;
switch (cnt % 3)
do
{
case 0: *--arr = c;
case 2: *--arr = b;
case 1: *--arr = a;
} while (--n > 0);
}
Рекурсию в массы!
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2, int idx = 0)
{
if (idx == cnt) return;
arr[idx] = a;
FillArray(cnt, arr, b, c, a, idx + 1);
}
В ответах на этот вопрос слишком мало STL!
Думаю std::generate_n отлично подойдет.
#include <algorithm>
void fillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2){
std::generate_n(arr, cnt, [=]{
static int i = 0;
static double values[] = {a, b, c};
return values[i++ % std::size(values)];
});
}
Или даже std::valarray:
#include <valarray>
void fillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2){
std::valarray<double> temp(cnt);
auto slice = [cnt](int from, int step){
return std::slice(from, (cnt - from + step - 1) / step, step);
};
temp[slice(0, 3)] = a;
temp[slice(1, 3)] = b;
temp[slice(2, 3)] = c;
std::copy(std::begin(temp), std::end(temp), arr);
}
Я бы вынес условия из цикла, понятно, что по факту на большинстве современных архитектур это ускорения почти наверняка не даст, да компилятор может догадаться сделать сам, но всё же...
void FillArray(int cnt, double *arr, double a = 0, double b = 1, double c = 2)
{
int i;
for (i = 0; i < cnt-2; i+=3) {
arr[i] = a;
arr[i + 1] = b;
arr[i + 2] = c;
}
if (i == cnt-2) {
arr[i] = a;
arr[i + 1] = b;
} else if (i == cnt-1) {
arr[i] = a;
}
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей