Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 | 3 |

 

  Вопрос: Многмерные массивы Добавлено: 04.07.06 17:38  

Автор вопроса:  ЛеШий
Имеется многомерный массив El(i, j, k). Вначале заполняется значение k, затем j и в последнюю очередь – i. Например:

For i = 1 to 3
  For j = 1 to 5
    For k = 1 to 10
      ‘запись элемента массива El(i, j, k)
    Next k
  Next j
Next i

Величины i, j и k разные. Оператор ReDim изменяет только крайнее правое значение (в данном случае - k).
Как можно заполнить подобный массив в таком цикле?

Ответить

  Ответы Всего ответов: 34  

Номер ответа: 1
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #1 Добавлено: 04.07.06 18:32
А ты сразу укажи размер массива
Dim El(3, 5, 10) as Byte
И заполняй на здоровье..

Ответить

Номер ответа: 2
Автор ответа:
 ЛеШий



Вопросов: 21
Ответов: 41
 Профиль | | #2 Добавлено: 05.07.06 09:28
Пока я так и делаю, но практичнее будет использовать динамические масивы.

Ответить

Номер ответа: 3
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #3 Добавлено: 05.07.06 12:21
практичнее будет использовать динамические масивы.

Это утверждение верно далеко не в каждой ситуации. Тесты показывают, что операция ReDim, и особенно ReDim Preserve, очень и очень ресурсоемки!! А в твоем случае это вообще будет проблемой. Поскольку размер первых 2-х границ ты изменить не сможешь, то тебе наверняка придется искать какой то выход. Либо заново пересобирать масси, либо еще что-то.. Лично я в подобных ситуациях предпочитаю использовать, вместо динамического массива, HashTable

Ответить

Номер ответа: 4
Автор ответа:
 ЛеШий



Вопросов: 21
Ответов: 41
 Профиль | | #4 Добавлено: 06.07.06 15:49
В общем решил я не париться с многомерными массивами и запихал одномерные массивы в другой массив, т.е. получил массив массивов. Вешь очень даже занимательная... Правда, появилась и другая проблемма.
Когда я использую такую схему:

For...
  For...
    'создание одномерного
    'массива типа Object
  Next
  'создание массива массивов
Next

все работает превосходно. А вот когда я использую такую схему:

For...
  For...
    'создание одномерного
    'массива типа Object
  Next
  If...
    'создание массива M(i) массивов
  End If
Next

то, при записи (ReDim Preserve M(i)) следующего элемента, перезаписывается и предыдущие элементы. Т.е. если M(0)=массив1, то при попытке присвоить M(1)=массив2, перезаписывается и M(0) (тоже на массив2). И получается, что весь массив заполняется последним элементом массив2.
Единственная разница между двумя вышеприведенными схемами: в первом случае все массивы динамические, а во втором случае массив1 статический - без этого ни как. Может кто подскажет как решается сия проблема.

Ответить

Номер ответа: 5
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #5 Добавлено: 06.07.06 20:47
опять ты за свое.. :-)))
ну нафига те весь этот геморрой с массивами?
сделай проще!!
 Создай структуру.. в ней 3 поля.. I,J,K.. Её будешь использовать в качестве ключа в HashTable. А в качестве значения записывай то, что по идее должно было быть в твоем массиве. И на этом все!!
Дальше, когда понадобится, по ключу выдергиваешь нужный тебе элемент из коллекции..
И это очень и очень удобно.. поверь мне.. если только у тебя нет каких то особых требований к использованию массива..

Ответить

Номер ответа: 6
Автор ответа:
 Sacred Phoenix



ICQ: 304238252 

Вопросов: 52
Ответов: 927
 Профиль | | #6 Добавлено: 07.07.06 00:29
Вот на всякий случай (EROS, поправь меня, если надо, я в смысле быстродействия :) ):
Public Class Form1

Private Structure Key
Dim I As System.Int32
Dim J As System.Int32
Dim K As System.Int32

Public Sub New(ByVal Key_I As System.Int32, ByVal Key_J As System.Int32, ByVal Key_K As System.Int32)
I = Key_I
J = Key_J
K = Key_K
End Sub
End Structure

Private M As New System.Collections.Hashtable

Private Sub Form1_Load(ByVal Sender As System.Object, ByVal Args As System.EventArgs) Handles MyBase.Load
Dim Random As New System.Random(My.Computer.Clock.TickCount)

For I As System.Int32 = 0 To 9
For J As System.Int32 = 0 To 9
For K As System.Int32 = 0 To 9
M.Add(New Key(I, J, K), Random.Next(0, 100))
Next
Next
Next

Me.Text = M.Item(New Key(3, 4, 5)).ToString
End Sub

End Class

Ответить

Номер ответа: 7
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #7 Добавлено: 07.07.06 01:23
Ну да! Именно об этом я и говорил!!!
Согласись, что все просто до безобразия!!
А что касается быстродействия, так единственное, что могу посоветовать, так это при объявлении HashTable сразу указывать максимальный размер будущей коллекции:
Private M As New System.Collections.Hashtable(1000)

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

Ответить

Номер ответа: 8
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #8 Добавлено: 07.07.06 01:59
Бред какой-то, зачем здесь вообще хэш таблица?

