Страница: 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, поправь меня, если надо, я в смысле быстродействия  
    
 ):
	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 сразу указывать максимальный размер будущей коллекции:
Поскольку динамически выделять память для каждого элемента будет медленнее, чем сделать это 1 раз.. хотя разница будет весьма небольшой.. в тысячные доли миллисекунды..
		
	  
			 
	
		 
    
       
    
Номер ответа: 8 
      
Автор ответа:
 Artyom
![]()
![]()
![]()
![]()
![]()
![]()
![]()
Разработчик
Вопросов: 130
Ответов: 6602
      
 Профиль |  | #8
       
Добавлено:  07.07.06 01:59
       
    
       
  
Бред какой-то, зачем здесь вообще хэш таблица?
 
    
Тебе нужна штука которая называется Jugged Arrays.
С ее помощью ты можешь вложить массивы друг в друга, и это будут именно массивы, а не какие-то объекты которые на самом деле не нужны.
		
	  
			 
	
		 
    
       
    
Номер ответа: 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
       
    
       
  
 
    
Во-первых, никто не видел кода на котором проводился бенчмарк, объемов данных, над которыми работал код, поэтому говорить сейчас о том, много это или мало - сущий бред.
Положа руку на сердце, пофиг, сколько будет выполняться такая процедура - 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 удобнее и этот метод будет якобы быстрее???
Это тебе надо учить матчасть.