Тема: Обработка одномерного динамического массива

Помогите пожалуйста разобраться с обработкой одномерного динамического массива.
Вид массива:
1) Название детали
2)Обозначение
3)Принадлежность
4)Номер
Далее идет следующая деталь
6) Название детали
7)Обозначение
8)Принадлежность
4)Номер
и т.д.

Нужно сравнить 1 деталь со 2 деталью,  потом с третьей и т.д. и если они одинаковые - лишние убрать и преобразовать массив в следующий вид:
1) Название детали
2)Обозначение
3)Принадлежность
4)Номер
5)КОЛИЧЕСТВО ОДИНАКОВЫХ ДЕТАЛЕЙ.

Re: Обработка одномерного динамического массива

Ситуация заключается в том, что массив формируется "навалом" разных деталей и естественно в нем есть одинаковые.
Как вообще сортировать массивы???
Может у кого есть литературка по этой теме???

Re: Обработка одномерного динамического массива

Дарья, а элементами массива являются данные пользовательского типа?

Public Type MyType
         ..............
         ..............
         ..............
     End Type

   
И еще. Как определяется размер массива? Может есть смысл использовать коллекцию объектов?

Ну а в общем случае надо создать дополнительную структуру (массив, коллекцию) и перебрасывать туда свои элементы после обработки первичной структуры.

Из литературы по сортировке (да и по структурам данных) могу посоветовать:
Род Стивенс
"Visual Basic
Готовые алгоритмы."

Re: Обработка одномерного динамического массива

С праздником !
:)

Option Explicit
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Type DetailIdentity
A_Name As String
B_Designation As String
C_Accessory As String
D_Number As String
E_Count As Integer
End Type
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub aha()

Dim a As Variant
a = Array( _
"detail_31", "desc_31", "access_11", "num_11", _
"detail_21", "desc_21", "access_21", "num_21", _
"detail_41", "desc_41", "access_41", "num_41", _
"detail_11", "desc_11", "access_11", "num_11", _
"detail_11", "desc_11", "access_11", "num_11", _
"detail_31", "desc_31", "access_31", "num_31", _
"detail_31", "desc_31", "access_31", "num_31", _
"detail_21", "desc_21", "access_21", "num_21", _
"detail_41", "desc_41", "access_41", "num_41", _
"detail_31", "desc_31", "access_31", "num_31", _
"detail_11", "desc_11", "access_11", "num_11")
Dim b() As DetailIdentity
Call CountDetails(b, a, 4)

End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Private Sub CountDetails(ByRef DetailIdentities() _
As DetailIdentity, ByVal Source As Variant, ByVal num As Integer)

Dim Item As Variant
Dim i As Integer, j As Integer, k As Integer

ReDim DetailIdentities(0) As DetailIdentity
For i = 0 To UBound(Source) Step num
ReDim Preserve DetailIdentities(k) As DetailIdentity
DetailIdentities(UBound(DetailIdentities)).A_Name = Source(i)
DetailIdentities(UBound(DetailIdentities)).B_Designation = Source(i + 1)
DetailIdentities(UBound(DetailIdentities)).C_Accessory = Source(i + 2)
DetailIdentities(UBound(DetailIdentities)).D_Number = Source(i + 3)
DetailIdentities(UBound(DetailIdentities)).E_Count = 0
k = k + 1
Next i

For i = 0 To UBound(Source) Step num
Item = Source(i)
For j = LBound(DetailIdentities) To UBound(DetailIdentities)
If Item = DetailIdentities(j).A_Name Then
DetailIdentities(j).E_Count = DetailIdentities(j).E_Count + 1
End If
Next j
Next i

