Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите отимизировать код небольшой функции 
:(
    Опции темы
ДЫМ
Дата 28.6.2006, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 224
Регистрация: 6.1.2004

Репутация: 8
Всего: 8



Функция нужна для сортировки строк со смешанными данными (символы и числа).
(вся информация здесь)

Код делает следующее: встречающиеся в строке числа добивает нулями слева, чтобы они были одной разрядности, например:

 fcGetFormattedString('Строка12Строка5', 5)
 возвращает строку:
 Строка00012Строка00005


Код

//**********************
// Функция форматирования строки
// 
function fcGetFormattedString(sStr: string; iDigits: Integer): string;
var i:Integer;
    sDigits:string;

begin
 sDigits:=''; Result:='';

 for i:=1 to Length(sStr)+1 do
 begin
  // выделяем из строки число
  if sStr[i] in ['0'..'9'] then
   begin
     sDigits:=sDigits+sStr[i];
   end
  else  // не цифры
   begin

    if sDigits<>'' then
     begin
      // добиваем текущее число нулями слева до iDigits
      Result:=Result+DupeString('0',iDigits-Length(sDigits))+sDigits;
      sDigits:='';
     end;
     if sStr[i]<>#0 then Result:=Result+sStr[i];
   end;// не цифры

 end;//for
end;

Вопрос вот в чем: можно ли как-то оптимизировать код, мне он представляется немного корявым и медленным.  

Это сообщение отредактировал(а) ДЫМ - 28.6.2006, 22:39
PM MAIL WWW   Вверх
Palladin
Дата 28.6.2006, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 932
Регистрация: 15.5.2007
Где: Беларусь г.Гомель

Репутация: 3
Всего: 17



Да нет, вроде всё нормально smile циклов я насчитал вообще только 1, хороший код, что тебе не устраивает, или прога тормозит smile  


--------------------
Глуп тот кто полагается на истину авторитета, а не на авторитет истины
[color=red]KAV&KIS==Evil[/color]
PM MAIL   Вверх
Yanis
Дата 28.6.2006, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 72
Всего: 111



ДЫМ
Голова уже не варит. Завтра гляну.... Но код имхо не идеальный.


M
Girder
Не флуди...
 


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Bose
Дата 29.6.2006, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



разве что заменить
Код

 for i:=1 to Length(sStr)+1 do


на
Код

 var c:integer;
 
 c:=Length(sStr)+1;
 for i:=1 to c do


и вместо:
Код

Result:=Result+DupeString('0',iDigits-Length(sDigits))+sDigits;

писать
Код

Result:=Result+ StringOfChar('0',iDigits-Length(sDigits))+sDigits;


и ещё, как вариант, добавить
var ch:byte;
ch:=sStr[i];
и заменить все обращения к sStr[i] на обращения к ch

Время исполнения 1 000 000 итераций из 3х строк у меня было такое:
Original 1000 000 iter 0:00:19:547
My 100 0000 iter 0:00:19:422

Тестовые цикл был такой:
Код

  sl:=TstringList.Create;
  sl.Clear;
  sl.Add('xzv7ccv1basfd5ye4rghg;lnmvbnmuyit4dh5474hdhd');
  sl.Add('cxvfg576ghmbn87hjk,m874657hnfnvcb73324bvxc2d');
  sl.Add('xcbxc5478hb67367v367vc665784n476824c345vxc2d');
  MeasureTime;
  for i:=0 to 1000000 do
    t:= fcGetFormattedStringOrig(sl.Strings[i mod 3],(i mod 3)*2+4);
  sl.Free;
  Memo1.Lines.Add('Original 100 000 iter '+  MeasureTime);


процедура MeasureTime моя, она запоминает текущий GetTickCount и возвращает разницу между предыдушим запомненным значением и текущим. 
PM MAIL WWW Skype   Вверх
Alexeis
Дата 29.6.2006, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Быстрее я не смог придумать
Код

function fcGetFormattedString(sStr: Ansistring; iDigits: Integer): string;
var
   i, j, jn1, jn2 : Integer;
   n, l, l1, l2, ls, ld  : Integer;
   s : array of AnsiString;
   Fl : Boolean;

begin
 n := 0;
 Fl := False;
 for i := 1 to Length(sStr)
 do
   if not (sStr[i] in ['0'..'9'])
   then
     Fl := True
   else
     if Fl
     then
       begin
         Fl := False;
         Inc(n);
       end;

 l := 0;
 SetLength(s, n);
 j := 1;  
 for i := 0 to n - 1
 do
   begin
     jn1 := j;
     while (not (sStr[jn1] in ['0'..'9'])) and (jn1 <= Length(sStr))
     do
       Inc(jn1);

     jn2 := jn1;
     while (sStr[jn2] in ['0'..'9']) and (jn2 <= Length(sStr))
     do
       Inc(jn2);

     ld := iDigits - (jn2 - jn1);
     ls := jn2 - j;
     l1 := jn1 - j;
     l2 := jn2 - jn1;

     SetLength(s[i], ls + ld);
     Move(sStr[j], s[i][1], l1);
     FillChar(s[i][l1 + 1], ld, Ord('0'));
     Move(sStr[jn1], s[i][l1 + ld + 1], l2);

     Inc(l, ls + ld);
     j := jn2;
   end;

  j := 1;
  SetLength(Result, l);
  for i := 0 to n - 1
  do
    begin
      Move(s[i][1], Result[j], Length(s[i]));
      Inc(j, Length(s[i]));
    end;
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
  ShowMessage(fcGetFormattedString('Строка12Строка5стр117', 5));
end;


Добавлено @ 15:38 
Мининимальное количество операций выделения памяти
2 прохода по строке "делфийских" и 2 "ассемблерных" 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Bose
Дата 29.6.2006, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Код

Alexis 1000 000 iter 0:00:03:719
My 1000 000 iter 0:00:20:719


alexeis1, 
выигрыш в 17 секунд по сравнению с моим вариантом.  smile 
держи + за мастер-класс smile 

 
PM MAIL WWW Skype   Вверх
ДЫМ
Дата 1.7.2006, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 224
Регистрация: 6.1.2004

Репутация: 8
Всего: 8



Всем спасибо, alexeis1 особенно.  
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0496 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.