Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Помогите написать программу, которая будет превращать двумерный массив в одномерный (http://forum.oszone.net/showthread.php?t=306703)

Normandez 15-10-2015 22:25 2564326

Помогите написать программу, которая будет превращать двумерный массив в одномерный
 
Вложений: 1
Собственно, задача заключается в том, что бы превратить двумерный массив (он должен быть динамическим и пользователь вводит каждый элемент) в одномерный путём считывания его элементов по часовой стрелке (как на картинке). Размерность задаётся пользователем, впрочем, как и элементы. Так вот, проблема именно с этим считыванием. Как его сделать правильно?? Я пробовал с помощью строк (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 2564463

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 2564713

Спасибки за идею. Действительно, так должно быть проще (через считывание по периметрам). Попробую

Drongo 17-10-2015 15:16 2564837

Цитата:

Цитата lxa85
Разбить квадраты на подквадраты?
Забудьте, что у вас спираль.
Считайте значения по периметру. Просто по периметру, по часовой стрелке.
Затем уменьшите размер квадрата на 1 и считайте еще раз. »

Думал тоже, первый вариант решения, наподобии задачки с поиском выхода из лабиринта, тоже обход по периметру(закон поиска пути гласит, из любого лабиринта есть выход если следовать строго по прямой держась за одну из сторон стены). А потом подумал, с обходом по подквадратам проще ведь действительно. Только уменьшается размер квадрата не на 1, а на 2, т.к. допустим у нас размер квадарата 5, то внутренний подквадрат будет не 4, а 3, т.к. минусуются внешние две границы. На примере, внешний квадрат # со сторонами 5, внутренний квадрат * со стороной 3 и ещё один - со стороной 1
Код:

# # # # #
# * * * #
# * - * #
# * * * #
# # # # #


Iska 17-10-2015 19:57 2564960

Цитата:

Цитата Drongo
закон поиска пути гласит, из любого лабиринта есть выход если следовать строго по прямой держась за одну из сторон стены »

Не «по прямой», а «не отрывая руку». И только в строго определённом случае.

Drongo 17-10-2015 20:59 2564999

Цитата:

Цитата Iska
Не «по прямой», а «не отрывая руку». »

Да, спасибо за уточнение. Определённый случай только один - когда второго выхода нет, ты всегда вернёшься к точке от которой начал

Iska 17-10-2015 22:15 2565040

Цитата:

Цитата Drongo
Определённый случай только один - когда второго выхода нет, ты всегда вернёшься к точке от которой начал »

Первое не совсем верно. Входов/выходов может быть и несколько. Я про другое.

Лабиринт — Википедия:
Цитата:

Считается, что если проходить лабиринт, касаясь только одного из краев стенок лабиринта, то этот лабиринт обязательно будет пройден, хотя это не всегда верно: в лабиринте с несвязанными стенами этот способ может не сработать.
Т.е., например, вот такой случай:
Скрытый текст

Будем ли мы пользоваться правилом правой руки или левой руки — выход мы не найдём.

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

Drongo 17-10-2015 23:14 2565066

Цитата:

Цитата Iska
в лабиринте с несвязанными стенами этот способ может не сработать. »

В условии задачи о лабиринте, которую я решал когда-то, отсчёт начинался от точки входа, а не с середины, т.к. прежде чем попасть на середину нужно туда войти\дойти через вход. В данном случае пример сравним с двумя окружностями (можно было не заморачиваться углами), большая окружность с входом и выходом и маленькая в середине без входов и выходов, к которой приложи хоть правую хоть левую руки ты будешь идти по кругу. И по существу этот пример некорректен, чтобы, попасть к такой несвязаной стене, нужно оторвать руку от другой стены, т.е. иметь заведомо не правильную точку отсчёта. Как-то так.

Iska 18-10-2015 02:45 2565103

Дело в том, что как вход, так и выход, могут быть где угодно, не только во внешней стене. Достаточно только представить, что вход и выход — не на плоскости, а в пространстве.

Вот скажем, была такая игрушка:
Скрытый текст

где надо было провести шарик с внешней окружности к центру — помните?

Drongo 18-10-2015 13:24 2565200

Цитата:

Цитата Iska
Дело в том, что как вход, так и выход, могут быть где угодно, не только во внешней стене. Достаточно только представить, что вход и выход — не на плоскости, а в пространстве. »

Эти условия не для правила правой\левой руки.

mwz 18-10-2015 14:01 2565228

Iska,
Цитата:

Цитата Iska
как вход, так и выход, могут быть где угодно, не только во внешней стене »

На приведённой для иллюстрации игрушке внешняя стена самого лабиринта – слева от текущего положения шарика. :)


Время: 08:01.

Время: 08:01.
© OSzone.net 2001-