Здравствуйте Аноним, Вы писали:
А>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
Приведи здесь свой код. Напомни, что тебя в нём не устраивает.
Не забудь воспользоваться тегами форматирования (они появятся внизу, когда будешь писать сообщение) и лучше зарегистрироваться -- приятнее разговаривать с кем-то конкретно, а не с безликим Анонимом. К нам даже заходят люди с совершенно простыми вопросами под своими именами, и им дают подробные ответы, не глядя на уровень вопроса. Так что не бойся показаться начинающим
Здравствуйте Аноним, Вы писали:
А>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
какой структурой масив задан? статический или динамический?
первое ччто приходит в голову — нужно знать размерность массива, и индексы его центра..
в цикле пока х и у не равны одновременно сентральной точке хранить дополнительное состояние — направление движения (право, вниз, влево, вверх) в зависимости от этих стостояний
изменять значения текущего х и у..
Так же можно разворячивать рекусрсивоно массив..
так же можно на чистой математике представить массив как линейный, использовать одну переменную для указания текущего индекса..
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Здравствуйте dad, Вы писали:
dad>Здравствуйте Аноним, Вы писали:
А>>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
dad>какой структурой масив задан? статический или динамический? dad>первое ччто приходит в голову — нужно знать размерность массива, и индексы его центра.. dad>в цикле пока х и у не равны одновременно сентральной точке хранить дополнительное состояние — направление движения (право, вниз, влево, вверх) в зависимости от этих стостояний dad>изменять значения текущего х и у.. dad>Так же можно разворячивать рекусрсивоно массив..
dad>так же можно на чистой математике представить массив как линейный, использовать одну переменную для указания текущего индекса..
Это я, бывший Аноним.
Размерность массива задается в пределах 1 < M < 10, 1 < N < 10. После чего требуется вывести спираль. Про статику и динамику в задании не слова, значит можно выбирать.
Здравствуйте Аноним, Вы писали:
А>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
Гм. Не знаю, в чем именно проблема, я бы решал так:
Начнем с "середины" массива, обозначив ее буквой v (пусть она уже изветстна). Нарисуем путь обхода:
+---
|+-+
||v|
|++|
+--+
Итак, видно, что мы идем так:
1 вниз, 1 влево
2 вверх, 2 вправо
3 вниз, 3 влево...
Ага, вырисовывается примерно такой псевдокод:
Четыре цикла, однако, составляют две очень похожие пары. Свернем их:
int l=1;
d=1;
while(1)
{
int i; // старые компиляторы не дадут нам повторно декларировать i во втором цикле...for(i=0; i<l; i++)
{
cout<< array[x][y];
y+=d; //идем либо вверх, либо вниз...
}
for(i=0; i<l; i++)
{
cout<< array[x][y];
x-=d; //идем либо влево, либо вправо...
}
l+=1; // увеличили шаг...
d= -d; // инвертировали направление...
}
можно еще обобщить понятие движения. Сделаем каждый проход по стороне спирали в едином цикле:
typedef enum {down, left, up, right} direction;
direction dir = down;
struct {
int dx;
int dy;
int l
} step_struct;
const step_struct turn_desc[] = {{0, 1, 1}, {-1, 0, 0}, {0, -1, 1}, {1, 0, 0}};
step_struct step = turn_desc[dir];
void move(const step_struct &step, int &x, int &y)
{
x+=step.dx;
y+=step.dy;
}
void turn(step_struct &step, direction &dir)
{
dir= (dir+1)%4;
step.dx = turn_desc[dir].dx;
step.dy = turn_desc[dir].dy;
step.l += turn_desc[dir].l;
}
while(1)
{
for(int i=0; i<step.l; i++)
{
cout<< array[x][y];
move(step, x, y); //идем в нужную сторону
}
turn(step, dir); // поворачиваем
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте Аноним, Вы писали:
А>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
В верхнем квадранте надо идти вправо, в правом вниз, в нижнем влево, в левом вверх.
Осталось внимательно посмотреть на границы и написать так, чтобы годилось и для чётных и для нечётных размерностей.
int array[N][N];
for(int x=N/2, y=N/2;
x>=0 && y>=0 && x<N && y<N;
x+y<N/2*2? (x<y? y--:x++):(x>y? y++:x--))
{
//do what you want with array[x][y]
}
Здравствуйте Pushkin, Вы писали:
P>Здравствуйте Аноним, Вы писали:
А>>Начал реализовывать, однако получается довольно громоздкий код с 3мя циклами, существует ли более изящное решение?
P>В верхнем квадранте надо идти вправо, в правом вниз, в нижнем влево, в левом вверх. P>Осталось внимательно посмотреть на границы и написать так, чтобы годилось и для чётных и для нечётных размерностей.
P>
P>int array[N][N];
P>for(int x=N/2, y=N/2;
P> x>=0 && y>=0 && x<N && y<N;
P> x+y<N/2*2? (x<y? y--:x++):(x>y? y++:x--))
P>{
P> //do what you want with array[x][y]
P>}
P>