Тебе нужна штука которая называется Jugged Arrays.
С ее помощью ты можешь вложить массивы друг в друга, и это будут именно массивы, а не какие-то объекты которые на самом деле не нужны.

Dim Data()()() As Integer

Ответить

Номер ответа: 9
Автор ответа:
 ЛеШий



Вопросов: 21
Ответов: 41
 Профиль | | #9 Добавлено: 07.07.06 09:40
2Brand:
Я как раз так и сделал. Но все равно это не очень удобно и не всегда получается.

Что же касается HashTable, то с этим я пока не работал. Попробую сегодня разобраться.

Ответить

Номер ответа: 10
Автор ответа:
 Sacred Phoenix



ICQ: 304238252 

Вопросов: 52
Ответов: 927
 Профиль | | #10 Добавлено: 07.07.06 11:31
хотя разница будет весьма небольшой.. в тысячные доли миллисекунды..

могу сказать точно (рез-ты на моём компе):
при выделении памяти динамически - 19-25 ms
при выделении памяти предварительно - 10-11 ms

Ответить

Номер ответа: 11
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #11 Добавлено: 07.07.06 14:54
Brand

Бред какой-то, зачем здесь вообще хэш таблица?

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

и это будут именно массивы, а не какие-то объекты

А по твоему.. массив - это не объект???

Ответить

Номер ответа: 12
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #12 Добавлено: 07.07.06 15:05
Во первых.. это не бред, а реальный совет, как выйти человеку из его ситуации..
Во вторых.. этот способ гораздо удобнее и прощее (имхо)


удобнее и проще?
ну расскажи тогда как ты предлагаешь в твоем варианте изменять размер массива

Ответить

Номер ответа: 13
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #13 Добавлено: 07.07.06 15:10
Sacred Phoenix,
разница по времени в 2 раза.. это уже более,чем ощутимо.. по моему.. вывод очевиден..

Ответить

Номер ответа: 14
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #14 Добавлено: 07.07.06 15:19
ну расскажи тогда как ты предлагаешь в твоем варианте изменять размер массива

ты сам то понял, что сказал???
Это с каких это пор в коллекции надо изменять размер? Учи мат.часть!!!
То, что при объявлении сразу указывается размер, это не говорит о том, что этот размер установлен жестко! Это говорит лишь о том, что коллекция сразу выделяет память для 1000 элементов.. Но если ты добавишь туда не 1000 , а скажем 5000 элементов, то ошибки никакой не будет.. Просто процесс добавления элементов будет несколько медленнее работать.. вот и все!
К тому же, если по каким либо причинам не подходит HashTable, можно использовать любую другую коллекцию, позволяющие хранить объекты типа ключ-значение..
И я отказался от массивов, как таковых, только по 1 причине, что в них крайне неудобно удалять элементы.. В то время, как в коллекции, это можно сделать элементарно.. хоть по индексу, хоть по ключу, хоть по самомму объекту.. плюс в коллекции еще куча всяких полезных и удобных фич...

Ответить

Номер ответа: 15
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #15 Добавлено: 07.07.06 16:20
разница по времени в 2 раза.. это уже более,чем ощутимо.. по моему.. вывод очевиден..

Во-первых, никто не видел кода на котором проводился бенчмарк, объемов данных, над которыми работал код, поэтому говорить сейчас о том, много это или мало - сущий бред.

Положа руку на сердце, пофиг, сколько будет выполняться такая процедура - 20 мс, 40 мс или 2 секунды - это все в пределах погрешности.

Это с каких это пор в коллекции надо изменять размер?

Перечитай вопрос.

Вообще, у меня возникло подозрение что ты путаешь понятия хэщ-таблица и коллекция.

На всякий случай поясню.
ArrayList, List, CollectionBase, Collection (та которая System.Collections.ObjectModel.Collection) имеют функциональность коллекции, "внизу" у них лежит массив, размер которого может быть при необходимости увеличен.
Небольшая ремарка - размер увеличивается не на 1 элемент, а на бОльшее кол-во элементов, это позволяет сэкономить время при последующих добавлениях элемнетов.
Эти классы отличаются друг от друга только степенью своей типизированости и абстрактности.

HashTable, Dictionary, DictionaryBase и KeyedCollection - это так называемые хэш-таблицы, элементы в них хранятся пары ключ-значение.
Опять же, внизу этих классов лежит тот же массив.

Возвращаясь к предложеному тобой варианту и моему вопросу.
У тебя хранится в хэщ-таблице хранится набор из 3-х значений, каждое из которых позволяет якобы идентифицировать элемент.
Теперь считаем, сколько мы имеем лишних объектов в памяти, и какие накладные расходы получаем при оперировании хэш-таблицей (учти, что время поиска элемента в массиве - O(n), а не O(log(n)), поискольку используется перебор, а не двоичный поиск), прибавляй к этому время на упаковку/распаковку структуры, про сдвиг массива при удалении элемента (O(1)) я вообще молчу.

И после этого ты будешь утверждать, что работать с Dictionary удобнее и этот метод будет якобы быстрее???

Это тебе надо учить матчасть.

Ответить

Страница: 1 | 2 | 3 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам