Войти

Показать полную графическую версию : Помогите написать программу, которая будет превращать двумерный массив в одномерный


Normandez
15-10-2015, 22:25
Собственно, задача заключается в том, что бы превратить двумерный массив (он должен быть динамическим и пользователь вводит каждый элемент) в одномерный путём считывания его элементов по часовой стрелке (как на картинке). Размерность задаётся пользователем, впрочем, как и элементы. Так вот, проблема именно с этим считыванием. Как его сделать правильно?? Я пробовал с помощью строк (string), но ничего не получилось (хотя, казалось бы, учёл всё что можно). Прошу помощи! Вот мой код:

#include<iostream>;
#include<cstring>

using namespace std;

int main(){
int m,n;
float provnch=0.25,provch=0.75,prov1,prov2;
string str1;
cin>>m;
cin>>n;
char**arr1=new char *[m]; //Задаём двумерный массив. Он должен быть квадратным!! Да, я знаю что не сделал условие, мол, если пользователь
for (int i=0;i<m;i++) arr1[i]=new char [n]; //введёт разное число строк и столбцов, но то для экономии времени. Так что считаем эту матрицу квадратной (m=n).
for (int i=0;i<m;i++) for (int j=0;j<n;j++) cin>>arr1[i][j];
for (int i=0;i<m;i++){
for (int j=0;j<n;j++) cout<<arr1[i][j]<<" ";
cout<<endl;
}
prov1=(m-1)*0.5+0.25;
prov2=(m-2)*0.5+0.75;
for (int f=0,g=0,v=-2,d=-1,q=-2,p=1,x=0,y=0;1;m--,n--,x++,y++,p++,q++,d++,v++,g++,f++){ //Эта куча счётчиков нужна для корректного осуществления поворотов.
for (int j=f;j<n;j++){ //Если вы сами проследите за всем процессом на листочке бумаги, то убедитесь, что всё с этими счётчиками верно.
str1.push_back(arr1[x][j]);
if (provnch==prov1) break;
}
for (int i=p;i<m;i++) { //4 цикла означают 4 поворота (ведь нам надо по часовой стрелке квадратный массив, значит - всего 4 поворота)
str1.push_back(arr1[i][n-1]); //Общий цикл нужен для корректировки этих поворотов (что бы не попадали прошлые символы снова) и для пары общих счётчиков
}
for (int j=n+q;j>d;j--){
str1.push_back(arr1[m-1][j]);
if (provch==prov2) break;
}
for (int i=m+v;i>g;i--){
str1.push_back(arr1[i][y]);
}
provnch++; //Эти 2 последние переменные - вообще отдельная тема. Просто если вы попробуете провести операцию, которую требуют в задаче, то заметите, что для этого
provch++; //надо обрезать выполнение главного цикла (так как всё доходит до последнего элемента и что бы дальше не щло выполнение иначе будут ошибки).
} //Собственно, я думал, что ошибка из-за этого. Сделал эти 2 переменные - всё равно не работает. Кстати, почему эти переменные имеют именно такой вид?
system ("pause"); //Если посмотреть "на бумаге", как должна работать прога, то можно заметить, что остановка должна осуществляться на х.25 итерации(для нечётных m и n)
return 0; //и на х.75 итерации (для чётных), где х - количество целых итераций. Ну тип я так записал дробь. 1.25(для 3х3), 2.75(для 6х6). Если нарисовать эти матрице на листочке, и сделать то, о чём требуют в задаче, то вы поймёте о чём я.
}


Посмотрите, что не так. Или предложите иной способ решения, только с использованием только массивов и строк (никаких доп файлов, доп функций и т.д., так как это ещё не изучали). Ещё раз -- хелп ми плизз!

lxa85
16-10-2015, 10:52
Normandez, параметрически то задачку решить не пробовали?
Разбить квадраты на подквадраты?
Забудьте, что у вас спираль.
Считайте значения по периметру. Просто по периметру, по часовой стрелке.
Затем уменьшите размер квадрата на 1 и считайте еще раз.

Это куча счетчиков - явная ошибка (я даже следить за ней не буду)
И уберите работу со строками - вас об этом не просят. Массив - значит массив.
Для удобства возьмите числа (все что не оговорено явно, трактуется в пользу студента).

Ах, да. Самое главное - дайте переменным нормальные названия!
i, j, k - по умолчанию счетчики. Остальное назвать полными именами.
f=0,g=0,v=-2,d=-1,q=-2,p=1,x=0,y=0;1;m--,n--,x++,y++,p++,q++,d++,v++,g++,f++
Это просто адовый треш. аж в глазах рябит.

Normandez
16-10-2015, 22:05
Спасибки за идею. Действительно, так должно быть проще (через считывание по периметрам). Попробую

Drongo
17-10-2015, 15:16
Разбить квадраты на подквадраты?
Забудьте, что у вас спираль.
Считайте значения по периметру. Просто по периметру, по часовой стрелке.
Затем уменьшите размер квадрата на 1 и считайте еще раз. »Думал тоже, первый вариант решения, наподобии задачки с поиском выхода из лабиринта, тоже обход по периметру(закон поиска пути гласит, из любого лабиринта есть выход если следовать строго по прямой держась за одну из сторон стены). А потом подумал, с обходом по подквадратам проще ведь действительно. Только уменьшается размер квадрата не на 1, а на 2, т.к. допустим у нас размер квадарата 5, то внутренний подквадрат будет не 4, а 3, т.к. минусуются внешние две границы. На примере, внешний квадрат # со сторонами 5, внутренний квадрат * со стороной 3 и ещё один - со стороной 1
# # # # #
# * * * #
# * - * #
# * * * #
# # # # #

Iska
17-10-2015, 19:57
закон поиска пути гласит, из любого лабиринта есть выход если следовать строго по прямой держась за одну из сторон стены »
Не «по прямой», а «не отрывая руку». И только в строго определённом случае.

Drongo
17-10-2015, 20:59
Не «по прямой», а «не отрывая руку». »Да, спасибо за уточнение. Определённый случай только один - когда второго выхода нет, ты всегда вернёшься к точке от которой начал

Iska
17-10-2015, 22:15
Определённый случай только один - когда второго выхода нет, ты всегда вернёшься к точке от которой начал »
Первое не совсем верно. Входов/выходов может быть и несколько. Я про другое.

Лабиринт — Википедия (https://ru.wikipedia.org/wiki/%D0%9B%D0%B0%D0%B1%D0%B8%D1%80%D0%B8%D0%BD%D1%82):
Считается, что если проходить лабиринт, касаясь только одного из краев стенок лабиринта, то этот лабиринт обязательно будет пройден, хотя это не всегда верно: в лабиринте с несвязанными стенами этот способ может не сработать.
Т.е., например, вот такой случай:
http://i.imgur.com/PZyfQtb.png
Будем ли мы пользоваться правилом правой руки или левой руки — выход мы не найдём.

Но второе — что в этом случае мы, рано или поздно, вернёмся в исходную точку — совершенно верно.

Drongo
17-10-2015, 23:14
в лабиринте с несвязанными стенами этот способ может не сработать. »В условии задачи о лабиринте, которую я решал когда-то (http://forum.oszone.net/post-1526413-9.html), отсчёт начинался от точки входа, а не с середины, т.к. прежде чем попасть на середину нужно туда войти\дойти через вход. В данном случае пример сравним с двумя окружностями (можно было не заморачиваться углами), большая окружность с входом и выходом и маленькая в середине без входов и выходов, к которой приложи хоть правую хоть левую руки ты будешь идти по кругу. И по существу этот пример некорректен, чтобы, попасть к такой несвязаной стене, нужно оторвать руку от другой стены, т.е. иметь заведомо не правильную точку отсчёта. Как-то так.

Iska
18-10-2015, 02:45
Дело в том, что как вход, так и выход, могут быть где угодно, не только во внешней стене. Достаточно только представить, что вход и выход — не на плоскости, а в пространстве.

Вот скажем, была такая игрушка:
http://cs619829.vk.me/v619829721/ff0e/p76gudgKYR4.jpg
где надо было провести шарик с внешней окружности к центру — помните?

Drongo
18-10-2015, 13:24
Дело в том, что как вход, так и выход, могут быть где угодно, не только во внешней стене. Достаточно только представить, что вход и выход — не на плоскости, а в пространстве. »Эти условия не для правила правой\левой руки.

mwz
18-10-2015, 14:01
Iska, как вход, так и выход, могут быть где угодно, не только во внешней стене »
На приведённой для иллюстрации игрушке внешняя стена самого лабиринта – слева от текущего положения шарика. :)




© OSzone.net 2001-2012