Dim Coll As Collection
Set Coll = New Collection
For j = LBound(DetailIdentities) To UBound(DetailIdentities)
Dim tmp(4) As Variant
tmp(0) = DetailIdentities(j).A_Name
tmp(1) = DetailIdentities(j).B_Designation
tmp(2) = DetailIdentities(j).C_Accessory
tmp(3) = DetailIdentities(j).D_Number
tmp(4) = DetailIdentities(j).E_Count
On Error Resume Next
Coll.Add Item:=tmp, key:=CStr(tmp(1))
Next j
j = 0
Dim elem
For Each elem In Coll
ReDim Preserve DetailIdentities(0 To j) As DetailIdentity
DetailIdentities(j).A_Name = elem(0)
DetailIdentities(j).B_Designation = elem(1)
DetailIdentities(j).C_Accessory = elem(2)
DetailIdentities(j).D_Number = elem(3)
DetailIdentities(j).E_Count = elem(4)
j = j + 1
Next
Debug.Print "Name" & vbTab & "Count" & vbCr & "|____________________|"
j = 0
For i = LBound(DetailIdentities) To UBound(DetailIdentities)
Debug.Print DetailIdentities(i).A_Name & vbTab & DetailIdentities(i).E_Count
j = j + CInt(DetailIdentities(i).E_Count)
Next i
Debug.Print "|____________________|" & vbCr & "Total: " & j
End Sub

~'J'~

Re: Обработка одномерного динамического массива

> LeonidSN
>fixo
Огромное спасибо за помощь :)  и поздравление :{}

Re: Обработка одномерного динамического массива

Рад помочь
Можно также обойтись без типов,
но это будет немного сложнее
Если будет время я напишу

Успехов  :)

~'J'~

Re: Обработка одномерного динамического массива

Скажите пожалуйста как можно рассортировать массив по другому признаку (массив As String объявлен):

0).....
1)(2х1х1)+(4х1х1)
2).....
3).....
4).....
5).....
'следующий элемент
6).....
7)(4х1х1)
8).....
9).....
10).....
11).....
'следующий элемент
12).....
13)(2х1х1)
14).....
15).....
16).....
17).....
и т.д.

Этот массив после сортировки должен принять вид:
0).....
1)(2х1х1)
2).....
3).....
4).....
5).....

'следующий элемент
6).....
7)(4х1х1)
8).....
9).....
10).....
11).....

'следующий элемент

0).....
1)(2х1х1)+(4х1х1)
2).....
3).....
4).....
5).....

и т.д.

Т.е. по возрастанию сначала все элементы типа (2х1х1), (2х2х1),(2х3х1),(2х4х1) и т.д.
затем все элементы (4х1х1), (4х2х1),(4х3х1),(4х4х1)
ну и напоследок все элементы типа (2х1х1)+(4х1х1), (2х2х1)+(4х1х1) и т.д.

Re: Обработка одномерного динамического массива

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


Я представляю это так:
Первый элемент массива сравнивается со всеми остальными и если он самый маленький, то он записывается первым.
Затем второй элемент массива сравнивается со всеми остальными(кроме первого) и если он самый маленький, то он записывается вторым.
Все идет по возрастанию.


Мне не удалось это сделать в цикле, т.к. не всегда первый элемент самый маленький и не всегда второй самый маленький :(

Re: Обработка одномерного динамического массива

Тьфу я напутала с видом массива:
'следующий элемент

Этот массив после сортировки должен принять вид:
0).....
1)(2х1х1)
2).....
3).....
4).....
5).....

'следующий элемент
6).....
7)(4х1х1)
.....
9).....
10).....
11).....

12).....
13)(2х1х1)+(4х1х1)
14).....
15).....
16).....
17).....


и т.д.

Re: Обработка одномерного динамического массива

Скопируй массив в текстовый файл и залей его на FileHosting
Сссылку на файл скинь сюда, нет времени создавать его самому :)

~'J'~

Re: Обработка одномерного динамического массива

Дарья, а может тебе не одномерный массив использовать? Как-то более структурировано было бы, если б данные были рассортированы. То есть, к примеру, создаешь динамический массив:

Dim Arr() as Variant

Потом (если я не ошибаюсь, ты все совершенствуешь программу создания спецификаций по опорам?  :) ) считываешь данные с объекта (с атрибутов блоков там или через Xdata) во "временный" массив

sub read_data()
...
Dim temp(0 to 5)
...
temp(0)=...' чтение данных у тебя уже как-то организовано
...
temp(5)=...
' и затем присваиваешь очередному элементу  Arr(i) значение массива temp:
Redim preserve Arr(ubound(Arr)+1)
Arr(ubound(Arr))=temp
...
end sub

Ну и с этим массивом будет уже проще, мне кажется, работать, чем с линейным.

Re: Обработка одномерного динамического массива

> fixo
http://webfile.ru/3088813
:)


>AlexV
Надо подумать :)

Re: Обработка одномерного динамического массива

Завтра посмотрю, файл скачал  8)

~'J'~

Re: Обработка одномерного динамического массива

> fixo
Хорошо


>AlexV
Неплохая идея!!!
А сортировать данные каким образом?
Я так поняла Вы предлагаете создать временный массив, а потом заполнить основной?
А каким образом заполнить основной? Надо поставить кучу условий If...Then?
У меня с сортировкой беда возникает. Можно создать и двухмерный и трехмерный и 60-мерный массив, но все равно надо сортировать данные каким-то образом.

Re: Обработка одномерного динамического массива

Может кто-нибудь теоретически расскажет как сортировать массивы???
Я делаю так:
1)создаю копию массива
2)начинаю сравнивать
  первую строку первого массива со всеми строками второго массива
  затем вторую строку первого массива со всеми строками второго массива
и т.д.
3)если при сравнении строк выполняется какое-либо заданное условие, то создается третий массив и в него закидывается строка, удовлетрворяющая условие

4)все это происходит в цикле
5)когда все строки сравнены между собой - цикл завершается :)

Re: Обработка одномерного динамического массива

Попробуй так

Option Explicit
' see also:
'  http://forum.developing.ru/showthread.php?p=53799#post53799
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
' written by Fatty T.O.H. (c)2006 * all rights removed '
' SourceArr - two dimensional array ' двухмерный массив
' iPos - "column" number (starting from 1) ' физический номер столбца
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Public Function CoolSort(SourceArr As Variant, iPos As Integer) As Variant

Dim Check As Boolean
ReDim tmpArr(UBound(SourceArr, 2)) As Variant
Dim iCount As Integer
Dim jCount As Integer
Dim nCount As Integer

iPos = iPos - 1
Check = False

Do Until Check
Check = True
For iCount = LBound(SourceArr, 1) To UBound(SourceArr, 1) - 1
If SourceArr(iCount, iPos) > SourceArr(iCount + 1, iPos) Then
For jCount = LBound(SourceArr, 2) To UBound(SourceArr, 2)
tmpArr(jCount) = SourceArr(iCount, jCount)
SourceArr(iCount, jCount) = SourceArr(iCount + 1, jCount)
SourceArr(iCount + 1, jCount) = tmpArr(jCount)
Check = False
Next
End If
Next
Loop

CoolSort = SourceArr

End Function
' usage example
Sub AA1()
ReDim ar(2, 3) As String
ar(0, 0) = "Cabinet1": ar(0, 1) = "Y-Total1": ar(0, 2) = "x1": ar(0, 3) = "Stud 1"
ar(1, 0) = "Cabinet1": ar(1, 1) = "Y-Total1": ar(1, 2) = "x3": ar(1, 3) = "Stud 1"
ar(2, 0) = "Cabinet1": ar(2, 1) = "Y-Total1": ar(2, 2) = "x2": ar(2, 3) = "Stud 1"
Dim res, i, j, msg As String
res = CoolSort(ar, 3)
msg = ""
For i = 0 To UBound(res, 1)
For j = 0 To UBound(res, 2)
msg = msg & " | " & res(i, j) & " | "
Next
msg = msg & vbCr
Next
MsgBox msg
End Sub

Sub Test()
Dim i As Long, j As Long
Dim newar As Variant
Dim arr(10, 3) As Integer
For i = 0 To 9
For j = 0 To 3
arr(i, j) = (-1 * i) ^ j
Next
Next
newar = CoolSort(arr, 2)

End Sub

~'J'~

Re: Обработка одномерного динамического массива

Может кто-нибудь теоретически расскажет как сортировать массивы???

Я делаю так:
...............
2)начинаю сравнивать

Дарья, задумайся пожалуйста, над своими задачами.
Сортировать массивы и сравнивать элементы в массиве не одно и то же.

Алгоритмы сортировки это целая наука. Почитай книжки.

Re: Обработка одномерного динамического массива

> fixo
А куда мой массив одставить??? Трудно соорентироваться :)

Re: Обработка одномерного динамического массива

Не доставай меня  :evil:


Option Explicit
' see also:
'  http://forum.developing.ru/showthread.php?p=53799#post53799
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
' written by Fatty T.O.H. (c)2006 * all rights removed '
' SourceArr - two dimensional array '
' iPos - "column" number (starting from 1) '
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Public Function CoolSort(SourceArr As Variant, iPos As Integer) As Variant

Dim Check As Boolean
ReDim tmpArr(UBound(SourceArr, 2)) As Variant
Dim iCount As Integer
Dim jCount As Integer
Dim nCount As Integer

iPos = iPos - 1
Check = False

Do Until Check
Check = True
For iCount = LBound(SourceArr, 1) To UBound(SourceArr, 1) - 1
If SourceArr(iCount, iPos) > SourceArr(iCount + 1, iPos) Then
For jCount = LBound(SourceArr, 2) To UBound(SourceArr, 2)
tmpArr(jCount) = SourceArr(iCount, jCount)
SourceArr(iCount, jCount) = SourceArr(iCount + 1, jCount)
SourceArr(iCount + 1, jCount) = tmpArr(jCount)
Check = False
Next
End If
Next
Loop

CoolSort = SourceArr

End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Private Function FillArray(ByVal fn As String) As String()

Dim ar() As String
Dim st As String
Dim i
Open fn For Input As #1
Do While Not EOF(1)
    Line Input #1, st
    ReDim Preserve ar(i)
    ar(i) = st
    i = i + 1
Loop
Close #1
FillArray = ar

End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Function GetCountBy(ByRef ar() As Variant) As Collection
Dim i As Integer, j As Integer, k As Integer, n As Integer, qty As Integer
Dim col As New Collection
Dim res As New Collection
'//
For i = LBound(ar, 1) To UBound(ar, 1)
For j = 0 To UBound(ar, 2)
On Error Resume Next
col.Add ar(i, 1), ar(i, 1)
Next
Next
'//
For i = 1 To col.Count
Dim match As String
match = CStr(col.Item(i))
qty = 0
ReDim tmp(UBound(ar, 2) + 1) As String
'//
For n = LBound(ar, 1) To UBound(ar, 1)
If StrComp(ar(n, 1), match) = 0 Then
For j = LBound(ar, 2) To UBound(ar, 2)
tmp(j) = ar(n, j)
Next j
Exit For
End If
Next n
tmp(j + 1) = 0
'//
For k = LBound(ar, 1) To UBound(ar, 1)
If StrComp(ar(k, 1), match) = 0 Then
qty = qty + 1
End If
Next k
tmp(UBound(tmp)) = qty
'//
On Error Resume Next
res.Add tmp, match
Next i
'//
Set GetCountBy = res
'//
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Sub TestGroupping()
Dim fn As String
'// имя текстового файла измени
fn = "C:\MASSIVE.txt"
'//
Dim ee() As String
ee = FillArray(fn)
'// вместо чтения массива из файла можешь использовать
'// свой исходный одномерный массив напрямую.
Dim i, j, k
ReDim na((UBound(ee) + 1) \ 6 - 1, 5)
For i = 0 To (UBound(ee) + 1) \ 6 - 1
For j = 0 To 5
na(i, j) = ee(k)
k = k + 1
Next
Next
'//
Dim sorted() As Variant
sorted = CoolSort(na, 2)
Dim ah As New Collection
''// сгруппированная коллекция с суммами вхождений элемента в массиве:
Set ah = GetCountBy(sorted) '--> то что тебе нужно, далее можешь преобразовать ее в массив:
ReDim countArr(0 To ah.Count - 1, 0 To UBound(ah.Item(1))) As String
For i = 1 To ah.Count
For j = 0 To UBound(ah.Item(1))
countArr(i - 1, j) = ah.Item(i)(j)
Next
Next

End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

~'J'~

Re: Обработка одномерного динамического массива

> fixo
Спасибо!  :oops:
;)

Re: Обработка одномерного динамического массива

Успехов :)

~'J'~