![]() |
|
Модераторы: bsa |
![]()
|
|
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Заранее прошу прощения, если нужно было не сюда, а в центр помощи, и если невнятно опишу проблему - учу язык всего месяц, да еще и самоучкой... Задачи ищу на просторах инета, и нашел вот такую:
Пользователь вводит матрицу размерностью N*M. Выведете на экран матрицу N*M, элементы которой сдвинуты на один элемент влево относительно исходной матрицы.т.е. первый элемент матрицы будет равен второму элементу исходной матрицы, а последний равен первому. Проблема в сдвиге... С массивом 2*2 проходит вроде как без проблем, а вот с другими...
Были мысли запихнуть в одноменрый массив, сдвинуть, а потом обратно в двумерный, но, это ж, я так понимаю, не верно? Заранее спасибо за любую помощь ) |
|||
|
||||
| gosn1ck |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 103 Регистрация: 18.4.2009 Репутация: 1 Всего: 1 |
и что же вы все пробелы то не любите.... ?
|
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Пробелы я люблю... Только здесь нагляднее было в строку, ну да ерунда это...
Да, ваш код работает. Спасибо. Вот только... Делал я так... и на моем коде, если брать массив 4*4, то 4,8 и 12 значения получаются... эм... не знаю, как это правильно сказать... вобщем длинным отрицательным числом (поэтому я и вставлял проверку на равность j)... Потому и обратился за помощью - сам ен могу найти где именно я накосячил ( Если я правильно понимаю, то в какой-то момент j+1 становится равным 4, а такого значения ведь нет... Это сообщение отредактировал(а) Santa12 - 4.6.2009, 14:00 |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Советую поднабраться знаний в сторону отладчиков. Этот вопрос думаю легко бы решился (см. пошаговая отладка). |
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Именно поэтому, я и говорю, что ставил проверку на j... Пошагово прошел по всему что можно... Но моих познаний не хватило. в моем случае, при массиве 4*4 в случае: mass[0][3] = mass[0][3+1] -- у меня в этом месте mass[0][3+1] равняется -33686019 а если напрямую копирую код gosn1ck - в этом месте появляется 5, т.е. значение, которое должно быть в mass[1][0] Это сообщение отредактировал(а) Santa12 - 4.6.2009, 14:35 |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Ты сам ответил на свой вопрос.........
Поясняю, в C индексы массивов начинаются с 0, т.е. [0], [1], [2], [3] уже 4 элемента. У тебя: mass[0] [3+1] <---- Добавлено через 1 минуту Если поподробнее, то ты обращаешься к элементу за массивом, который естессно не инициализирован никаким значением. |
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Я и говорю про это!!! Ммм... Как объяснить... я знаю, что значения 4 тут не существует, и из-за этого, у меня появляется непонятное число. Именно поэтому, я и ставил проверку J, не равно ли оно 4 (в случае 4*4). Но, при этом:
|
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Ты меняешь каждый элемент i,n на m,0. Ты этого хотел? Сомниваюсь.
n,m - размерность массива ЗЫ Если в голове не можешь проработать задачу делай рисунки - на порядок проще думать. ЗЫ Приводи кусок своего кода в постах, ч-то искать по листингу влом, думаю не только мне. Т.к. двигаешь влево надо скопировать первый элемент заранее. А то он затирается при первой же итерации. В конце копируешь это значение в конец. Это сообщение отредактировал(а) fry - 4.6.2009, 14:58 |
|||
|
||||
| Santa12 |
|
||||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Ок. Значит, попробую еще раз... я создаю динамически массив N*M. Передаю его в функцию, которая его сдвигает на одно значение. Первый элемент я сперва копирую в темп, в конце копирую его в последний элемент массива.
А если я просто беру код gosn1ck
Рисовать - рисую, но в данном случае - не помогло... |
||||
|
|||||
| fry |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Проверка как раз и сделана для того, чтобы этого не случилось, т.е. при j=3 она срабатывает и выполняется то, что я описал в предыдущем посте.
будет возвращать один и тотже элемент, а тебе, по моему, надо всего лишь
Только надо проверять чтобы [i+1] не было за пределами массива (последняя итерация). Кстати, гораздо легче будет если ты будешь создавать массив одномерный. его и сдвигать проще и быстрее работать будет. Конкретный элемент в нем можно искать так: i+j*n. Работать будет быстрее, чем у gosn1ck . Это сообщение отредактировал(а) fry - 4.6.2009, 15:29 |
||||||
|
|||||||
| Santa12 |
|
||||||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
ну, для этого я ее и сделал ;) При этом, в коде gosn1ck все отрабатывает без такой проверки. Почему?
вот примерно об этом я изначально и спрашивал... на последней итерации в этом случае вылетает, все правильно, не могу сообразить, как обработать правильно... сообразил. Изначально в этом и была моя ошибка - стормозил, и начал городить огород...
Я хочу с многомерными массивами разобтаться, не переводя их в одномерные ))) С одномерными, вроде бы уже вопросов и не возникает ))) Что ж, всем спасибо ;) Вопрос решен. Это сообщение отредактировал(а) Santa12 - 4.6.2009, 15:42 |
||||||
|
|||||||
| fry |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Т.е. "не наигралсо". В том варианте, который я описал, не надо ничего переводить, он (2мерный) будет храниться в памяти как 1мерный и усе.
Потому, что у него ошибка: На последней итерации
Вообще лучше не решать задачу разными способами, при том что они заведомо хуже первого, а заняться другой. Еще лучьше поставить более менее реальную задачу и ее решить, а не двигать элементы матрицы в двойном цикле. |
||||||||||
|
|||||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Santa12, в статических многомерных массивах элементы располагаются линейно. Т.е весь массив в памяти занимает непрерывный кусок памяти и за последним элементом одной строки идет первый элемент следующей. Динамические многомерные массивы представлены многоуровнево, т.е 2х мерный массив является массивом указателей на одномерные массивы, которые могут лежать в произвольных местах памяти. Именно из этого расхождения представления и получается различное поведение. Это сообщение отредактировал(а) mes - 4.6.2009, 15:55 |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Я и говорил ему о динамическом варианте с линейным расположением элементов. Однако, о каком представлении идет речь если проги работают именно с 2мерным динамическим? ЗЫ И то неправильно. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
О! Не знал что динамический и статический хранятся в памяти по разному! Спасибо! Буду знать. Видимо, или не попалось мне это в книгах/статьях, или не придал этому значения. Потому и не акцентировал внимание, что в приведенном примере был статический массив.
есть такое ;) Есть такая. Но она мне пока не по плечу ) сделал лишь половину, и решил сперва сначала с базовыми вещами разобраться... Вот, разбираюсь... Еще бы со списками понять работу ) Заучил. Теперь не забуду. |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
mes, незаметил объявление, смотрел на работу (2 цикла по индексам) с массивом. Извини за поклеп.
ЗЫ Нах автор второго варианта делал с 2 циклами если лучше с одним?! (только, чтобы показать "как правильно", но это ему тоже до конца не удалось) Все еще думаю что в этом случае(в случае автора темы) лучше динамика с линейным расположением элементов т.к. проще и быстрее. Добавлено через 4 минуты и 28 секунд Santa12, имей ввиду, что хранение динамического массива частями (2мерного) далеко не является рациональным решением т.к. заведомо менее производительно и несколько менее, но все же расточительнее. |
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Учту. Но, я правильно понимаю, что к статическому это замечание не относится? Жаль, никому не могу поставить плюсы. Исправлюсь, как только наберу сотню постов ;) |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
только при запоминании, делайте акцент не на статичность, и динамичность, а на способ выделения памяти под массив. потому как в этом примере динамический массив (хотя динамично только одно его направление) будет располагаться в памяти линейно :
это высказывание требует слишком много оговорок, и в принципе справедливо лишь к "излишнe" занимаемой памяти. |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Santa12, если массив не динамический (статический), то он просто выделяется в стеке в виде линейно упорядоченных элементов,т.е. то, что я описал, только в стеке. Если выделять динамически (предложенный мной вариант), то есть два варианта:
1. выделить также линейно 2. выделить сначала массив указателей, а затем каждый элемент этого массива проинициализировать своей частью памяти. В первом варианте все элементы располагаются рядом. К ним обращение будет происходить без лишних операций со стороны операционной сис-мы(ОС). Во втором возможно падение производительности т.к. ОС не гарантирует что выделенная память будет располагаться за памятью выделенной ранее, что потребует некоторых манипульций со стороны ОС в случае обращения к элементам. К тому же код твоей программы во втором варианте будит несколько днлинее, чем во втором (сложнее будет код выделения массива, высвобождения массиваб работы с массивом).
посмотри на код в постах выше и прикинь код в случае линейного расположения элементов. Вложенности циклов не будет. Проявятся возможности ОС по части кэширования. Проще код, меньше жрет памяти, думаю, что прога возможно будет по размеру меньше (критично в некоторых местах(контроллеры и т.п.)). ЗЫ ты в своем посте проверку на невозможность выделения забыл. Это сообщение отредактировал(а) fry - 4.6.2009, 18:09 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
если это высказывание относится только применительно к конкретному коду, то спорить не буду (см. код лень). Однако для общего случая высказывание не корректно. |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
По какой из частей моего суждения некорректно? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
В том что линейное раположение строк эффективнее в производительности при работе с матрицей, чем не линейное. Речь идет об одном и том же решении примененного к статическому и динамическому массиву. Если решение конкретной задачи приведено к линейному виду, то естественно у него будет преимущество. это обсуждалось в частности здесь : http://forum.vingrad.ru/forum/topic-249780...tml#st_0_view_0 Это сообщение отредактировал(а) mes - 4.6.2009, 18:19 |
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Так... я создаю динамический массив вот таким образом:
mes, т .е. в отличие от приведенного вами варианта, он будет располагаться в памяти не линейно? Я правильно понимаю? fry, а можно немножко пояснить: КАК задать массив линейно? И как выглядит код первого, а как второго вариантов? Приношу свои извинения за назойливость, просто я пока все не "разжую" мне сложно понять что имеется в виду... Если вместо ответа будут ссылки на статьи/книги - тоже буду рад ) |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
правильно, так как выделяете память кусками. хотя это относится к целевому массиву. А вот вспомогательные массивы (строки и массив указателей на строки) располагается линейно. Это сообщение отредактировал(а) mes - 4.6.2009, 18:24 |
|||
|
||||
| fry |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Там нет технологии тестирования, это раз, в данном случае не надо будет вычислять смещение по двум индексам это два. По части всего остального остаюсь при своем.
Кстати
Данная строчка будет не так красиво смотреться при добавнеии обработки исключений. Хотя конечно строчка красивая. mes, при всем уважении
Это не совсем правильно Это сообщение отредактировал(а) fry - 4.6.2009, 18:23 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Согласен, но, думаю, так тс легче будет понять когда массив линейный, а когда нет. Это сообщение отредактировал(а) mes - 4.6.2009, 18:26 |
|||
|
||||
| fry |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Это сообщение отредактировал(а) fry - 4.6.2009, 18:28 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
При чем тут исключения по отношению к подобной записи ? В том примере использовался динамический массив строк постоянной длины. И ничего особенного от обычного синтаксиса массивов не имеет. Добавлено @ 18:34 т.е Вы утверждаете что что new int[n][20]; вернет массив, элементы которого расположены не линейно ?! Это сообщение отредактировал(а) mes - 4.6.2009, 18:35 |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Ну может именно с исключениями я конечно перебарщил, но проверку на корректное выделение памяти для каждой части массива провести необходимо.
Или я чего не понял, тогда поясни. Мне как-то приплюснутый вариант выделения через stl более по душе. Добавлено @ 18:39 Все допер.. Сорри. Добавлено @ 18:41 В твоем случае и в моем я ч-то не заметил разницы в смысле, а в синтаксисе огромная. Поясни почему сделал так. Если не сложно. Это сообщение отредактировал(а) fry - 8.6.2009, 00:05 |
|||
|
||||
| Santa12 |
|
|||
|
вечный чечако Профиль Группа: Участник Сообщений: 46 Регистрация: 20.5.2009 Репутация: нет Всего: нет |
Еще раз спасибо )
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Для того чтоб показать, что если в массиве только одно измерение динамическое, то можно для него выделить общий кусок памяти и соответственно элементы будут располагаться линейно. |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
В целом, лично для меня, данный синтаксис имеет преимущество в виде возможности писать " [ i ][ j ] "
И недостатки: синтаксис ( ИМХО ИМХО ИМХО ИМХО ИМХО ИМХО ), статика одного измерения. Кстати подозреваю, что вычисление смещения по индексам будет темже (подозреваю). Рад за mes, что повесилил. Это сообщение отредактировал(а) fry - 4.6.2009, 18:56 |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Это следствие, так как наш массив объявлен многомерным Если быть точнее, то преимущество в том, что одно (но только одно) из измерений является динамическим. Добавлено через 7 минут и 39 секунд
Хотя длина строки и константна, но оптимизация умножения может быть возможно, только в случае констаного индекса строки. Т.е. обращение mas[n][m] требует одинаковых вычислений, mas[5][m] может быть лишен умножения, а mas[5][2] - заменен на линейный индекс. Это сообщение отредактировал(а) mes - 4.6.2009, 18:59 |
||||
|
|||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Думаю ответ на вопрос какой вариант пользовать знает тот, кто знает что ему надо (и к чему он привык): "[ ][ ]" или менее напрягающий код объявления (это про два варианта объявления динамических массивов). Ну и конечно от ситуации зависит.
|
|||
|
||||
| fry |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Понимаю, что тема закрыта, однако создавать по такой мелочевке тему не хочется, да и не надо.
к
Забавы ради и удовлетворения любопытства для провел тест на ОС Linux (Fedora 10) на линейные и нелинейные массивы, точнее скорости выделения и работы. Код теста (взят частично отсюда, переделан за неимением conio и vcl):
Выдает: Без оптимизации: Create On Pointers = 50000 Create solid = 0 Fill pointers = 900000 Fill solid = 920000 С оптимизацией: Create On Pointers = 40000 Create solid = 0 Fill pointers = 540000 Fill solid = 540000 ЗЫ ДАННЫЙ ПОСТ НЕ ИМЕЕТ ЦЕЛЬ ЧЕГО-ТО ДОКАЗАТЬ |
||||
|
|||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |