![]() |
![]() |
![]() |
|
Наиболее быстро определить является ли строка числом... Ø |
☑ | ||
---|---|---|---|---|
0
Los
16.10.06
✎
20:18
|
Дано: много строк (>10000), длина каждой < 40 символов, могут содержать любые алфавитно-цифровые символы, точки и запятые.
Задача: нужно максимально быстро определить, является ли эта строка числом. При этом строка, являющаяся числом, может содержать нули в старших разрядах и нули на хвосте дробной части. Разделителем разрядов может быть как точка, так и запятая. Знака изначально в строке быть не может, поэтому на + и - пофиг. Например числа: 0100,99900 100 100.99 Не числа: 100.0,12 Asd100xЩ 100.0Ю Предложите быстрый алгоритм, плз? |
|||
1
Гена
16.10.06
✎
20:21
|
умножить на любое число, например 1... если ругнётся - не число...
Попытка, Исключение |
|||
2
Los
16.10.06
✎
20:25
|
(1) Не... Стр*1 - Операция умножения не определена для строковых величин, 1*Стр - умножит всегда, преобразовав по правилам Число()
|
|||
3
Los
16.10.06
✎
20:30
|
Если б не нули в начале и конце, прокатило бы:
... Если СокрЛП(Строка(Число(Стр)))=СокрЛП(Стр) Тогда ... с предварительной заменой запятой на точку. А с нулями - хз... Очень не хочется посимвольно разбирать строку, ибо много их... |
|||
4
yabodr
16.10.06
✎
20:32
|
А так
?(Число(Стр)=Стр,Число(Стр),"Не число"); не прокатит? |
|||
5
Los
16.10.06
✎
20:35
|
(4) Не, "123" - не число
|
|||
6
Sasha
16.10.06
✎
20:35
|
1. Определяешь количество левых и правых нулей
2. Преобразуешь в число 3. Если стрДлина(КонечныйРезультат)+колЛевыхнулей+колправыхНулей = стрДлина(ИсходнаяСтрока) Тогда //число КонецЕсли; |
|||
7
Дурочка 1С ™
16.10.06
✎
20:39
|
(0) Зачем?
|
|||
8
yabodr
16.10.06
✎
20:39
|
(5) пачему?
|
|||
9
Sasha
16.10.06
✎
20:41
|
(8)твое условие никогда не будет выполняться
Число(стр) всегда не равно Стр |
|||
10
Любитель XML
16.10.06
✎
20:42
|
?(Строка(Число(Стр))=Стр,Число(Стр),"Не число"); // ;)~
|
|||
11
Los
16.10.06
✎
20:42
|
(6) п. 1 - я сходу вижу только посимвольным разбором... Чего как-раз и не хочется... Как быстро нули посчитать?
(7) Игра ума. Лучше алгоритм предложи. Быстрый. (8) Потому что Число("123") - это число. А число не равно строке. Засунь в конфигуратор - увидишь. |
|||
12
yabodr
16.10.06
✎
20:43
|
Да и вообще, функция Найти() работает достаточно быстро
Если Найти("АБВГДЕЁЖЗ......",Стр) = 0 Тогда Сообщить("Поздравляю, " + Стр + " является числом!"); КонецЕсли; |
|||
13
Sasha
16.10.06
✎
20:43
|
(10)а как быть с правыми и левыми нулями?
|
|||
14
Los
16.10.06
✎
20:44
|
(10) Это написано в (3). Для строки "0100" условие не выполняется. Я ж говорю - проблема в нулях.
|
|||
15
Sasha
16.10.06
✎
20:46
|
(12)не взлетит
(11) без посимвольного не обойтись, на этапе отсечения нулей - перебор будет короче всего |
|||
16
VZ
16.10.06
✎
20:47
|
(12) Повезло тебе, что не на китайском пишешь. У них там, грят, около 5000 основных иероглифов..... У какая длинная строка с Найти() была бы ;)
|
|||
17
2Green
16.10.06
✎
20:58
|
если (3) катит с предварительной заменой точек и запятых...
то замени в исходной строке Стр все "0" на любую другую цифирь |
|||
18
yabodr
16.10.06
✎
21:07
|
(0) а в принципе, как такая задача родилась?
Тест что ли какой-то? |
|||
19
Гена
16.10.06
✎
21:24
|
(18) скорее всего автор хочет привести все Наименования какого-то Справочника к числовому виду
|
|||
20
yabodr
16.10.06
✎
21:29
|
(19) Не все, а те которые получится? А, зачем?
|
|||
21
Susanna
16.10.06
✎
21:33
|
(19)Скорее, коды. Когда нарушают уникальность, потом начинают вводить всякую чепуху.
|
|||
22
yabodr
16.10.06
✎
21:36
|
(21) 40 символов???
|
|||
23
Гена
16.10.06
✎
21:39
|
(20) м.б. автор хочет производить какие-то матоперации с наименованиями...
м.б. это лотерейные билеты или номера скидочных карточек покупателя... (21) коды я отмёл сразу - (22) прав... самое бОлшее я видел 15 знаков кода... |
|||
24
Susanna
16.10.06
✎
21:41
|
(22) хотя да...
(23) жизни вы не видели, я видела 100:) Они туда закодировали производителя, иерархию и пр. |
|||
25
Susanna
16.10.06
✎
21:44
|
+(24)Чорт... то были артикулы:)
|
|||
26
Гена
16.10.06
✎
21:46
|
(24) Боже!
а зачем же так код мучать? реквизит в Справочник нельзя добавить? |
|||
27
reanimator
16.10.06
✎
21:58
|
(17) +1
|
|||
28
yabodr
16.10.06
✎
22:02
|
(23) На мой взгляд, для решения этой задачи, надо знать полностью условие, потому как от условий возможна разная реализация, сама по себе задача решаема в лоб без всяких проблем, если она единовременная, то можно плюнуть на быстродействие. Допустим, если автор действительно хочет "перекодировать" справочник, то нужен дополнительный алгоритм, потому как при использовании одного алгоритма преобразования строки состоящей из одних цифр или из цифр и каких-то символов в число, может "задвоится" число, т.е. при одинаковом преобразовании строки цифр и строки символов имеем вероятность получить на выходе одно и то же число.
|
|||
29
Гена
16.10.06
✎
22:20
|
(28) логично... об уникальности я не подумал...
0099.9, 099.9, 99.990 дадут одно число 99.9 |
|||
30
КонецЦикла
16.10.06
✎
22:50
|
Че токо не придумают...
|
|||
31
Natalia
16.10.06
✎
23:13
|
Если нужно просто "достать число" - то есть очень простой способ извлечения числа из строки, без перебора.
|
|||
32
Пудель
16.10.06
✎
23:36
|
ИсходнаяСтрока=СокрЛП(ИсходнаяСтрока);
Для К=0 По 9 Цикл ИсходнаяСтрока=СтрЗаменить(ИсходнаяСтрока,""+К,""); КонецЦикла; Если СтрДлина(ИсходнаяСтрока)>1 Тогда Сообщить("Это не число"); ИначеЕсли Найти(",.",ИсходнаяСтрока)>0 Тогда//"" есть в любой строке Сообщить("Это число"); КонецЕсли; |
|||
33
trdm
16.10.06
✎
23:37
|
ре.patern = "^([0-9]+[\.\,]?[0-9])$"
ре.test(вСтрока) В точности не уверен, можно потестировать если надо..... |
|||
34
trdm
16.10.06
✎
23:41
|
Пример работы с регулярными выражениями в 1С:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=5&lid=5166 для кого писал? |
|||
35
Любитель XML
16.10.06
✎
23:51
|
(34) ну мы ж тупые и жадные адинэснеги
|
|||
36
Young
17.10.06
✎
00:54
|
MyString = "";
objRegExp = CreateObject("VBScript.RegExp"); objRegExp.Pattern = "^\d*[\.,]?\d*$"; Сообщить(objRegExp.Test(MyString)); //звёздочки по вкусу заменить на плюсики :) |
|||
37
smaharbA
17.10.06
✎
06:01
|
Если Шаблон("["+Х+"+0]")="["+Х+"+0]" Тогда
|
|||
38
smaharbA
17.10.06
✎
06:05
|
+(37)
Если Шаблон("["+стрзаменить(Х,",",".")+"+0]") = "["+стрзаменить(Х,",",".")+"+0]" Тогда |
|||
39
0xFFFFFF
17.10.06
✎
07:34
|
СтрБезНулей = СтрЗаменить(СокрЛП(СтрЗаменить(Стр, "0", " ")), " ", "0")
Если СокрЛП(Строка(Число(СтрБезНулей)))=СокрЛП(СтрБезНулей) Тогда |
|||
40
0xFFFFFF
17.10.06
✎
07:44
|
Полная версия
Процедура ЭтоЧисло(Стр) СтрБезНулей = СтрЗаменить(СокрЛП(СтрЗаменить(Стр, "0", " ")), " ", "0"); СтрБезЗПТ = СтрЗаменить(СтрБезНулей, ",","."); Если СокрЛП(Строка(Число(СтрБезЗПТ)))=СокрЛП(СтрБезЗПТ) Тогда Сообщить(""+Стр+" число"); Иначе Сообщить(""+Стр+" не число"); КонецЕсли; КонецПроцедуры |
|||
41
Рэйв
17.10.06
✎
07:57
|
Рискну вставить свои 5 копеек:-)
Вариант помоему простой и достаточно быстрый: --------------- Сравниваемое="1"+СокрЛП(СтрЗаменить(Код,",","."))+"1"; Проверка=Строка(Число(Сравниваемое)); Если Проверка=Сравниваемое Тогда Сообщить(Код+"- > Число"); Иначе Сообщить(Код+"- > Не число "); КонецЕсли; |
|||
42
nikmar
17.10.06
✎
09:13
|
Только что проверял:
Если Число(СтрЗаменить(СтрЗаменить(Выб, ",", "."), "0", "1"))=0 тогда //Не число Иначе //Число КонецЕсли; |
|||
43
0xFFFFFF
17.10.06
✎
09:15
|
(42) Я понял, что нужно еще определить само значение если строка является числом.
|
|||
44
Рэйв
17.10.06
✎
09:21
|
(42) Попробуй прогнать "1,Ф" ...
Будет 1.Это число? |
|||
45
nikmar
17.10.06
✎
09:26
|
(44) Мистика блин.
|
|||
46
Рэйв
17.10.06
✎
09:31
|
(45) :-)
0 будет только если проверяемое выражение начинается не с цифры. А все первые цифры буду превращаться в число, остальное отбрасываться. |
|||
47
2Green
17.10.06
✎
10:10
|
эк вас плющит
|
|||
48
orefkov
17.10.06
✎
11:01
|
Тупо и влоб:
Функция ЭтоЧисло(Знач Стр, НайденноеЧисло) НайденноеЧисло = 0; _Стр = ""; Стр = СокрЛП(Стр); Длина = СтрДлина(Стр); ЕстьТочка = 0; Для Индекс=1 По Длина Цикл с = КодСимв(Сред(Стр, Индекс, 1)); Если (с = 46) ИЛИ (с = 44) Тогда // ., Если ЕстьТочка<>0 Тогда Возврат 0; Иначе ЕстьТочка = 1; _Стр = _Стр + "."; Продолжить; КонецЕсли; ИначеЕсли (с > 47) И (с < 58) Тогда _Стр = _Стр + Симв(с); Иначе Возврат 0; КонецЕсли; КонецЦикла; НайденноеЧисло = Число(_Стр); Возврат 1; КонецФункции // ЭтоЧисло |
|||
49
Natalia
17.10.06
✎
11:07
|
Рискну предложить свой вариант
Функция ЧислоИзСтроки(Знач Стр) Экспорт Стр = СтрЗаменить(Стр,Симв(34),""); Сп = СоздатьОбъект("СписокЗначений"); Сп.ИзСтрокиСРазделителями(Стр); Если Сп.Размерсписка()>0 Тогда Возврат Сп.ПолучитьЗначение(1) КонецЕсли; Возврат ""; КонецФункции //ЧислоИзСтроки() ////////////////////// СтрЧисло= ЧислоИзСтроки(Стр); Стр = СтрЗаменить(Стр,СтрЧисло,""); Стр = СтрЗаменить(Стр,"0",""); Если Стр="" Тогда Сообщить("Это число") Иначе Сообщить("Это не число"); КонецЕсли; |
|||
50
Uho
17.10.06
✎
11:19
|
(41) +1
|
|||
51
orefkov
17.10.06
✎
11:20
|
Вот еще вариант:
Функция ЭтоЧисло(Знач Стр, НайденноеЧисло) Стр = СокрЛП(Стр); НайденноеЧисло = 0; _Стр = Нрег(Стр); Если _Стр <> Стр Тогда Возврат 0; КонецЕсли; _Стр = Врег(Стр); Если _Стр <> Стр Тогда Возврат 0; КонецЕсли; Стр = СтрЗаменить(Стр, ",", "."); ЕстьТочка = СтрЧислоВхождений(Стр, "."); Если ЕстьТочка > 1 Тогда Возврат 0; КонецЕсли; Длина = СтрДлина(Стр) - ЕстьТочка; ЧислоВхождений = 0; Цифра = 1; Пока 1=1 Цикл ЧислоВхождений = ЧислоВхождений + СтрЧислоВхождений(Стр, "" + Цифра); Если ЧислоВхождений = Длина Тогда Прервать; КонецЕсли; Если Цифра = 9 Тогда Прервать; КонецЕсли; Цифра = Цифра + 1; КонецЦикла; Если ЧислоВхождений = Длина Тогда НайденноеЧисло = Число(Стр); Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ЭтоЧисло |
|||
52
Сли то
17.10.06
✎
11:22
|
А почему (17) или (41) не устраиват?
|
|||
53
orefkov
17.10.06
✎
11:32
|
(41)
Кошерно. Только вот в табло Строка(Число("1"+".000000000000000000001"+"1")) = 1 |
|||
54
Сли то
17.10.06
✎
11:34
|
(53) Ограничение знаков после запятой. Для 1С это не число
|
|||
55
orefkov
17.10.06
✎
11:35
|
В терминах поставленной задачи эта строка - число, со значением в 1С, равным нулю.
|
|||
56
smaharbA
17.10.06
✎
11:37
|
А что в (37) и (38) никто не плюнул ?
|
|||
57
orefkov
17.10.06
✎
11:42
|
Тут надо определится, считатать ли например строку
"1.00000000000000000001" - числом. Потому как все попытки сравнивать строки до и после преобразования функцией "Число", натыкаются на ограниченность разрядов. |
|||
58
Сли то
17.10.06
✎
11:45
|
(56) а плеваться то? 37,38 - фигня
(57) можно и не определяться, по такому принципоу пойти Число("1"+".000000000000000000001"+"1")*10000000000000000000000 |
|||
59
Сли то
17.10.06
✎
11:47
|
Проверил в табло
Число("1"+".00000000000000000000000000000000000001"+"1")*1000000000000000000000000000000000000000 = 1000000000000000000000000000000000000011 |
|||
60
smaharbA
17.10.06
✎
11:54
|
(58) не фигня, так многое можно определить и не только строка или число
|
|||
61
orefkov
17.10.06
✎
11:54
|
(59)
Число("1"+"9876543210"+"1")*1000000000000000000000000000000000000000 = 198765432101000000000000000000000000000000000000000 |
|||
62
smaharbA
17.10.06
✎
11:57
|
(58)(59) а это - Число("1толиДатолиНет"+".000000000000000000001"+"1")*10000000000000000000000 число ?
|
|||
63
Сли то
17.10.06
✎
11:57
|
(61) Не, ну понятно. Я сказал что принцып такой. Позицию разделителя дробной найти.
|
|||
64
orefkov
17.10.06
✎
12:17
|
Функция ЭтоЧисло(Знач Стр, НайденноеЧисло)
Стр = СтрЗаменить(Стр, ",", "."); ЕстьТочка = СтрЧислоВхождений(Стр, "."); Если ЕстьТочка>1 Тогда Возврат 0; КонецЕсли; _Стр = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(Стр, "-", "+"), "9", "-"), "8", "-"), "7", "-"), "6", "-"), "5", "-"), "4", "-"), "3", "-"), "2", "-"), "1", "-"), "0", "-"); Если СтрЧислоВхождений(_Стр, "-") = СтрДлина(Стр) - ЕстьТочка Тогда НайденноеЧисло = Число(Стр); Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ЭтоЧисло |
|||
65
orefkov
17.10.06
✎
12:22
|
Маленькая ошибка в (64). Вот:
Функция ЭтоЧисло(Знач Стр, НайденноеЧисло) Стр = СтрЗаменить(СокрЛП(Стр), ",", "."); ЕстьТочка = СтрЧислоВхождений(Стр, "."); Если ЕстьТочка>1 Тогда Возврат 0; КонецЕсли; _Стр = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(Стр, "-", "+"), "9", "-"), "8", "-"), "7", "-"), "6", "-"), "5", "-"), "4", "-"), "3", "-"), "2", "-"), "1", "-"), "0", "-"); Если СтрЧислоВхождений(_Стр, "-") =СтрДлина(_Стр) - ЕстьТочка Тогда НайденноеЧисло = Число(Стр); Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ЭтоЧисло |
|||
66
Рэйв
17.10.06
✎
12:23
|
(53) Как я понял, 1С не видит больше 20 знаков после точки.
Тогда можно извернуться так. Часть вторая.усовершенствованная :-): -------------------- Функция ЭтоЧисло (Часть) Сравниваемое="1"+СокрЛП(СтрЗаменить(Часть,",","."))+"1"; Проверка=Строка(Число(Сравниваемое)); Если Проверка=Сравниваемое Тогда Возврат 1; Иначе Возврат 0;; КонецЕсли; КонецФункции //----------------------- можно и на три части разрезать. С запасом:) Процедура Сформировать() Часть1=Лев(Код,СтрДлина(Код)/2); Часть2=Прав(Код,СтрДлина(Код)-СтрДлина(Часть1)); Если (ЭтоЧисло(Часть1)+ЭтоЧисло(Часть2))=2 Тогда Сообщить(Код+"-> число"); Иначе Сообщить(Код+"-> не число"); КонецЕсли; КонецПроцедуры; |
|||
67
Сли то
17.10.06
✎
12:23
|
При условии Что Стр="1.00000000000000000000000000000000000000001"
Что же вернет "НайденноеЧисло = Число(Стр);" ?? Ну, ладно, это я уже стебаюсь. Имхо можно эти способы объединить или выбрать более удобный для (0). |
|||
68
BlinOFF
17.10.06
✎
12:24
|
КодСимв(<?>)
Синтаксис: КодСимв(<Символ>) Назначение: Возвращает код первого символа, содержащегося в строке. Параметры: <Символ> - строковое выражение. |
|||
69
BlinOFF
17.10.06
✎
12:26
|
КодСимв("0")=48
КодСимв("9")=57 |
|||
70
orefkov
17.10.06
✎
12:29
|
(67)
То и вернет, что строка является числом, и его значение. Фишка в том, что число в 1С ограниченно 69 разрядами (чего хватает для этой задачи), но при преобразовании его в строку обрезает до 23 знаков после запятой. |
|||
71
orefkov
17.10.06
✎
12:38
|
(66)
Неправильно отработает, если будет две точки, и они попадут в разные части. Либо в середине строки будут пробелы, которые попадут в первую часть в конец, во вторую часть в начало. |
|||
72
Рэйв
17.10.06
✎
12:46
|
(71) Легко решается несколькими строками в начале процедуры Сформировать
:-) //--------- Если СтрЧислоВхождений(СтрЗаменить(Код,",","."),".") >1 Тогда Сообщить(Код+"-> не число"); Возврат; КонецЕсли; Код=СтрЗаменить(Код," ",""); //----- |
|||
73
Рэйв
17.10.06
✎
12:49
|
(+72) Правда если выражение с пробелами в середине не считать за число, то надо сделать тоже проверку на пробелы
|
|||
74
smaharbA
17.10.06
✎
13:02
|
не всеже объясните тупым и алкоголикам чем шаблон плох ? медленно ?
|
|||
75
Пудель
17.10.06
✎
13:02
|
32 всё равно оптимальный код.
|
|||
76
Сли то
17.10.06
✎
13:21
|
(75) Только еще одно уловие поставить надо, если нет дробной части. Просто хотелось не перебором.
(74) Ну чего ты этими шаблонами добьешься? Попробуй че нить подсунуть. К примеру 00А00.5115.1 |
|||
77
trdm
17.10.06
✎
13:28
|
база-вокзал одним словом.....
|
|||
78
trdm
17.10.06
✎
13:31
|
а, собственно, регулярные выражения чем не устроили?
|
|||
79
Пудель
17.10.06
✎
14:06
|
(76) Не надо доп. условий, там в комментарии пояснено, почему не надо. И перебора там нет - СтрЗаменить-то без перебора работает.
(78) Спортивно средствами встроенного языка. |
|||
80
Сли то
17.10.06
✎
14:12
|
Тогда
Найти(""",.",ИсходнаяСтрока)>0 |
|||
81
BlinOFF
17.10.06
✎
14:24
|
Процедура НайтиЧисло(Стр)
Цифра=""; фл=0; Для Н=1 По СтрДлина(Стр) Цикл Символ=Сред(Стр,Н,1); Если ((КодСимв(Символ)>=48) и (КодСимв(Символ)<=57)) или ((Цифра<>"") и (КодСимв(Символ)=46)) Тогда Цифра=Цифра+Символ; фл=1; Продолжить; КонецЕсли; Если фл=1 Тогда Сообщить(Цифра); НайтиЧисло(Прав(Стр,СтрДлина(Стр)-Н+1)); Возврат; КонецЕсли; КонецЦикла; Сообщить(Цифра); КонецПроцедуры //******************************************* Процедура Сформировать() НайтиЧисло(Строчка); КонецПроцедуры |
|||
82
Vacony
17.10.06
✎
14:30
|
такое чувство, что из предложенных вриантов не все тестировали (больше писали на угад) + кто скажет что быстрее ? :)
П.С. сам пока думаю... :) |
|||
83
Vacony
17.10.06
✎
15:00
|
Ну вот и я придумал.. (опробовал на всех вариантах предложенных)
Имхо. Работает достаточно быстро... стр1 = исходная строка Процедура Сформировать() стр=Сокрлп(СтрЗаменить(стр1,",",".")); //привели к строке вида ххх.ххх.... й=1; Пока й=1 Цикл сообщить(""+стр); Если СтрЗаменить(стр,"0","")="" Тогда Сообщить("число"); й=0; КонецЕсли; Зн = (Число(стр)*1); Если Зн=0 Тогда Сообщить("не число"); й=0; КонецЕсли; Поз = Найти(стр,Зн); Если Поз+СтрДлина(Зн)-1=СтрДлина(стр) Тогда й=0; Сообщить("число"); Иначе стр = ПРав(стр,СтрДлина(стр)-СтрДлина(Зн)); Если Стр="" Тогда Сообщить("не число"); й=0; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры ======== Жду коментов... |
|||
84
Los
17.10.06
✎
15:43
|
Мда... Не ожидал я такого спортивного интереса, когда тему поднимал :)
Сразу повторю свой ответ на вопрос "а на хрена?" - это действительно игра ума :) Была реальная, но разовая задача, сделал ее "в лоб" перебором, потом стало интересно, а как быстрее, поставил граничные условия, запостил сюда, пошел домой спать :) Самый быстрый вариант, как ни странно, оказался самым первым, у 2Green. Но он не работает с числами >20 знаков. Результат меня сильно удивил, потому как я думал о первом варианте Рэйва. Замер производительности показал: стр="1"+стр+"1"; 0.048389 стр=СтрЗаменить(стр, "0", "1"); 0.039269 Для меня это было неожиданностью. :) (В тиках - 110 и 117 соответственно) Дальше идет вариант с регулярными выражениями (154 тика), вариант orefkov'а (187 тиков), вариант Пуделя (551 тик). Остальные варианты пока не померил. |
|||
85
Vacony
17.10.06
✎
16:04
|
84 - ждем :)
|
|||
86
smaharbA
17.10.06
✎
16:07
|
(76) Либо ты (0) нечитал, либо я (0) непонял...
|
|||
87
smaharbA
17.10.06
✎
16:09
|
(84) с регулярами заметь, можно весь тект за один присест, не построчно, "рассортировать"...
|
|||
88
Пудель
17.10.06
✎
16:11
|
(84) Блин, ты просто моё время с временем Сообщить замерял :))). Я только что проверил - у меня быстрее орефкова (моё 0.004647, орефкова 0.004695)
|
|||
89
trdm
17.10.06
✎
16:11
|
(84) Попробуй вариант для регулярных не по одной строке, а по "тексту" т.е. строке разделенной "РазделительСтрок". Если конечно в условия задачи вползает.
|
|||
90
Vacony
17.10.06
✎
16:28
|
да, надо из замера Сообщить убрать ...
|
|||
91
smaharbA
17.10.06
✎
16:29
|
Да с Шаблон медленно когда не число зато код простой, можна и еще просче :)
... Функция ЭтоЧисло2(Знач Стр, НайденноеЧисло) Стр = СтрЗаменить(СокрЛП(Стр), ",", "."); Если Шаблон("["+Стр+"]") <> "["+Стр+"]" Тогда НайденноеЧисло = Число(Стр); Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ЭтоЧисло |
|||
92
Vacony
17.10.06
✎
17:46
|
ну и где результаты тестов других алгоритмов ?
|
|||
93
Los
17.10.06
✎
18:55
|
(88) Не-а... Правда твой код я переписал, оставил только идею:
Функция алг_Пудель() Перем стр, й, Ч, К; Ч=0; Для й=1 По 10000 Цикл стр=Массив[й]; Для К=0 По 9 Цикл стр=СтрЗаменить(стр,""+К,""); КонецЦикла; Если СтрДлина(стр)=1 Тогда Если Найти(",.",стр)>0 Тогда Ч=Ч+1; КонецЕсли; ИначеЕсли СтрДлина(стр)=0 Тогда Ч=Ч+1; КонецЕсли; КонецЦикла; Возврат Ч; КонецФункции (87) Надо "тестовый стенд" для этого переписывать. Сейчас он выглядит так: 1. Исходные данные живут в дбф. 10000 строк. Строки формировались так: 1.1. Случайная длина строки от 1 до 40 1.2. Каждый символ строки генерировался случайным образом из набора "01234567890.,AB". Такой набор получил опытным путем - меня устроил процент "правильных" чисел: ~15% (точнее - 1360 из 10000) 1.3. Массив строк хранится в глобальной переменной и перед началом работы считывается из dbf 2. Все алгоритмы загонялись в функцию, возвращающую количество чисел в наборе. Шаблон функции: Функция алг() Перем стр, й, Ч; Ч=0; Для й=1 По 10000 Цикл стр=Массив[й]; // Тут проверяем стр на число, если число - Ч=Ч+1 КонецЦикла; Возврат Ч; КонецФункции 3. Функция вызывалась так: Т1=_GetPerformanceCounter(); Сообщить("Чисел: "+алг()); Т2=_GetPerformanceCounter(); Сообщить(""+(Т2-Т1)+" тиков"); (92) Пока нет времени переписать под стенд :) Если кто-нить хочет по#@$%ся самостоятельно - могу выложить куда-нить этот dbf со строками. |
|||
94
2Green
17.10.06
✎
19:25
|
(84) ну, с учётом что исходные строки длиной <40, и что ограничение на дробную часть в 20 знаков...
можно добавить Лев(Стр,20) и Прав(Стр,20) |
|||
95
Ёпрст
17.10.06
✎
19:52
|
Я, пожалуй, тоже отмечусь ... :)
Функция ЭтоЧисло(Знач Стр) Стр = СокрЛП(СтрЗаменить(Стр,",","")); Возврат ?(Формат(Число(Стр),"Ч(0)"+СтрДлина(Стр)+"."+?(Найти(Стр,".")=0,0,СтрДлина(Стр)-Найти(Стр,".")))=Стр,"число"," не число"); КонецФункции |
|||
96
СочинскийДед
17.10.06
✎
20:20
|
Забавно.
//******************************************* Функция ЭтоЧисло(СтрокаПроверить) // 1 - это число ,0 - нет, не число ,нули давите сами Перем ДлинаСтрокиПроверить; Перем СтрокаФильтр; Перем ДлинаСтрокиФильтр; Перем НашлиСимволов; СтрокаПроверить = СокрЛП(СтрокаПроверить); СтрокаФильтр = "1234567890.,"; // проверим на ноль - стандарт Если СтрокаПроверить = "0" Тогда Возврат 1; КонецЕсли; // проверим две точки Если СтрЧислоВхождений(СтрокаПроверить, ".") > 1 Тогда Возврат 0; КонецЕсли; // проверим две запятых Если СтрЧислоВхождений(СтрокаПроверить, ",") > 1 Тогда Возврат 0; КонецЕсли; // проверим обе Если СтрЧислоВхождений(СтрокаПроверить, ".") * СтрЧислоВхождений(СтрокаПроверить, ",") <> 0 Тогда Возврат 0; КонецЕсли; ДлинаСтрокиПроверить = СтрДлина(СтрокаПроверить); ДлинаСтрокиФильтр = СтрДлина(СтрокаФильтр); НашлиСимволов = 0; Для СчФильтр = 1 По ДлинаСтрокиФильтр Цикл НашлиСимволов = НашлиСимволов + СтрЧислоВхождений(СтрокаПроверить, Сред(СтрокаФильтр, СчФильтр, 1)); КонецЦикла; Если НашлиСимволов <> ДлинаСтрокиПроверить Тогда Возврат 0; Иначе Возврат 1; КонецЕсли; КонецФункции Сообщить("ЭтоЧисло(""0100,99900"") = "+ЭтоЧисло("0100,99900")); Сообщить("ЭтоЧисло(""100"") = "+ЭтоЧисло("100")); Сообщить("ЭтоЧисло(""100.99"") = "+ЭтоЧисло("100.99")); Сообщить("ЭтоЧисло(""100.0,12"") = "+ЭтоЧисло("100.0,12")); Сообщить("ЭтоЧисло(""Asd100xЩ"") = "+ЭтоЧисло("Asd100xЩ")); Сообщить("ЭтоЧисло(""100.0Ю"") = "+ЭтоЧисло("100.0Ю")); Сообщить("ЭтоЧисло(""0"") = "+ЭтоЧисло("0")); Сообщить("ЭтоЧисло(""0/00"") = "+ЭтоЧисло("0/00")); Сообщить("ЭтоЧисло(""0.00.00.0000.0....000000.0"") = "+ЭтоЧисло("0.00.00.0000.0....000000.0")); Сообщить("ЭтоЧисло(""0000"") = "+ЭтоЧисло("0000")); |
|||
97
Пудель
17.10.06
✎
20:26
|
(93) Нет, ты кое-что испортил:
"Если СтрДлина(стр)=1 Тогда Если Найти(",.",стр)>0 Тогда Ч=Ч+1; КонецЕсли; ИначеЕсли СтрДлина(стр)=0 Тогда Ч=Ч+1; КонецЕсли;" это плохой код, так как неоправданно два раза обращается к СтрДлина, а у меня такого не было. Одна из идей моего кусочка кода в том, что Найти(",.","")=1, именно поэтому можно ограничиться Если СтрДлина(ИсходнаяСтрока)>1 Тогда Сообщить("Это не число"); ИначеЕсли Найти(",.",ИсходнаяСтрока)>0 Тогда//"" есть в любой строке Сообщить("Это число"); КонецЕсли; обрати внимание на комментарий!!!!! |
|||
98
Дурочка 1С ™
17.10.06
✎
20:34
|
Функция ЭтоЧисло(Знач СтрокаПроверки)
//Сначала надо договориться и выбрать что-то одно: // // Если считается, что " 001.1000 000" (т.е. в середине есть пробелы) - это строка, тогда Если СтрЧислоВхождений(СокрЛП(СтрокаПроверки)," ")>0 Тогда Возврат 0; КонецЕсли; // Иначе // Если считается, что " 001.1000 000" (т.е. в середине есть пробелы) - это все же число, тогда начнем так: СтрокаПроверки=СтрЗаменить(СтрокаПроверки," ",""); // Раз договорились, ... СтрокаПроверки=СтрЗаменить(СтрокаПроверки,",","."); ЕслиЭтоЧислоТоОно = 0+СтрокаПроверки; Если ЕслиЭтоЧислоТоОно=0 Тогда Возврат 0; КонецЕсли; ЧтоОсталось=СокрЛП(СтрЗаменить(СтрЗаменить(СтрокаПроверки,ЕслиЭтоЧислоТоОно,""),"0","")); // Если это было число, то от него могли остаться только лидирующие нули и нули после запятой Если ЧтоОсталось="" Тогда Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции // ЭтоЧисло() |
|||
99
СочинскийДед
17.10.06
✎
20:40
|
+(96) Еще вариант
//******************************************* Функция ЭтоЧисло(СтрокаПроверить) // 1 - это число ,0 - нет, не число ,нули давите сами Перем ДлинаСтрокиПроверить; Перем СтрокаФильтр; Перем ДлинаСтрокиФильтр; Перем НашлиСимволов; СтрокаПроверить = СокрЛП(СтрокаПроверить); СтрокаФильтр = "1234567890.,"; // проверим на ноль - стандарт Если СтрокаПроверить = "0" Тогда Возврат 1; КонецЕсли; // проверим две точки Если СтрЧислоВхождений(СтрокаПроверить, ".") > 1 Тогда Возврат 0; КонецЕсли; // проверим две запятых Если СтрЧислоВхождений(СтрокаПроверить, ",") > 1 Тогда Возврат 0; КонецЕсли; // проверим обе Если СтрЧислоВхождений(СтрокаПроверить, ".") * СтрЧислоВхождений(СтрокаПроверить, ",") <> 0 Тогда Возврат 0; КонецЕсли; ДлинаСтрокиПроверить = СтрДлина(СтрокаПроверить); ДлинаСтрокиФильтр = СтрДлина(СтрокаФильтр); НашлиСимволов = 0; Для СчПроверить = 1 По ДлинаСтрокиПроверить Цикл Для СчФильтр = 1 По ДлинаСтрокиФильтр Цикл Если СтрЧислоВхождений(СтрокаФильтр, Сред(СтрокаПроверить, СчПроверить, 1)) = 0 Тогда Возврат 0; КонецЕсли; КонецЦикла; КонецЦикла; Возврат 1; КонецФункции Сообщить("ЭтоЧисло(""0100,99900"") = "+ЭтоЧисло("0100,99900")); Сообщить("ЭтоЧисло(""100"") = "+ЭтоЧисло("100")); Сообщить("ЭтоЧисло(""100.99"") = "+ЭтоЧисло("100.99")); Сообщить("ЭтоЧисло(""100.0,12"") = "+ЭтоЧисло("100.0,12")); Сообщить("ЭтоЧисло(""Asd100xЩ"") = "+ЭтоЧисло("Asd100xЩ")); Сообщить("ЭтоЧисло(""100.0Ю"") = "+ЭтоЧисло("100.0Ю")); Сообщить("ЭтоЧисло(""0"") = "+ЭтоЧисло("0")); Сообщить("ЭтоЧисло(""0/00"") = "+ЭтоЧисло("0/00")); Сообщить("ЭтоЧисло(""0.00.00.0000.0....000000.0"") = "+ЭтоЧисло("0.00.00.0000.0....000000.0")); Сообщить("ЭтоЧисло(""0000"") = "+ЭтоЧисло("0000")); |
|||
100
Пудель
17.10.06
✎
20:41
|
(98) А нули? СтрокаПроверки=0000000.00000?? Не число у тебя. ЕслиЭтоЧислоТоОно = 0+СтрокаПроверки;
|
|||
101
Дурочка 1С ™
17.10.06
✎
20:54
|
(100) В (0) много чего не договОрено ... В том числе, не понятно признает он 0 числом или нет ...
Функция ЭтоЧисло(Знач СтрокаПроверки) Если ПустаяСтрока(СтрокаПроверки)=1 Тогда Возврат "Совсем сдурели!"; КонецЕсли; //Сначала надо договориться и выбрать что-то одно: // // Если считается, что " 001.1000 000" (т.е. в середине есть пробелы) - это строка, тогда Если СтрЧислоВхождений(СокрЛП(СтрокаПроверки)," ")>0 Тогда Возврат 0; КонецЕсли; // Иначе // Если считается, что " 001.1000 000" (т.е. в середине есть пробелы) - это все же число, тогда начнем так: СтрокаПроверки=СтрЗаменить(СтрокаПроверки," ",""); // Раз договорились, ... СтрокаПроверки=СтрЗаменить(СтрокаПроверки,",","."); ДикиеЛюди= СокрЛП(СтрЗаменить(СтрокаПроверки,"0",""); Если (ДикиеЛюди="") или (ДикиеЛюди=".") Тогда Возврат 1; КонецЕсли; ЕслиЭтоЧислоТоОно = 0+СтрокаПроверки; Если ЕслиЭтоЧислоТоОно=0 Тогда Возврат 0; КонецЕсли; ЧтоОсталось=СтрЗаменить(СтрЗаменить(СтрокаПроверки,ЕслиЭтоЧислоТоОно,""),"0",""); // Если это было число, то от него могли остаться только лидирующие нули и нули после запятой Если ЧтоОсталось="" Тогда Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции // ЭтоЧисло() |
|||
102
smaharbA
18.10.06
✎
07:21
|
Чет я совсем тупенький, ниче не понимаю...
|
|||
103
Рэйв
18.10.06
✎
08:11
|
Интересно, а призы будут?:) по всем понятиям Los уже должен начать об этом думать:))
|
|||
104
orefkov
18.10.06
✎
08:46
|
Вот слегка улучшенный вариант Пуделя.
---- Функция ЭтоЧисло(Стр) Стр=СокрЛП(Стр); _Стр = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Стр, "9", ""), "8", ""), "7", ""), "6", ""), "5", ""), "4", ""), "3", ""), "2", ""), "1", ""), "0", ""); Если _Стр="" Тогда Возврат 1; ИначеЕсли _Стр="." Тогда Возврат 1; ИначеЕсли _Стр="," Тогда Стр=СтрЗаменить(Стр, ",", "."); Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции // ЭтоЧисло |
|||
105
orefkov
18.10.06
✎
09:48
|
Самый быстрейший вариант:
---- Перем ЭтоЧисло; Функция ЭтоЧисло(Стр) Возврат ЭтоЧисло.ЭтоЧисло(Стр); КонецФункции // ЭтоЧисло Попытка ЭтоЧисло = СоздатьОбъект("ЭтоЧисло"); Исключение ЗагрузитьВнешнююКомпоненту(КаталогПрограммы() + "isnumber.dll"); ЭтоЧисло = СоздатьОбъект("ЭтоЧисло"); КонецПопытки; --- isnumber.dll качать с http://www.infostart.ru/file.php?0,file=48 (4КБ, не требует регистрации в реестре) |
|||
106
2Green
18.10.06
✎
10:12
|
(105) "0/00", "0+2"
|
|||
107
orefkov
18.10.06
✎
10:28
|
(106)
Исправлено. Перекачай. |
|||
108
orefkov
18.10.06
✎
10:35
|
+107
http://www.infostart.ru/file.php?0,file=49 |
|||
109
2Green
18.10.06
✎
11:02
|
(107)
так не интересно. исходники языком 1С в студию! :-)) ну или хоть своими словами... |
|||
110
Buhta
18.10.06
✎
11:07
|
Во людям заняться нечем:) Все не читала, но мне понравилось решение Пуделя в (32)
|
|||
111
orefkov
18.10.06
✎
11:10
|
(109)
Все определяется за один проход по исходной строке: --- class CIsNumber : public CContextImpl<CIsNumber> { public: BL_BEGIN_CONTEXT("IsNumber", "ЭтоЧисло"); BL_FUNC(IsNumber, "ЭтоЧисло", 1) { if(ppParams[0]->type!=2) CBLModule::RaiseExtRuntimeError("Передана не строка", FALSE); char *ptr=const_cast<char*>(ppParams[0]->m_String.operator LPCTSTR()), *decPos=NULL; DWORD dwState=0; while(dwState != -1) { DWORD s=context_obj::str_find::symbol(ptr); if(!s) break; switch(dwState) { case 0: // Начало строки if(s>='0' && s<='9') dwState = 1; else if(s!=' ') { if(s=='.') dwState = 2; else if(s==',') { decPos=ptr; dwState = 2; } else dwState = -1; } break; case 1: // Началось число if(s<'0') { if(s=='.') dwState = 2; else if(s==',') { decPos=ptr; dwState = 2; } else if(s==' ') dwState = 3; else dwState=-1; } else if(s>'9') dwState=-1; break; case 2: // Была точка if(s<'0') { if(s==' ') dwState = 3; else dwState = -1; } else if(s>'9') dwState = -1; break; case 3: // Был пробел после числа if(s!=' ') dwState = -1; } ptr++; } if(static_cast<int>(dwState) > 0) { if(decPos) *decPos = '.'; retVal = 1L; } else retVal = 0L; return TRUE; } BL_END_CONTEXT(); }; |
|||
112
Biger
18.10.06
✎
11:12
|
мож чего пропустил, но если символы между 48 и 57 ,и 44 и 46 не более одного раза, не пойдет?
|
|||
113
Дурочка 1С ™
18.10.06
✎
11:14
|
(110) Оно не решает даже сабжа (не говоря уже о вариантах). Например, число 100 из условия примет за строку ...
|
|||
114
Buhta
18.10.06
✎
11:17
|
(113)А если чуть добавить иначе и при СтрДлина(ИсходнаяСтрока)=0 выв. "число"?
|
|||
115
Пудель
18.10.06
✎
11:21
|
(113) Сколько раз объяснять! Найти (".,","")=1 !!!!! Всё нормально там. Внимательно читай код, Дурочка!!! И не утверждай, не проверив!!!
|
|||
116
Buhta
18.10.06
✎
11:22
|
+114 А ",100" и "100," это числа? Ну еще тогда отбросить... некогда мне, ЕСН с НДСом жмут...
|
|||
117
Дурочка 1С ™
18.10.06
✎
11:23
|
+(113) Вру! Сабж решает ... Пробелы в середине считает строкой, хотя, может это и правильно - в условии не оговорено ...
|
|||
118
2Green
18.10.06
✎
11:23
|
(115) неа. вот в условии (0) есть пример "Asd100xЩ"
|
|||
119
Пудель
18.10.06
✎
11:25
|
(118) И что? Моя функция понимает, что это не число. Разумеется.
|
|||
120
2Green
18.10.06
✎
11:26
|
упс
|
|||
121
Дурочка 1С ™
18.10.06
✎
11:26
|
(116) По условию 100 - число, про ",100" ничего не сказано. ЕСН с НДСом давно сдали и забыли ...
|
|||
122
Buhta
18.10.06
✎
11:28
|
(121)Везет же, а у меня сводные... еще не все отчеты подогнали... пойду "сводить"...
|
|||
123
Vacony
18.10.06
✎
11:30
|
а тестить на скорость кто будет ? :) интересно просто, а самому влом :)
|
|||
124
Дурочка 1С ™
18.10.06
✎
11:31
|
(122) Юзайте 1С! В экселе, небось, до сих пор считаете ...
|
|||
125
Buhta
18.10.06
✎
11:33
|
(124)Нет, на счетах и пальцы загибаем:) Но из (32) ИМХО можно получить решение для всех случаев...
|
|||
126
Пудель
18.10.06
✎
11:37
|
Угу, и что самое приятное - она работает с любыми размерами строк (до 64К, видимо :) ). И чем больше длина строки, тем более явным будет её преимущество - она ведь "сжимает" длинные строки среднестатистически на 1/10 на каждом шаге цикла СтрЗаменить.
|
|||
127
Дурочка 1С ™
18.10.06
✎
12:17
|
(126) С точки зрения 1С "1.00000000000000000000000000000000000000001" - это строка ...
|
|||
128
Los
18.10.06
✎
14:56
|
Ну вот пожалуй и все... Самый быстрый алгоритм получен :)
Лидеров осталось двое: алгоритм Пуделя в модификации orefkov, и моя модификация алгоритма 2Green/Рэйв. Функции: ============================== Функция ЭтоЧисло_Пудель(Стр) Перем _Стр; _Стр = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить( СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Стр, "9", ""), "8", ""), "7", ""), "6", ""), "5", ""), "4", ""), "3", ""), "2", ""), "1", ""), "0", ""); Если _Стр="" Тогда Возврат 1; ИначеЕсли _Стр="." Тогда Возврат 1; ИначеЕсли _Стр="," Тогда Стр=СтрЗаменить(Стр, ",", "."); Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции Функция ЭтоЧисло_2Green(Стр) Перем Куски, Дл, й, _Стр, _С; Дл=СтрДлина(Стр); _Стр=СтрЗаменить(СтрЗаменить(Стр, "0", "1"), ",", "."); Если СтрЧислоВхождений(_Стр, ".")<2 Тогда _Стр=СтрЗаменить(_Стр, ".", "1"); й=1; Пока й<=Дл Цикл _С=Сред(_Стр, й, Мин(18,Дл-й+1)); Если СокрЛП(Строка(Число(_С)))<>СокрЛП(_С) Тогда Возврат 0; КонецЕсли; й=й+18; КонецЦикла; Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции ========================== Вызов: Перем Н, Ч, й, Т1, Т2; Н=ПрочитатьФайл(); Сообщить("Алгоритм Пуделя:"); Ч=0; Т1=_GetPerformanceCounter(); Для й=1 По Н Цикл Ч=Ч+ЭтоЧисло_Пудель(Массив[й]); КонецЦикла; Т2=_GetPerformanceCounter(); Сообщить("Чисел: "+Ч); Сообщить("Время работы: "+(Т2-Т1)+" тик"); Сообщить("============================="); Сообщить("Алгоритм 2Green+Рэйв:"); Ч=0; Т1=_GetPerformanceCounter(); Для й=1 По Н Цикл Ч=Ч+ЭтоЧисло_2Green(Массив[й]); КонецЦикла; Т2=_GetPerformanceCounter(); Сообщить("Чисел: "+Ч); Сообщить("Время работы: "+(Т2-Т1)+" тик"); Сообщить("============================="); =============================================== Содержимое файла: 9999 записей, сформированных по алгоритму из (93) Пример: ,.3.211.34829.AA694S80470438S05775,S.3 98987A4 ,4 360862 20A.S7553.964A1.41,6.6237 1SA9, 48.733454, 50,2 ================================================== Вывод: Прочитано записей: 9999 Алгоритм Пуделя: Чисел: 1359 Время работы: 211 тик ============================= Алгоритм 2Green+Рэйв: Чисел: 1359 Время работы: 159 тик ============================= Через некоторое время из спортивного интереса попробую на очень длинных строках... Кстати, дайте идею, какую строку считать очень длинной и какой алгоритм генерации строк использовать. :-) |
|||
129
orefkov
18.10.06
✎
15:29
|
(128)
Интересно узнать сравнение с ВК из (105) + (108) (вне конкурса) |
|||
130
СочинскийДед
18.10.06
✎
15:57
|
(128)
Если не влом, проверь 99 сколько "тиков". |
|||
131
Сли то
18.10.06
✎
16:07
|
Вы все больные
|
|||
132
smaharbA
18.10.06
✎
16:09
|
А че мой алгоритм не проверили ?
И всетаки регулярами будет гораздо быстрее, и ненадо построчно бегать |
|||
133
orefkov
18.10.06
✎
16:10
|
(131)
Мы все удачники, у которых есть время на всякую хрень :) |
|||
134
СочинскийДед
18.10.06
✎
16:18
|
(131)
Где еще увидишь такое у 1снегов: "у кого меньше?" |
|||
135
Los
18.10.06
✎
16:52
|
(130) Вот что такое лень... Хороший алгоритм пропустил :( Короче сейчас идет почти совсем поровну... Пудель/2Green/СочинскийДед 212/158/159
Сейчас перегенерю строки на побольше, добавлю регуляры и ВК и посмотрим... |
|||
136
Los
18.10.06
✎
17:14
|
(135) Предыдущий пост прошу считать недействительным :) Глючит меня. Если два алгоритма выдают одинаковые результаты - всегда стоит задуматься, а может это на самом деле один алгоритм? ;)
|
|||
137
Дурочка 1С ™
18.10.06
✎
17:17
|
Может я, конечно, не в теме, но мне совсем не понятно, как при
>> Каждый символ строки генерировался случайным образом из набора "01234567890.,AB". могли получиться строки: >> Asd100xЩ >> 100.0Ю ??? Кстати, про "набор" можно было бы сразу сказать - ведь тогда становится очевидным, что пробелов не может быть ни в начале, ни в конце, ни в середине. И, соответственно, самый простой алгоритм - проверить двойное вхождение точек и запятых и наличие в строке букв A и B ... |
|||
138
Los
18.10.06
✎
17:31
|
(137) Когда я генерировал массив данных - я хотел получить примерно такое же соотношение Число/НеЧисло, как в реальной задаче. При этом там использовались все алфавитно-цифровые символы, причем и кириллица и латиница. Пробелов, кстати, изначально не было.
Если я возьму просто набор случайных строк из всего множества символов - я практически наверняка не получу длинных чисел. Поэтому ограничил количество исходных символов. Предложи другой алгоритм генерации исходных данных - возьму на вооружение. |
|||
139
СочинскийДед
18.10.06
✎
17:40
|
(138)
Алгоритм генерации. 1. Берем ЭнБольшое. 2. Для Сч = 1 По ЭнБольшое Цикл ТекЧисло = rand() Если ТекЧисло четное Тогда Будет цифра Иначе |
|||
140
Los
18.10.06
✎
17:40
|
Продолжим. 65534 строк, от 1 до 200 символов из набора "0123456789,.А"
Результаты: Прочитано записей: 65534 Алгоритм Пуделя: Чисел: 2418 Время работы: 3066 тик ============================= Алгоритм 2Green+Рэйв: Чисел: 2418 Время работы: 1542 тик ============================= Алгоритм Сочинский Дед: Чисел: 2418 Время работы: 1902 тик ============================= Алгоритм orefkov (ВК): Чисел: 2098 Время работы: 320 тик ============================= Регулярные выражения: Чисел: 2418 Время работы: 105456 тик ============================= |
|||
141
СочинскийДед
18.10.06
✎
17:43
|
Алгоритм генерации.
1. Берем ЭнБольшое. 2. Для Сч = 1 По ЭнБольшое Цикл ТекЧисло = rand() Если ТекЧисло четное Тогда Будет цифра Иначе Будет число КонецЕсли Выбираем длину строки - тоже rand() Генерим число или цифру КонецЦикла Итого у тебя гарантировано 40-60 процентов - числа с длиной от 1-до 40 (n-малое) |
|||
142
Пудель
18.10.06
✎
17:51
|
Чёрт :). Не самый оптимальный выходит :). Не пойму, что в моём варианте (точнее, моём, дополненным орефковым) тормозит. Вряд ли лишнее Стр=СтрЗаменить(Стр,",",".") могло сыграть большую роль... хм. Может, Найти работает быстрее сравнения строк? Тоже вряд ли.
В общем, рулит разбиение на куски и преобразование типов туда-сюда. Инстина найдена! Ура автору темы и ТуГрину с Рейвом! :) |
|||
143
Vacony
18.10.06
✎
18:03
|
да, можно протестить всех ? а то меня упустили (83)
|
|||
144
smaharbA
18.10.06
✎
18:14
|
Не, непонял че за дискриминация по националному признаку ?
Че шаблон - то не "исследовали" ? ... Или слишком просто ? |
|||
145
Дурочка 1С ™
18.10.06
✎
18:19
|
Алгоритм Д1С: 12346578901.0123 - это число.
Алгоритм Д1С: 5111 тиков (при 100000 тестах) Алгоритм Пудель: 12346578901.0123 - это число. Алгоритм Пудель: 10341 тиков (при 100000 тестах) Алгоритм Сочинский Дед: 12346578901.0123 - это строка. Алгоритм Сочинский Дед: 170099 тиков (при 100000 тестах) Алгоритм orefkov: 12346578901.0123 - это число. Алгоритм orefkov: 4972 тиков (при 100000 тестах) |
|||
146
Дурочка 1С ™
18.10.06
✎
18:30
|
+(145)
http://protrendy.narod.ru/test_alg.zip (16kB) |
|||
147
2Green
18.10.06
✎
18:33
|
(Los,Дурочка 1С ™) пришлите окончательные тестовые проги с вариантами решений и заполнением <массива> целиком, пожалуйста
|
|||
149
Дурочка 1С ™
18.10.06
✎
18:42
|
+(145)
Алгоритм Vacony: 12346578901.0123 - это число. Алгоритм Vacony: 4266 тиков (при 100000 тестах) |
|||
150
Дурочка 1С ™
18.10.06
✎
18:44
|
Ну, у кого еще длиннее?
Номера постов говорите ... |
|||
151
smaharbA
18.10.06
✎
18:45
|
(150) у меня, но короче :) (91)
|
|||
152
Дурочка 1С ™
18.10.06
✎
18:48
|
+(149) Алгоритм Vacony - понимает только числа и в случае пробелов или букв зацикливается ...
|
|||
153
СочинскийДед
18.10.06
✎
18:50
|
(141) ?
|
|||
154
Дурочка 1С ™
18.10.06
✎
18:53
|
Алгоритм smaharbA: 12346578901.0123 - это число.
Алгоритм smaharbA: 5301 тиков (при 100000 тестах) |
|||
155
Дурочка 1С ™
18.10.06
✎
19:01
|
http://protrendy.narod.ru/test_alg.zip (6kB)
|
|||
156
smaharbA
18.10.06
✎
19:03
|
(154) Спасибо за внимание, зато самый простой...
+ //******************************************* Процедура Сформировать() Стр=" 0054h.5 "; Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl"); Скрипт.Language="vbscript"; Сообщить(Скрипт.Eval("IsNumeric(replace("""+Стр+""",""."","",""))")); Стр=" 0054.5 "; Сообщить(Скрипт.Eval("IsNumeric(replace("""+Стр+""",""."","",""))")); КонецПроцедуры |
|||
157
СочинскийДед
18.10.06
✎
19:03
|
Алгоритм Д1С: ..84657067фывапфщиаттиьищхфьищзхьвфаищз6767895678957689576767678957689574356890743568907овармлорпраг - это строка.
Алгоритм Д1С: 4160 тиков (при 100000 тестах) Алгоритм Пудель: ..84657067фывапфщиаттиьищхфьищзхьвфаищз6767895678957689576767678957689574356890743568907овармлорпраг - это строка. Алгоритм Пудель: 12767 тиков (при 100000 тестах) Алгоритм Сочинский Дед: ..84657067фывапфщиаттиьищхфьищзхьвфаищз6767895678957689576767678957689574356890743568907овармлорпраг - это строка. Алгоритм Сочинский Дед: 2049 тиков (при 100000 тестах) Алгоритм orefkov: ..84657067фывапфщиаттиьищхфьищзхьвфаищз6767895678957689576767678957689574356890743568907овармлорпраг - это строка. Алгоритм orefkov: 2463 тиков (при 100000 тестах) ЗЫ1: Вывод - СИЛЬНО зависит от данных ЗЫ1 мой алгоритм - 96 |
|||
158
Дурочка 1С ™
18.10.06
✎
19:05
|
+(154) Кстати, алгоритм smaharbA ничуть не хуже Vacony - умеют работать только с числами: не вылетел - число, вылетел - строка ... очень низкий сорт ... студенты, короче ...
|
|||
159
СочинскийДед
18.10.06
✎
19:06
|
Надо готовить данные.
|
|||
160
2Green
18.10.06
✎
19:10
|
а я уже типа победил, меня не тестируем? :-))
вот ещё ускорил, особо на длинных строках должно быстрее Функция ЭтоЧисло2Green(Стр) _Стр = СтрЗаменить(Стр,",","."); Дл=СтрДлина(_Стр); Если СтрЧислоВхождений(_Стр, ".")<2 Тогда _Стр = СокрЛП(СтрЗаменить(_Стр,".","")); й=1; Пока й<=Дл Цикл _С=Сред(_Стр, й, Мин(63,Дл-й+1)); Если Число(_Стр)*10 <> Число(_Стр+"0") Тогда Возврат 0; КонецЕсли; й=й+63; КонецЦикла; Иначе Возврат 0; КонецЕсли; Возврат 1; КонецФункции // ЭтоЧисло2Green() |
|||
161
Дурочка 1С ™
18.10.06
✎
19:10
|
(156) Извини, но в следующий раз, прежде чем вываливать свою линейку проверь свой код и протестируй хотябы на сабже ...
Зачем ты вместо Функции которая должна возвращать 0-строка, 1-число суешь какие-то придурковатые процедуры, которые к тому же вываливаются с ошибками? |
|||
162
Дурочка 1С ™
18.10.06
✎
19:14
|
Алгоритм 2Green: 12346578901.0123 - это число.
Алгоритм 2Green: 6932 тиков (при 100000 тестах) |
|||
163
smaharbA
18.10.06
✎
19:15
|
(158) Это как-это "вылетел", работает со всем подрят, ну то что ошибки при числе сыпются можно и окно сообщений поменьше сделать :)
Зато всех просче... |
|||
164
Los
18.10.06
✎
19:16
|
Vacony - ошибка в алгоритме...
|
|||
165
2Green
18.10.06
✎
19:17
|
(162) персонально для твоего теста
Функция ЭтоЧисло2GreenToД1C(Стр) Возврат 1; КонецФункции // ЭтоЧисло2GreenToД1C() |
|||
166
smaharbA
18.10.06
✎
19:17
|
+(163) при не числе
|
|||
167
Los
18.10.06
✎
19:20
|
Дурочка 1С - в отличии от всех остальных не считает ".12", ".", "1." числом.
|
|||
168
Los
18.10.06
✎
19:22
|
smarahbA - как ты думаешь, сколько я буду ждать окончания теста, если в окно сообщений вывалится порядка 60000 ошибок?
|
|||
169
Дурочка 1С ™
18.10.06
✎
19:24
|
(163)
12346578901.0123 <<?>>А Неопознанный оператор http://protrendy.narod.ru/test_alg.zip (7kB) Твоя простота хуже типовых конфигураций от 1С ... Здесь не простота нужна, качество и скорость ... Работай, короче, над своим поведением ... |
|||
170
2Green
18.10.06
✎
19:25
|
(168) см. 160
|
|||
171
smaharbA
18.10.06
✎
19:28
|
(168) Дак тебе народ уже с "регулярами" предложил, ты весь текст пересортируешь так на число/строку без циклов и беганья по строкам текста
|
|||
172
2Green
18.10.06
✎
19:30
|
(171) дык по условиям задачи, текст в строках, или ячейках, или записях. одним словом получается по кускам.
|
|||
173
Los
18.10.06
✎
19:42
|
(171) Я уже писал - у меня нет текста, есть dbf, в котором много строк :) А в оригинале это вообще были элементы справочника... А построчные регуляры - тихо курят в стороне: см. 140.
Короче: Сам тестовый стенд тут: _ttp://www.webfile.ru/1154854 Кнопок много, жать на самую большую. Только перед этим путь к array.dbf поправить в исходном коде. Генератор массива там есть, но я им ни разу так и не воспользовался, потому как ждать устал. :) Я генерирую данные без 1С, усилием мысли. :) Готовый массив можно взять тут: _ttp://www.webfile.ru/1154858 Размер: 1043Кб (65534 строки от 1 до 40 символов) |
|||
174
Los
18.10.06
✎
19:54
|
(160) Действительно ускорил :) Если б она еще научилась "не числа" правильно распознавать :))) Корень зла тут: Число(_Стр)*10 <> Число(_Стр+"0")
|
|||
175
2Green
18.10.06
✎
20:07
|
(174) уже вижу, думаю
|
|||
176
СочинскийДед
18.10.06
✎
20:12
|
Вариант 96 - 6659 "тиков"
Вариант 99 - 6260 "тиков" // убрал СокрЛП() Функция Сформировать() Т1=_GetPerformanceCounter(); ДБФ=СоздатьОбъект("XBase"); ДБФ.ОткрытьФайл("C:\array.dbf"); ДБФ.Первая(); Пока ДБФ.ВКонце() = 0 Цикл МояСтрока = СокрЛП(ДБФ.STR); ЭтоЧисло(МояСтрока); ДБФ.Следующая(); КонецЦикла; Т2=_GetPerformanceCounter(); Сообщить(""+(Т2-Т1)+" тиков"); КонецФункции |
|||
177
smaharbA
18.10.06
✎
20:19
|
Ну все блин, я больше немогу...
... Функция ЭтоЧисло4(Знач Стр, НайденноеЧисло) Стр=СокрЛП(СтрЗаменить(Стр,",",".")); Где=" ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ[];'\/QWERTYUIOP[]ASDFGHJKL;'ZXCVBNM!@#$%^&*()_+`~"; Для к=1 По СтрДлина(Стр) Цикл Символ=Сред(Стр,к,1); Если Найти(Где,Врег(Символ))>0 Тогда Возврат 0; КонецЕсли; КонецЦикла; НайденноеЧисло = Число(Стр); Возврат 1; КонецФункции ... Кому не так, то так... - ... Функция ЭтоЧисло4(Знач Стр, НайденноеЧисло) Стр=СокрЛП(СтрЗаменить(Стр,",",".")); Где=" йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁёqwertyuiop[]asdfghjkl;'\zxcvbnm/QWERTYUIOP[]ASDFGHJKL;'ZXCVBNM!@#$%^&*()_+`~"; Для к=1 По СтрДлина(Стр) Цикл Символ=Сред(Стр,к,1); Если Найти(Где,Символ))>0 Тогда Возврат 0; КонецЕсли; КонецЦикла; НайденноеЧисло = Число(Стр); Возврат 1; КонецФункции |
|||
178
Los
18.10.06
✎
20:21
|
(176) Выкинь нафиг чтение DBF. Считывай его в массив заранее, потом используй. Между Т1 и Т2 должен быть минимум операторов, только то, что ты хочешь померить. И потом, тики сами по себе ничего не значат - есть смысл только сравнивать несколько результатов между собой. Компы-то у всех разные...
|
|||
179
2Green
18.10.06
✎
20:23
|
(174) можно так:
Если (Число(_Стр)*10+1) <> Число(_Стр+"1") Тогда |
|||
180
Гена
18.10.06
✎
20:26
|
(177) не проще ли алгоритмически пойти не от "лишних" знаков, а от нужных... их же меньше...
типа: если не 0-9 И количество точек ИЛИ запятых больше 1,- то однозначно НеЧисло? а Иначе - число... |
|||
181
smaharbA
18.10.06
✎
20:27
|
(180) Нет Гена, а куда девать "ненужные" ?
|
|||
182
Los
18.10.06
✎
20:30
|
(177) Ошибка в алгоритме в обоих вариантах. Подсказать или сам найдешь?
|
|||
183
Дурочка 1С ™
18.10.06
✎
20:32
|
http://protrendy.narod.ru/test_alg.zip (7kB)
Алгоритм Д1С: 12346578901.0123 - это число. Алгоритм Д1С: 4742 тиков (при 100000 тестах) Алгоритм Пудель: 12346578901.0123 - это число. Алгоритм Пудель: 10231 тиков (при 100000 тестах) Алгоритм Сочинский Дед: 12346578901.0123 - это строка. Алгоритм Сочинский Дед: 159050 тиков (при 100000 тестах) Алгоритм orefkov: 12346578901.0123 - это число. Алгоритм orefkov: 4999 тиков (при 100000 тестах) Алгоритм Vacony: 12346578901.0123 - это число. Алгоритм Vacony: 4254 тиков (при 100000 тестах) Алгоритм smaharbA: 12346578901.0123 - это число. Алгоритм smaharbA: 5302 тиков (при 100000 тестах) Алгоритм 2Green: 12346578901.0123 - это число. Алгоритм 2Green: 6990 тиков (при 100000 тестах) Алгоритм Д1С: - это число. Алгоритм Д1С: 3156 тиков (при 100000 тестах) Алгоритм Пудель: - это число. Алгоритм Пудель: 9525 тиков (при 100000 тестах) Алгоритм orefkov: - это число. Алгоритм orefkov: 3617 тиков (при 100000 тестах) Алгоритм Vacony: - это число. Алгоритм Vacony: 3816 тиков (при 100000 тестах) Алгоритм smaharbA вылетает с ошибкой Алгоритм 2Green: - это число. Алгоритм 2Green: 6961 тиков (при 100000 тестах) Алгоритм Сочинский Дед: - это строка. Алгоритм Сочинский Дед: 5211 тиков (при 100000 тестах) Алгоритм Д1С: 12346578901.0123 хзщхзщ цфцхзш вц - это строка. Алгоритм Д1С: 4655 тиков (при 100000 тестах) Алгоритм Пудель: 12346578901.0123 хзщхзщ цфцхзш вц - это строка. Алгоритм Пудель: 10733 тиков (при 100000 тестах) Алгоритм Сочинский Дед: 12346578901.0123 хзщхзщ цфцхзш вц - это строка. Алгоритм Сочинский Дед: 163426 тиков (при 100000 тестах) Алгоритм orefkov: 12346578901.0123 хзщхзщ цфцхзш вц - это строка. Алгоритм orefkov: 5831 тиков (при 100000 тестах) Алгоритм 2Green: 12346578901.0123 хзщхзщ цфцхзш вц - это строка. Алгоритм 2Green: 5046 тиков (при 100000 тестах) |
|||
184
Los
18.10.06
✎
20:38
|
Дурочка, а почему у тебя по СочинскомуДеду 12346578901.0123 - это строка, а у меня это число? (просто интересно)
Правда каюсь, у меня некоторые алгоритмы переписаны с сохранением идеи... |
|||
185
Гена
18.10.06
✎
20:41
|
(181) я думал, что задача только ОПРЕДЕЛИТЬ число или нет... а не причести все нечисла к числам...
я был неправ в понимании автора? |
|||
186
smaharbA
18.10.06
✎
20:42
|
(182) Подскажи
|
|||
187
Los
18.10.06
✎
20:43
|
(186) "123.123.123"
|
|||
188
smaharbA
18.10.06
✎
20:45
|
Непонял всеже где вылетает с ошибкой, ошибки да сыпются в сообщить при числах, но он (алгоритм с "Шаблон") честно определяет
|
|||
189
smaharbA
18.10.06
✎
20:48
|
(187) Ну да... Но этож одним движением правится...
|
|||
190
Los
18.10.06
✎
20:48
|
(185) По-моему он хочет сказать, что достаточно найти один ненужный символ, вместо того, чтобы искать все нужные, а потом смотреть, не осталось ли лишнего. Красивая идея...
|
|||
191
Пудель
18.10.06
✎
20:48
|
Дурочка, Лось, и другие тестировщики: Простестируйте, пожалуйста, на больших строках, с несколькими тысячами символов, скажем, 10'000 символов.
|
|||
192
Дурочка 1С ™
18.10.06
✎
20:50
|
(184,191)
http://protrendy.narod.ru/test_alg.zip (7kB) Качните и найдите ответы на свои вопросы ... |
|||
193
Пудель
18.10.06
✎
20:51
|
Да у меня нету 7.7 тут.
|
|||
194
2Green
18.10.06
✎
20:57
|
(183) в том моем варианте ошибка. вот правильный.
только тесты твои - нереальные, у Los'a более приближенные к реальности. Функция ЭтоЧисло2Green(Стр) _Стр = СтрЗаменить(Стр,",","."); Дл=СтрДлина(_Стр); Если СтрЧислоВхождений(_Стр, ".")<2 Тогда _Стр = СокрЛП(СтрЗаменить(_Стр,".","")); й=1; Пока й<=Дл Цикл _С=Сред(_Стр, й, Мин(63,Дл-й+1)); Если (Число(_Стр)*10+1) <> Число(_Стр+"1") Тогда Возврат 0; КонецЕсли; й=й+63; КонецЦикла; Иначе Возврат 0; КонецЕсли; Возврат 1; КонецФункции // ЭтоЧисло2Green() у меня результаты по Los'у(запускал три раза подряд): Прочитано записей: 65534 Алгоритм Пуделя: Чисел: 1588 Время работы: 8736 тик ============================= Алгоритм 2Green+Рэйв: Чисел: 1588 Время работы: 2744 тик ============================= Алгоритм 2Green 2: Чисел: 1588 Время работы: 2567 тик ============================= Алгоритм Сочинский Дед: Чисел: 1588 Время работы: 6712 тик ============================= Алгоритм Д1С: Чисел: 1605 Время работы: 3201 тик ============================= Прочитано записей: 65534 Алгоритм Пуделя: Чисел: 1588 Время работы: 6090 тик ============================= Алгоритм 2Green+Рэйв: Чисел: 1588 Время работы: 1888 тик ============================= Алгоритм 2Green 2: Чисел: 1588 Время работы: 1820 тик ============================= Алгоритм Сочинский Дед: Чисел: 1588 Время работы: 4744 тик ============================= Алгоритм Д1С: Чисел: 1605 Время работы: 2276 тик ============================= Прочитано записей: 65534 Алгоритм Пуделя: Чисел: 1588 Время работы: 6651 тик ============================= Алгоритм 2Green+Рэйв: Чисел: 1588 Время работы: 2113 тик ============================= Алгоритм 2Green 2: Чисел: 1588 Время работы: 2042 тик ============================= Алгоритм Сочинский Дед: Чисел: 1588 Время работы: 5359 тик ============================= Алгоритм Д1С: Чисел: 1605 Время работы: 2578 тик ============================= |
|||
195
2Green
18.10.06
✎
20:59
|
(194+) остальных заремил, ибо ошибки лезут
|
|||
196
ДЕД
18.10.06
✎
21:04
|
(180) Согласен, простая и гениальная идея.
Итак, алгоритм по этой идее: Считаем, сколько точек и запятых в строке. Если их в сумме больше 1, не число, иначе Сравниваем исходную строку посимвольно со строкой "0123456789.,". Если символ не содержится в этой строке, не число. Если прошли цикл до конца - число. |
|||
197
Гена
18.10.06
✎
21:05
|
(190) дык... заложить 0-9 и проверку на количество точек или запятых менее 2-х... и в случае ПЕРВОГО же несоответствия выходить на НеЧисло...
так разве неоптимально? |
|||
198
Los
18.10.06
✎
21:12
|
(192) Да я это, собственно, к тому, что нафиг тестировать и постить сюда результаты заведомо неработающих алгоритмов? Тем более, что лишние пробелы идут из твоего теста...
|
|||
199
Los
18.10.06
✎
21:17
|
Пудель: надо стенд переписывать. В DBF такие строки не загнать :) Да и лень - я для себя уже вывод сделал.
К тому же на таких строках остро встает проблема генерации исходного массива - здесь уже придется задавать фиксированный процент заведомых чисел, и от это го процента будет сильно зависеть конечный результат... Как у Дурочки с ее прогонами на фиксированных значениях... (196) Это алгоритм СочинскогоДеда :) Вы не братья? |
|||
200
2Green
18.10.06
✎
21:20
|
(190) всех ненужных символов - их мнооого
(197) это алгоритм Пуделя. не оптимально. Поправочка*: в (194) строку "_С=Сред(_Стр, й, Мин(63,Дл-й+1));" конечно же читать как "_Стр=Сред(_Стр, й, Мин(63,Дл-й+1));" чего-то я уже приустал в монитор глядеть, пойду покурю |
|||
201
Пудель
18.10.06
✎
21:22
|
(197,200) Да, видимо, функция СтрЗаменить слишком медленно работает.
|
|||
202
smaharbA
18.10.06
✎
21:23
|
Около Генин алгоритм...
... Функция ЭтоЧисло5(Знач Стр, НайденноеЧисло) СтрВрем=СокрЛП(Стр); Где="1234567890"; Для к=1 По СтрДлина(Где) Цикл Символ=Сред(Где,к,1); СтрВрем=СтрЗаменить(СтрВрем,Символ,""); КонецЦикла; Если (Стр="") или (Найти(".,",Стр)=1) Тогда НайденноеЧисло = Число(СтрЗаменить(Стр,",",".")); Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ... Но только непонял "." и "," и "" считаются числами ? |
|||
203
Пудель
18.10.06
✎
21:25
|
(202) Это мой алгоритм (см. 32), причём ухудшенный :).
|
|||
204
smaharbA
18.10.06
✎
21:28
|
(203) Пожалуй да...
|
|||
205
2Green
18.10.06
✎
21:29
|
хотя в принципе если знать заранее процент содержания "не цифр" в каждой из строк, то наверное посимвольное сравнение с "цифрами" может оказаться оптимальней. Ну если вероятность получить не_цифру в первом же символе каждой строки будет близкой к 100%.
Т.е. кто знает как сеют символы в строки - тот и рулит :-) может там на каждую из строк длиной по 200 по одной цифре только |
|||
206
Дурочка 1С ™
18.10.06
✎
21:51
|
(198) Производительность алгоритмов сильно зависит от строки.
Если orefkov в первой же строке проверяет ЕстьТочка = СтрЧислоВхождений(Стр1, "."); Если ЕстьТочка>1 Тогда Возврат 0; КонецЕсли; и больше ничего не делает, ясно, что этот алгоритм будет выигрывать на строках с двумя точками перед теми, кто будет перебирать строку посимвольно и искать буквы. На строках же без запятых и начинающихся с букв алгоритмы поменяются местами в производительности. |
|||
207
Buhta
18.10.06
✎
21:58
|
все развлекаетесь?
|
|||
208
Пудель
18.10.06
✎
21:59
|
Угу, пока перемещения перепроводятся.
|
|||
209
Buhta
18.10.06
✎
22:07
|
(208)пока они перепроводятся можно в другом месте что-нибудь переначислить... так и не успела все перепровести:(
|
|||
210
Дурочка 1С ™
18.10.06
✎
22:17
|
Вот шустрая штука из (40):
Алгоритм 0xFFFFFF: 12346578901.0123 - это число. Алгоритм 0xFFFFFF: 3525 тиков (при 100000 тестах) |
|||
211
Пудель
18.10.06
✎
22:17
|
Ну, я тоже не всё с начала года перепровожу, а только кусочек. Товарооборот за один день перепроводится примерно 15 часов тут, где я сейчас сижу :). К балансу уже не успеем :).
|
|||
212
angro
18.10.06
✎
22:34
|
(211) О, система реального времени :)
|
|||
213
Пудель
18.10.06
✎
22:42
|
(212) За один месяц, сорри :). То есть 9 месяцев будут перепроводиться 15*9=135 часов=неделю :).
|
|||
214
2Green
18.10.06
✎
23:00
|
Надо учить С.
orefkov, не подскажешь_где_найти/поделишься? |
|||
215
Дурочка 1С ®
19.10.06
✎
03:07
|
У меня, короче, резюме такое: все алгоритмы практически одинаковы по скорости, за исключением откровенно глючных (например, Сочинский Дед) и выполняющих простой, "в лоб", перебор символов строки и с увеличением длины строки они отстают все больше и больше ...
Быстрее всех работаю алгоритмы которые не все учитывают (например: Vacony, smaharbA) - дайте им число - всех обгонят, дайте строку - вылетят с ошибкой ... У меня и 0xFFFFFF оказался по сути зеркальный вариант. Мой проигрывает. Догадались почему? (для дятлов: см. какие алгоритмы работают быстрее всех) Вывод: если все авторы допишут свои алгоритмы до полностью корректной работы и уберут из своих функций ненужные методы, скорость выполнения с учетом погрешности будет одинаковая у всех ... тик в тик ... |
|||
216
Дурочка 1С ®
19.10.06
✎
03:26
|
Мы, конечно, фингей развлекаемся (© Buhta), но за свои деньги (© orefkov) ...
А вот как разлекаются писатели для всей страны (© Mike) уже за деньги наших юзеров: - возьмите типовую бухгалтерию и оприходуйте (товар, материал, услугу, ... неважно что) на маленькую сумму, например, на 12 копеек. НДС поставьте "18% в сумме". Что получим? Правильно: 2 коп. НДС. Округление есть округление. Ничего не поделаешь. (Для пущего эффекта можно сделать договор в валюте - числа в проводке будут вопиющебезобразными) - А теперь сформируйте книгу покупок и посмотрите что получилось ... А?!! О-о-от!!! - А теперь пойдите в модуль и посмотрите как(!) это сделано!!! ... ну, чего вы замолчали-то? ... скажите, хоть что-нибудь ... Я утверждаю, что типовые конфигурации 1С пишут сейчас лучшие студенты, которых выгнали из лучших франей ... И не надо мне говорить "вот через годик, через два ..." - я это уже четвертый год слышу ... Халва! Халва! Халва! ... |
|||
217
smaharbA
19.10.06
✎
07:30
|
Не, я упертый, не "глючит" мой алгоритм с Шаблоном, ошибки выдает в область сообщений при "строках", но отробатывае дальше и выдает верный вариант(пусть хоть все будут "строки", а только одно "число" в последовательности, отработает и не выпадывает, а "мусор" сообщений - побочный продукт :) ), можно конечно все еще быстрее сделать, но тут я понимаю речь о штатных средствах 1С.
Пелять - этот топик седня с бабами во сне решал, бабы такие - нормальные, а мене некогда с ними цацы разводить, числа ищю блин... |
|||
218
Buhta
19.10.06
✎
08:38
|
(216) Но они этим дают поразвлекаться и нам не за свои, а за деньги клиентов:)
|
|||
219
orefkov
19.10.06
✎
08:49
|
(140)
Почему-то у меня количество чисел отличается от остальных алгоритмов. Нельзя ли привести пример, на каких данных это происходит? те другие алгоритмы определяют одно, а моя ВК другое? |
|||
220
Vacony
19.10.06
✎
10:25
|
жаль ушел на перерыв...сейчас проверю что и где там циклится...
(164) Los - не понял что за ошибка в алгоритме ? Требуется определить число или нет, или еще и сказать что за число ? |
|||
221
Vacony
19.10.06
✎
10:33
|
Защищая свою честь :)
(152) - Дурчка, дай пример где же он при буквах или пробелах циклится ??? Строки типа "234234ouih234 9283yh4 92y49283 y4982 21934 2" " DF sdufhsufidh F*&DSFTS ihgdsf" " 3498ывагр 348yDUF 92Q "Э Проходят на ура... Что же может циклиться ? |
|||
222
Vacony
19.10.06
✎
10:42
|
не пинайте ногами .
(149) Извини Дурочка 1С, но просто вопрос - у меня строка "12346578901.0123" дала Алгоритм Vacony: 2950 тиков (при 100000 тестах) , а в 149 написано Алгоритм Vacony: 4266 тиков (при 100000 тестах) - разница из-за скорости машин ? |
|||
223
Uno
19.10.06
✎
10:46
|
Стр=СоклЛП(Стр);
СтрЗаменить(Стр,"0",""); СтрЗаменить(Стр,"1",""); ... СтрЗаменить(Стр,"9",""); Если (Стр=".")или(Стр=",") Тогда Сообщить("Число") Иначе Сообщить("Не число"); КонецЕсли; |
|||
224
Гена
19.10.06
✎
10:52
|
(223) ...Или (Стр="")
|
|||
225
smaharbA
19.10.06
✎
10:55
|
(223)(224) см (32)
|
|||
226
Uno
19.10.06
✎
11:00
|
2(225)Не заметил. Но без цикла на коротких строках быстрее раза в полтора будет
|
|||
227
Vacony
19.10.06
✎
11:03
|
:-)))))))))
Алгоритмы : Д1С: Пудель: Сочинский Дед: orefkov: НЕ работают ! Т.к. Строка вида "-123" дают как СТРОКА , а это ЧИСЛО ! |
|||
228
Ёпрст
19.10.06
✎
11:05
|
Кто там главный замерщик? Моё твоерние в (95) можете замерить, а ?
|
|||
229
СочинскийДед
19.10.06
✎
11:06
|
(215) С дуба рухнул? Где ты глюки увидел?
Здесь? Для СчФильтр = 1 По ДлинаСтрокиФильтр Цикл НашлиСимволов = НашлиСимволов + СтрЧислоВхождений(СтрокаПроверить, Сред(СтрокаФильтр, СчФильтр, 1)); КонецЦикла; Если НашлиСимволов <> ДлинаСтрокиПроверить Тогда Возврат 0; Иначе Возврат 1; КонецЕсли; Или здесь? Для СчПроверить = 1 По ДлинаСтрокиПроверить Цикл Для СчФильтр = 1 По ДлинаСтрокиФильтр Цикл Если СтрЧислоВхождений(СтрокаФильтр, Сред(СтрокаПроверить, СчПроверить, 1)) = 0 Тогда Возврат 0; КонецЕсли; КонецЦикла; КонецЦикла; /////////////////////// Итого: Алгоритм должен оцениваться по параметрам. 1. Правильность. 2. Удобочитаемость кода. 3. Оптимальность. 4. "Красота". :) Чего я, к сожалению, не увидел здесь или вернее увидел не у всех. |
|||
230
СочинскийДед
19.10.06
✎
11:08
|
(227)
Читай сабж внимательнЕе. |
|||
231
smaharbA
19.10.06
✎
11:10
|
Ну красота это предположим тут (91) ;) короче ниукого нету :))
|
|||
232
orefkov
19.10.06
✎
11:14
|
Кстати, пустая строка по условиям задачи число или нет?
|
|||
233
СочинскийДед
19.10.06
✎
11:15
|
(231) Значит (91) не "1снег". Хотя все течет, все изменяется.
|
|||
234
Vacony
19.10.06
✎
11:15
|
230 - с ИЗНАЧАЛЬНО в строке - согласен. НО строка "0-34" будет числом по вашему или строкой ?
(0) - рассуди Да и ИМХО если строка "-123" разбирается как число одним алгоритмом, а другим как строка - то первый (опять же ИМХО) лучше... |
|||
235
smaharbA
19.10.06
✎
11:16
|
(233) уже да, не адинэснег :)
|
|||
236
СочинскийДед
19.10.06
✎
11:19
|
(234) Тебе дали ТЗ.
По ТЗ "0-34" - это строка, "-123" тоже строка. Когда ты придешь сдавать работу, ты скажешь - это число, и будешь "послан" переделывать. |
|||
237
Дурочка 1С ®
19.10.06
✎
11:43
|
(231) Вот самый короткий (all) и самый надежный вариант (никогда не ошибается):
Функция ЭтоЧисло(Знач Стр) Если Вопрос("Слышь, братан, глянь сюда:+"+РазделительСтрок+Стр+ "|Это число называется? ... В глаза мне смотри!",4)=6 Тогда Возврат 1; КонецЕсли; Возврат 0; КонецФункции // ЭтоЧисло |
|||
238
Vacony
19.10.06
✎
14:08
|
(236) - не буду спорить. жду автора ТЗ.
П.С. зачем спорить в принципе.. проверь на моем и твоем алгоритме строку "23423щ4шо" - мой вариант 4984 тиков, ваш - 36849 тиков. Проверял по обработке Дурочки. (237) - это самый медленный вариант, т.к. юзер думает долго |
|||
239
Los
19.10.06
✎
16:34
|
(Vacony) Где ошибка, говоришь?! Неужели самому не найти? Например, по твоему алгоритму ".94Z8" - это число...
(orefkov) В тех данных были пустые строки. Вопрос не принципиальный. Потом я поправил, больше их не было. |
|||
240
Los
19.10.06
✎
16:42
|
(238) По условиям задачи ни "0-34", ни "-121" в исходных данных быть не может :) Я всегда считал, что алфавитно-цифровые символы - это буквы и цифры, но не знаки препинания. А про "+" и "-" я даже сказал в (0) особо.
Если же отвлечься от задачи, то мое ХО, "-121" - число, "0-34" не число, "12e3" - число, "12E+5" - тоже число. Но это уже более сложная задача, не имеющая отношения к этой :) |
|||
241
Los
19.10.06
✎
16:44
|
+(240) Но в условиях (0) "12e3" - не число! :)
|
|||
242
smaharbA
19.10.06
✎
16:56
|
а че (154) не позырили, можна исчо упростить если джавускр пользовать
|
|||
243
2Green
19.10.06
✎
19:40
|
Los, а призы будут(материальные или там реклама на сайте каком)?
:-) |
|||
244
Los
19.10.06
✎
19:55
|
(243) Не-а :)
|
|||
245
2Green
19.10.06
✎
19:58
|
ну слава богу :-)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |