Заполнение двумерного массива по спирали СИ
Хочу заполнить двумерный массив по спирали. Ввожу число, затем генерируется двумерный массив, который заполняется от единицы до этого числа. Следующие элементы массива, если они есть, заполняются нулями. Однако, код работает не всегда. Например, если массив 3*4 а введенное число равно 65, результат показывается некорректно. Что в коде не так? `
#include #include void spiral(int array[100][100], int m, int n, int s) < int size, b, x = 0, y = 1, num = 1; size = m*n; for (num=1;num<=size+1;num++) < for (b = x; b < n; b++) < if (num <=s) < array[x][b] = num; num++; >else array[x][b] = 0; > if (num == size + 1) < break; >for (b = y; b < m; b++) < if (num <=s) < array[b][n - 1] = num; num++; >else array[b][n - 1] = 0; > if (num == size + 1) < break; >y++; n--; for (b = n - 1; b > x; b--) < if (num else array[m - 1][b] = 0; > if (num == size + 1) < break; >for (b = m - 1; b > x; b--) < if (num else array[b][x] = 0; > x++; m--; > > int main() < int m, n, s, array[100][100]; srand(time(NULL)); //m=3; // n=4; m = 2 + rand() % 5; n = 2 + rand() % 5; //memset(array, 0, sizeof(array[0][0]) * 10 * 10); printf("enter the number \n"); scanf("%i", &s); spiral(array, m, n, s); for (int i = 0; i < m; i++) < for (int j = 0; j < n; j++) < printf("%i\t", array[i][j]); >printf("\n"); > return (0); >`
Отслеживать
Altynbek Tanbayev
задан 27 апр 2017 в 15:15
Altynbek Tanbayev Altynbek Tanbayev
45 9 9 бронзовых знаков
Воспользуйтесь дебаггером и найдете проблему.
27 апр 2017 в 15:19
связанный вопрос: Помогите понять код: алгоритм генерации матрицы со спиралью
27 апр 2017 в 17:23
spiral(int array[100][100]. никогда так не делайте в Си.
27 апр 2017 в 18:35
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
int[,] FillMatrixtoSpiral(int row, int col) < int[,] array = new int[row, col]; int Up = 0; // Сужение сверху int Down = 0; // Сужение снизу int Left = 0; // Сужение слева int Right = 0; // Сужение справа // Переменные счетчики используемые в расчетах int k = 1; // Счетчик, который присваивает значение элемнетам массива int i = 0; // Координары строки int j = 0; // Координаты столбца while (k Left) --j; // производится движение по столбцу влево // Проверка возможности движения вверх else --i; // производится движение по строкам вверх // Сужение диапазона, если окружность заполнена if ((i == Up + 1) && (j == Left) && (Left != col - Right - 1)) < ++Up; ++Down; ++Right; ++Left; >++k; // Счетчик увеличен на 1 // Цикл начинается заново > return array; > // Блок вывода элементов двумерного массива void PrintArray(int[,] array) < for (int x = 0; x < array.GetLength(0); ++x) < for (int y = 0; y < array.GetLength(1); ++y) < System.Console.Write(array[x, y] + "\t"); >System.Console.WriteLine(); > > // Основной блок программы int[,] SpiralArray = FillMatrixtoSpiral(4, 4); PrintArray(SpiralArray);
Отслеживать
ответ дан 9 фев 2023 в 14:31
11 2 2 бронзовых знака
Но вопрос по си.
10 фев 2023 в 5:16
- c
- массивы
-
Важное на Мете
Связанные
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.9.3159
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Как заполнить массив по спирали
Алгоритм заполнения двумерного массива по спирали
Наверное у многих было задание на уроках программирования, написать программу которая должна заполнить двумерный массив числами по спирали. Недавно у меня тоже появилась необходимость решить данную задачу. Я ее писал много раз на разных языках программирования — и каждый раз приходилось вспоминать, как я ее писал, но теперь я написал алгоритм, который может заполнить любой массив, любого размера — даже не семетричные.
Для начала объясню собственно алгоритм. При заполнении двумерного массива по спирали ( заполнять будем слева-на-право-сверху-вниз ). При заполнении массива улиткой — количество итераций на каждом четвертом проходе будет равно РазмерМассива — 2 . Теперь от этих данных и начнем.
Сперва напишем кусочек кода отвечающий за заполнение только слева-на-право:
if ( y == 0 && x < sizeX - CorrectX && Countгде y - текущая сторона (0 - вверх, 1 - право, 2 - . )
sizeX - размер массива по горизонтали
CorrectX - переменная, которая отвечает за автоматическое декриментирование
Count - переменная, которая отвечает за текущую цыфру внутри массива
Summ - произведение ширины на высоту, нужно для устранения ошибки (см. Далее)
Mas - название двумерного массива
x - собственно позиция внутри массиваНу, а остальные стороны делаются по вышеописанному принципу, за тем исключением, что меняются местами переменные, а также немного видоизменяется условие. Если Вы заметили, то было написанно, что переменная Summ, нужна для устранения ошибки - да, так и есть. Ошибка заключается в том, что при последнем цикле первое условии (См. Код) - отрабатывает, а изменить его никак не удавалось, потому пришлось ввести еще одну переменную.
Ниже приведен код функции, которая заполняет массив по спирали. Заполнение происходит только в одном направлении - слева-на-право-сверху-вниз. Ну кто захочет - сможет переписать еe таким образом, чтобы она стартовала откуда угодно. Удачи !
void FillHelix( int **Mas, int sizeY, int sizeX ) < int Summ = sizeX * sizeY; int CorrectY = 0; int CorrectX = 0; int Count = 1; while( sizeY > 0 ) < for ( int y = 0; y < 4; y++ ) < for ( int x = 0; x < ( ( sizeX < sizeY ) ? sizeY : sizeX ); x++ ) < if ( y == 0 && x < sizeX - CorrectX && Count if ( y == 1 && x < sizeY - CorrectY && x != 0 && Count if ( y == 2 && x < sizeX - CorrectX && x != 0 && Count if ( y == 3 && x < sizeY - ( CorrectY + 1 ) && x != 0 && Count > sizeY--; sizeX--; CorrectY += 1; CorrectX += 1; > >Готовый вариант программы сможете найти, щелкнув в навигационной панели ссылку Готовые программы.
|
© Spyrytus_LTD © 2003 - 2006 гг. | |
QuadTheMage / Spiral.java
Clone via HTTPS Clone with Git or checkout with SVN using the repository’s web address.
Learn more about clone URLs
Заполнение массива по спирали
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| package com . company ; |
| /** |
| * Заполнение массива по спирали |
| */ |
| public class Spiral |
| public static void main ( String [] args ) |
| int row = 11 , col = 11 ; |
| int [][] array = new int [ row ][ col ]; |
| int minRow = 0 , maxRow = row - 1 , minCol = 0 , maxCol = col - 1 ; |
| int count = 0 ; |
| int max = row * col ; |
| while ( count < max ) |
| for ( int i = minCol ; i <= maxCol ; i ++) |
| array [ minRow ][ i ] = count ; |
| count ++; |
| > |
| minRow = minRow + 1 ; |
| for ( int i = minRow ; i <= maxRow ; i ++) |
| array [ i ][ maxCol ] = count ; |
| count ++; |
| > |
| maxCol = maxCol - 1 ; |
| for ( int i = maxCol ; i >= minCol ; i --) |
| array [ maxRow ][ i ] = count ; |
| count ++; |
| > |
| maxRow = maxRow - 1 ; |
| for ( int i = maxRow ; i >= minRow ; i --) |
| array [ i ][ minCol ] = count ; |
| count ++; |
| > |
| minCol = minCol + 1 ; |
| > |
| for ( int i = 0 ; i < row ; i ++) |
| for ( int j = 0 ; j < col ; j ++) |
| System . out . printf ( "%3d " , array [ i ][ j ]); |
| > |
| System . out . println ( "" ); |
| > |
| > |
| > |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Заполнение двумерной матрицы по спирали
На днях встретил простую на вид задачу. Как оказалось, не легко решить такую задачу за пять, и даже за 50 минут. Здесь пришлось подумать и поэкспериментировать.
Дана матрица, или, на нашем языке, двумерный массив. Его размеры не могут превышать 10х10. Они задаются пользователем и это может быть не только квадрат, но и прямоугольник. Обозначим длины сторон через N и M. Нам необходимо заполнить эту матрицу числами от 1 и по возрастающей до M*N. Прежде, чем привести код целиком, мне хотелось бы изложить ход мыслей, чтобы стало понятно как все работает. Если же тебе просто нужно решение, то ты можешь пролистать ниже, скопировать его и закрыть страницу как больше не нужную.
Стандартно, нам нужен сам массив и переменные для хранения длин сторон прямоугольного (двумерного) массива.
int a[10][10] = ; int N, M;
Также мы будем действовать по слогике, что при заполнении мы очерчиваем прямоугольники, каждый их которых на единицу меньше с каждой стороны. Если смотреть на эти прямоугольники в декартовой системе координат, то начало каждой из сторон сдвигается на 1 вправо или вниз, а конец влево или вверх. Договоримся, что оси направлены вправо и вниз от точки [0,0].
Таким образом нам нужно знать точки начала и конца очерчиваемого прямоугольника. Это и будут точки излома (поворота). Но я еще и решил пойти следующим путем. Точки конца сторон будут равняться длине стороны первого прямоугольника минус длине текущего прямоугольника.
Обозначим их следующим образом:
int Ibeg = 0, Ifin = 0, Jbeg = 0, Jfin = 0;
Ну, и, нам нужна переменная, значением которой мы будем заполнять массив, пока она не достигнет значения M*N
int k = 1;
В цикле начинаем заполнять массив. Сначала точке a[i][j] присваиваем значение k. Это удобно тем, что если длина сторон равна 0, то мы не войдем в массив. Иначе в точку a[i][j] положим значение k, в конце же цикла инкреминируем его.
a[i][j] = k; /** * Код между началом и концом цикла */ ++k;
Далее вычисляем следующий шаг
- Если у нас верхняя сторона прямоугольника и мы не достигла правой стороны, то двигаемся вправо: ++j
- Если мы на правой стороне прямоугольника и не достигли нижней стороны, то двигаемся вниз: ++i
- Если мы на нижней стороне прямоугольника и не достигли левой стороны, то двигаемся влево: --j
- Иначе двигаемся вверх: --i
if (i == Ibeg && j < M - Jfin - 1) ++j; else if (j == M - Jfin - 1 && i < N - Ifin - 1) ++i; else if (i == N - Ifin - 1 && j >Jbeg) --j; else --i;
В конце же каждого прохода проверяем, завершился ли прямоугольник и стои ли начинать прочерчивать новый - меньший:
- Если мы находимся на второй строке
- Если мы находимся на первом столбце
- И, в случае, если чертим не прямоугльник, а вертикальную линию, если первая строка не равна последней. (этот пункт самый сложный во всем алгоритме. Его я достиг путем экспериментов)
Тогда увеличиваем отступы от краев первого прямоугольника:
if ((i == Ibeg + 1) && (j == Jbeg) && (Jbeg != M - Jfin - 1))
Собственно это весь алгоритм. А ниже код всей программы:
#include int main() < int a[10][10] = ; int N, M; scanf("%d%d", &N, &M); int Ibeg = 0, Ifin = 0, Jbeg = 0, Jfin = 0; int k = 1; int i = 0; int j = 0; while (k Jbeg) --j; else --i; if ((i == Ibeg + 1) && (j == Jbeg) && (Jbeg != M - Jfin - 1)) < ++Ibeg; ++Ifin; ++Jbeg; ++Jfin; >++k; > for (int i = 0; i < 10; ++i)< for (int j = 0; j < 10; ++j) printf("%3d", a[i][j]); printf("\n"); >return 0; >
Я видел более изящные решения данной задачи, наполненные математикой и побитовыми операциями. Но для понимания того, как последовательно наполняется пассив по спирали, достаточно данного алгоритма. Буду рад, если вы оставите в комментариях свои решения и поделитесь мыслями.