Страница 1 из 1

Поменять местами четверти матрицы

Добавлено: 13 дек 2015, 23:26
Alex21
Поменять местами элементы первой четверти массива с элементами четвёртой четверти. Борюсь с ней неделю. Ненавижу массивы. Смог осмыслить только пол задания. Помогите пожалуйста?

Код: Выделить всё

#include "stdafx.h"
int main()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int k = a[i][j];
a[i][j] = a[i + n / 2, j + n / 2];
a[i + n / 2, j + n / 2] = k;
}
}
return 0;
}

Re: Поменять местами четверти матрицы

Добавлено: 14 дек 2015, 00:45
Absurd
Может c заменой индексов [0..N) на [-N .. N] проще дело пойдет? Не совсем то, но я бы порядок элементов сначала изменил.

Код: Выделить всё

#include <cassert>
#include <iostream>
#include <algorithm>

template <typename T, int LoBound, int HiBound> class Array {
  T arr_[HiBound - LoBound + 1];
public:
  Array()
  {
    std::fill(arr_, arr_ + sizeof(arr_) / sizeof(arr_[0]), T{});
  }
  Array(const Array& other)
    :arr_(other.arr_)
  {}
  Array(std::initializer_list<T> initList)
  {
    std::copy(initList.begin(), initList.end(), arr_);
  }
  T& operator[](int ix)
  {
    assert(ix >= LoBound && ix <= HiBound);
    return arr_[ix - LoBound];
  }
  const T& operator[](int ix) const
  {
    assert(ix >= LoBound && ix <= HiBound);
    return arr_[ix - LoBound];
  }
};

int main()
{
  enum {LoBound = -2, HiBound = 2};
  using A1D = Array<int, LoBound, HiBound>;
  Array<A1D, LoBound, HiBound> arr = 
   { A1D{ 1,  2,  3,  4,  5},
     A1D{ 6,  7,  8,  9, 10},
    A1D{11, 12, 13, 14, 15},
    A1D{16, 17, 18, 19, 20},
    A1D{21, 22, 23, 24, 25} };
  for (int i = LoBound; i <= HiBound; ++i) {
    for (int j = LoBound; j <= HiBound; ++j) {
      std::cout << arr[-i][-j] << " ";
    }
    std::cout << "\n";
  }
  return 0;
}

Re: Поменять местами четверти матрицы

Добавлено: 14 дек 2015, 01:58
Alex21
Спасибо большое, ваш вариант придётся кстати, ибо мой учитель как раз ценит нестандартные решения. Ещё раз спасибо :D .

Re: Поменять местами четверти матрицы

Добавлено: 14 дек 2015, 10:02
Romeo
Alex21, боюсь, ты это даже не сможешь объяснить учителю :)

Absurd , я нахожу даже забавным явное усложнение задания, с целью добиться полного непонимания у людей, которым лень разобраться самостоятельно :)

Re: Поменять местами четверти матрицы

Добавлено: 14 дек 2015, 10:06
Decoder
То решение, которое предложил Absurd, слишком сложно для начинающего.
Надо что-то более простое и понятное. Например так...

Код: Выделить всё

#include <iostream>
#include <algorithm>

using namespace std;

#define	DIM	4	// Matrix dimension

template <typename T>
void DisplayMatrix(const T& matrix)
{
	for (unsigned v = 0; v < DIM; v++)
	{
		for (unsigned h = 0; h < DIM; h++)
		{
			cout << matrix[v][h] << '\t';
		}
		cout << endl;
	}
}

template <typename T>
void SwapQuarters(T& matrix)
{
	for (unsigned v = 0; v < DIM/2; v++)
	{
		for (unsigned h = 0; h < DIM/2; h++)
		{
			swap(matrix[v][h], matrix[v + DIM/2][h + DIM/2]);
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int MX[DIM][DIM] = 
	{
		{1,		1,		2,		2},
		{1,		1,		2,		2},
		{3,		3,		4,		4},
		{3,		3,		4,		4}
	};
	
	SwapQuarters(MX);

	DisplayMatrix(MX);

	_gettch();

	return 0;
}


Re: Поменять местами четверти матрицы

Добавлено: 14 дек 2015, 13:03
Absurd
я нахожу даже забавным явное усложнение задания, с целью добиться полного непонимания у людей, которым лень разобраться самостоятельно
Ну не знаю. Хорошая практика это использовать те типы данных в которых идею можно выразить наиболее ясно. Пользоваться полярными координатами вместо прямоугольных если нужно вращать а не сдвигать. Если идея связана с симметрией, то и структура данных должна быть симметричной. Но к сожалению в Си (в С++- к счастью, язык и так перегружен) нельзя создавать массивы как в Паскале, типа Integer[-2..2][-2..2]. Но можно воткнуть костыль который позволяет добиться желаемого. А насчет того что он сложен, так его предполагается использовать а не писать. Мне вот тоже в институте предложили написать текстовой GUI, я не знал как это делать, мне сосед показал непонятное заклинание на Паскале для его лабы в другом ВУЗ-е и я просто использовал его чтобы выводить псевдографику на экран без понимания того как оно работает. Потом выяснил что это заклинание помещало двухмерный массив char[80][25] по абсолютному адресу туда где находится видеопамять текстового режима.