Проблеми TypeScript у світі React-додатків вiд Iллi Климова на React fwdays | 27 березня
×Закрыть

Задачка на поиск связей между элементами строкового массива.

Это классическая задача подбора имортированных товаров к товарам из каталога. Например в каталоге товар записана как Apple iphone 5s (16Gb, silver), магазин же в прайсе пишет товар Silver Iphone 5s 16 Gb Facetime . В самом элементарном виде мы имеем входящее название товара, нужно для входящего товара подобрать похожие товары из каталога и вывести результат в массив до 10 похожих товаров. Вот входнящий товар:
Silver Iphone 5s 16 Gb Facetime

и массив всех товаров из каталога:

(Samsung Galaxy 2,Samsung Galaxy s3,Samsung Galaxy s4,Samsung Galaxy s5,Samsung Galaxy Duos,Samsung Galaxy Duos 2,Samsung Galaxy Mega, Samsung Galaxy Mega 2, Samsung Galaxy Yong,Sony Xperia XL,Sony Xperia L,Sony Xperia SL,Sony Xperia S,Apple Iphone 5s 16Gb gray,Apple Iphone 5s 16Gb gold,Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver)

Вот пример вывода для Silver Iphone 5s 16 Gb Facetime

(Apple Iphone 5s 16Gb silver, Apple Iphone 5s 32Gb silver, Apple Iphone 5s 16Gb gray, Apple Iphone 5s 16Gb gold, Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver ).

Свое решение выложу вечером, топорное решение заняло где то 30 минут на PHP и подозреваю на java занимает столько же. Естественно приветсвуются елегантные быстрые решения.

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn

Похожие топики

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

расстояние Левенштейна с ограницением на глубину что ли?

Вариант реализации на JS gist.github.com/...73aa6a57d17e778

Вибрали всі би айфони та і фіг з ним

данунафиг? дорого, без дроида, без миниюсб и проги нужно покупать...
Панты могут быть только у баранов :)

Ви не мене так зрозуміли.
Я про те, що ввели якесь стоп-слово, і ті продукти, що з ним пов’язані, і показувати

Пример простой. Я искала флай. Их более 50 моделей в линейке. А мне нужны параметры особые... В общем неделю мучалась...
И оказалось, что по моим параметрам мне больше всего подошёл ЛыЖик :)

2a часа с отладкой и комментами, или 120 минут по сравнению с 3мя минутами питона или 10 минутами пхп нееффективно вообще- чувствуется незнание явы или нехватка либ. Принимаются улучшения, если конечно не в облом такой листинг читать.

import acm.program.ConsoleProgram;
import java.util.Arrays;


public class connection extends ConsoleProgram {
	
	String listOfAllDevices = "Samsung Galaxy 2,Samsung Galaxy s3,Samsung Galaxy s4,Samsung Galaxy s5,Samsung Galaxy Duos,Samsung Galaxy Duos 2,Samsung Galaxy Mega, Samsung Galaxy Mega 2, Samsung Galaxy Yong,Sony Xperia XL,Sony Xperia L,Sony Xperia SL,Sony Xperia S,Apple Iphone 5s 16Gb gray,Apple Iphone 5s 16Gb gold,Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver";
	String inputString= "Silver Iphone 5s 16 Gb Facetime";
	static int lookForProducts=7;
	
	 public void run() {
		 String[] DevicesArray=DropAllDevicesToArrays(listOfAllDevices);
		 MakeComparisonAndPrint(DevicesArray,inputString);		
	 }

////////////////////////////////////////////////////////////////////
//// Method to drop long string with all available devices into array of Strings 
//// Elements of array will be compared with input string by method StringIntersection 
////////////////////////////////////////////////////////////////////	 
		 public String[] DropAllDevicesToArrays(String devicesInputlist){
			 String[] DevicesArray = devicesInputlist.toLowerCase().split(",");
			 return (DevicesArray);
			 
		 }
		 
////////////////////////////////////////////////////////////////////
////	 Method to compare each element of Strings array to inputString 
////	 output will be an int array with with the number of common words in compared string
////	 final int array will send to print method
////////////////////////////////////////////////////////////////////				 
		 public void MakeComparisonAndPrint(String[] DevicesArray,String inputStringforCompare ){
			 int [] result=new int[DevicesArray.length];
			 String[] droppedinputStringforCompare = sortedString(inputStringforCompare);
			 for(int i=0;i<DevicesArray.length;i++){
				 result[i] = StringIntersection(DevicesArray[i],droppedinputStringforCompare);
				 System.out.println(result[i]);
			 }
			 PrintMatchingArray(result,DevicesArray);
			 
		 };
		 
////////////////////////////////////////////////////////////////////
////	 Method to compare 2 strings by each word using .equals, returns number of common words
////////////////////////////////////////////////////////////////////		 
		 public int StringIntersection(String candidate, String[] droppedInputStringforCompare){
			 int commonWords=0;
			 String[] droppedCandidate=sortedString(candidate);
			 ////////compare each word from candidate to inputString
			 for(int i=0; i<droppedCandidate.length;i++ ){
				 for(int j=0; j<droppedInputStringforCompare.length;j++ ){
					 if(droppedCandidate[i].equals(droppedInputStringforCompare[j])){commonWords++;}; 
			 } 
				 }
			 
			 return commonWords;
		 }

////////////////////////////////////////////////////////////////////
////	 Method to sort string by words, generally used for lover case
////////////////////////////////////////////////////////////////////	
		 public String[] sortedString(String inputString){
			 String[] droppedInputString=inputString.toLowerCase().split(" ");
			 //Arrays.sort(droppedInputString);
			 return droppedInputString;
		 };
		 
////////////////////////////////////////////////////////////////////
////	 Method to print matching devices
////	 receive number of common words in devices list and input string
////	 searching for elements with max number and save it into array bestMatchingProducts 
		 
////////////////////////////////////////////////////////////////////		 	 
		 public void PrintMatchingArray(int [] numberOfCommonWords,String[] DevicesArray){
			 int [] bestMatchingProducts=new int[lookForProducts];
			 int tempMaxOFArray=0; 
			 
			 ///////// go for array numberOfCommonWords and select max values 
			 for(int i=0;i<lookForProducts;i++){
				 bestMatchingProducts[i]=0;
			 for(int j=0;j<numberOfCommonWords.length;j++){
				 if (tempMaxOFArray<numberOfCommonWords[j]){
					 tempMaxOFArray=numberOfCommonWords[j];
					 bestMatchingProducts[i]=j;}
			 }  if (tempMaxOFArray>0){numberOfCommonWords[bestMatchingProducts[i]]=0;};
			 	tempMaxOFArray=0;
			 }
			 ////////print list of best matching products
			 for(int i=0;i<lookForProducts;i++){
				 System.out.println(i+" place="+DevicesArray[bestMatchingProducts[i]]);
			 }
			 }
		 };
	

вот ответ на “Silver Iphone 5s 16 Gb Facetime”
0 place=apple iphone 5s 16gb silver
1 place=apple iphone 5s 32gb silver
2 place=apple iphone 5s 64gb silver
3 place=apple iphone 5s 16gb gray
4 place=apple iphone 5s 16gb gold
5 place=apple iphone 5s 32gb gray
6 place=apple iphone 5s 32gb gold
done in: 13ms

Да и вообще это дерьмовый юай. Посмотрите как на розетке или цитрусе сделано: айфон -номенклатура, а цвет и память -радиобаттоны.

Есть мнение что это одним запросом делается.

наслышаны, полнотекстовый поиск, листинга никто не привел. может и делается

полез в постгрес и питон. постгрес92 из коробки, все настройки по умолчанию. Вся инфа про постгрес и полнотекстовый поиск с индексами взята из доки и туториала, предварительного опыта с полнотекстовым поиском и постгресом — 0.
Ваяние всего — пара часов неспеша.

заполнение таблицы «случайными» данными и сами данные pastebin.com/zNwSVyVm

"HTC 32 G One Gold"
"32 G Mk.II GoldStar mafon Black"
"4GB iPad Apple Pink"
"Zoppo Luppo"
"32 G Mayak   mafon"
"player 256MB  Mayak Mk.IV"
"GoldStar Gold 256MB Mk.IV mafon"
"32 G Adidas shoes Mk.II"
"Luppo Zoppo Pink"
"Note 256MB   Samsung"

/*
CREATE TABLE products( name text, id serial NOT NULL)
WITH ( OIDS=FALSE);
ALTER TABLE products OWNER TO postgres;
 
CREATE INDEX name_ginidx ON products USING gin (to_tsvector('english'::regconfig, name));
 
*/
-- в таблице миллион строк
select count(*) from products
1000000

-- условие поиска: Apple && (iPod || iPad)
--
-- полнотекстовый поиск
select * from products where to_tsvector('english', name) @@ to_tsquery('Apples & (iPod | iPad)')
83485 rows, 104ms

-- case-insensitive like
select * from products where name ilike '%apple%' and (name ilike '%ipad%' or name ilike '%ipod%')
83485 rows, 1295ms

-- case-sensitive like
select * from products where name like '%Apple%' and (name like '%iPad%' or name like '%iPod%')
83485 rows, 228ms

к сожалению база mySQL, а не постгерес. В mySQL все сложнее, не знаю как в нынешних версиях, но в тех версиях что раньше были — там не желательно использовать слова меньше 3х символов, таблицу нада индескировать по полям.

С сиквелами так в лоб не выйдет. Т. к. У вас индекс пока чистый как слеза. Посмотрите на его размер после, скажем 10кк рандомных делетов, апдейтов и инсертов в эту таблицу, цифры будут на порядок минимум отличаться.
Второе — если позанудствовать об условии, то нужно две таблицы и выбирать из второй результат выборки из первой.

в лоб не всегда пройдёт, да. с другой стороны в постгри есть функциональные индексы, партицирование. вакуум, обновление статистики, реиндексация.
Про условие согласен, но если занудствовать про условие, то вообще сама постановка «найти похожее» мне не нравится. я бы, всё же, разбил предварительно по брендам/маркам, задал бы веса для полнотекстового поиска, применил бы упомянутого левенштейна. а так я просто сравнил грубо
разные виды выборки из БД.
ну а про индекс — тоже не всё однозначно. это же не кластерный, т.е. размер самого индекса мелок по сравнению с данными. ну и зная пропорции вставки/удаления надо просто предусмотреть соответствующий филфактор

Ну и в конце — БД пилят десятки человек уже десятки лет подряд. Все придуманные нами в этой теме алгоритмы уже обсосаны и вылизаны разработчиками БД, потому я лично доверюсь постгресу/мсскулю в работе с данными, чем буду ваять вилисапед.

сама постановка «найти похожее» мне не нравится
Логично. Всегда очень неприятно и сложно работать с неструктурированными данными и в 90% случаев их намного проще предварительно структурировать.
В БД с четкой структурой категорий товара, производителей, моделей, цветов и особенностей задача превращается в элементарную, использующую в худшем случае быстрые иннер-джоины.
Интерфейс ввода с выбором из списков также сильно снижает возможность ошибок и опечаток ввода, которые сами по себе тот еще бич подобных систем.
я лично доверюсь постгресу/мсскулю в работе с данными
С этим не поспоришь за одним исключением — если аппликэйшн как правило несложно размножить при увеличении нагрузки, то с БД такой фокус не проходит и приходится менять железо на намного более дорогое (да и это не всегда спасает). Штуки типа Oracle RAC хороши. но имеют свои неиллюзорные пределы производительности и шкалирования (4 ноды, если быть точным, дальше эффективность только падает).
Т.е. сразу нагружать СУБД очень тяжелыми транзакциями с этой точки зрения не стоит, если предполагается значительное увеличение нагрузки в будущем, лучше переложить вычислительную часть на апликэйшн.
С этим не поспоришь за одним исключением — если аппликэйшн как правило несложно размножить при увеличении нагрузки.....
а я наоборот, подумал о том, что вынести задачу в БД = разделить нагрузку.
Но согласен, в зависимости от нагрузки оптимальные решения могут быть прямо противоположными
вынести задачу в БД = разделить нагрузку.
Пока индексы помещаются в память и относительная однотипность запросов позволяет держать 60-70% результатов в кеше — будет безусловно лучше. Т.к. самое узкое место обычно ввод-вывод. Гонять гигабайты сырой выборки, чтобы обсчитать ее на аппликэйшне, тоже вариант хреновый. А вот переформатировать запрос или отсортировать результат — уже вполне.
Короче — это отдельная область. Ближе к ДевОпс, чем к изначальной задаче топика.

В таком случае, за листингом на фриланс нужно.

Честно? Очень плохо. Именно сам алгоритм. Для текущей задачи пойдет (т.к. данных очень мало и один раз запрос делается вообще), но сложность алгоритма по О у тебя получилась очень большая. На любых сколько нибудь значительных объемах данных этот алгоритм ляжет

ну как я понял твой алгоритм вообще не работает )))) я думал про сравнение упорядоченных строк и где то мелькал вариант делать пересечение строк по хешмапу — типа первую строку грузим в хешмап давая каждому значению 1 а вторую строку просто вызваем из хешмапа и плюсуем все полученные значения. Но хешмапы городить — это еще полчаса или час на отладку.

Даже не пытайтесь сравнивать скорость написания кода на строго типизированном языке и Питоне — без шансов, Питон всегда выиграет. Затраты в Питоне появляются когда код нужно сопровождать и он становится все больше и больше.

По поводу вашего решения — ну все простенько и в лоб. Вообще мне кажется вы чуть поспешили.
Для начала ответьте сами себе простыми словами:
если ищется «Silver Iphone 5s 16 Gb Facetime» то какие варианты из каталога наиболее предпочтительны, а главное почему. Короче формально введите меру расстояния между двумя строками продуктов. А потом исходя из вашей меры, нужно делать оптимизацию. Ну или чуть менять меру, что бы оптимизация была лучше.

у питона строгая типизация.
строгая, но динамическая.
«буду бить сильно, но аккуратно» (ц)

если я не забыл названия, то у Питона: динамическая, сильная, неявная.
на самом деле я не силен в терминах и могу что-то путать. строгая это синоним сильная? если да, то я фигню написал конечно.

та похоже что сильная и строгая — синонимы
хотя в вике

Примечание: В русскоязычной литературе часто встречается перевод термина «strong typing» как «строгая типизация»; более корректный вариант «сильная типизация» используется лишь при противопоставлении «слабой типизации». Следует иметь ввиду, что использование термина «строгий» в отношении системы типов языка может вызвать путаницу со строгой семантикой вычислений[en] языка (англ. strict evaluation).

Я мож чё дурное скажу, но у перла есть пакован библиотек, где такие задачки сами по себе решаются...
Я к тому, что шить сапоги должен сапожник, строить дома — строитель, а язык на котором программируете нужно подбирать согласно поставленной задаче. Для лингвистических задач лучше перла я КАГБЭ языка не вижу. Ибо там решается всё не в туеву кучу кода, а максимум в 10-15 строк вместе с объявлениями данных...
И да, эта... Кто там в ответке начнёт писакать «А ВОТ ТЫ РЕШИ, ДАЙ ОТВЕТ» и прочее — пишите дальше на жавах, пихапе и прочих инструментариях... Я с вами заранее согласна, что ВЫ — САМЫЙ ЛУЧШИЙ ПРОГРАММЕР :)

а вы видели решение на питоне за 3и минуты ?

а вы будете изучать 150 языков и для 150 разных задач, которые решаются за 3 минуты ? 3-минуты это что показатель ? Или у вас главное решить задачу за 3 минуты, а как кон написан, качество, поддерживать, другим читать и т.д. не главное ?

а шо как то напряжно выучить яву, питон, руби, хагуп, перл после того как уже знаешь бейсик, паскаль, ассамблер, вижуал бейсик, с и с++?

у вас под языком что именно ? ключевые слова, которых 20-30 или API ? я вот уже 2-й год изучаю ДЖАВА, я даже конца не вижу, всю жизнь надо будет изучать.

бейсик, паскаль, ассамблер, вижуал бейсик, с и с++
= что то мне в это вопше не вериться. У нас наверно с вам разное понимание выученного языка.

выученный язык — это способность читать код и исправить баг если он есть.

Угу. При таком подходе это еще и способность менять легко локализуемый авторский баг на другой, который без щепотки анаши и не выкуришь.

найдите пользователя с кривыми руками — он методом тыка вам воспроизведёт вашего динозавра и выкурит баг из берлоги... Ну и попутно ещё динозаврят-багунчиков :)

всю жизнь надо будет изучать
Не надо — лет через 5-7 половина существующих фреймворков и функций будут deprecated. А потом вообще появится ЯП помоднее.

и что за последние 5-7 лет полезного такого появилось, поделитесь опытом из студентом =)

Например, появилась Java 8, практически отмерли JSP и EJB, изменился принцип расположения объектов в памяти и работы сборщика мусора.
А лет 10 назад многопоточность была совсем другая и дженериков не было... Это то, что сходу на ум приходит.

EJB 2 умерли, EJB 3.2 живее всех живых.

То, что они умерли не значит, что с ними нельзя встретиться на легаси проектах

Конечно, но на EJB 3.2 и новые проекты появляются.

JSP умер? бугага, ну вы отжигаете, это UI 80% всех вебных проектов на Java. EJB нафиг не нужен со своими тяжеловесными бинами при наличие Spring, которые позволяет управлять легковесными бинами.

JSP умер?
Я написал практически отмер, т.е. новых проектов на чистом JSP почти не пишут.
EJB нафиг не нужен со своими тяжеловесными бинами при наличие Spring
Именно, это и есть то, что в Java поменялось за последние 7 лет.

что подразумевается под чистым JSP ? Я использую JSTL и Struts тэги на ней, а также подключаю внешние JS+CSS, от JSP остается одна разметка с импортами.

Порекомендуете более достойную альтернативу JSP ?

что подразумевается под чистым JSP ?
«Классика» JSP + Servlets.
Порекомендуете более достойную альтернативу JSP ?
Для GUI сейчас тренд — JavaScript frameworks.
Для GUI сейчас тренд — JavaScript frameworks.
Backbone.js, Angular.js, Ember.js?

Угу, только их больше трех ;)

Я в курсе про количество, где-то наталкивался на статью про обзор десятка mvvm, mvc фреймворков.

Не отрицаю, но legacy есть legacy.
Тут хакер хвастался, шо самые крутые спецы держат гуглы на 1.4.2 и вообще без фреймворков, а вы за struts зацепились.

Ушел я из легаси, теперь вообще никаких JSP.

Язык учится за 3 месяца. Этого времени вполне достаточно для освоения синтаксиса и возможностей языка. К слову, стандартный набор начинающего прогера должен быть как минимум Паскаль + Си + один из вебовских языков.
Честно — не понимаю что можно учить 2 года в языке?
После 3-х месяцев остальное время — либо отработка алгоритмов, либо унивесализация работы, либо изучение методологий, либо ещё туева куча остального... Но это никаким боком с языком не связано. Если после этого вам ещё нужно время на изучение самого языка, значит программирование — это не ваша отрасль :)

ну я вот яву выучил за две недели, но есть два но. Некоторые примеры кода на ява 8 которые тут постит Пупкин вганяют меня в ступор, тоесть мои знания явно ограничены синтаксисом 6ой явы. Второе — есть нюансы которые я счас и прорабатываю, типа открыть файл с буфером для чтения или как байнари, разные либы которые облегчают жизнь, или тоже копировани строк которое лучше делать буферами, или токины которые я пока тоже не успел затронуть нигде.

Мне вот интересно, если из C# выкинуть соснули.рф, то пулучается какбы джава. Но я так смотрю, там вообще ничего не остается. Тупо голяк. Даже выучить нечего.

Ну у вас есть ещё резерв — 2,5 месяца, за которые вы освоите 8-ю яву :)

я видел ваш пример, про чтение файла 100к символов, вы там даже не понимаете, что делаете, то ли вам строку то ли символ прочитать, + вывод в консоль по 1-му символу а не например массивом для эффективности, это вы называете ИЗУЧИЛИ ЯЗЫК ? да смешно, к ваш код за 3 минуты, да мне бы на работе яйца сразу бы оторвали за такое, загнобили на весь опенспейс в офисе.

нельзя просто так взять и оторвать СЕО яйца.
и девушке тоже
dou.ua/...ic/9772/#468830

Видимо фигурально.

я про 100к символов ничего не писал, вопрос у меня был про то как ускорить чтение и проблема оказалась в либе еклипса, а не в скорости чтения. Изначальное чтение у меня было буферизированное но оно тоже медленно работало и я его менял на символьное. ну и как я сказал выше — именно на нюансах и идет отработка опыта и заполнение шаблонов для копипаста. Сча я выложу свой листинг для строк в яве приходите поржать, может что то улучшите )))

Доростете до синиора, зовите mobile к себе в опенспейс ;)

Язык учится за 3 месяца.
ну я вот яву выучил за две недели
www.youtube.com/...h?v=FmbHTvSR3Og
Язык учится за 3 месяца.
Это не моё мнение, а моих преподов из универа... Лично мне как аналитику этих трёх месяцев хватило для написания лаб, курсовых и дипломных :)
На трёх языках...

я не стану холиварить, ладно?))

Такое ощущение, что вы невнимательно читаете, то, что я пишу:
1) 3 месяцев ВПОЛНЕ достаточно для понимания синтаксиса и возможностей языка
2) 3 месяцев ВПОЛНЕ достаточно, чтобы читать код и фиксить баги
3) для решения задачи поставленной автором темы ДОСТАТОЧНО подобного знания языка
.
ГДЕ вы увидели, что после 3 месяцев изучения языка я сказала, что чел становится супер-пупер-синьором?
Всё — теперь холиварьте :) Жду :)

Мда... А говорили «индусы, индусы...»

рассуждения на уровне обывателя, вы понимаете, что баги бывают разные?
Это не только двигать кнопочку на 5px влево, который и верстальщик пофиксит.

Чаще всего приходится дебажить и искать в граничных диапазонах, покрывать unit и функциональными тестами, чтобы баги не повторились, лазить в JS и CSS, а также в БД.

самые сложные и противные баги — многопоточные в г*внокоде, такое не всегда под силу пофиксить даже senior-у, а вы говорите.

такое не всегда под силу пофиксить даже senior-у, а вы говорите.
ЧИТАЕМ ВНИМАТЕЛЬНО:
ГДЕ вы увидели, что после 3 месяцев изучения языка я сказала, что чел становится супер-пупер-синьором?

3 месяца — это даже много, не нужно ничего учить, главное хороший титул на погоны и требовать себе огромную з.п.

Вот у нас на прошлом проекте (легаси-сапорт) были индусы, 1 х senior + 1 х техлид. Мне как миддлу приходилось за ними прибирать, но меня это не смущало, т.к. я получал на уровне senior-а. Вот основной список индусятских заслуг:
1) иногда делают force commit в гите вместо мёржа своих изменений,
2) знают 2 команды в мавене, что их не всегда спасает,
3) не переключаются на ветку, а заново клонируют весь репозиторий
4) пишут JS прямо на JSP, иногда вместе с частью CSS типа font-size=14
5) в Java-коде столько бреда, что перечислять можно часами.
6) импорт проекта в Eclipse-у просто эпопея, т.к. 200$ на IDEA их жаба давит.

Вывод — не совершенствуйтесь и не прогрессируйте, 3 месяца для 3-х языков вполне достаточно.

непонимание всех 1-6 пунктов, что вы перечислили не мешает мне быть аналитиком :)
И да, я прогрессирую и совершенствуюсь в анализе :) Для меня вполне достаточно знания языка за 3 месяца, чтобы понимать его специфику и возможности. А что я не знаю — должен знать кодер :) Я не лезу в его парафию :)
.
Конкретно для решения ЭТОЙ задачи, то есть той, что автор привёл вверху — действительно достаточно 3-х месяцев знания языка... :)

Аналитик это разве не такая девочка, которая бегает от заказчика к команде с кучей бумажек и схем и кричит что все пропало и надо «на вчера»?

хаха. толсто, но весело.
а вообще, может, это и есть аналитик. только испорченный какой-то. с истекших сроком годности.

Это не аналитик — это

девочка, которая бегает от заказчика к команде с кучей бумажек и схем и кричит что все пропало и надо «на вчера»
:)

Ну вот как раз потому, что в ИТ-отрасли вместо аналитиков бегают вот такие мальчики-девочки и кричат «Шеф, всё пропало» — потому и фейлятся релизы... :)
.
И нет, аналитик это тот человек, который ЧЁТКО и ЯСНО представляет себе то, что хочет Заказчик и доходчиво объясняет это разработчикам, зачастую корректируя видение последних по поводу конечной задачи в сторону пожеланий Заказчика :)

зачастую корректируя видение последних по поводу конечной задачи в сторону пожеланий Заказчика
www.youtube.com/...h?v=BKorP55Aqvg

Мля... Ну как вы уже достали этими Профессионалами. Задача поставленная Заказчиком из скетча решается максимум в 15 минут. И только люди с косным и стандартным мышлением будут дальше продолжать ржать вместо того, чтобы погуглив найти минимум 6 ответов на поставленную задачу.

Не вижу смысла спорить и пытаться метать бисер, т.к. он все равно отскакивает как горох от стенки.

ОК — я перестаю метать бисер :)

Надеюсь мне не повезет работать с людьми, которые изучают язык за 3 месяца. Если вы изучаете язык за 3 месяца, наверно документацию вопше не читаете и не знаете про API, например как в Джаве SE и EE, рекомендую в гугле вбить java api и сразу 1-ю ссылку, это за 3 месяца не реально изучить. Хотя нет, если вы изучили язык за 3 месяца и оттачиваете мастерство, не изучая дальше API, то есть не интересуетесь, что там дальше есть, и пользуетесь несколькими класама / методами для решения задач + копипаст с стековерлофа, то полагаю, просто не интересно, то, что есть еще в API, можно сказать — программирование не ваша отрасль :)

это вы как экстрасенс по фейковому нику судите ?) научите ?)

О! да вы ещё веб-фразеологизмов не знаете :)
Простите, но мне не доплачивают, чтобы я кого-то чему-то учила здесь :) А желания это делать задарма у меня нет :)

точно экстрасенс, увы я редко на форуме отсиживаюсь и изучаю

веб-фразеологизмов
, нет, не из за того, что чего то не знаю, вы не так подумали =) а из та того, что ценю свое время, но как видно, сегодня время спустил коту под хвост, ибо ничего полезного из топика не извлек, а вам случайно не доплачивают за трату времени на форумах ? =)
вы не так подумали =)
да я вообще о вас не думаю.
Я с вами заранее согласна, что ВЫ — САМЫЙ ЛУЧШИЙ ПРОГРАММЕР :)
:)

хватит мне льстить =))) спасибо за мотивацию =) я буду стараться стать самым самым лучшим, но путь еще далекий =)

Методом тыка можно вообще без изучения кодить. Всего-то делов — распечатать листок А4 A5 с ключевыми словами и семантикой ))
Вот только есть подлянки тонкости, которые могут и через год, и через два, и после получения лычки сениора вылезти, и никакие три месяца самого усердного изучения в начале пути этому не воспрепятствуют, и сидишь потом такой и думаешь «Хоспади! Ну шо ж за даун клепал этот гребаный ПоХаПэ?!» «я знаю, что ничего не знаю».
Я не говорю, что придется по пять раз на день охреневать, но стабильно раз в полгода — вполне ;) Примеров не ждите, как чего интересного вылезет, запощу, если не забуду.

Да при чём тут тонкости-подлянки... По сути — это применение алгоритмов используя семантику языка. Образно: можно один и тот же пейзаж написать акварелью, гуашью, маслом... Он выглядеть будет по-разному. Но самой технике написания не надо много учиться. Много нужно учиться перспективе, передаче цветовой гаммы и прочее, что не всегда связано с красками, которыми рисуешь...
Но вопрос был не в этом, а в том, что изучить 5 языков за 15 месяцев ВПОЛНЕ возможно, чтобы во всех языках можно было «читать код и фиксить баги» :) Ну и попутно решать задачки, описанные автором темы :) Ну и ещё попутнее выбрать — на каком же языке проще писать решение к математической задачке, а на каком — к лингвистической :) Вопрос был приземлённее :)

Образно: можно один и тот же пейзаж написать акварелью, гуашью, маслом...

Ой ли? :)
Не сарказма ради, у самого руки из жопы к рисованию, но все же знаю примеры, когда человек офигенно рисующий, скажем, маслом, рисует откровенный фуфел гуашью, и не потому, что «выглядят они по-разному», а потому что другой, который всю жизнь предпочтение отдает гуаши полюбому нарисует то же самое в сто раз краше.

Но вопрос был не в этом, а в том, что изучить 5 языков за 15 месяцев ВПОЛНЕ возможно, чтобы во всех языках можно было «читать код и фиксить баги» :)

А, ну это да, особенно если эти пять идут как от 6-го по 10-й ))

Не сарказма ради
Так вот... имелось ввидучто ОДНИ И ТЕ ЖЕ яблоки можно написать и акварелью, и гуашью, и маслом... Если чел не знает техники работы с гуашью — то у него выйдут какульки, а не яблоки...
Допустим на технику освоения работы с гуашью тратится те самые пресловутые 3 месяца (число зистели в отношении красок) — остальное время тратится на то, чтобы уметь смешивать краски (колористика в принципе для всех красок практически одинакова), нарабатывать штрихи, методику нанесения, чтобы руки не дрожали и прочее...
.
Оффтоп-аналогия. Я люблю бадминтон. Это конечно не теннис, но подача, скажем так, у меня не слабая... И вот меня начали учить играть в настольный теннис. И я со своей подачей чуть стенку шариком не пробила :) В смысле я не владела техникой обращения с теннисной ракеткой ВАЩЕ :)
Если чел не знает техники работы с гуашью — то у него выйдут какульки, а не яблоки...
ну, че, кисть в руках держит === «знаком с синтаксисом». что ж яблоки никак не выходят тогда?

1) а где vs знает технику наложения мазков гуашью === возможности языка?
2) ну и наконец если всё равно получаются какульки, а не яблоки и

руки из жопы к рисованию
то
программирование рисование не ваша отрасль :)

Интересно, что ты имеешь ввиду. Если синтаксис, то достаточно и месяца, а если грамотно использовать контравариантность всякую, то соглашусь.

я имею в виду АПИ, а не 20-30 ключевых слов и их семантика использования, открывает простую книгу по сдаче сертификата и там весь твой синтаксис на 1-2 страницы вместиться — это не изучение языка программирования, с таким успехом я могу за 1 год изучать 150 языков и на форумах мерятся ...

а шо как то напряжно выучить яву, питон, руби, хагуп, перл после того как уже знаешь бейсик, паскаль, ассамблер, вижуал бейсик, с и с++?
на уровне СЕО может и не напряжно,
а если активно педалить, то да — напряжно.

ну сам понимаешь,если за программирование платят меньше чем за что то другое что ты можешь делать, то программирование отходит на второй план.

Я вам скажу как математик... Ну или Аналитик...
Любую задачу можно решить множеством способов. Но выигрышным будет оптимальное по времени, ресурсам, и прочему. Далее...

другим читать и т.д. не главное ?
если вы знаете только джаву, а кто-то ещё 5 языков, то почему он должен опускаться до вашего уровня и писать ответ на джаве?
Может стоит самообразованием заняться?

где я написал, что он должен это писать на ДЖАВЕ ? Вы вопрос читали сверху ? Может надо внимательность подправить ?

Тогда в чём проблема написания ответа на перле или питоне?

читайте внимательно вопрос, а не задавайте вопрос на вопрос, не ужели тяжело прочитать и вдуматься ? или надо истолковать вам как математику ?)))

не ужели тяжело прочитать и вдуматься ?
специально для таких я выше писала:
Я с вами заранее согласна, что ВЫ — САМЫЙ ЛУЧШИЙ ПРОГРАММЕР :)
:)
Но выигрышным будет оптимальное по времени, ресурсам, и прочему
нет. «выигрышным» будет по тому признаку, который приоритетнее.
для прототипа покатит «побыстрее».
для идиота-заказчика прокатит «подешевле».
для разового проекта с огромным финансированием, типа запуска марсохода, в приоритете будет стабильность работы(куча эвристики на случай непредвиденных, перепроверка данных от датчиков и 100% покрытие кода тестами как идеал).
как вы себе представляете решение, которое лучшее по всем параметрам? и кто его создаст? несуществующие идеальные программисты?
нет. «выигрышным» будет по тому признаку, который приоритетнее.
Ну вообще-то там было перечисление:
выигрышным будет оптимальное по времени, ресурсам, и прочему
порядок расставляет заинтересованное лицо :)
.
как вы себе представляете решение, которое лучшее по всем параметрам? и кто его создаст? несуществующие идеальные программисты?
по опыту работы — ИДЕАЛЬНЫХ программистов не бывает. Просто потому, что они зачастую элементарные вещи предметной области НЕ ЗНАЮТ.
Из того же опыта — обычно беру БАААЛЬШОЙ напильДничек и напильДниваю то, что наваяли супер-пупер-программеры путём обнаружения багов :)
Как говорится — если я не нахожу багов в программе, то это не достоинство прогеров, а моя недоработка :)
.
Если же касается предложенной задачи, то она не лежит в плоскости моего оценивания. Здесь меряются линейками кодом и функциями, а меня в первую очередь будет интересовать удовлетворённость пользователя.
И с этой позиции скажу, что если из 5 слов
Apple iphone 5s (16Gb, silver)
мне выдастся первых 10 удовлетворяющих только «Apple iphone silver» — то мну будет ЗОЛНЕМЕРЯНО :)
На счёт приоритетности — если пользователь вводит рэндомно в поисковую строку все 5 слов, то стоит первому слову приписывать максимальную приоритетность, а последнему — минимальную. Обычно чел психологически на первые места ставит самое важное.
То есть если я ставлю 16 гиг на первое место, а Apple iphone на последнее — то мне будет параллельно — айфон мне выдастся или флай :)
Ну это так — мысли вслух...
порядок расставляет заинтересованное лицо :)
я так понял, речь идет о «все и сразу». видимо, не верно понял, ага.
То есть если я ставлю 16 гиг на первое место, а Apple iphone на последнее — то мне будет параллельно — айфон мне выдастся или флай :)
ничего себе. хорошо, что гугл имеет другой подход.
ничего себе. хорошо, что гугл имеет другой подход.
чем хорошо?
Мну лично это напрягает... Вечно приходится в гугле плюсики ставить :(

если я ввожу что-то в поле поиска, я никак не рассчитываю, что это будет упрямо и стабильно игнорироваться. если все равно — ihpone или samsung — не вводить. и всё.

Если у вас неполное соответствие поиску в 100-й ссылке, то там может и проигнорироваться часть слов, если вы их вводите МНОГА...
.
Из практики — гугля около 32-х слов одновременного поиска поддерживает. Вы бы видели этот дикий поиск с кучей +/- среди туевой кучи зеркал и в принципе фигни :)

Если у вас неполное соответствие поиску в 100-й ссылке, то там может и проигнорироваться часть слов, если вы их вводите МНОГА...
угу. а еще искомые слова могут искаться в пределах всей страницы. даже не блока контента. хорошо, хоть собственный adsense не индексирует как часть страницы.
кстати, касательно исходной задачи. там речь не о поисковике для пользователя, а про автоматическое сопоставление сторонних каталогов без ID поля с основной БД. думаю, в этом случае «пофиг, iphone или fly» — это бага, а не фича.

Нет. Не видела.
Я вполне предполагаю, что на других языках, кроме перла, можно тоже красивым образом реализовать вашу задачу. Я просто увидела слова «ява», «пихапи» и решила поднять более глобальный вопрос относительно данной задачи — на счёт языка написания... :)
Пи.Эс.
Всегда рада послушать противоположное мнение, несущее вэлью :)

Для лингвистических задач лучше перла я КАГБЭ языка не вижу.
потому что он написан лингвистами для лингвистов? что за заключение о «подходящести перла»?

Вы знаете семантику перла и его возможности?
Ну это я просто — чтобы понять с какого уровня знанием перла собеседником мне приходится общаться... Так сказать — для более предметного общения...

задайте тестовое задание, че ли.
профессионального опыта не имею.
знаю, что это язык общего назначения, реализовавший крутой стандарт регулярок PCRE.
еще знаю, что в зависимости от типа по-разному именуются переменные.
что есть «семантика» в вашем вопросе?

Семантика:
#! /bin/usr/perl
@mas_value = (’Samsung Galaxy 2′, ’Samsung Galaxy s3′, ’Samsung Galaxy s4′, ’Samsung Galaxy s5′, ’Samsung Galaxy Duos’, ’Samsung Galaxy Duos 2′, ’Samsung Galaxy Mega’, ’Samsung Galaxy Mega 2′, ’Samsung Galaxy Yong’, ’Sony Xperia XL’, ’Sony Xperia L’, ’Sony Xperia SL’, ’Sony Xperia S’, ’Apple Iphone 5s 16Gb gray’, ’Apple Iphone 5s 16Gb gold’, ’Apple Iphone 5s 16Gb silver’, ’Apple Iphone 5s 32Gb gray’, ’Apple Iphone 5s 32Gb gold’, ’Apple Iphone 5s 32Gb silver’, ’Apple Iphone 5s 64Gb gray’, ’Apple Iphone 5s 64Gb gold’, ’Apple Iphone 5s 64Gb silver’, ’Apple Iphone 5 16Gb gray’, ’Apple Iphone 5 16Gb gold’, ’Apple Iphone 5 16Gb silver’)
print “What do you want to find?”
$user_string = <stdin> #User enter the string
@list = qw($string) #Set user string as array
$a = $mas_value
while $a— > −1
{$b = $list
@aa[$mas_value — $a] = 0
while $b— > −1
{$c = @mas_value[$mas_value — $a]
@aa[$mas_value — $a]++ if $c =~ m/@list[$list — $b]/
}
}
Это был поиск, а потом нужно выявить индекса массива @aa с максимальными значениями и вывести первые 10 значений массива @mas_value с теми же индексами
.
//Блин, заставили вспомнить то, что учила более 12 лет назад :)
Уж простите — не всё комментила... Я знаю, что ас-перловец смог бы лучше написать и у меня примитив... :)

це не перл))) ось Ваш пошук на перлі:

my @matches = grep { /pattern/ } @mas_value;

та ну ладно. и как тогда «iphone silver 32» совпадет со строкой «32 iphone»?
в приведенном коде токенизация и подсчет совпадений для каждого токена, как я понял. впрочем, не уверен.

Ну смысл — засовываем строку в массив, где каждое слово — новый элемент, а потом двойным циклом высчитывем количество совпадений.

Микл, я же сказала — учила перл БОЛЕЕ 12 лет назад И больше к нему не возвращалась... Думаю если бы я потратила на воспоминания хотябы неделю с обязательным кодингом — то было бы менее громоздкое и более похожее на перл, чем на Си :)
И вообще, я аналитик, а не прогер. :) Я совсем не собираюсь с вами состязаться. Этот код — результат часа воспоминаний по Самоучителям :)

более похожее на перл, чем на Си :)
ось це я і мав на увазі,що це універсальний С-подібний код ))
зараз сяду, і щось накидаю
#!/usr/bin/perl -w 
use strict;
use warnings;
use Data::Dumper;

my @mas_value = ('Samsung Galaxy 2', 'Samsung Galaxy s3', 'Samsung Galaxy s4', 'Samsung Galaxy s5', 'Samsung Galaxy Duos', 'Samsung Galaxy Duos 2', 'Samsung Galaxy Mega', 'Samsung Galaxy Mega 2', 'Samsung Galaxy Yong', 'Sony Xperia XL', 'Sony Xperia L', 'Sony Xperia SL', 'Sony Xperia S', 'Apple Iphone 5s 16Gb gray', 'Apple Iphone 5s 16Gb gold', 'Apple Iphone 5s 16Gb silver', 'Apple Iphone 5s 32Gb gray', 'Apple Iphone 5s 32Gb gold', 'Apple Iphone 5s 32Gb silver', 'Apple Iphone 5s 64Gb gray', 'Apple Iphone 5s 64Gb gold', 'Apple Iphone 5s 64Gb silver', 'Apple Iphone 5 16Gb gray', 'Apple Iphone 5 16Gb gold', 'Apple Iphone 5 16Gb silver');

while (<STDIN>) 
{
 last if ($_ =~ /^\s*$/); # Exit if it was just spaces (or just an enter)

 my @pattern_list = split /\s+/, $_; #user string as array

 my @results = ();
 foreach my $pattern (@pattern_list) 
 {
  my @matches = grep { /\b($pattern)\b/i } @mas_value;#  /\b....\b/i - in general it should be more complex
  @results = (@results, @matches);#merge two arrays; could be performed different ways
 }

 @results = do { my %seen; grep { !$seen{$_}++ } @results };#remove duplicates; could be performed different ways

 @results = sort { lc($a) cmp lc($b) } @results;#sort results by name

 print "\n", "You typed:", $_, "\n";
 print Dumper(\@results);
}
my @pattern_list = split /\s+/, $_; #user string as array
А почему не использовать стандартній оператор qw()? Он же как раз по пробелам разделяет строку на элементы массива? Или у вас цель посимвольно разделить? В чём смысл?
sort results by name
А зачем по имени? Может лучше по количеству совпадений?
.
Ну а так — 16 строк — вполне аргумент, почему я и предлагала лингвистические задачки на перле решать :)
А почему не использовать стандартній оператор qw()?
Якщо назви продуктів давати укожна у новій стрічці, тоді можна. Але я взяв Ваш масив за основу,щоб не витрачати час))
А зачем по имени? Может лучше по количеству совпадений?
1.Можна і так. Правда, спершу к-сть співпадінь слід порахувати перед «#remove duplicates;» (дублікати ми маємо )
2.Задача не стояла зробити коректний код, а реалізувати Вашу логіку
3.Якщо вибірка товарів велика (тисячі, десятки тисяч і більше). Особисто я б у такому випадку не використовував регулярні вирази (повільно).
Створив би hash of hash (програмно, не хардкод), де key були б окремі слова товар із словника.
Можна додати важливість того чи іншого слова як ’range’ (2 в степені n)
Наприклад, ’Samsung Galaxy 2′ дає нам 3 keys:
my %word_hash = (
’Samsung’ => {
’array_keys’ => (0,1,2,3,4,5,6,7,8),#(0..8)
’range’=>32, #importance of the key, 2^n
},
’Galaxy’ => {
’array_keys’ => (0..8),
’range’=>16,
},
’2′ => {
’array_keys’ => (0,5,6),
’range’=>1,
}
);

Тоді у циклі перевіряємо наявність кюча у нашому хеші слів.

foreach my $pattern (@pattern_list)
{
if (exists $word_hash{$pattern})
{

}
}

Код загалом на десяток стірчок більше, але ефективніший (перевірено на словниках від 50 тисяч фраз і більше)

Якщо назви продуктів давати укожна у новій стрічці, тоді можна. Але я взяв Ваш масив за основу,щоб не витрачати час))
Так у меня как раз оператор qw для пользовательского массива использован :)
В смысле словарь мобфонов — это строчки, а пользовательский ввод — массив слов. Тогда пробегаемся по словарю — выставляя сколько раз массив слов встречается в строчке словаря... и т.д.
Створив би hash of hash (програмно, не хардкод), де key були б окремі слова товар із словника.
Я тоже об этом думала :)
Но я же говорю — давно на перле не общалась — посчитала, что слишком много ошибок наваяю...
Через хеши вообще было бы проще — АДНАЗНАЧНА :)
Может и не с моей первоначальной логикой... ;)
Так у меня как раз оператор qw для пользовательского массива использован :)

1.@myNames = (’Jacob’, ’Michael’, ’Joshua’, ’Matthew’, ’Alexander’, ’Andrew’);
2.@myNames = qw(Jacob Michael Joshua Matthew Alexander Andrew);
3.@myNames = qw(
Jacob
Michael
Joshua
Matthew
Alexander
Andrew
);

На жаль , Ваш варіант ініціалізації масива неправильний — суміш підходів 1 і 2.

Почему неправильный?

$user_string = <stdin> #User enter the string
@list = qw($user_string) #Set user string as array
Сначала считали строку, а потом попробельно записали её слова в массив...
//я действительно не понимаю своей ошибки, если она есть :(

Перепрошую,у Вас усе правильно у цій конструкції. )) Неуважність із мого боку. (((
Я зранку спросоння "запам"ятав" чомусь, що у Вас
@myNames =qw (’Jacob’, ’Michael’, ’Joshua’, ’Matthew’, ’Alexander’, ’Andrew’);
Ще раз перепрошую.

прикольно почитать вашу дискуссию после того как появилось понимание перла. НЕ сильно понимаю нафига делать объединение массивов, при этом массив объединяется с самим собой вместо того что бы создать массив с оригинальым индексом проверяемой строки и количества совпадений.

@results = (@results, @matches);#merge two arrays; could be performed different ways
could be performed different ways
Тому і прокоментовано, що можна зробити різними способами. Зрештою, код накидано нашвидкоруч суботнього ранку.

и шо у тебя будет в этом массиве, как оно будет выглядеть ?

Код працює. Ось Вам і простір для практичного застосування своїх знань Perl.
Зрозумієте мій код, тоді легше буде зрозуміти код (див. нижче), що використовує List::MoreUtils.

Типичный сисадмин-стайл. Очень много синтаксического мусора, много лишних манипуляций с данными, дублирование семантики, комментирование очевидного, игнорирование возможностей «батарейки» языка и изобретение велосипедов. Вам советую почитать Perl Best Practices и пользоваться перл-критиком.

прокоментовано, щоб не пояснювати роботу кожної стрічки.
А так, звісно, facepalm

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use List::MoreUtils qw(uniq); my @mas_value = qw(); while (my $each_line = <STDIN>) { last if $each_line =~ m{^\s*$}; my @results; foreach my $pattern (split m{\s+}, $each_line) { # /\b....\b/i - in general it should be more complex map { push @results, $_ } grep { m{\b($pattern)\b}i } @mas_value; } @results = sort { lc $a cmp lc $b } uniq @results; printf "\nYou typed: %s\nprogram match: %s", $each_line, Dumper(\@results); }

возможно, Перл отбил охоту к программированию.

Нет. Абсолютно.
Я заранее знала, что пойду не по стезе кодинга, а по стезе написания алгоритмов для работы ПО.
Чем успешно и занимаюсь почти всю свою трудовую жизнь :)
==
Тут обмолвились о Питоне — возможно на досуге посмотрю на него :) Достаточно интересно стало. Опять же оговорюсь — мне это нужно для расширения «карты памяти» в сфере возможностей языков программирования. Для чего перл, собственно, и учился :)

из необычного для себя увидел постфиксную запись условного оператора(впрочем, для многострочного блока это будет плохочитаемо) и отдельный оператор «сопоставления с шаблоном».
еще веселит получение длины массива при помощи конструкции $<имя переменной-массива>, но я был морально готов :)
можете конкретно тыкнуть пальцем. какой набор конструкций, как вы считаете, заточен именно на упрощение работы с текстовыми данными?
~=, ага. что еще?
PS

if $c =~ m/@list[$list — $b]/
там разве экранировать не надо? ну, чтоб введенное человеком .* не трактовалось как регулярка «все, что угодно»?
еще веселит получение длины массива при помощи конструкции $<имя переменной-массива>, но я был морально готов :)
Это — стандартная семантика перла — я почему и говорю, что он проще.
По-хорошему можно вообще считать от 0 в бесконечность индекса и проверять на возврат ненуллового результата из массива. Думаю на пару строк будет сокращение...
На счёт экранирования и прочей фигни — в задаче * не указывалась — раз, ну и что вы хотите с аналитика, видевшего перл в последний раз 12 лет назад?
Это — стандартная семантика перла — я почему и говорю, что он проще.
не понял, в чем тут простота. просветите, пожалуйста.
и нет, я и не думал цепляться к алгоритму или кодостилю. я пытаюсь понять позицию «general purpose ЯП лучше других подходит для работы с текстом», вот, и задаю вопросы.
я пытаюсь понять позицию «general purpose ЯП лучше других подходит для работы с текстом»
в нём поиск происходит по факту в 1 строку. Ещё раз повторю — я ОЧЕНЬ рагульно за час накидала нечто, больше похожее на Сю :)
По-факту моя дипломная, которая создавала кучу вебстраниц из БД по вводимому пользователем слову заняла всего 13 строк с объявлением переменных.
И я — аналитик... По факту на тех же сях у меня код вышел бы раза в 2 больше. Вот так и меряю... :)
Ещё раз — моё ИМХО может не совпадать с чужим ИМХО.
А почему это моё ИМХО — ну просто потому, что когда был выбор, какой веб-язык учить — я выбрала перл из-за его оригинальности в отличие от пихпи и жавы, которые при сильно большом старании знающий Си и Паскаль сможет понять/прочесть. Я не говорю кодить — достаточно понять чужое...
Это — стандартная семантика перла — я почему и говорю, что он проще.
настільки «проста»,що деякі знайомі розказували, що свого часу сиділи по кілька годин і намагалися зрозуміти логіку роботи однієї стрічки коду (уже маючи більш-менш достатньо досвіду на перлі) )))

Ну я имела ввиду, что «проще написать» :)
Сама помню как по полчаса в день только могла перлом себя загружать — ибо мозги пухли от напряга :)

мне у перла нравится «_», хранящий результат последней операции. позволяет лихо сооружать головоломные врайт-онли однострочники

вместо композиции функций, так?
правда, «в обычной жизни» значит, добавляя новую строку без явного влияния на процесс(логирование?), можешь повлиять на работу из-за изменения значения _, верно я понял?

вроде да. я перл просматривал лет десять тому назад)
но да, если логика завязана на данные в _, а унутрь вставлено что-то, делающее нужную вещь, но изменяющее _, то будет упс.

Фишку удобно использовать в действительно коротких вещах, скриптах, однострочниках

перл который я счас учил имеет две фишки — это нетипизированность массивов и простота работы с хештагами. Нетипизированность массивов позволяет запихнуть в один массив другие массивы с переменами разного типа тоесть массив вида а=((1,2,3), (а,б,в,г,д)) — это нормально. Вторая примочка это когда строка пакуется в хештаги и потом количество вхождения слова в строку возвращается просто возврвтом хеша для этого слова. К сожаления в вашем решении и в решении Микла Ковача — ни того ни другого не наблюдается. И как вы и сами подметили настоящий програмист может писать на любом языке с-образный код )))

АНУСБАЦАЙТЕ своё решение :)
//вы забыли, что и я и Микл активно перлом не пользуемся, а вспоминаем «прошлые деньки» :)

да наверно на следующей неделе я буду готов что то свое писать.

Если нужно шибко быстрое решение:

1. Вводится функция оценки важности слов. Скорее всего нужно сделать ее так:
— есть словарь (Apple, iPhone, Sony, ...) для которых важность задана руками
— для остальных слов важность можно считать как длину строки
— возможно стоит принимать во внимание, как часто данное слово встречается в каталоге для всех позиций

2. Для статических данных (все товары) строится дерево поиска. Выбираете все слова для каждой позиции, агрегируете все позиции, сортируете по важности и строите дерево.

3. Для входной строки та же операция:
— бьете на слова
— считаете важность каждого слова и сортируете
— ищете по дереву

Скорее всего дерево тут можно сделать довольно условное. Просто позиции в каталоге можно отсортировать по двум признакам: суммарная важность (не уверен ???), максимальная важность одного слова, след максимальная важность и так далее. И вдобавок иметь простой хеш.

Простым решением будет — бьете на слова, сортируете по длина слова + лексикографически. тупо просматриваете весь каталог и выбираете подходящие (хотя бы одно слово совпало). просмотр можно делать одним циклом, у вас слова отсортированы. ну или просто в лоб.
так как вам нужно не более 10 результатов, то при нахождении 11го выкидываете самый плохой результат.

внизу пон Пупкин набросал какой то алгоритм, говорит что с деревьями и графами, код он не документирует а за 5 минтут которые у меня были я не смог понять что он там делает.

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

та да я пытался понять его, но за 5 минут я не врубился в прохождение по веткам и т.д. счас я вот до компа добрался — начну на яве свою версию писать.

ну все относительно в мире.
если вас устраивает, что кол-во ответов может быть больше 10.
и результаты для его варианта каталога и следующих двух строк: «Silver Iphone 5s 16 Gb Facetime» и «a b Iphone» будут одинаковые.
ну или то, что «a Samsung Iphone» и «a Galaxy Iphone» даст принципиально разные результаты.
то это решение.

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

дык внизу ж в объяснении алгоритма есть приписка что я его не тестил полноценно. И что оно может и не работать нормально тоже. Придумано быстро и может вообще не работает )
10-ю вариантами ограничить легко. Остальное — или баги или показатель неправильности алгоритма, я ж не знаю :) .
П.с.
Вариант на питоне фигня так как использует пересечения.. А на базе из миллиона товаров сделайте поиск для тысячи товаров...

так вроде обсудили уже, товаров всего 100 −200. Я где то тут бизнес логику описывал.

Да я не критикую вас. Я просто глазами пробежал и высказал свое мнение.

Вариант на Питоне на мой взгляд лучше по выдаваемому результату, как я и указал в исходном сообщении. Да и со скоростью там не все так однозначно ;) wiki.python.org/...eComplexity#set Питон быстрая штука ... пока памяти хватает.

если делать один запрос на поиск по одной базе (ну один товар обработали и забыли) то ок, решение с пересечениями, возможно, будет достаточно быстрым (так как не надо делать предварительную работу). Если же по одной и той же базе делать много поисков — то пересечения это слишком дорого, так как мы каждый раз делаем одну и ту же работу. В этом случае лучше сделать подготовку данных (построить более удобную для поиска структуру). Это ж основа для очень многих алгоритмов

названия товаров скинуты в одну таблицу с индексом по группе, запрос — миллисикунды.

$parts = explode(' ',$products);

foreach($parts as $part)
{
    if(strlen($part)< 3){ // skip small words
         continue;
   }
   $part = mysql_real_escape_string($part);
   $result = mysql_query("SELECT id, title FROM table WHERE title LIKE '%$part%'");
   //..............you can retrieve the list and do some processing here 
}

Варіант2. FULLTEXT Indexing and Searching vs LIKE

Наконец-то на DOU стали появляться хоть какие-то программерские темы вместо непрекращающегося плача о собственной никчемности или тотальном п*здеце.
Завтра попробую решить. :-)

сама задача обсуждаема?
а то у меня замечания с точки зрения требований.
Apple Iphone 3GS 32Gb и Apply iphone 3GS 32Gb Grey должны совпадать.
А Apple Iphone 3GS 16Gb Grey и Apply iphone 2GS 16Gb Grey не должны.
И кстати, почему 5S и 5 совпадают? В каком это мире? :)
Я не цепляюсь ради придирки, условия не совсем понятны.

я не совсем понимаю о чем вы но могу немного расказать про то как это работает. К каталогу с ценами типа хотлайн.уа или яндекс.маркет подключается магазин Березка ( не интернет а простой магазин) путем присылания ексель файла. В ексель файле 60 товарных позиций по мобильным телефонам которые написаны как в примере который я дал. ни номеров ску (уникальй код товара) ни другой инфы нет. Девочка на бекенде запускает импорт ексель файла в базу березки в которой уже присутсвуют большинство ску и названия товаров, но для 5и самых новых моделей телефонов нет никаких данных. что бы девочке не рыться руками в общей базе в поисках есть ли там такие телефоны или нет, парсер делает это за нее — ищет наиболее похожие названия товаров по имени и предлагает ей в ручную залинковать новую модель телефона с одним из предложенных названий. После этого в базе березки для этого товара появляется СКУ, и его цена включается в каталог. Поэтому нет нужды в точных совпадениях, но для экономии времени девочки лучше быть максимально точным в ранжировании. Стоимость реализации такой процедуры на пхп гдето 80 долларов (4 часа по 20 баксов в час), ну там оригинально были еще небольшие усложнения типа вывести картинку, что делать когда товара не нашлось и т.д. Я реально поражен предложенными решениями на питоне которые пишутся за 3 минуты )))) .

Ну вот набросал. Смысл алгоритма сначала подготовить удобную структуру для работы а потом уже на ней делать поиск. Подготовка позволяет потом вызывать поиск сколько угодно раз и находить похожие продукты очень быстро.

import java.util.*;

public class Search {


    public static void main(String[] args) {
        String s = "Samsung Galaxy 2,Samsung Galaxy s3,Samsung Galaxy s4,Samsung Galaxy s5,Samsung Galaxy Duos,Samsung Galaxy Duos 2,Samsung Galaxy Mega, Samsung Galaxy Mega 2, Samsung Galaxy Yong,Sony Xperia XL,Sony Xperia L,Sony Xperia SL,Sony Xperia S,Apple Iphone 5s 16Gb gray,Apple Iphone 5s 16Gb gold,Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver";

        Search search = new Search();
        search.prepare(s);
        System.out.print(search.search("Silver Iphone 5s 16 Gb Facetime"));

    }


    public void prepare(String data) {
        String[] products = data.toLowerCase().split(",");

        for (int i = 0; i < products.length; i++) {
            String[] tags = products[i].split(" ");
            Arrays.sort(tags);
            List<Node> prev = new ArrayList<>();
            for (int k = 0; k < tags.length; k++) {
                if (!nodes.containsKey(tags[k])) {
                    nodes.put(tags[k], new Node());
                }
                Node node = nodes.get(tags[k]);
                for (Node pr:prev) {
                    pr.nodes.put(tags[k],node);
                }
                prev.add(node);

                if (i >= 2) node.products.add(products[i]);
            }
        }
    }

    public Set<String> search(String product) {
        String[] tags = product.toLowerCase().split(" ");
        Arrays.sort(tags);

        Set<String> r = new HashSet<>();
        for (int i = 0; i < tags.length; i++) {
            iter(tags,r,0);
        }

        return r;
    }

    public void iter(String[] tags, Set<String> r, int depth) {
        if (depth >= tags.length) return;
        for (int i = depth; i < tags.length; i++) {
            iter(tags,r,depth+1);
        }
        if (depth >= 2) {
            if (nodes.containsKey(tags[depth]))
                r.addAll(nodes.get(tags[depth]).products);
        }
    }

    private Map<String, Node> nodes = new HashMap<String,Node>();

    private static final class Node {
        public Map<String, Node> nodes = new HashMap<>();
        public List<String> products = new ArrayList<>();
    }

}

Я колись таке робив. Тоді простий спосіб із застосуванням функції similar_text() працював чудово.
Ще є levenshtein(). Я не памятаю що конкретно використовував. Але задача була саме така.

Трохи деталей тут stackoverflow.com/...similar-strings

внизу нормальные пацаны такую задачу решают за 3 минуты. ))))

Тоді простий спосіб із застосуванням функції similar_text() працював чудово.
Ще є levenshtein()
перестановка слов местами убивает “чисто строковые подходы”.
надо разбивать на токены.

кстааааати. отличная идея. только применять расстояние Левенштейна не на буквах одной строки, а на захешированных токенах.
1. Однозначно маппим все токены в строке с названием в символы. Например, Apple -> A, Samsung->S, 32Gb->w и т.д. 65536 символов Юникода хватит всем :)
Это потому что расстояние Левенштейна работает с символами. Да, можно заточить его на обработку токена как единого целого. Но зачем? :)
2. Сортируем коды-символы. Как угодно. Хоть лексикографически. Так решается проблема с перестановкой слов в названии.
3. Рассчитываем расстояние Левенштейна между этой строкой-кодом и строками-кодами для уже забитых в базу моделей.
4. Выбираем строку с минимальным расстоянием.

Правда, O(M x N) для одной пары строк и переборной характер делают этот подход не работоспособным на сравнительно небольших объемах :(

побили по словам, сделали множество, нашли пересечение искомого и имеющегося. если пересечение больше порогового — добавляем в результат. На питоне прототип три минуты вместе с отладкой.

In [24]: mas = "Samsung Galaxy 2,Samsung Galaxy s3,Samsung Galaxy s4,Samsung Galaxy s5,Samsung Galaxy Duos,Samsung Galaxy Duos 2,Samsung Galaxy Mega, Samsung Galaxy Mega 2, Samsung Galaxy Yong,Sony Xperia XL,Sony Xperia L,Sony Xperia SL,Sony Xperia S,Apple Iphone 5s 16Gb gray,Apple Iphone 5s 16Gb gold,Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver".split(',')

In [25]: inp = set('Silver Iphone 5s 16 Gb Facetime'.split(' '))

In [26]: [set(i.split(' ')).intersection(inp) for i in mas]
Out[26]: 
[set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 set(),
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'5s', 'Iphone'},
 {'Iphone'},
 {'Iphone'},
 {'Iphone'}]
inp = set('Silver Iphone 5s 16 Gb Facetime'.split())
intersections = [set(i.split()) & inp for i in mas]
return [mas[counter] for counter, i in enumerate(intersections) if i]
>>> [mas[counter] for counter, i in enumerate(intersections) if i]
['Apple Iphone 5s 16Gb gray', 'Apple Iphone 5s 16Gb gold', 'Apple Iphone 5s 16Gb silver', 'Apple Iphone 5s 32Gb gray', 'Apple Iphone 5s 32Gb gold',  'Apple Iphone 5s 32Gb silver', 'Apple Iphone 5s 64Gb gray', 'Apple Iphone 5s 64Gb gold', 'Apple Iphone 5s 64Gb silver', 'Apple Iphone 5 16Gb gray', 'Apple Iphone 5 16Gb gold', 'Apple Iphone 5 16Gb silver']

Сорри, пять копеек и чуть-чуть добил

Ага, а теперь то же самое, но поиск вызывается на базе из миллиона продуктов для тысячи разных продуктов :) . И посмотрим как пересечения тут управятся :)

я могу ответить по снобски, и сказать, что в задачи не было условия скалируемости, и были конкретные входные данные.

Да и мой алгоритм — это 3 минуты кода, а ваш?

ну нихрена себе за 3и минуты в месте с отладкой. выучить что ли питон раз на нем можна такое за 3 минуты делать.

PHP

print_r(array_intersect(
  explode(' ', 'Silver Iphone 5s 16 Gb Facetime'),
  explode(',', 'Samsung Galaxy 2,Samsung Galaxy s3,Samsung Galaxy s4,Samsung Galaxy s5,Samsung Galaxy Duos,Samsung Galaxy Duos 2,Samsung Galaxy Mega, Samsung Galaxy Mega 2, Samsung Galaxy Yong,Sony Xperia XL,Sony Xperia L,Sony Xperia SL,Sony Xperia S,Apple Iphone 5s 16Gb gray,Apple Iphone 5s 16Gb gold,Apple Iphone 5s 16Gb silver,Apple Iphone 5s 32Gb gray,Apple Iphone 5s 32Gb gold,Apple Iphone 5s 32Gb silver,Apple Iphone 5s 64Gb gray,Apple Iphone 5s 64Gb gold,Apple Iphone 5s 64Gb silver,Apple Iphone 5 16Gb gray,Apple Iphone 5 16Gb gold,Apple Iphone 5 16Gb silver')
));

а работает оно у вас ? насколько я помню там каждый продукт из списка нада в отдельный массив преобразовать и тогда уже искать пересечения.

Так, Ви праві. Але думаю array_filter()/foreach() допоможе.

Та і взагалі — таке треба робити через бд/повнотекстовий пошук імхо.

а сколько времени занимает бд/повнотекстовий поиск по массивам приведенным в примере ? за 6 минут напишете ? )))

через орм не больше трёх минут, а для поиска нужно применять отдельные либы типа solr/sphinx

а какая польза в данном случае от полнострокового поиска ?

коли наіменувань в базі кілька сотень тисяч і імпортуються тисячі рядків, то БД з своїми індексами і оптимізованими механізмами всяк шустріше коду.

Ага, а теперь то же самое, но поиск вызывается на базе из миллиона продуктов для тысячи разных продуктов :) . И посмотрим как пересечения тут управятся :)

заменять БД самописными конструкциями неэффективно)
а ежели всё же без БД, то в любом случае придётся считать пересечения. Но на больших объёмах «в лоб» делать глупо тоже — наверняка можно формализовать и упростить многое.

посмотрите мой код выше. Никаких пересечений.

ага, да, согласен.
яву я просматривал несколько лет назад обзорно и уже забыл почти всё. Насколько я понял, строится множество слов и список продуктов, содержащих каждое слово?
и как оно по памяти на миллионе продуктов ? )
я где-то потерялся, или серч/итер отдадут список продуктов, в которых встречается хотя бы одно слово из искомого названия?
Ну и, опять же, в БД с индексами это будет эффективнее.

Насколько я понял, строится множество слов и список продуктов, содержащих каждое слово?
ну идея немного сложнее. Строится граф слов. Вершины — слова, переход в другое слово есть если два слова (вершины) есть в каком-то одном продукте. Но тут я не строю все возможные ребра. Ребра однонаправленные, и связывают слова идущие слева направо. Чтоб это сработало, сортирую слова в названии продукта. Например для продукта «ааа ббб ввв» будет граф с тремя вершинами и связи будут идти так, из ааа будет переход в ббб и будет переход в ввв, из ббб будет переход в ввв, из ввв переходов не будет. Далее если добавляем в граф продукт, скажем, «ааа ввв ггг» то просто добавим вершину ггг (так как ааа и ббб у нас уже есть) и сделаем переход в нее из ааа и ввв. При построении части графа по продукту, я также считаю сколько ребер было добавлено (или обнаружено, что они добавлены раньше) и при достижении числа 3 (так как продукт похож тут по условию, если хотя-бы 3 общих слова есть), добавляю в эту вершину инфу о продукте (в данном случае его название). Пытался понятно объяснить, если нет — спрашивайте )
и как оно по памяти на миллионе продуктов ? )
ну, если я правильно посчитал использование памяти то тут О(n) оценка. Ну сожрет на миллионе несколько десятков метров. Не критично. Если неправильно посчитал — пусть кто-то поправит.
я где-то потерялся, или серч/итер отдадут список продуктов, в которых встречается хотя бы одно слово из искомого названия?

серч/итер идут по всем словам, что есть в названии продукта и пытаются «стартонуть» обход графа с вершины, соответствующей этому слову. Далее из этой вершины просто пытаемся сделать не меньше 3-х переходов, переходя к вершинам со словами, которые тоже есть в этом продукте. Если сделали не меньше 3-х переходов и нашли в вершине какой-то продукт — то это похожий продукт и его добавляем.

Да, алгоритм придумал достаточно быстро и не тестировал его полноценно, так что могут быть ошибки :) . Но на первый взгляд вроде работает :) Хотя это может только на первый взгляд и это фигня вообще а не алгоритм :)

принцип понял, я о приблизительно таком поведенни и подумал, но потерялся в коде.
Надо будет пробежаться по яве ещё разз

Подписаться на комментарии