Подсчёт строк в TStringList
Я сделал это 2мя способами но не один меня своей скоростью не устроил..
Вот первый:
{
int count = 1;
str = list->Strings[i++];
for(int j = i; j < list->Count; j++)
if(str == list->Strings[j])
{
list->Delete(j);
j--;
count++;
}
Memo1->Lines->Add(str + ": " + IntToStr(count));
}
Вот второй сопсоб:
{
int count = 0;
str = list->Strings[i++];
for(;; )
if(list->IndexOf(str) != -1){
list->Delete(list->IndexOf(str));
count++;}
else break;
Memo1->Lines->Add(str + ": " + IntToStr(count));
}
Который как ни странно на 30% медленее первого..
а листы в которых должен идти подсчёт строк очень и очень большие.
Пожалуйста помогите.. как можно сделать быстрее??
Пожалуйста посоветуйте что нибуть
TList *numbers;
int *x,idx;
numbers=new TList();
for(int i=0; i<list->Count; i++)
{
x=new int(0); // Достаточно затратная операция
idx=list->IndexOf(list->Strings);
if(idx!= -1)
{
*(int *)numbers->Items[idx]++;
numbers->Add(x);
}
else
{
*x=1;
numbers->Add(x);
}
}
for(int i=0; i<list->Count; i++)
{
if (*(int *)numbers->Items!=0)
Memo1->Lines->Add(list->Items + ": " + IntToStr(*(int *)numbers->Items));
}
Вдруг будет быстрее? Напишите, может еще чего-нибудь придумаем.
str : count+1. Правда нужно будет вызывать функции обработки строк, поэтому может быть имеет смысл подумать об использовании какого-нибудь двухстолбцового компонента.
Исправил ляп, вроде как процентов на 10 стало быстрее =)
Только я не смог заставить приведённый шикарный код верно работать из-за неправильной записи этой строки:
*(int *)numbers->Items[idx]++;
так даже не компилит, а так
*(int *)numbers->Items[idx] += 1;
компилит но выдаёт ошибку..
Мысль смутно ясна и в тоже время нет =))
непонимаю как это можно сделать без вложенных циклов
спасибо за помощ =))
Исправил ляп, вроде как процентов на 10 стало быстрее =)
Только я не смог заставить приведённый шикарный код верно работать из-за неправильной записи этой строки:
*(int *)numbers->Items[idx]++;
так даже не компилит, а так
*(int *)numbers->Items[idx] += 1;
компилит но выдаёт ошибку..
Мысль смутно ясна и в тоже время нет =))
непонимаю как это можно сделать без вложенных циклов
Положим, что list у вас отсортирован, а значит все одинаковые строки располагаются друг за другом. Пишем код:
str=list->strings[0];
count=1;
for (i=1;i<list->Count;i++)
{
if (list->Strings==str) count++;
else
{
Вывод в Memo;
count=1;
str= list->Strings;
}
}
Единственный недостаток – строки в мемо будут в другом порядке, чем в исходном несортированном списке. Насчет первого алгоритма, раз уж вы его реализовали – попробуйте запустить (хотя бы временно сделайте v= *(int *)numbers->Items[idx]; v++; *(int *)numbers->Items[idx]=v; ) - мне интересно J
всё работает, я сделал тот что с сортировкой..
у меня на 100МБ лист ушло 60 секунд когда теме старыми способами что я делал ушло бы окола 1.5 часа! а тот способ что приводился кусок кода так и не удолось заставить работать верно, но это не важно.. важно что идея с сортировкой была очень хороша! Огромное спасибо!
Ураа!!..
всё работает, я сделал тот что с сортировкой..
у меня на 100МБ лист ушло 60 секунд когда теме старыми способами что я делал ушло бы окола 1.5 часа! а тот способ что приводился кусок кода так и не удолось заставить работать верно, но это не важно.. важно что идея с сортировкой была очень хороша! Огромное спасибо!
Рад, что помогло!