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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрое сравнение строк, желательно на асме. 
V
    Опции темы
delphixxx
Дата 28.3.2006, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем привет.

Меня интересует функция сравнения двух спецыфических
строк.

строки выглядят примерно так: '541/45/63'
(цыфра разделитель, цыфра разделитель, цыфра разделитель)
числовые значения перед разделитетлем и после, могут быть любой величины.

Нужно сравнить две строки и определить какая больше
по принцыпу как с типом TDateTime


Пример :

X1 = 2:145:165
X2 = 4:200:399
X3 = 1:500:660

X1 > X3
X2 > X1
X2 > X3

Вот и желателбно чтобы это было на ассемблере так как в моём проекте очень важна скорость.





PM MAIL   Вверх
Демо
Дата 28.3.2006, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

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



Цитата(delphixxx @ 28.3.2006, 19:59 Найти цитируемый пост)
Вот и желателбно чтобы это было на ассемблере так как в моём проекте очень важна скорость.


С чего ты взял, что на ассемблере быстрее будет?

Код

var
  s1,s2: String;
begin
  s1 := '2:145:165';
  s2 := '1:500:660';
  if s1>s2 then ShowMessage('s1>s2');




--------------------
    
PM MAIL ICQ Skype   Вверх
Guedda
Дата 28.3.2006, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

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



Интересно. Я написал код, который написал Демо, но message не появилось... Немного исправив, появилась мессага, типа эти строки равны.
Вообще по определению такое сравнение ведет к побайтовому сравнению... Сколько байт занято...


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
delphixxx
Дата 28.3.2006, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Демо,
не всё так просто как вы думаете, тут полюбому нужно разбивать строки и сравнивать цыфры, ибо
если дейсвовать по вашему методу то например '12' < '4' .
PM MAIL   Вверх
Демо
Дата 29.3.2006, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

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



Цитата(delphixxx @ 28.3.2006, 23:14 Найти цитируемый пост)
не всё так просто как вы думаете, тут полюбому нужно разбивать строки и сравнивать цыфры, ибо
если дейсвовать по вашему методу то например '12' < '4' .


А где было написано, что значность может быть разная?

В приведенном в топике примере было видно четкое форматирование.


--------------------
    
PM MAIL ICQ Skype   Вверх
Guedda
Дата 29.3.2006, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

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



Тогда просто необходимо парсить строки, переводить в Integer и сравнивать. По другому, никак.


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
RA
Дата 29.3.2006, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


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

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



Цитата(Демо @ 29.3.2006, 11:43 Найти цитируемый пост)
А где было написано, что значность может быть разная?


Цитата(delphixxx @ 28.3.2006, 19:59 Найти цитируемый пост)
числовые значения перед разделитетлем и после, могут быть любой величины.

smile

Это сообщение отредактировал(а) RAdmin - 29.3.2006, 23:30
PM   Вверх
Демо
Дата 29.3.2006, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

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



RAdmin,
А-а, тогда понятно.


--------------------
    
PM MAIL ICQ Skype   Вверх
Romikgy
Дата 29.3.2006, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



Код

var
  s1,s2: String;
i: integer;
begin
  s1 := '2:145:165';
  s2 := '1:500:660';
  i:=AnsiStrComp(Pchar(s1),Pchar(s2));
  if i>0 then ShowMessage('s1>s2')
else if i<0 then ShowMessage('s1<s2')
else ShowMessage('s1=s2');



А так не?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Digitalator
Дата 29.3.2006, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



а если
s1 := '2:1450:165';
s2 := '12:500:660';

надо разбивать строки на числа и сравнивать ... на асме такое писать неинтересно smile
PM MAIL   Вверх
Digitalator
Дата 29.3.2006, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



пример на неасме
Код

//константа - разделитель
const schar : char = ':';
//функция для разбивки строк, возвращает true если удалось отделить подстроку, обрезает исходную строку
function sxpld(var s, substr : string) : boolean;
  var vpos : integer;
  begin
  vpos := pos(schar, s);
  if length(s) = 0 then
    begin
    result := false;
    exit;
    end;
  result := true;
  if vpos > 0 then
    begin
    substr := copy(s, 1, vpos-1);
    if length(substr) = 0 then
      begin
      result := false;
      exit;
      end;
    s:=copy(s, vpos+1, length(s)-vpos);
    end else begin
    substr := s;
    s := '';
    end;
  end;
//Функция для сравнения возвращает 0 если строки равны, 1 если больше строка 1, 2 если больше строка 2.
//если не возникло ошибок, то code = 0
function scmp(s1, s2 : string; var code : integer) : integer;
  var str : string;
      ds1, ds2 : array[1..3] of string;
      di1, di2 : array[1..3] of integer;
      i : integer;

  begin
  code := 0;
  result := 0;
  //Разбиваем первую строку
  str := s1;
  for i := 1 to 3 do
   if not sxpld(str, ds1[i]) then
      begin
      code := -1;
      exit;
      end;
  if length(str) > 0 then
    begin
    code := -1;
    exit;
    end;
  //Разбиваем вторую строку
  str := s2;
  for i := 1 to 3 do
   if not sxpld(str, ds2[i]) then
      begin
      code := -1;
      exit;
      end;
  if length(str) > 0 then
    begin
    code := -1;
    exit;
    end;
  //Преобразуем строки в целый тип
  for i := 1 to 3 do
    begin
    val(ds1[i], di1[i], code);
    if code <> 0 then exit;
    val(ds2[i], di2[i], code);
    if code <> 0 then exit;
    end;
  //сравниваем
  i:=1;
  while i<=3 do
    begin
    if di1[i] > di2[i] then
      begin
      result := 1;
      exit;
      end;
    if di2[i] > di1[i] then
      begin
      result := 2;
      exit;
      end;
    inc(i);
    end;
  end;

{$R *.dfm}
//пример сравнения
procedure TForm1.Button1Click(Sender: TObject);
var res, code : integer;
    str : string;
begin
res := scmp(edit1.Text, edit2.Text, code);
if code = 0 then
 begin
 case res of
   0: str:='строки равны';
   1: str:='строка 1 больше';
   2: str:='строка 2 больше';
   end;
 label1.Caption := str;
 end else label1.Caption := 'ошибка сравнения');
end;

PM MAIL   Вверх
Snowy
Дата 29.3.2006, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Вот, нарисовал простое, элегантное решение:
Код
function CompDigStr(s1, s2: string): integer;
  function ModStr(s:string): string;
  var
    i: integer;
    c: integer;
  begin
    c := 0; result := s;
    for i := Length(s) downto 1 do
      if s[i] = ':' then begin
        insert(chr(c+48), result, i+1);
        c := 0;
      end else inc(c);
    result := chr(c+48) + result;
  end;
begin
  result := CompareStr(ModStr(s1), ModStr(s2));
end;
Возвращает -1, если s1<s2; 0, если s1=s2; 1, если s1>s2

Пример:
Код
  ShowMessage(IntToStr(CompDigStr('2:1450:165','12:500:660')));

PM MAIL   Вверх
delphixxx
Дата 29.3.2006, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Snowy, Спасибо smile
PM MAIL   Вверх
Digitalator
Дата 31.3.2006, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Snowy)
Возвращает -1, если s1<s2; 0, если s1=s2; 1, если s1>s2

не совсем так
Цитата(Delphi Help)
CompareStr compares S1 to S2, with case-sensitivity. The return value is less than 0 if S1 is less than S2, 0 if S1 equals S2, or greater than 0 if S1 is greater than S2. The compare operation is based on the 8-bit ordinal value of each character and is not affected by the current locale.


Очень интересное решение, единственный минус - не проверяется корректность сравниваемых строк, хотя в конкретных случаях это может быть и не нужно.
PM MAIL   Вверх
Guedda
Дата 31.3.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

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



Нужно быстро и на асме?
Бери:
Код

function CompareStr(const S1, S2: string): Integer; assembler;
asm
          PUSH    ESI
          PUSH    EDI
          MOV     ESI,EAX
          MOV     EDI,EDX
          OR      EAX,EAX
          JE      @@1
          MOV     EAX,[EAX-4]
@@1:    OR      EDX,EDX
          JE      @@2
          MOV     EDX,[EDX-4]
@@2:    MOV     ECX,EAX
          CMP     ECX,EDX
          JBE     @@3
          MOV     ECX,EDX
@@3:    CMP     ECX,ECX
          REPE    CMPSB
          JE      @@4
          MOVZX   EAX,BYTE PTR [ESI-1]
          MOVZX   EDX,BYTE PTR [EDI-1]
@@4:    SUB     EAX,EDX
          POP     EDI
          POP     ESI
end;



--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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