Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
Внизкопирование нестандартной длины строки Найти похожие ветки
← →
Yurij-7 (2005-02-23 16:44) [0]Господа прошу помочь в следующей ситуации:
есть строка вида : "обороты 2180."
как из нее вытянуть только числовую векличину, в данном случае 2180, но может быть и 3 числа в конце строки.
Спасибо.
← →
Sandman25 © (2005-02-23 16:45) [1]Сканировать строку с конца и смотреть, когда закончатся цифры?
← →
Antonn © (2005-02-23 16:47) [2]Yurij-7 (23.02.05 16:44)
перебрать строку посимвольно, копировать в переменную только цифры и делиметр.
← →
olookin © (2005-02-23 16:53) [3][2] Antonn © (23.02.05 16:47)
При строке типа "обороты на 20.03.2005 составили 1.452.000 млн руб." и делимитере "." получится "20.03.20051.452.000.". И чем это поможет?
← →
Antonn © (2005-02-23 16:55) [4]Antonn © (23.02.05 16:47) [2]
function str2num(s:string):string;
var i:integer; s_tmp:string;
begin
result:="";
for i:=0 to length(s) do
if (ord(s[i])>47)and(ord(s[i])<58) then
result:=result+s[i];
end;
← →
Antonn © (2005-02-23 16:57) [5]olookin © (23.02.05 16:53) [3]
какое условие, такое и решение:)
← →
olookin © (2005-02-23 16:57) [6]Тогда уж кусать строку на части по пробелам. А потом уже применять StrToNum
← →
olookin © (2005-02-23 16:58) [7][5] Antonn © (23.02.05 16:57)
Здрасьте, а разве решение не должно подразумевать многозначность входной величины?
← →
Yurij-7 (2005-02-23 16:58) [8]а какую функцию использовать неподскажите?
← →
Sandman25 © (2005-02-23 16:59) [9]for
if
:=
IntToStr
← →
Sandman25 © (2005-02-23 17:01) [10]StrToInt
← →
Antonn © (2005-02-23 17:04) [11]Yurij-7
в обрабатываемой строке сколько численых значений? а то может там даты, проценты...
← →
Yurij-7 (2005-02-23 17:07) [12]нет там только число типа количество
← →
olookin © (2005-02-23 17:11) [13][12] Yurij-7 (23.02.05 17:07)
А разделитель между строчной и числовой частями строки есть?
← →
Yurij-7 (2005-02-23 17:19) [14]да пробел, а в конце числа точка
← →
olookin © (2005-02-23 17:21) [15]Тогда удалем из строки все до последнего встречающегося пробела (включая его самого). Оставшуюся часть проверяем на соответствие числу. Кажется, все...
← →
Antonn © (2005-02-23 17:27) [16]
> Оставшуюся часть проверяем на соответствие числу.
самое интересное:))
Ну тогда еще учтем делимитер для полного счастья:)
function str2num(s:string):real;
var i:integer; s_tmp:string;
begin
s_tmp:="";
if length
for i:=0 to length(s) do
case ord(s[i]) of
48..57: s_tmp:=s_tmp+s[i];
44: s_tmp:=s_tmp+",";
46: s_tmp:=s_tmp+",";
end;
result:= strtofloat(s_tmp);
end;
← →
Yurij-7 (2005-02-23 17:28) [17]а неподскажите как именно это сделать или может где прочитать ну в справке ничего немогу найти :(
← →
Antonn © (2005-02-23 17:29) [18]Yurij-7 (23.02.05 17:28) [17]
сделать inttostr или floattostr в блоке try..except, если прокатит, значит число:)
← →
Antonn © (2005-02-23 17:30) [19]Antonn © (23.02.05 17:29) [18]
т.е. strtoint или strtofloat
← →
begin...end © (2005-02-23 17:31) [20]TryStrToInt, TryStrToFloat
← →
olookin © (2005-02-23 17:33) [21][16] Antonn © (23.02.05 17:27)
А я бы сделал не так...
function str2num(s:string):real;
var i:integer; s_tmp:string;
begin
s_tmp:="";
//if length вот этого я вообще не понял - это что такое?
for i:=1{элемент, т.е. символ строки начинается с 1, а не с 0} to length(s) do
if Pos("0123456789.(или ,)",s[i])<>0 then s_tmp:=s_tmp+s[i];
result:= strtofloat(s_tmp);
end;
← →
olookin © (2005-02-23 17:36) [22]Для полного счастья видимо так...
function str2num(s:string):real;
var i:integer; s_tmp:string;
z: string;
begin
z:="0123456789"+DecimalSeparator;
s_tmp:="";
for i:=1 to length(s) do
if Pos(z,s[i])<>0 then s_tmp:=s_tmp+s[i];
try
result:= strtofloat(s_tmp);
except НЕ_ПОМНЮ_ЧЕГО end;
//или просто использовать функцию Val
end;
← →
Antonn © (2005-02-23 17:36) [23]olookin © (23.02.05 17:33) [21]
яж "на коленке писал". {if length} - это не стертый кусок проверки длины начальной строки:)
> result:= strtofloat(s_tmp);
еще try..except вроде ставить надо для приличия. Или не стоит?
← →
olookin © (2005-02-23 17:37) [24]Нет, счастье не придет. Если не поменять z и s[i] местами... Хе-хе
← →
Antonn © (2005-02-23 17:41) [25]olookin © (23.02.05 17:36) [22]
DecimalSeparator;
а если у него в тексте этот сепаратор другой?
← →
begin...end © (2005-02-23 17:42) [26]> Antonn © (23.02.05 17:27) [16]
Нагляднее использовать не коды символов, а сами символы:
case s[i] of
"0".."9" : ...
...
end.
> olookin © (23.02.05 17:33) [21]
> olookin © (23.02.05 17:36) [22]
1. В Pos параметры перепутаны местами.
2. Каждый символ искать во всей строке - медленно.
> Antonn © (23.02.05 17:36) [23]
> еще try..except вроде ставить надо для приличия. Или
> не стоит?
Стоит. Или см. [20].
Я бы использовал множества: if s[i] in ["0".."9", DecimalSeparator] then ... ну и последнюю точку как-то учитывал.
← →
olookin © (2005-02-23 17:49) [27][25] Antonn © (23.02.05 17:41)
А при конвертации строки сепаратором является тот, которрый указан в DecimalSeparator. Так что разделителем может быть хоть символ "%"... Лишь бы это было учтено...
← →
olookin © (2005-02-23 17:50) [28][26] begin...end © (23.02.05 17:42)
>>Каждый символ искать во всей строке - медленно.
Варианты какие есть?
← →
Yurij-7 (2005-02-23 17:50) [29]Всем большое спасибо, разобрался.
← →
begin...end © (2005-02-23 17:53) [30]> olookin © (23.02.05 17:50) [28]
Множество или case.
← →
Antonn © (2005-02-23 17:54) [31]olookin © (23.02.05 17:49) [27]
А при конвертации строки сепаратором является тот, которрый указан в DecimalSeparator. Так что разделителем может быть хоть символ "%"... Лишь бы это было учтено...
значит нужно еще прогнать строку и назначить сепаратор? А не накладно-ли?
← →
olookin © (2005-02-23 17:54) [32][30] begin...end © (23.02.05 17:53)
Логично, но убыстряет ли это поиск при длине строки, сопоставимой с "длиной" множества?
← →
Юрий Зотов © (2005-02-23 17:56) [33]> olookin © (23.02.05 17:54) [32]
В сотни раз. Если не в сотни тысяч раз.
← →
olookin © (2005-02-23 17:56) [34][31] Antonn © (23.02.05 17:54)
Нет, DecimalSeparator задается перед вызовом функции. Просто при конвертации строки будет считаться валидным сепаратором именно тот, что задан DecimalSeparator. Например, если есть строка "0,1235", а DecimalSeparator равен ".", то при вызове StrToFloat возникнет ошибка. А если перед этим установить DEcimalSeparator:=",", то ошибки не будет.
← →
olookin © (2005-02-23 17:57) [35][33] Юрий Зотов © (23.02.05 17:56)
Вот как? Почему? Есть множество из 10 элементов и строка из 10 символов. Неужели механизм сравнения для них отличается?
← →
Antonn © (2005-02-23 17:58) [36]olookin © (23.02.05 17:56) [34]
но мы же не знаем какой сепаратор в тексте. Или знаем?
← →
olookin © (2005-02-23 18:01) [37][36] Antonn © (23.02.05 17:58)
Знаем. Инчае что мы вообще обрабатываем? Неизвестного формата данные?
← →
Юрий Зотов © (2005-02-23 18:02) [38]> olookin © (23.02.05 17:57) [35]
Отличается принципиально.
Проверка вхождения символа в строку - это цикл.
Проверка вхождения элемента во множество - близко к обыкновенному AND.
← →
olookin © (2005-02-23 18:04) [39][38] Юрий Зотов © (23.02.05 18:02)
А реально? Согласитесь, что простым AND я не обойдусь, пытаясь выяснить вхождение элемента в множество. Надо так или иначе перебирать все эелемнты этого множества и проверять их на соответствие элементу. Тот же цикл.
← →
begin...end © (2005-02-23 18:07) [40]> olookin © (23.02.05 17:54) [32]
Убыстряет.const
SymbolsCount = 100000;
DecimalSymbols = "0123456789";
var
I: Integer;
S: string;
T1, T2, Count1, Count2: Cardinal;
begin
// Заполнение строки
SetLength(S, SymbolsCount);
Randomize;
for I := 1 to SymbolsCount do
S[I] := Chr(Random(255));
// Тест с множеством
Count1 := 0;
T1 := GetTickCount;
for I := 1 to Length(S) do
if S[I] in ["0".."9"] then
Inc(Count1);
T1 := GetTickCount - T1;
// Тест с Pos
Count2 := 0;
T2 := GetTickCount;
for I := 1 to Length(S) do
if Pos(S[I], DecimalSymbols) > 0 then
Inc(Count2);
T2 := GetTickCount - T2;
ShowMessageFmt("Count1 = %d, Count2 = %d, множество: %d мс; Pos: %d мс", [Count1, Count2, T1, T2])
end.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.039 c