Phorce
Phorce

Reputation: 4642

Split array into sub blocks

What I am trying to achieve is this:

I have an image and I need to split it into sub blocks of 16x16 and I am working on the algorithm for this. For testing purposes though, I am using a small matrix:

A = {1, 2, 3, 4}

Now what I want to end up is this: 2 blocks containing:

A[1] = {1 2};
A[2] = {3, 4}; 

I have tried to use the following:

double matrix[4] = {1, 2, 3, 4};

for(int i = 0; (i < 4); i++)
{
        for(unsigned j=i; (j < 2); j +=2)
        {
            std::cout << j << ' ';
        }
        std::cout << std::endl;
}

My thought process was to loop through the entire array (4) and then increment by 2 each time to create the 1x2 block. This did not work however.

Where am I going wrong here?

Upvotes: 2

Views: 1290

Answers (3)

Lorah Attkins
Lorah Attkins

Reputation: 5856

The following is a demo of how to do the splitting for custom block size (rough cut though, corner cases and input verification are ommited) using boost range and the boost::slice functionality (here "output creation" is presented)

#include <iterator>
#include <iostream>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>

using namespace std;
using namespace boost::adaptors;

template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
   for (size_t i(0); i <= N-block_size; i += block_size)
   {
       cout << "{ ";
       boost::copy(input | sliced(i, i+block_size),
           std::ostream_iterator<int>(std::cout, " "));
       cout << "}\n"; 
   }
}


int main()
{
    int A[] = {1, 2, 3, 4};
    split(A, 2); 
}

Demo

Output

{ 1 2 }

{ 3 4 }

What if I don't want to do output

To some the following may look more readable

template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
   for (size_t i(0); i <= N-block_size; i += block_size)
   {
       cout << "{ ";
       // do whatever with the i slice (again I'm showing output)
       for (auto k : (input | sliced(i, i+block_size))) cout << k << " "; 
       cout << "}\n"; 
   }
}

Upvotes: 1

wgslr
wgslr

Reputation: 76

Just for output you could do something like that:

#include <iostream>

int main(){
  const size_t SIZE = 4;
  const size_t PART_SIZE = 2;
  double matrix[4] = {1, 2, 3, 4};

  for(int i = 0; (i < SIZE); i += PART_SIZE)
  {
    for(size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1)
    {
        std::cout << matrix[j] << ' ';
    }
    std::cout << std::endl;
  }
}

To add another matrix:

#include <iostream>

int main(){
    const size_t SIZE = 4;
    const size_t PART_SIZE = 2;
    size_t partsNumber = SIZE / PART_SIZE; // Beware of SIZE that is not divisible by PART_SIZE - partsNumber will be too small
    double matrix[4] = { 1, 2, 3, 4 };

    // To do it properly I should make it dynamic array with size of partsNumber instead of the 2 literals
    double parts_matrix[2][PART_SIZE]; 

    for (int i = 0; (i < SIZE); i += PART_SIZE) {
        for (size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1) {
            std::cout << matrix[j] << ' ';
            parts_matrix[j / partsNumber][j % PART_SIZE] = matrix[j];
        }
        std::cout << std::endl;
    }
    std::cout << parts_matrix[0][0] << " " << parts_matrix[0][1] << std::endl << parts_matrix[1][0] << " " << parts_matrix[1][1]; // Check if it works
}

Upvotes: 1

Ashalynd
Ashalynd

Reputation: 12563

Something like that? (Does both output and assignment)

int LEN = 4;
int INNER = 2;
int OUTER_LEN = LEN/INNER_LEN;
double matrix[LEN] = {1, 2, 3, 4};
double* matrix2[OUTER_LEN];

for(int i = 0; i < OUTER_LEN; i++)
{ 
        matrix2[i] = &matrix[i*INNER_LEN];
        for(unsigned j=0; j < INNER_LEN; j++)
        {
            std::cout << matrix[i*INNER_LEN+j] << ' ';
        }
        std::cout << std::endl;
}

Upvotes: 1

Related Questions