Как найти и удалить дубликаты из "List`а(списка)

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Dmitriy2003 » 27.02.2010 (Сб) 19:26

Хакер писал(а):(ss=ß)?

weiß(белый) - нельзя написать weiss
wissen(знать) - нельзя написать wißen

Правила

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 27.02.2010 (Сб) 21:52

Для начала его(список) мне нужно построить, вот тут - тормоза (на VB) !

"есть ли смыл в поиске в дереве" - конечно есть! А как же иначе искать дубликаты?
Ну для начала: "дубликаты" - это полные пути к файлам (xxx:\workr\p1\proekt_021\винтик_03_32_548.sldprt).
Чтобы открыть этот файл, мне нужно знать полный путь к нему.
Если в сборке 20 деталей и все копии, то они ссылаются на один и тот же файл. А если я примитивно создам список, то там и будет 20 записей с одним и тем же именем. И потом, вторая часть моей программы будет их "тупо открывать". А этого, как раз, мне и не нужно! Даже наооборот - вредно. Тут и возникает вопрос об "очистке списка от дубликатов"...

Насчет этого:
- Кодировка, в которой хранятся имена элементов - думаю в WinXP это значения особого не имеет - не встречал какие-либо трудности
- Регистрозависимость сравнения - не нужно
- Учитываем национальные особенности языка при сравнении (ss=ß)? тоже не нужно.

qwertyhp
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 156
Зарегистрирован: 07.10.2009 (Ср) 15:02
Откуда: Москва

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение qwertyhp » 27.02.2010 (Сб) 22:23

Удалено
Последний раз редактировалось qwertyhp 28.02.2010 (Вс) 0:20, всего редактировалось 1 раз.
Пятачок Forever! :)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Хакер » 27.02.2010 (Сб) 22:50

- Кодировка, в которой хранятся имена элементов - думаю в WinXP это значения особого не имеет - не встречал какие-либо трудности

Бред. Прозревай.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

qwertyhp
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 156
Зарегистрирован: 07.10.2009 (Ср) 15:02
Откуда: Москва

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение qwertyhp » 27.02.2010 (Сб) 23:13

Хакер, спасибо за ссылку.
Пятачок Forever! :)

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 27.02.2010 (Сб) 23:49

Это типа иронии что-ли...
Ой-ой-ой...
ssv22 ! 27.02.2010 (Сб) в 17:03 Вы писали :
Я задал вопрос, который НЕ имеет никакого отношения к SW !

В 21:52 Вы пишите:
Для начала его(список) мне нужно построить

Но список строится при обращении к SW, поэтому имеет прямое отношение к SW.
[/quote]
например?
Зачем нам отвлечённые примеры??? Вы приведите СВОЙ код/алгоритм - без этого мы не можем сказать, что у ВАС тормозит! (гм: или можем?) Если не хотите показывать свой код - так и напишите: "Не покажу!"
А то дурацкий разговор получается: Вы жалуетесь, что код VB тормозит, но категорически обходите предложения на него посмотреть. Поэтому - какой код? Нет никакого кода. Не видим мы никаких тормозов. Всё работает ништяк! Так держать!
Говорите, кодите уже лет 20?
Ой-ой-ой... Что такое это "Ой-ой-ой" ?

дурацкий разговор - это у нас с Вами получается.
Мой код не отличается от приведеного примера.
Вы вообще-то писали приложения к конкретным прграммам (SW, AutoCAD, Corel, MS Office)... ?
Не нужны Вам "отвлечённые примеры" - не читайте. В чем проблема? Mожете вообще мои сообщения игнорировать.

"Поэтому - какой код? Нет никакого кода"
Этт прямо в стиле конртразведки... Откуда Вы знаете, что нет кода, откуда такой вывод?
Код я привел выше. Что Вы от меня еще хотите? Не пойму...

"Не видим мы никаких тормозов. Всё работает ништяк! Не видим мы никаких тормозов"

И где Вы это проверяли? В SW? Сколько было компонентов? Если 2-3, тогда да, все - "ништяк". А если 3-6 тысяч?
Вам просто видимо поговорить охота...

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение iGrok » 28.02.2010 (Вс) 0:05

qwertyhp, может хватит, а? Самому не надоело?
Почему все остальные хоть что-то пишут по теме, а ты ушёл в полный оффтоп и несёшь какую-то ерунду?

ssv22, ну если получение происходит именно так, как показано в твоём коде, лично я не вижу мест, которые могли бы вызывать серьёзные пробелмы с производительностью. Нет, конечно то, как ты формируешь паддинг - это ужас, но особых тормозов оно не внесёт.
Ну и Variant.. Но это, я так понимаю, требование API SW.
Скажи, а программы на C - работают через тот же самый API, или это всё-таки "плагины - dll-ки", как я успел вычитать где-то в гугле?
Если второй вариант, то вполне логично, что софт на C будет работать на пару порядков быстрей..

По теме - там нет никакой возможности получить дерево проекта СРАЗУ ЦЕЛИКОМ? Обязательно нужно вытаскивать по одному узлу?
Если да - напиши маленькую программку, которая будет ТОЛЬКО вытаскивать узлы дерева из SW, даже никуда не сохраяя. Если тормоза останутся теми же - значит ты с этим ничего не сделаешь.
label:
cli
jmp label

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 0:19

Да, конечно, вот цитата из help`a SW API (цитата - это я чтобы права правообладателя не нарушать) :
...
You can use any programming language that supports COM to create SolidWorks standalone API (.exe files) and add-in (.dll files) applications. The programming languages most commonly used are:

Visual Basic .NET (VB.NET)
Visual C++/CLI
Visual C# .NET
Visual C++ 6.0
...
Кто-то даже на Delphi писал, но там трудновато получалось

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение iGrok » 28.02.2010 (Вс) 0:24

А решение на си написано по тому же принципу и действительно работает быстрее на том же кол-ве компонентов?
И ты это видел своими глазами?
label:
cli
jmp label

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 1:07

to `iGrok`
[quote]
ssv22, ну если получение происходит именно так, как показано в твоём коде, лично я не вижу мест, которые могли бы вызывать серьёзные пробелмы с производительностью. Нет, конечно то, как ты формируешь паддинг - это ужас, но особых тормозов оно не внесёт.
Ну и Variant.. Но это, я так понимаю, требование API SW.
Скажи, а программы на C - работают через тот же самый API, или это всё-таки "плагины - dll-ки", как я успел вычитать где-то в гугле?
Если второй вариант, то вполне логично, что софт на C будет работать на пару порядков быстрей..

По теме - там нет никакой возможности получить дерево проекта СРАЗУ ЦЕЛИКОМ? Обязательно нужно вытаскивать по одному узлу?
Если да - напиши маленькую программку, которая будет ТОЛЬКО вытаскивать узлы дерева из SW, даже никуда не сохраяя. Если тормоза останутся теми же - значит ты с этим ничего не сделаешь.
1) а рекурсия? как там с памятью/стеком. Вроде `C` с этим лучше управлется...Там может и ASM задействован... Или может я и отстал от жизни...
2) Variant - это не требование API SW, там есть спец.типы данных, которые дают ускорение в работе. Можно и те и те использовать. Хотя рекомендуются именно спец.типы данных.
3) возможность получить дерево проекта СРАЗУ ЦЕЛИКОМ ИМХО не имеет смысла - я могу получить дерево только самого верхнего(первого) уровня: а дальше в этом дереве м.б. подузлы, в которых тоже м.б. также подузлы. Т.е. явно просматривается рекурсия.
Тут что-то мне напоминает считывание дерева каталогов с HDD - опять же неизвестно сколько в конкретной папке имеется ПОДпапок, а в них еще и еще. Пока до файла не дойдем...
Но это же все реализовано другими методами. И потом, это же ОС, а не прикладная программа...
У меня друг уже лет 5 пишет на `C` (но только для SW). Так у него считывание дерева из 2000 компонентов занимает милисекунды. а у меня на VB - 1-2 мин. Считаю, что это долго...
Сам SW тоже считывает дерево за милисекунды! Но он (SW) и памяти "жрет" - 200-500Мб. Это при общей RAM в 2Гб.

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 1:18

А решение на си написано по тому же принципу и действительно работает быстрее на том же кол-ве компонентов?
И ты это видел своими глазами?
А решение на си написано по тому же принципу и действительно работает быстрее на том же кол-ве компонентов?
И ты это видел своими глазами?


Насколько я понимаю в `C`, принцип тот же...(хотя могу и ошибаться)
Вот пример на `C`:

Traverse Assembly Example (C++ COM)
This example shows how to traverse an assembly using the Component2 object. The method Component2::IGetChildren returns an array, so this code must be used in an in-process DLL. Otherwise, use the method Component2::GetChildren that returns a VARIANT.

Код: Выделить всё
void GetModelAssembly(ISldWorks* m_pSldWorks)

{

LPCONFIGURATION pConfiguration = NULL;

LPCOMPONENT pRootComponent = NULL;

LPMODELDOC2 pModelDoc = NULL;

HRESULT hres = S_OK;

long RecurseLevel = 0;

hres = m_pSldWorks->get_IActiveDoc2( &pModelDoc ); 

// Retrieve model document pointer

if( S_OK != hres || pModelDoc == NULL )

  return; 


// Get the active configuration and root component

if ( pModelDoc->IGetActiveConfiguration(&pConfiguration) == S_OK )

{

  if ( pConfiguration->IGetRootComponent(&pRootComponent) == S_OK )

  {

   CString MyString;

   TraverseChildren(RecurseLevel,&MyString,pRootComponent);



   pRootComponent->Release();



   // Display the structure in a message box

   AfxMessageBox (MyString);

  }

  pConfiguration->Release();

}

pModelDoc->Release();

}


//////////////////////////////////////////////////////////////////////////

// Function: TraverseChildren

// Arguments: RecurseLevel - Level of recursion

//    MyString - Textural record of assembly

//    pComponent - Component to traverse

// Return: Number of children

// Description: Perform any operations specific to the component, then

//    if the component has children, recursively call

//    this function for each child.

//////////////////////////////////////////////////////////////////////////

int TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT pComponent)

{

LPCOMPONENT* pChildren = NULL;

int   nChildren;

int   i;

BSTR   Name;

HRESULT  hres = S_OK;

LPMODELDOC  pModelDoc = NULL;

// Retrieve the component name

if(RecurseLevel==0)

{

  // Special case of top-level components

  hres = m_pSldWorks->get_IActiveDoc( &pModelDoc );

  if( S_OK == hres || pModelDoc != NULL )

   hres = pModelDoc->GetTitle(&Name);

}

else

{

  // Get the component name

  hres = pComponent->get_Name(&Name);

}


if( S_OK == hres && Name != NULL )

{

  CString tempstr;

  for( i=1; I<=RecurseLevel; i++)

  {

   tempstr += " ";

  }

  CString Tmp(Name);

  tempstr += Tmp;

  tempstr += "\r\n";

  *MyString = *MyString + tempstr;

}

RecurseLevel++;

hres = pComponent->IGetChildrenCount(&nChildren);

// Check if this component has children

if ( S_OK == hres || nChildren > 0 )

{

  pChildren = new LPCOMPONENT [nChildren];


  hres = pComponent->IGetChildren((LPCOMPONENT**)&pChildren);

  if(S_OK == hres)

  {

   // Recursively traverse the children   <= рекурсивный вызов!
   for ( i=0; i<nChildren; i++ )
   {
    TraverseChildren(RecurseLevel,MyString,pChildren[i]);
    pChildren[i]->Release();

   }

  }

  delete [] pChildren;

}


RecurseLevel--;

return nChildren;

}

//***

[Viper] :: Тебя же предупреждали о тэге CODE? Получай предупреждение уже не устное. Также стоит корректнее использовать тэги цитирования и не надо начинать каждое предложение с новой строки!

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение iGrok » 28.02.2010 (Вс) 2:25

Тебя же уже просили пользоваться тегом CODE, а не выкладывать простыни на форум!
Плюс ты как-то умудряешься терять теги цитирования, и цитаты у тебя тоже расползаются.
Ну реально же неприятно читать!

Теоретически, подвох со скоростью может крыться вот тут:
ssv22 писал(а):Traverse Assembly Example (C++ COM)
This example shows how to traverse an assembly using the Component2 object. The method Component2::IGetChildren returns an array, so this code must be used in an in-process DLL. Otherwise, use the method Component2::GetChildren that returns a VARIANT.


Есть два метода - IGetChildren, и GetChildren. Первый возвращает массив, второй - VARIANT.
Но первый может быть использован только в dll. Теоретически, он должен работать существенно быстрее.
Если решение на си твой друг писал с использованием первого метода, то это может объяснить разницу в скорости.

Примеры кода из хелпа можешь больше не приводить - толку от них как с козла молока.
Если кто-то и сможет сказать, почему именно скорости так отличаются, то только видя конкретный код на Си и конкретный код на VB, которые делают одно и то же, но работают с настолько разной скоростью.
label:
cli
jmp label

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 3:02

Да я не так давно на этом форуме, поэтому еще и не разобрался со всякими тэгами - извиняюсь!
В отношении dll : есть такая штучка "API SDK". После ее установки вроде можно делать dll на VB и, соответственно, "настоящий " Addinn(плагин) к SW.
Как-то скачивал, да потерял где-то на моих HDD :-(
PS. некоторые методы/свойства в API SW на VB и на `C` отличаются ... может тут "собака и зарыта" ?
PPS. некоторые методы/свойства в API SW вообще не поддерживаются в VB, только в `C`

Т.е. выходит, что разница в скорости обусловленна именно в реализации API SW на VB и на `C`...
Видимо прийдется все-таки переходить на C# хотя-бы.... Но после VB это тяжеловато, однако.
Вот Delphi плюс OpnGL я освоил (для конкретной задачи) за месяц.
А вот `C` меня несколько "пугает" :-)

Ладно, спасибо за ответы!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Хакер » 28.02.2010 (Вс) 12:06

Блин, ну я поражаюсь.

Ты понимаешь, что сишарп не равно С, и что сишарп едва ли будет быстрее VB? И что все твои медленности твоими же руками порождены?

И что самое главное: выделить 140 уникальный элементов из 20000, и что здесь важен алгоритм трижды, а язык --- в последнюю очередь. Понимаешь?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 15:07

Ну не надо "поражаться". Есть много удивительного на свете!
Все это я понимаю. И про С# тоже понимаю.
Вот только не пойму вот этого:
"...все твои медленности твоими же руками порождены..."
Если можно - поподробнее...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Хакер » 28.02.2010 (Вс) 15:44

Что по подробнее? Ты будешь нормально вести ход беседы?
И вообще, прекрати использовать косые одинарные кавычки.

Как сейчас ты решаешь задачу удаления повторов?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 17:48

Пытаюсь...(нормально вести ход беседы). Ну не научился еще. Много форумов у меня и практически на каждом свои правила...
Удаление повторов: загоняю все строки во вспомогательный список, а потом его перебираю. В случае совпадения имен - удаляю данный элемент.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Хакер » 28.02.2010 (Вс) 18:32

Как ты определяешь, является ли элемент повторяющимся? Как в том коде, с двойным циклом-обходом?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ssv22
Обычный пользователь
Обычный пользователь
 
Сообщения: 89
Зарегистрирован: 06.11.2005 (Вс) 8:47

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение ssv22 » 28.02.2010 (Вс) 19:42

В моем случае элемент - это полный путь к файлу SW.
Т.е. я беру текущий элемент и, пробегая по списку проверяю их на совпадениe.
If Эл01=Эл02(из списка) then
RemoveItem(Эл02)
end if

Это конечно тупо, но как еще?

Вот случайно взял книжку по Delphi, там есть метод "IndexOf" у ComboBox, который возвращает отрицательное значение, если строка уже присутствует в списке.И вот не могу разобраться есть-ли аналог данного метода в VB. Вот он-то мне и нужен!
Тогда вопрос "очистки" списка от дубликатов вообще отпадает.
Вообщем, немного подзапутался со списками в VB...

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Денис » 01.03.2010 (Пн) 10:37

Я тут погуглил. Говорят, будет быстрее, если массив сначала отсортировать, а уж потом удалять дубликаты. (Насчет того, чтобы выгружать данные в массив из контрола, это даже не обсуждается.)
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение alibek » 01.03.2010 (Пн) 10:43

Денис писал(а):Я тут погуглил. Говорят, будет быстрее, если массив сначала отсортировать, а уж потом удалять дубликаты. (Насчет того, чтобы выгружать данные в массив из контрола, это даже не обсуждается.)

Это будет быстрее только в том случае, если с массивом предполагается дальнейшая работа.
Если нужно разово исключить дубликаты, то предварительная сортировка съест всю экономию от поиска дубликатов в отсортированном списке.
Нормальный совет дали давно, не понимаю, почему его еще не использовали.
Перебирай элементы, добавляя их в массив, если их там еще нет. Чтобы ускорить проверку, что они там уже есть, добавляй их упорядоченно (при добавлении сортируй), чтобы увеличить скорость сравнения и сократить объем памяти, добавляй не значения, а хеши. Чтобы не делать это все вручную, можно использовать коллекции и отлавливать ошибки при добавлении ключа.
Lasciate ogni speranza, voi ch'entrate.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Денис » 01.03.2010 (Пн) 10:51

alibek писал(а):Нормальный совет дали давно, не понимаю, почему его еще не использовали.

Потому шо у человека (ssv22) не хватает времени, изучить коллекции, что это такое и с чем это едят. ИМХО.
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: Как найти и удалить дубликаты из "List`а(списка)

Сообщение Viper » 01.03.2010 (Пн) 10:53

Денис писал(а):
alibek писал(а):Нормальный совет дали давно, не понимаю, почему его еще не использовали.

Потому шо у человека (ssv22) не хватает времени, изучить коллекции, что это такое и с чем это едят. ИМХО.
Что там изучать то? Метод Add и все! Если при добавлении ошибка, то значит путь в коллекции уже есть.
Весь мир матрица, а мы в нем потоки байтов!

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: PetalBot и гости: 15

    TopList