Сведения о вопросе

Математик

22:33, 26th August, 2020

Теги

c++   c   arrays   microsoft-dynamics    

Как суммировать размеры массива, заданного во время выполнения?

Просмотров: 453   Ответов: 10

Я работаю над функцией для установления энтропии распределения. Он использует связку, если кто-то знаком с этим. Мне нужно суммировать значения в массиве, основываясь на том, какие измерения являются "cared about."

Пример: рассмотрим следующий пример...

Dimension 0 (across)
_ _ _ _ _ _ _ _ _ _ _ _ _
|_ 0 _|_ 0 _|_ 0 _|_ 2 _|  Dimension 1
|_ 1 _|_ 0 _|_ 2 _|_ 0 _|   (down)
|_ 0 _|_ 3 _|_ 0 _|_ 6 _|
|_ 0 _|_ 0 _|_ 0 _|_ 0 _|

I "care about" dimension 0 only, and "don't care" about the rest (dim 1).
Summing this array with the above specifications will
"collapse" the "stacks" of dimension 1 down to a single 4 x 1 array:

_ _ _ _ _ _ _ _ _ _ _ _ _ 
|_ 1 _|_ 3 _|_ 2 _|_ 8 _|

This can then be summed, or have any operation performed.

Мне нужно сделать это с массивом 'n' измерений, которые могли бы реально be 20. Кроме того, мне нужно быть в состоянии сделать это, заботясь о некоторых размерах и разрушая rest. Мне особенно трудно с этим, потому что я не могу визуализировать 20 измерений :p . Если бы кто-нибудь мог помочь мне настроить некоторый код c/c++ на collapse/sum,, я был бы очень благодарен.

Обновление:

Только что вернулся домой. Вот некоторая информация, чтобы ответить на ваши вопросы:

  1. Извините за откат правок, я надеялся, что когда я нажму откат, он покажет мне изменения, чтобы я мог увидеть, что я испортил, немного похоже на Википедию. Как я выяснил, это был не тот случай.
  2. @jeff-что не имеет смысла? Я использую этот отличный сервис для (что я думаю) законной причины. Я хочу стать лучше в своем хобби, которое все это, как я в средней школе. Многие из моих сообщений касаются реализации генетического алгоритма (этот пост, sparsearray, ранжирование массива, манипуляция указателем).
  3. Я использую разреженное представление массива, поскольку можно превысить количество молекул во Вселенной, используя традиционный (плотный) массив. На данный момент реализация самого sparsearray не имеет большого значения, поскольку я работаю над тем, чтобы заставить его работать со стандартным массивом, прежде чем перейти к разреженному представлению. Для тех, кто не видел мои предыдущие вопросы, я использую двоичное дерево поиска в качестве структуры, содержащей разреженные точки массива, и функцию "driver" для обхода дерева по мере необходимости, возвращая все, что функция предназначена для выполнения. Это является гибким, так что я могу разместить много различных методов доступа к массиву.
  4. Структура является гиперкубом, и количество измерений задается во время выполнения, а также длина каждого измерения (которые все одинаковы, так как это гиперкуб).

Спасибо всем за ваше вменение.



  Сведения об ответе

darknet

12:54, 19th August, 2020

Это может иметь приложения. Допустим, вы реализовали игру жизни Конвея 2D (которая определяет плоскость 2D, 1 для 'alive', 0 для 'dead'), и вы сохранили историю игр для каждой итерации (которая затем определяет куб 3D). Если бы вы хотели знать, сколько бактерий было живым за всю историю, вы бы использовали приведенный выше алгоритм. Вы можете использовать тот же алгоритм для A 3D, (и 4D, 5D и т. д.) версия Game of Life grid.

Я бы сказал, что это был вопрос для рекурсии, я еще не программист C, но я знаю, что это возможно в C. В python,


def iter_arr(array):
  sum = 0
  for i in array:
    if type(i) == type(list()):
      sum = sum + iter_arr(i)
    else:
      sum = sum + i
  return sum 
  1. Перебирать каждый элемент в массиве
  2. Если элемент является другим массивом, вызовите функцию еще раз
  3. Если элемент не является массивом, добавьте его в сумму
  4. Возврат суммы

Затем вы примените это к каждому элементу в измерении 'cared about'.

Это проще в python из-за утиной печати, хотя ...


  Сведения об ответе

lats

04:03, 18th August, 2020

@Jeff

Я действительно думаю, что это интересный вопрос. Я не уверен, насколько это полезно, но это правильный вопрос.

@Ed

Можете ли вы предоставить немного больше информации по этому вопросу? Вы сказали, что размер массива является динамическим, но является ли число элементов динамическим?

EDIT: я все равно попытаюсь ответить на этот вопрос. Я не могу дать вам код с моей головы (это займет некоторое время, чтобы получить его правильно без какого-либо компилятора здесь на этом PC), но я могу указать вам в правильном направлении ...

В качестве примера возьмем 8 измерений (0-7) с индексами от 0 до 3. Вы заботитесь только о 1,2 и 6. Это означает, что у вас есть два массива. Во-первых, array_care[4][4][4] для 1,2 и 6. array_care[4][4][4] будет содержать конечный результат.

Далее, мы хотим сделать итерацию очень специфическим способом. У нас есть массив input[4][4][4][4][4][4][4][4] для разбора, и мы заботимся о размерах 1, 2 и 6.

Нам нужно определить некоторые временные индексы:

int dim[8] = {0,0,0,0,0,0,0,0};

Нам также нужно сохранить порядок, в котором мы хотим увеличить индексы:

int increase_index_order[8] = {7,5,4,3,0,6,2,1};
int i = 0;

Этот заказ важен для выполнения того, что вы просили.

Определение флага завершения:

bool terminate=false;

Теперь мы можем создать наш цикл:

while (terminate)
{
array_care[dim[1]][dim[2]][dim[6]] += input[dim[0]][dim[1]][dim[2]][dim[3]][dim[4]][dim[5]][dim[6]][dim[7]];

while ((dim[increase_index_order[i]] = 3) && (i < 8))
{
dim[increase_index_order[i]]=0;
i++;
}

if (i < 8) {
dim[increase_index_order[i]]++; i=0;
} else {
terminate=true;
}
}

Это должно работать для 8 измерений, заботясь о 3 измерениях. Это займет немного больше времени, чтобы сделать его динамичным, и у меня нет времени. Надеюсь, это поможет. Прошу прощения, но я еще не выучил кодовые накладки. :(


  Сведения об ответе

9090

07:55, 24th August, 2020

Это намного проще, если вы используете контейнеры STL или, возможно, Boost.MultiArray . Но если вы должны использовать массив:

#include <iostream>
#include <boost/foreach.hpp>
#include <vector>

int sum(int x) {
    return x;
}

template <class T, unsigned N>
int sum(const T (&x)[N]) {
    int r = 0;
    for(int i = 0; i < N; ++i) {
        r += sum(x[i]);
    }
    return r;
}

template <class T, unsigned N>
std::vector<int> reduce(const T (&x)[N]) {
    std::vector<int> result;
    for(int i = 0; i < N; ++i) {
        result.push_back(sum(x[i]));
    }
    return result;
}

int main() {
    int x[][2][2] = {
        { { 1, 2 }, { 3, 4 } },
        { { 5, 6 }, { 7, 8 } }
    };

    BOOST_FOREACH(int v, reduce(x)) {
        std::cout<<v<<"\n";
    }
}


  Сведения об ответе

VERSUION

07:04, 28th August, 2020

На самом деле, свернув столбцы, вы уже суммировали их, поэтому размерность не имеет никакого значения для вашего примера. Я что-то пропустил или ты?


  Сведения об ответе

crush

23:50, 15th August, 2020

Я думаю, что лучше всего было бы сделать здесь одну / обе из двух вещей:

  1. Переосмыслите дизайн, если он слишком сложный, найдите менее сложный способ.
  2. Перестаньте пытаться визуализировать это.. :P просто сохраните соответствующие измерения, которые вам нужно суммировать,а затем выполняйте их по одному. После того, как у вас есть базовый код, а затем посмотреть на повышение эффективности вашего алгоритма.


  Сведения об ответе

DINO

05:41, 17th August, 2020

Я позволю себе не согласиться, есть ALWAYS другой способ..

И если вы действительно не можете рефакторинг, то вам нужно разбить проблему на более мелкие части.. Как я уже сказал, определите, какие измерения вам нужно суммировать,а затем ударяйте по ним по одному..

Кроме того, прекратите изменять правки, они исправляют ваши орфографические ошибки, они пытаются помочь вам ;)


  Сведения об ответе

PROGA

12:27, 22nd August, 2020

Когда вы говорите, что не знаете, сколько существует измерений, как именно вы определяете структуры данных?

В какой-то момент кому-то нужно создать этот массив, и для этого им нужно знать размеры массива. Вы можете заставить создателя передать эти данные вместе с массивом.

Если только речь не идет о том, чтобы определить такую структуру данных...


  Сведения об ответе

DAAA

18:49, 20th August, 2020

Вы делаете это в c/c++..., так что у вас есть массив массива массива... вам не нужно визуализировать 20 измерений, так как это не так, как данные выложены в памяти, для 2-мерного:

[1] --> [1,2,3,4,5,6,...]
[2] --> [1,2,3,4,5,6,...]
[3] --> [1,2,3,4,5,6,...]
[4] --> [1,2,3,4,5,6,...]
[5] --> [1,2,3,4,5,6,...]
 .           .
 .           .
 .           .

Итак, почему вы не можете перебрать первый, суммируя его содержимое? Если вы пытаетесь найти размер, то sizeof(array)/sizeof(int) -это рискованный подход. Вы должны знать измерение, чтобы иметь возможность обрабатывать эти данные и настраивать память, поэтому вы знаете глубину рекурсии для суммирования. Вот некоторые псевдо-код того, что, кажется, вы должны сделать,

sum( n_matrix, depth )
  running_total = 0
  if depth = 0 then
    foreach element in the array
      running_total += elm
  else 
     foreach element in the array
       running_total += sum( elm , depth-1 )
  return running_total


  Сведения об ответе

davran

01:28, 9th August, 2020

x = number_of_dimensions;
while (x > 1)
{
  switch (x)
  {
    case 20:
      reduce20DimensionArray();
      x--;
    break;
    case 19:
      .....
  }
}

(Извините, не удержался.)


  Сведения об ответе

qwerty101

19:52, 25th August, 2020

Если я правильно понимаю, вы хотите суммировать все значения в поперечном сечении, определенном в каждом "bin" вдоль 1 измерения. Я предлагаю сделать 1D массив для вашего назначения, а затем перебирать каждый элемент в вашем массиве, добавляя значение в пункт назначения с индексом интересующего измерения.

Если вы используете произвольное количество измерений, у вас должен быть способ адресации элементов (мне было бы любопытно, как вы это реализуете). Ваша реализация этого будет влиять на то, как вы устанавливаете целевой индекс. Но очевидным способом было бы, если бы операторы проверялись в циклах итерации.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться