Страницы

Поиск по вопросам

понедельник, 3 февраля 2020 г.

Графы - дорожная сеть

#графы #cpp


Как точно называется задача для покрытия дорожной сетью?

Например есть такой неограф:



Вес дуг это расстояние между городами.

Применив минимальное остовное дерево получается такая картина:
Все вершины связаны в одну большую дорогу, но если перемещаться из Рязани в Казань(по
остовному дереву), то потребуется 3+7+7+3=20 шагов.


То есть данный вид связи подходит для телефонной сети, но не для дорожной.
А в идеале, должна быть еще дорога между Рязанью и Казанью.



То есть должны быть еще элементы оптимизации, где будет коэфицент зависимость стоимости
прокладки дороги по отношению к времени перемещения из городов(как то так).Чем выше
такой коэфицент тем больше дуг будет между вершинами.

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


Ответы

Ответ 1



В первой формулировке (без наложения вспомогательных constraint'ов на стоимость строительства дорог) это — задача нахождения Shortest total path length spanning tree [1], для которой доказано, что она NP-трудная. Решить эту задачу можно с помощью приближенных алгоритмов (см., например, первую ссылку). Для такой же задачи, где стоимость постройки дороги не связана с длиной дороги, это будет задача нахождения "Constrained shortest total path length spanning tree". Нестрого говоря, эта задача не проще предыдущей, поэтому тоже является NP-трудной. Если формально это доказывать, наверно, нужно сделать такой же переход, как сделали вот здесь [2] при переходе от задачи Minimum Spanning Tree → Constrained Minimum Spanning Tree. Думаю, что для приближенного решения этой задачи можно придумать, как совместить подходы [1] и [2], если у вас, конечно, много свободного времени :)

Как составить алгоритм комбинаторной задачи?

#objective_c #c #cpp #алгоритм


Уже второй день не могу составить алгоритм решения данной задачи.
+Даны три буквы - Б, С, К 
+Сколько существует способов заполнить этими буквами N-количество клеток, при условии что:

1) Никакая из букв не может быть записана подряд;
2) Буква С может быть только между буквами Б и К (или К и Б).

К примеру при N=3 существует четыре способы:

БКБ КБК БСК КСБ
    


Ответы

Ответ 1



Всё просто. Обозначим a_i количество способов, которыми можно правильно заполнить ряд из i клеток. Попробуем найти рекуррентное соотношение на a_i. Как можно «собрать» строку длиной i? Вы начинаете с пустой строки, приписываете каждый раз либо один символ (Б или К), либо пару символов (СК или СБ). При этом на каждом шаге у вас правильная строка. Итак, какой у нас последний шаг? Вы приписываете к строке длины i-1 один символ. Правильная строка заканчивается либо на Б, либо на К, поэтому чтобы получить правильную строку на этом шаге, вы приписываете «противоположный» символ: К или Б. Такой шаг вы можете провести, имея любую правильную строку длины i-1. Вы приписываете к строке длины i-2 два символа: С и символ, «противоположный» последнему символу в строке. Такой шаг вы можете провести, имея любую правильную строку длины i-2. Строки, полученные при помощи шагов типа 1 и 2 не совпадают между собой (у вторых на предпоследнем месте С), а значит, мы получили все возможные варианты без повторений. Отлично, теперь подсчитаем общее количество путей. Вы можете сделать шаг типа 1 начиная от a_{i-1} правильных слов, и шаг сам по себе однозначен. Вы можете сделать шаг типа 2 начиная от a_{i-2} правильных слов, и такой шаг тоже однозначен. Итого: a_i = a_{i-1} + a_{i - 2} Найдём начальные значения: легко видеть, что a_1 = 2, a_2 = 2. Дальше легко. Вы можете применить любой из стандартных методов вычисления рекуррентных последовательностей. Например: a = 2 a_prev = 2 repeat (n-2) times tmp = a a = a + aprev aprev = tmp (который считает за O(n)). Или матричный, который считает за O(log n). Или применить производящие функции и получить замкнутую формулу. Или заметить, что ваша последовательность почленно вдвое больше последовательности Фибоначчи. Заметьте, что @Михаил М предлагает по существу ту же идею, я просто расписал по-другому. Распишу решение с производящими функциями, может, кому-то пригодится. (Это очень мощная техника; за строгостью и теоретическим обоснованием лучше обращаться на маткод.) Не нарушая рекуррентного соотношения, можно положить a_0 = 0. Рассмотрим формальный ряд: G(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... (*) тогда x G(x) = a_0 x + a_1 x^2 + a_2 x^3 + ... (**) x^2 G(x) = a_0 x^2 + a_1 x^3 + ... (***) отсюда вычитая (**) и (***) из (*), имеем: G(x) (1 - x - x^2) = a_0 + (a_1 - a_0)x = 2x то есть G(x) = 2x / (1 - x - x^2). Разлагаем на элементарные дроби: G(x) = (2/sqrt(5)) [ (sqrt(5) - 1) / (sqrt(5) - 1 - 2x) - (sqrt(5) + 1) / (sqrt(5) + 1 + 2x) ] Разложим дроби в бесконечный ряд. Вспоминая ряд для геометрической прогрессии: a / (a - x) = 1 + x/a + x^2/a^2 + ... тут же получаем (P = sqrt(5) - 1, Q = sqrt(5) + 1, y = 2x): G(x) = (2/sqrt(5)) [ ( 1 + y/P + y^2/P^2 + y^3/P^3 + ... ) - ( 1 - y/Q + y^2/Q^2 - y^3/Q^3 - ... ) ] = (положим p = (sqrt(5) - 1)/2, q = -(sqrt(5) + 1)/2, продолжаем) = (2/sqrt(5)) [ ( 1 + x/p + x^2/p^2 + y^3/p^3 + ... ) - ( 1 + x/q + x^2/q^2 + y^3/q^3 - ... ) ]. Собирая коэффициенты слева и справа при x^i, имеем a_i = 2/sqrt(5) (1/p^i - 1/q^i). Заметив, что pq = -1, получим окончательно в более приятном виде a_i = 2/sqrt(5) [ ((sqrt(5) + 1)/2)^i - ((1 - sqrt(5))/2)^i ].

Ответ 2



Надо завести массив от 1 до нужного N и постепенно его заполнять. В i-й ячейке будет написано, сколько вариантов заполнения i клеток. Собрать вариант длины P можно из ...Б + К..., ...К + Б..., либо ...Б/К + С + К/Б... При этом любой из фрагментов может иметь любую длину меньше P. Причём, никогда С не будет на концах строки/подстроки. Достаточно очевидно, что ровно половина вариантов длины i - кончается на Б, ровно половина - на K. Таким образом, имеем внешний цикл от 2 до N по нашему массиву и внутренний цикл по длине левой части. Суммируем, перемножаем, записываем... Например, для правила ...Б + К... будет V[i] += V[j] / 2 * V[i - j] / 2 Upd: V[0] = 0; V[1] = 2; // В одной клетке - либо Б, либо К for (int i = 2; i <= N; i++) { V[i] = 0; for (...) { V[i] += V[j] / 2 * V[i - j] / 2

Как в PHP строку разбить на массив

#php #массивы #регулярные_выражения


Как разбить строку:
|ele1||ele2||ele3||ele4||var5||nubmr|

На массив вида:
[0]=>ele1
[1]=>ele2
[2]=>ele3
[3]=>ele4
[4]=>var5
[5]=>nubmr

как вариант хотелось бы удалить первый и последний элемент строки с помощью preg_replace
(не знаю как если знаете то подскажите)
а потом разбить через explode    


Ответы

Ответ 1



. preg_replace('/^\|(.+)\|$/','$1','|ele1||ele2||ele3||ele4||var5||nubmr|');

Ответ 2



Проще. explode('||', "ele1||ele2||ele3||ele4||var5||nub") И потом удалить из массива

Получить видео VKontakte Api

#вконтакте #ios #vkontakte_api #видео


Привет всем) такая проблемка - не могу получить ссылку на видео.  Есть access_key,
vid, owner_id. Все это я получаю из newsfeed. Причем, на странице документации ВК,
если в поле для проверки запроса вписать просто owner_id, то без проблем выдает весь
список видеозаписей данного пользователя/группы, но если установить videos, то приходит
ответ типа

response: {
count: 1,
items: []
}

т.е., items - пустой. Причем я пробовал и с access_key и без него. 
Кто такое уже делал, подскажите, что у меня не так?    


Ответы

Ответ 1



Все, разобрался. В русской версии документации API неполное описание. Пользуйтесь английской версией!

Ответ 2



Обычно ВК не отдает прямой ссылки на видео Это потому-что используете заголовок запроса "User-Agent", если он пуст то тогда и будут прямые ссылки в files. Сделайте запрос типа: https://api.vk.com/method/video.get?videos=-53956136_169543800&access_token=%access_token% с пустым заголовком "User-Agent", выйдет: { 'response' : [1, { 'duration' : 1452, 'vid' : 169543800, 'views' : 4790, 'owner_id' : -53956136, 'player' : 'https://vk.com/video_ext.php?oid=-53956136&id=169543800&hash=06da65ec2f1a6d00', 'date' : 1408830421, 'link' : 'video-53956136_169543800', 'files' : { 'mp4_240' : 'https://cs543208.vk.me/u222975331/videos/fd8d6c3d4d.240.mp4?extra=d1xg726trlMQIwAZ4X8NTUJRI2kk-uw9TJ66bWZtq_odwiDxYverCALb8PNb_z-zjbPhvX07ftxnZRXZ-li8XiFKJZ_oEJnbrPVPqLrKUiFM9J1FfYFEEm3c5SfRXRDSSU29k7QTkS_7uTxg', 'mp4_720' : 'https://cs543208.vk.me/u222975331/videos/fd8d6c3d4d.720.mp4?extra=d1xg726trlMQIwAZ4X8NTUJRI2kk-uw9TJ66bWZtq_odwiDxYverCALb8PNb_z-zjbPhvX07ftxnZRXZ-li8XiFKJZ_oEJnbrPVPqLrKUiFM9J1FfYFEEm3c5SfRXRDSSU29k7QTkS_7uTxg', 'mp4_360' : 'https://cs543208.vk.me/u222975331/videos/fd8d6c3d4d.360.mp4?extra=d1xg726trlMQIwAZ4X8NTUJRI2kk-uw9TJ66bWZtq_odwiDxYverCALb8PNb_z-zjbPhvX07ftxnZRXZ-li8XiFKJZ_oEJnbrPVPqLrKUiFM9J1FfYFEEm3c5SfRXRDSSU29k7QTkS_7uTxg', 'mp4_480' : 'https://cs543208.vk.me/u222975331/videos/fd8d6c3d4d.480.mp4?extra=d1xg726trlMQIwAZ4X8NTUJRI2kk-uw9TJ66bWZtq_odwiDxYverCALb8PNb_z-zjbPhvX07ftxnZRXZ-li8XiFKJZ_oEJnbrPVPqLrKUiFM9J1FfYFEEm3c5SfRXRDSSU29k7QTkS_7uTxg' }, 'description' : 'Видео предоставлено группой [club53956136|AniZUR Аниме на любой вкус]

Следующая серия: http://vk.com/video-53956136_169543833', 'comments' : 5, 'title' : 'Hunter x Hunter Remake / Хантер x Хантер - 2 сезон 66 серия [Озвучка: Ancord]', 'image' : 'http://cs543208.vk.me/u222975331/video/m_1a4f8d0d.jpg', 'image_medium' : 'http://cs543208.vk.me/u222975331/video/l_7bbad3fc.jpg' } ] } Если нужен постоянный access_token(может быть опасно) вот: https://oauth.vk.com/authorize?client_id=3087106&scope=wall,offline&redirect_uri=http://api.vk.com/blank.html&display=page&response_type=token !Обновлено Новый ВК API теперь требует новый обязательный параметр: версию API: v=5.73(Актуальная на данный момент). И полная ссылка будет выглядеть примерно так: https://api.vk.com/method/video.get?videos=-53956136_169543800&access_token=%access_token%&v=5.73

Ответ 3



смотри, вот такой запрос: https://api.vk.com/method/video.get?v=5.12&videos=71057340_167884774_6e2f5cee5c04b2b898&access_token=myaccesstoken получаю такой ответ: { response = { count = 1; items = ( { comments = 4; date = 1395082963; description = "::::::\U0418\U041d\U0424\U041e\U0420\U041c\U0410\U0426\U0418\U041e\U041d\U041d\U0410\U042f \U0412\U041e\U0419\U041d\U0410:::::::\n:::::http://vkontakte.ru/club4121067:::::"; duration = 64; id = 167884774; "owner_id" = 71057340; "photo_130" = "http://cs540303.vk.me/u12911501/video/s_f1c9b9d6.jpg"; "photo_320" = "http://cs540303.vk.me/u12911501/video/l_074712cb.jpg"; player = "http://vk.com/video_ext.php?oid=71057340&id=167884774&hash=32fa35ec6b845a99"; title = "\U041e\U0442\U0434\U044b\U0445 \U0432 \U041a\U0440\U044b\U043c\U0443 - 2014 \U0423\U043a\U0440\U0430\U0438\U043d\U0430. "; views = 707; } ); }; } Обычно ВК не отдает прямой ссылки на видео, хотя иногда есть исключения (они в словаре files должны быть). В таком случае приходиться пользоваться ссылкой на плеер и открывать ее в браузере.

Ответ 4



Это потому-что используете заголовок запроса "User-Agent", если он пуст то тогда и будут прямые ссылки в files. На данный момент не работает. Доступ к секции "files" возможен лишь при авторизации как доверенное приложение, либо парсингом страницы https://vk.com/dev/video.get

Ответ 5



Возможно дело в owner_id видео. Параметр owner_id можно взять из данных newsfeed.get. То есть owner_id видео может отличаться от source_id поста, которому принадлежит видео, так как может быть перепост видео другой группой или пользователем.

.NET Native и RyuJIT

#c_sharp #cpp #net #net_native


Недавно, прочитав интервью от Джеффри Рихтера, узнал о .NET Native компиляторе, который
превращает код CIL в нативный код, неотличимый от кода после компиляции С++, также
узнал о RyuJIT и появилось несколько вопросов, ответы на которые я не нашел в интернете:

.NET Native и RyuJIT - это одно и то-же? В какой код компилирует RyuJIT?
XAMARIN тоже компилирует в натив, не эти ли компиляторы они используют?
В боксе VisualStudio 2013 уже есть поддержка этих компиляторов? Если есть - как использовать
и как оно действует?, если нет - КАКОГО ЧЕРТА НЕ ВВЕЛИ??
    


Ответы

Ответ 1



о RuyJIT, о том, как его попробовать, можно почитать на хабре. Если очень коротко, то это сильно переписаный код стандартного JIT компилятора из .NET. .NET Native и RyuJIT - это одно и то-же? В какой код компилирует RyuJIT? и нет, и да. .NET Native пытается сделать код для конкретной платформы. RyuJIT - это просто улучшенный компилятор .NET. Умеет ли он делать native код - непонятно. XAMARIN тоже компилирует в натив, не эти ли компиляторы они используют? XAMARIN базируется на проекте Mono (это свободная версия .NET, которая работает на многих платформах, в том числе и на линуксе, достаточно совместима с .NET). Поэтому, короткий ответ на эти два вопроса - нет и (скорее всего) нет. В боксе VisualStudio 2013 уже есть поддержка этих компиляторов? Если есть - как использовать и как оно действует?, если нет - КАКОГО ЧЕРТА НЕ ВВЕЛИ?? в статье на хабре есть описание как ее потестить. Не ввели, потому что похоже только разрабатывается. А .NET Native получается, если использовать nugen (утилита из поставки .Net framework).

Ответ 2



1) Нет. RyuJIT — это улучшенная версия JIT-компилятора, а .NET Native вовсе не JIT. [JIT == just in time, программа компилируется в нативный код во время выполнения. .NET Native компилирует в нативный код на машине разработчика.] 2) Не знаю, не имел дела с Xamarin. Не думаю, что там нативная компиляция, скорее всего, он основан на Mono. 3) Да. Смотрите комментарий @Flammable.

Как монтировать ISO-образы на Windows 7?

#windows #поиск_программ #образ #iso_образ


Многие крупные скачиваемые обновления поставляются в виде образов для болванок -
файлов формата ISO. Прожигать диски, чтобы с них устанавливать обновления, - это пустая
трата расходников, потому что после обновления диски уже не нужны - получается, что
это диски однократного использования. Вопрос в том, как правильно монтировать образы
в Windows, какие для этого существуют встроенные или устанавливаемые инструменты?    


Ответы

Ответ 1



Daemon tools (Lite-версия бесплатна), alcohol и множество других ,есть кстати и утилита от майкрософта, но не помню, как называется... Да и в конце концов можно просто открыть архиватором - 7-zip'ом, например. )

Ответ 2



Давно использую Virtual CloneDrive. Бесплатная, работает хорошо, позволяет создавать несколько виртуальных дисководов и умеет автоматически подключать образ после перезагрузки. Имеется русский язык (и не только). Впрочем, он там не особо нужен.

Ответ 3



Лучше UltraISO не найти. Он не только монтирует, ну и сжимает папки в ISO. А еще плюс такой, скачали .MDF (.mds не качайте, он не нужен), переименовываете в ISO и монтируете! На счет Daemon tools вы должны иметь ввиду, что NOD32 ругается что там вирус, и приходится добавлять исключения вручную. Потому от использования этой программы я навеки отказался. Обратитесь ко мне, дам скачать через свой сервер напрямую!

Ответ 4



XP: Small, Free Way to Use and Mount Images (ISO files) Without Burning Them.В отличии от демона и алкоголя не нужно перегружать комп. Маленькая, простая, шустрая.

Ответ 5



От себя порекомендовал бы https://ru.wikipedia.org/wiki/ImDisk Компактная и многофункциональная утилита. Абсолютно бесплатная и позволяет работать с образами разных форматов. Часто использую ее для эмуляции дискет. Скачать: http://www.ltr-data.se/opencode.html/#ImDisk

Градиент на CSS3

#css3 #css


Здравствуйте, подскажите, пожалуйста, как сделать такой градиент на CSS3, без картинок.
С помощью каких сервисов?
    


Ответы

Ответ 1



* { padding: 0; margin: 0; } div { min-height: 100px; background: #f5f8f9; /* Old browsers */ background: -moz-linear-gradient(left, #f5f8f9 0%, #1d97d3 50%, #0591d5 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, right top, color-stop(0%, #f5f8f9), color-stop(50%, #1d97d3), color-stop(100%, #0591d5)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(left, #f5f8f9 0%, #1d97d3 50%, #0591d5 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(left, #f5f8f9 0%, #1d97d3 50%, #0591d5 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(left, #f5f8f9 0%, #1d97d3 50%, #0591d5 100%); /* IE10+ */ background: linear-gradient(to right, #f5f8f9 0%, #1d97d3 50%, #0591d5 100%); /* W3C */ filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#f5f8f9', endColorstr='#0591d5', GradientType=1); /* IE6-9 */ }
http://jsfiddle.net/6bv5hmrz/ http://www.colorzilla.com/gradient-editor/ вот есть такой сервис

Ответ 2



Да ну нет же! Не с помощью сервисов, а с помощью background-image: #gradient { .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+ background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ background-repeat: repeat-x; filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down } } извините за less, упрощаю себе жизнь немного :)

Доступность сайта одновременно по HTTP и HTTPS

#http #https


Есть сайт, для него установлен бесплатный сертификат для работы HTTPS.

Можно ли коим-то образом сделать сайт доступным одновременно по HTTP и по HTTPS?
    


Ответы

Ответ 1



Да, просто нужно настроить апач (или другой веб-сервер). HTTP работает на 80 порту, а HTTPS работает на 443-м. В апаче необходимо создать 2 виртуальных хоста, один для 80-го порта, 2-й для 443-го. Для этих виртуальных хостов установить одинаковые настройки (какие вам необходимы), кроме этого, для ВХ на 443-м порту необходимо активировать SSLEngine, чтобы иметь возможность соединяться по HTTPS: SSLEngine on #путь к сертификату. SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem #путь к ключу SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

Ответ 2



Добавлю вариант для nginx (из документации): server { listen 80; listen 443 ssl; server_name www.example.com; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key; ... }

Как собрать messenger для Android

#android


Добрый день.
У меня возник вопрос, с чего нужно начать разработку messenger для Аndroid. Как лучше
его сделать. Программирование знаю, но за разработку приложения взялся впервые, поэтому
даже не знаю, как правильно его построить. Подскажите, пожалуйста.    


Ответы

Ответ 1



Для мессендера Вам понадобиться две вещи - клиент и сервер. Можно, конечно, все разработать с нуля, сделать свой мегакрутой протокол и потратить несколько лет на него. Поэтому для начала рекомендую взять готовое - xmpp. Во-первых, получаете готовые сервер - eJabber, openfire и много других. Для андроида есть куча готовых библиотек для работы с xmpp - qsmack, Babbler. Большинство из них предоставляют готовые методы для подключения, отправки сообщений и много другого. Также в наличии документация по протоколу и даже частичный перевод. Наличие готовых клиентов поможет в начальной отладке - ведь для тестов нужно хотя бы два клиента. Сам протокол расширяемый, так что в будущем можно добавить своих штук.

Как сделать генератор случайных чисел?

#javascript


Нужно, чтобы выпадали цифры от 1 до 5 с вероятностью: 
1 = 70%, 
2 = 20%, 
3 = 5%, 
4 = 4%, 
5 = 1%     


Ответы

Ответ 1



Эта задача решается очень просто. function specialRandom() { var r = Math.random() * 100; if (r < 70) { return 1;} else if (r < 90) { return 2;} else if (r < 95) { return 3;} else if (r < 99) { return 4;} else { return 5;} }

Ответ 2



http://jsfiddle.net/kaoq5yv0/3/ Как вариант. Большую часть кода можно убрать, если вы сами будете следить, чтобы сумма интервалов была равна 100%.

Ошибка в setText

#android #java


Если писать так, то нет ошибки
mOtvetTextView.setText(2+2*4 + "ответ");

Если писать так, то ошибка "The operator - is undefined for the argument type(s)
String, double"
mOtvetTextView.setText("ответ" + 2+2*4);

А вообще хотелось бы написать так:                                              
                                

mOtvetTextView.setText("пример" + 2+2*4 + "равен");
    


Ответы

Ответ 1



Я бы не делал так. Я бы создал переменную, в которую записывал результат вычисления. Потом уже формировал вывод. Я считаю, что так лучше и красивее. Проще назвать нельзя, так как на одну строчку больше кода выходит)))) Integer otvet = 2+2*4; mOtvetTextView.setText("Пример " + otvet + " равен."); // Лично мне нравится выносить отдельно всевозможные вычисления, считаю, что так удобнее после редактировать код - нагляднее он смотрится. // Но это дело каждого, поэтому решайте сами, код я Вам предложил. Обновление Чтобы работать с дробной частью, нужно применить double тип переменной. Код я предлагаю следующий: // var = 0.66(6) - 0.66 и 6 в периоде, то есть длинный хвост из "6". double var = 2+2*4/15; // задаем формат для var и выводим в textView. 0.66 в textView. mOtvetTextView.setText(new DecimalFormat("##.##").format(var));

Ответ 2



Странно, у меня все 3 варианта отработали нормально. В любом случае, пишите так, чтоб наверняка: mOtvetTextView.setText("пример" + (2+2*4) + "равен");

Цикл while «Сумма последовательности чисел»

#python #python_3x


Здравствуйте. 
Начал изучать питон, иногда нападают жуткие тупняки. Ряд задач с этим циклом, вроде,
решен и понятен, тут не могу никак понять, как формулировать решение.
Определите сумму всех элементов последовательности, завершающейся числом 0. В этой
и во всех следующих задачах числа, следующие за первым нулем, учитывать не нужно.
def по этому курсу еще не было, не знаю, что это. Т.е. задачу нужно решить, исходя
из того, что материал был по
Занятие 1. Ввод-вывод, арифметические операции
Занятие 2. Условная инструкция
Занятие 3. Операции с целыми и вещественными числами
Занятие 4. Цикл for
Занятие 5. Строки
Занятие 6. Цикл while
Вот просто чего не понял.
i = 0
while int(input()) > 0:
    i += int(input())
print(i)

Но в этом случае суммируются элементы без первого, т.е. в том порядке, как входят,
если делаю
i = 0
a = 0
while int(input()) >0:
    i += 1 
for j in range(0:a):
    a += int(input())
print(a)

то говорит, что закончились числа для ввода. Т.е. в целом я понимаю, что вообще что-то
не то делаю.    


Ответы

Ответ 1



Ошибка в том, что функция input() вызывается в двух местах, нужно вызывать её только в одном месте и использовать одно и то же возвращаемое значение как для проверки на ноль, так и для суммирования: total = 0 # общая сумма while True: # бесконечный цикл n = int(input()) # каждая строка содержит целое число if n == 0: # нашли нуль break # выходим из цикла total += n # суммируем print(total) # печатаем результат Код предполагает, что каждая последовательность завершается нулём. В противном случае нужно ловить EOFError исключение и обрабатывать возвращаемую пустую строку. Чтобы самостоятельно найти ошибку в своём коде, в таких простых случаях, полезно выписать словами, что код делает строчка за строчкой (отладка методом утёнка). Другие способы выразить то же самое для тестов (и для улучшения понимания задачи людьми, которые уже знают Питон, не для прямого использования): import sys from itertools import takewhile print(sum(takewhile(lambda n: n != 0, map(int, sys.stdin)))) Не нулевые целые числа являются истиной в булевом контексте в Питоне, поэтому вместо lambda n: n != 0 можно использовать просто bool (менее читаемый (явный) вариант). Или даже (если каждая строчка содержит только числа, без пробелов): print(sum(map(int, iter(input, '0'))))

Ответ 2



Как-то так (проверял только глазами, вроде все правильно, в любом случае главное - принцип): def sum0(lst): if 0 in lst: return sum(lst[:lst.index(0)]) else: return sum(lst)

Ответ 3



Ну, насколько я понимаю, проходить в цикле элементы, суммируя их, пока значение элемента не будет 0. Если 0 - покидаем цикл.

Шахматный конь, рекурсия, максимумы

#c #алгоритм


Имеется шахматная доска 8х8. Предположим в каждой клетке доски содержится некоторое
количество яблок. Шахматная фигура “конь” может ходить по классическим правилами хода
коня. Оказываясь в очередной клетке, конь собирает все яблоки, которые в ней находятся.
Имеется ограничения на количество ходов. Ваша программа должна принимать на вход следующие
аргументы: максимальное число ходов, имя файла, содержащего схему заполнения шахматной
доски яблоками. Строки в файле соответствуют строкам шахматной доски, строки разделяются
переносами. Числа в строках разделяются пробелами. Ваша программа должна вывести максимально
возможное количество собираемых яблок конем, при заданном ограничении ходов и произвольном
выборе начальной позиции.
Собственно, хотелось бы понять, каким образом/методом следует решать эту задачу.
Сам код мне, конечно, нужен, но думаю и сам смогу написать программу, если пойму её
основную идею.
Была идея решать через жадный алгоритм, передвигаясь в клетку, содержащую в себе
максимально возможное число яблок (сравнивал количество яблок в каждой из клеток, доступных
в данный момент и шел в клетку с максимальным числом), но, как мне кажется, это решение,
мягко говоря, не совсем верное. Задача должна содержать в себе рекурсию. Подайте идею
решения данной
проги или посоветуйте литературы по этой теме, пожалуйста. 
Заранее благодарю! :D    


Ответы

Ответ 1



Думаю, что подобные задачи решаются полным перебором. То есть, для каждой клетки делаем полный перебор ходов. Да, это будет долго, но... Специалисты могут решат задачу другим способом. Шахматная доска для коня - это граф. Кол-во яблок в клетке - это значение в вершине. Задача сводиться к поиску цепочки с максимальной суммой. В теории графов есть много алгоритмов для поиска кратчайшего пути, но думаю, они легко "перевернутся".

Ответ 2



Ну и, помимо упомянутого графа, так же стоит добавить, что Ваш вариант с жадный алгоритмом неверен. Просто потому, что путь 2-1 даст меньше, чем путь 1-9, который будет проигнорирован подобным жадным алгоритмом. Стоит заметить, что конь ходит в любую точку доски за 4-5 ходов, поэтому хороший граф будет очень запутанным в данной задаче и достаточно сложен в построении и анализе. Поэтому, для упрощения можно воспользоваться его частным видом - неориентированным восьминарным (по числу ходов коня) деревом высотой в ограничение ходов коня.

Ответ 3



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

Как в питоне сгенерировать все возможные строки, соответствующие регулярному выражению?

#python #регулярные_выражения


Есть некое регулярное выражение, например, "[a-z][0-9]{3}|[a-z]{3}". Как получить
список всех возможных строк, соответствующих этому выражению? Примерно такой:
['a781', 'b000', 'c476', 'u132', 'd997', 'exe', 'use' и т.д.]
    


Ответы

Ответ 1



Кроме самых простых случаев (без *+), кол-во строк, соотвествующих заданному регулярному выражению, может быть бесконечно. Обратить регулярное выражение достаточно легко, например, re модуль позволяет получить регулярное выражение в виде дерева, обходя которое можно cгенерировать подходящую строку: import re from pprint import pprint regex = "[a-z][0-9]{3}|[a-z]{3}" pprint(re.sre_parse.parse(regex).data) Результат: [('branch', (None, [[('in', [('range', (97, 122))]), ('max_repeat', (3, 3, [('in', [('range', (48, 57))])]))], [('max_repeat', (3, 3, [('in', [('range', (97, 122))])]))]]))] bjmc написал rstr.xeger функцию, которая возвращает (одну, любую) строку, удовлетворяющую заданному regex: import rstr # $ pip install rstr regex = "[a-z][0-9]{3}|[a-z]{3}" print(rstr.xeger(regex)) # print a single string that matches the regex # -> ycu Paul McGuire (pyparsing) упомянул сайт Инвертер регулярных выражений, основанный на invRegex.py примере: from itertools import islice from invRegex import invert # http://pyparsing.wikispaces.com/file/view/invRegex.py regex = "[a-z][0-9]{3}|[a-z]{3}" print("\n".join(islice(invert(regex), 10000))) # print < 10000 matching strings Результат: a000 a001 a002 a003 a004 a005 a006 a007 a008 a009 a010 a011 a012 a013 a014 a015 a016 a017 a018 a019 a020 a021 a022 a023 a024 ... Примеры взяты из ответов к Reversing a regular expression in python.

Ответ 2



Для начала нужно проанализировать выражение с целью выявления, можно ли вообще перебрать все варианты для него. Потом уже составить варианты перебора. Потом посмотреть на замечательный модуль itertools и, собственно, перебрать все нужные варианты. Для указанного регулярного выражения это будет выглядеть примерно вот так: from string import digits, ascii_lowercase from itertools import product # [a-z][0-9]{3} l1 = list( product(ascii_lowercase, digits, digits, digits) ) # [a-z]{3} l2 = list( product(ascii_lowercase, ascii_lowercase, ascii_lowercase ) ) # concatenate l = l1 + l2 # and join inner lists res = [''.join(i) for i in l]

Почему в mysql на дату ставят длину значения 11 вместо 10?

#mysql


Начал оптимизацию бд, посчитал, что в функции time 10 цифр. Когда будет 11, то наступит
2400 год.
Вопрос: почему люди пишут int(11) вместо int(10)?    


Ответы

Ответ 1



Для int`а значение в скобках указывает не на длину значения, не на размер значения, а показывает лишь возможную длину вывода. И только в случае, когда у столбца указан атрибут zerofill Рассмотрим примеры: >> CREATE TABLE test ( id INT, id1 INT(10), id2 INT(11), id3 INT(2), id4 INT(10) ZEROFILL, id5 INT(11) ZEROFILL, id6 INT(2) ZEROFILL ); >> SHOW CREATE TABLE test; CREATE TABLE `test` ( `id` int(11) DEFAULT NULL, `id1` int(10) DEFAULT NULL, `id2` int(11) DEFAULT NULL, `id3` int(2) DEFAULT NULL, `id4` int(10) unsigned zerofill DEFAULT NULL, `id5` int(11) unsigned zerofill DEFAULT NULL, `id6` int(2) unsigned zerofill DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 >> INSERT INTO test VALUES (1, 1, 1, 1, 1, 1, 1), (111, 111, 111, 111, 111, 111, 111); >> SELECT * FROM test; +------+------+------+------+------------+-------------+------+ | id | id1 | id2 | id3 | id4 | id5 | id6 | +------+------+------+------+------------+-------------+------+ | 1 | 1 | 1 | 1 | 0000000001 | 00000000001 | 01 | | 111 | 111 | 111 | 111 | 0000000111 | 00000000111 | 111 | +------+------+------+------+------------+-------------+------+ Для столбцов id, id1, id2, id3 мы не указали атрибут ZEROFILL и в выводе этих столбцов нет никаких различий даже несмотря на то, что размер вывода для этих столбцов отличается. Для столбцов id4, id5, id6 мы указали атрибут ZEROFILL и для каждого столбца свой размер вывода, поэтому если длина строкового представления числа меньше размера вывода (размера, указанного в скобках), то строковое представление числа будет дополнено нулями слева до требуемой длины. Если же длина строкового представления числа больше размера вывода (столбец id6 и его значение 111), то никакого дополнения нулями не происходит Стоит обратить внимание на поле id - размер вывода для него мы не указывали, но при этом в SHOW CREATE TABLE размер все равно проставлен и равен 11. 11 - т.к. столбец id у нас INT, т.е. целое знаковое, согласно документации там может быть значение равное -2147483648, что как раз равно 11 знакам (10 цифр + знак минус) Если же мы опишем столбец как INT UNSIGNED, то отрицательных значений быть не может (знака минус), а максимальное по длине число равно 4294967295, что равняется 10 знакам. Поэтому для INT UNSIGNED в выводе SHOW CREATE TABLE будет указано INT(10)

Обмен данными между вкладками одного сайта

#javascript #html5


Понадобились такие возможности:

узнать список открытых вкладок (в пределах одного домена, разумеется);
обмениваться данными между этими вкладками

Есть ли в современном хтмл5 подобное апи? (кроме cookie и localStorage)    


Ответы

Ответ 1



SharedWorker — очень слабая поддержка LocalConnection — Flash и все вытекающие из этого проблемы BNC Connector — убер-штука, эмуляция TPC/IP через cookie, все браузеры wormhole.js — SharedWorker + LocalStorage, есть возможность узнать кол-во открытых вкладок, поддерживает Master/Slave, а так же CORS (но пока сыро и временно заморожено, есть более важные задачи)

Ответ 2



Возможно, это то, что Вам нужно http://ldalab.ru/post/obmen_soobweniyami_mezhdu_documentami.html

Ошибка ресурсов приложения в android studio

#android #java #android_studio


В проекте Android Studio вдруг выделилась красным цветом буква R.   

  setContentView(R.layout.la_t);

Нашел в Сети, что это может означать ошибку ресурсов.
Но что с этим делать? Как исправить?
Помогите, пожалуйста!    


Ответы

Ответ 1



Обычно помогает Tools -> Android -> Sync Project witch Gradle Files , либо Build -> Clean Project , Rebuild Project

Ответ 2



Да, такое бывает время от времени. Пугаться этого особо не стоит - с вашим проектом все в порядке, если вы его, конечно же, не импортировали. Причины тут разные могут быть: синхронизируйте заново конфиг Gradle (сборщик вашего Android-проекта), убедитесь, что пути до Android SDK не изменились. А если залезете в конфиг проекта, что в контекстном меню, то, скорее всего увидите источник ошибки. Полазьте по Project Structure..., перезапустите ADB, в конце концов. Это, в общем-то, может быть и баг в еще не до конца стабильной Android Studio.

Ответ 3



Попробуйте перезайти в проект, до этого сохранив все. Если не поможет, перейдите во вкладку Build - Clean Project/ Rebuild Project.

перенос слов по дефису

#html #css


Столкнулся с непонятной мне проблемой в css. Хром переносит слова по дефису. Т.е.
фраза: "Проект дома я-455-555", если не влезает в ширину переносит не словом целиком,
а может взять и отрезать именно по дефису: "Проект дома я-455-(перенос)555"


Никакие white-space, типа pre-wrap, pre-line не работают.

Кто-нибудь сталкивался с этой проблемой?
    


Ответы

Ответ 1



Как вариант использовать неразрывный дефис http://jsfiddle.net/nghtpxwc/

Проект дома я‑455‑555

p { white-space: pre-wrap; width: 150px; min-height: 100px; border: 1px solid #000000; padding: 10px; } или так http://jsfiddle.net/jmwqngjc/

Ответ 2



Если это частный случай, то можно посмотреть в сторону тега nobr

Ответ 3



Используйте преобразование дефиса при сохранении в БД. Код для php (между вторыми кавычками стоит неразрывный дефис): $content = str_replace('-', '‑', $content);

Ответ 4



Вы можете убрать перенос совсем. Для этого используйте следующие стили: p{ white-space: nowrap; }

узнать ID li элемента

#javascript


Как при клике на элемент списка можно узнать его id, без использования атрибута 
onclick в li. Только на чистом JS, без Jquery.

  • Red
  • Green
  • Blue


Ответы

Ответ 1



onClick вообще не рекомендуется использовать. Причин достаточно, см. гугл. Чтобы не трогать вообще элементы li, можно делегировать обработчик на ul и с него определять id. Приятная плюшка в том, что теперь можно динамически добавлять/убирать элементы li - код будет работать, тогда как навешивание кучи обработчиков на каждый элемент имеет две плохие стороны: на новые новые элементы действовать не будет и куча ненужных обработчиков, что плохо :) Пример: document.querySelector('#drag').addEventListener('click', function(e){ // Вешаем обработчик клика на UL, не LI var id = e.target.id; // Получили ID, т.к. в e.target содержится элемент по которому кликнули document.querySelector('#test strong').innerHTML = id; // For example }); li{ cursor: pointer; }
  • Red
  • Green
  • Blue
Вы выбрали ничего

Ответ 2



Элементарно: var inputs = document.getElementsByTagName("li"); for (var i = 0; i < inputs.length; i++) { inputs[i].addEventListener("click", myFunction); } function myFunction() { alert(this.id); }

Инициализация View в классе Activity

#android #оптимизация #инициализация


Пытаюсь инициализировать View через метод findViewById(), прямо в классе MainActivity,
чтобы затем, при многократном использовании одного и того же View через onClick, метод
findViewById() не вызывался много раз, но при инициализации прямо в классе MainActivity
приложение вылетает. 

Что я делаю неправильно и как можно один раз инициализировать View для всех последующих
методов?

public class MainActivity extends Activity {    

public View customView = (View) findViewById(R.id.btn);

public void onCustomClick(View view) {
    switch (view.getId()) {
        case R.id.btn:
            customMethod(customView);
            break;
        // и т.д.

    }
}

private void customMethod (View customVar)
{
    // тело метода 
}
}

    


Ответы

Ответ 1



findViewById должно вызываться например в onCreate() методе активити. Т.е. оставьте public View customView; а в onCreate добавьте: customView = (View) findViewById(R.id.btn); UPD. Если копнуть глубже то в Activity у вас в самом начале метода onCreate() есть вызов setContentView(). Это именно этот вызов инициализирует разметку для Activity и только после того как он отработал можно вызывать findViewById(). UPD2. Диаграмма жизненного цикла Activity, спасибо @hardsky за идею, см. http://developer.android.com/training/basics/activity-lifecycle/starting.html Таким образом, исходя из диаграммы, провести инициализацию можно в: onCreate() после setContentView(), в методах onStart() и onResume().

Ответ 2



Ссылки на элементы разметки из .xml будут доступны после того , как этот .xml пройдет инфлейт (inflate) - преобразование из декларативного языка разметки в объекты виджетов. После такого преобразования мы можем получить ссылку на какой либо объект View по его id , заданному в разметке, с помощью метода findViewById(). Следует различать две разных реализации этого метода: Activity.findViewById() - данный метод будет возвращать ссылки на объекты виджетов из разметки только после применения метода активити setContentView() , который свяжет указанную в методе разметку с отображаемым на экране и проведет инфлейт этой разметки в объекты. View.findViewById() - данный метод вернет ссылку на объект виджета по его id , если виджет с таким id присутствует в View. При этом данный View может быть создан динамически - из кода, и тогда ему вообще не требуется инфлейт из XML-разметки , так как мы сразу получаем объекты виджетов, либо пройти инфлейт из XML-разметки отдельно от метода setContentView() , с помощью метода класса LayoutInflater - getLayoutInflater() и метода inflate(). Стоит заметить , что увидеть на экране полученные таким образом View можно будет только после того , как они будут добавлены в разметку , которая указана в методе setContentView(): //контейнер Layout1 присутствует в разметке , подключенной методом setContentView() LinearLayout layout = (LinearLayout) findViewById(R.id.Layout1); //контейнер view1 содержит TextView text1 и будет добавлен в контейнер Layout1 LayoutInflater inflater = getLayoutInflater(); View view1 = inflater.inflate(R.layout.view1, layout, false); TextView text = (TextView) view1.findViewById(R.id.text1); text.setText("Hello"); layout.addView(view1); view1 и text1 изначально не присутствуют в разметке , подключенной методом setContentView() , мы добавляем ее самостоятельно позже , так же устанавливаем значение одному из ее виджетов и только потом переносим в основную разметку , отображаемую на экране Для того, чтобы ссылка на объект (а View это тоже объект в глобальном понимании) была доступна для всех методов в пределах класса (а Activity это тоже класс , в глобальном понимании) необходимо сделать ссылку на этот объект полем класса: public class MainActivity extends Activity { View customView; ... } В коде к такому полю класса следует обращаться только по его имени , без указания класса: //Правильное обращение к полю класса. customView =(View) findViewById(R.id.customView); customView.setText("Hello"); //Неправильное обращение к полю класса. //Данный код создаст ЛОКАЛЬНУЮ переменную с именем, аналогичным имени поля класса , // но она никак не будет связана с полем класса View customView =(View) findViewById(R.id.customView); customView.setText("Hello");

Глобальный фиксированный порядок блокировок

#многопоточность #теория


Как работает задание блокировкам глобального фиксированного порядка? Для чего это нужно?
    


Ответы

Ответ 1



Это способ избежать взаимоблокировок (deadlocks). Работает он просто: всем ресурсам присваиваются уникальные номера. Блокировать ресурсы каждому потоку разрешается только в порядке увеличения номера, снятие блокировки, соответственно, происходит в порядке уменьшения. Полезнее всего данный метод оказывается в ситуациях, когда все ресурсы, для которых понадобится взять блокировку, оказываются известны заранее. Так, в задаче об обедающих философах можно пронумеровать вилки и заставить философов брать вилки в порядке возрастания. Аналогичное решение применимо в задаче о банковских счетах и переводах между ними.

Объясните как работают sticky intent?

#android_sdk


Объясните как работают sticky intent?

Я понимаю что происходит при регистрации BroadcastReceiver, при sendBroadcast и т.д.

Но вот, например, в книге есть такое пример:

IntentFilter batIntentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent battery = context.registerReceiver(null, batIntentFilter);
int status = battery.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = ((status == BatteryManager.BATTERY_STATUS_CHARGING) || (status
== BatteryManager.BATTERY_STATUS_FULL));


Создается IntentFilter, дальше вызывается метод регистрации BroadcastReceiver, но
вместо приемника ему передается null.
Ему должны передаваться BroadcastReceiver и IntentFilter для него - для регистрации.

Но, как я понял из документации, если передать null вернется sticky intent. И что
он делает? Зачем он? Как он применяется?
    


Ответы

Ответ 1



Система может "выбрасывать" sticky и обычные интенты. Обычные интенты срабатывают когда произошло какое то событие, но после регистрации на это события. Sticky интент, в случае если он уже сработал, будет доставлен сразу же после регистрации на это событие, другими словами если какое то событие уже произошло, то после регистрации на него оно сразу же доставится receiver'y. Если в метод registerReceiver передать null в качестве receiver, то в случае со sticky сразу же будет возвращен intent с информацией о событии, но без последующей регистрации для него. В вашем случае ACTION_BATTERY_CHANGED является sticky и поэтому вам будет сразу возвращен intent с информацией и состоянии батареи, но без регистрации на это событие.

PHPStorm вставка <?php ?> тега в html

#phpstorm


Как в PHPStorm6 реализовать вставку в html php тега при вводе: php клавиша
[tab] ? Сейчас выдает .

Нужно:

Получаю:


Ответы

Ответ 1



Выберите пункт меню File -> Settings -> -- IDE Settings -- -> Live Templates -> Add Далее скриншоты из 8-ой версии, но суть абсолютно та же: Заполните данные следующим образом: Abbreviation: php Template Text: Потом определите контекст (HTML): Закройте окно и сохраните изменения. Вот и все. Дополнительно: Live Templates (Snippets) in PhpStorm - PhpStorm Video Tutorial Составлено на основе вопроса на SO: Phpstorm zen coding: insert tag

Помощь в построении регулярного выражения

#java #регулярные_выражения


Как будет выглядеть регулярное выражения для проверки условия
"Строка содержит маленькие латинские буквы, большие латинские буквы и цифры (выполнение
всех трех условий сразу)." Также интересует быстродействие регулярных выражений. Это
быстро? Сильно быстрее, чем посимвольная проверка? Заранее спасибо!
    


Ответы

Ответ 1



Могу предложить такую регулярку: (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]) (?= ... ) — это zero-width positive lookahead assertion, то есть проверка, что строка в впереди удовлетворяет паттерну, при этом проверка не "съедает" символы при проверке, то есть после проверки возвращается на изначальную позицию. Скорее всего, это не самый оптимальный подход: вряд ли движок оптимизирует выражение. При желании можно написать и выражение попроще: ^((?[a-z])|(?[A-Z])|(?[0-9])|.)+(?(a)|(?!))(?(b)|(?!))(?(c)|(?!))$ Или оптимальнее: ^(?>(?:(?[a-z])|(?[A-Z])|(?[0-9])|.)+)(?(a)|(?!))(?(b)|(?!))(?(c)|(?!))$ Если вы охотитесь за производительностью, и какой-то алгоритм тривиально решается без регулярных выражений, то не используйте регулярные выражения. Они заведомо не будут быстрее. RE: ReinRaus Фига себе в джаве тормозной стандартный регекс. :) Перевёл один-в-один в дотнет (плюс оптимизировал вторую регулярку: там был один лишний захват и, как следствие, баг в реализации от @ReinRaus, возникший при замене именованных групп на индексные): using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; namespace RegexPasswordPerf { class Program { static void Main (string[] args) { const int Loops = 30000; const string Text = "AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8"; //const string Text = "AaluhfDnaoufbicbIHBDIHBKJXNdCJKfB1"; var regexes = new Dictionary { { "Discord 1", "^(([a-z])|([A-Z])|([0-9])|.)+(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))$" }, { "Discord 2", "^(?>(?:([a-z])|([A-Z])|([0-9])|.)+)(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))$" }, { "ReinRaus 1", "^(?=(?>[^a-z]*)[a-z])(?=(?>[^A-Z]*)[A-Z])(?=(?>\\D*)\\d)(?>[a-zA-Z0-9]+)$" }, { "ReinRaus 2", "^(?:([a-z])|([A-Z])|([0-9]))(?(1)(?>[a-z]*)(?:([A-Z])|([0-9]))(?(4)(?>[a-zA-Z]*)[0-9]‌​(?>[a-zA-Z0-9]*)$|(?(5)(?>[a-z0-9]*)[A-Z](?>[a-zA-Z0-9]*)$|(?!))))(?(2)(?>[A-Z]*)(?:([a-z])|(‌​[0-9]))(?(6)(?>[a-zA-Z]*)[0-9](?>[a-zA-Z0-9]*)$|(?(7)(?>[A-Z0-9]*)[a-z](?>[a-zA-Z0-9]*)$|(?!)‌​)))(?(3)(?>[0-9]*)(?:([A-Z])|([a-z]))(?(8)(?>[0-9A-Z]*)[a-z](?>[a-zA-Z0-9]*)$|(?(9)(?>[0-9a-z‌​]*)[A-Z](?>[a-zA-Z0-9]*)$|(?!))))" }, }; foreach (var entry in regexes) { var regex = new Regex(entry.Value, RegexOptions.Compiled); bool isCorrect = false; var sw = new Stopwatch(); sw.Start(); for (int i = 0; i < Loops; i++) isCorrect = regex.IsMatch(Text); sw.Stop(); Console.WriteLine("{0}\t{1}\t{2}", entry.Key, sw.ElapsedMilliseconds, isCorrect); } } } } Результат: Discord 1 3378 True Discord 2 2518 True ReinRaus 1 738 True ReinRaus 2 721 True Если строку сделать больше похожей на пароль, то есть короче в несколько раз, то разрыв будет раза в два-три, а не три-четыре: Discord 1 1247 True Discord 2 1037 True ReinRaus 1 650 True ReinRaus 2 383 True Подозреваю, что дотнетовый регекс проседает по производительности из-за того, что сохраняет абсолютно все совпадения. Если посмотреть содержимое результата: string s = string.Join("\n", m.Groups .Cast().Select(g => string.Format("{0}: {1}", g.Index, string.Join(", ", g.Captures .Cast().Select(c => c.Value))))); То можно увидеть это: 0: AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8 1021: a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g 990: A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D 1022: 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8 Это удобно, но не лучшим образом сказывается на производительности — особенно если соревноваться с регулярками, которые все совпадения не сохраняют. Для полного удовлетворения любопытства надо будет найти плюсовые или шарповые регексы, которые построены ради скорости, а не удобства. Если память не изменяет, регулярки из boost по умолчанию такой фигнёй не занимаются, но есть опция для компиляции.

Ответ 2



Вернусь к давно забытой теме, потому что где-то в дебрях чата я выкладывал весьма неплохую регулярку по данному вопросу. Разъяснять по какому принципу построены регулярные выражения не буду - просто приведу сравнение производительности. Код бенчмарка очень прост: import java.util.HashMap; import java.util.Map.Entry; //import java.util.regex.Pattern; import jregex.Pattern; public class test { public static void main(String[] args) { int loops = 30000; long startTime, endTime, diffTime; String key, value; Pattern regex; boolean isCorrect = false; String text = "AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8"; HashMap regexs = getRegexs(); for( Entry entry : regexs.entrySet() ) { key = entry.getKey(); value = entry.getValue(); regex = new Pattern( value ); //regex = Pattern.compile( value ); startTime = System.currentTimeMillis(); for( int i=0; i < loops; i++ ) { isCorrect = regex.matcher( text ).matches(); } endTime = System.currentTimeMillis(); diffTime = endTime - startTime; System.out.println( key + "\t"+ diffTime + "\t" + isCorrect ); } } } Можно увидеть, что я использовал сторонний модуль jregex.Pattern. Он старый, не развивается с 2002 года, но он более соответствует PCRE и дает производительность в 5 раз выше, чем java.util.regex, ну просто мне очень хотелось поддержку условных выражений (?(N)then|else). Этот модуль не поддерживает сверхжадную квантификацию, поэтому пришлось заменить ее на атомарные группировки. Все приведенные ответы требуют наличие условий, поэтому применение данного модуля было вынужденной необходимостью, но у него к сожалению видимо жестко проседает производительность на создании точек возврата, поэтому регулярные выражения @Discord заметно медленнее моих :( Печалька :( Честным был бы замер скорости выражений в PHP или Perl, но в Java поддержка PCRE только из-под палки :( public static HashMap getRegexs () { HashMap result = new HashMap (); result.put( "Discord 1", "^(([a-z])|([A-Z])|([0-9])|.)+(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))$"); result.put( "Discord 2", "^(?>(([a-z])|([A-Z])|([0-9])|.)+)(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))$" ); result.put( "ReinRaus 1", "^(?=(?>[^a-z]*)[a-z])(?=(?>[^A-Z]*)[A-Z])(?=(?>\\D*)\\d)(?>[a-zA-Z0-9]+)$"); result.put( "ReinRaus 2", "^(?:([a-z])|([A-Z])|([0-9]))(?(1)(?>[a-z]*)(?:([A-Z])|([0-9]))(?(4)(?>[a-zA-Z]*)[0-9]‌​(?>[a-zA-Z0-9]*)$|(?(5)(?>[a-z0-9]*)[A-Z](?>[a-zA-Z0-9]*)$|(?!))))(?(2)(?>[A-Z]*)(?:([a-z])|(‌​[0-9]))(?(6)(?>[a-zA-Z]*)[0-9](?>[a-zA-Z0-9]*)$|(?(7)(?>[A-Z0-9]*)[a-z](?>[a-zA-Z0-9]*)$|(?!)‌​)))(?(3)(?>[0-9]*)(?:([A-Z])|([a-z]))(?(8)(?>[0-9A-Z]*)[a-z](?>[a-zA-Z0-9]*)$|(?(9)(?>[0-9a-z‌​]*)[A-Z](?>[a-zA-Z0-9]*)$|(?!))))" ); return result; } Результат: Discord 1 5096 true Discord 2 4718 true ReinRaus 1 72 true ReinRaus 2 62 true Если нужен именно встроенный движок регулярных выражений, то единственным вариантом будет ReinRaus 1. У меня на jregex при цикле 3000000 повторений это выражение дает в среднем время 5500ms, а на java.util.regex в среднем 38000ms, что в 7 раз медленнее.

SQL одним запросом одинаковые аккаунты

#sql


Как выдернуть все аккаунты с одинаковым ip (IP) по логину (login). То есть по условию
подставляя в запрос один логин, получить аккаунты с таким же ip. 
    


Ответы

Ответ 1



примерно так: select id from accounts where ip in (select ip from accounts where login="логин");

Ответ 2



Как-то так: select distinct a.login from logs a inner join logs b on a.ip = b.ip where b.login = @login

Регулярное выражение с набором разрешенных значений

#c_sharp #linux #регулярные_выражения #веб_программирование


Возможно ли в рамках одной регулярки реализовать следующее:

Есть строка в которую пользователь может вводить все что угодно, но есть одно НО!

Есть перечень слов, которые должны употребляться только с определенной цифрой:

20 гв
30 гв
45 гв

Т.е если юзер ввел строчку: 123 qwe 20 гв. Все ок. Совпадение есть

Если юзер вбил 100500 гв 123 qwe, то совпадений нет, так сочетание 100500 гв отсутствует
в списке.
Слова могут идти в произвольном порядке.

Реально ли это сделать в виде 1 регулярки?
    


Ответы

Ответ 1



Хочу пояснить и дополнить ответ Qwertiy. Более правильный ответ: ^((20|30|45)\s+гв\b|(?!\bгв\b).)*$ (20|30|45)\s+гв дает совпадение в строках, где за "20", "30" или "45" следует пустое пространство, а затем - "гв" (?!гв). дает совпадение на одном любом символе, если с него не начинается "гв" \b добавлены, чтобы не было ложных негативных срабатываний, например на словах "гвардия" или "агв" (давайте считать, что это слово). Этому выражению удовлетворяет граница слова (\w+), при этом оно не поглащает символ. Когда мы сочетаем их через комбинатор "или", получившаяся регулярка пытается заглотить оба одновременно: если встречается 2, 3 или 4, он идет по первой ветви, иначе - по второй. При этом если встречается "гв", то строка отвергается (negative lookahead). Наконец, поскольку удовлетворяющих выражению подстрок может быть несколько (в частности, вторая ветвь "или" поглощает только один символ), а также строка может быть пустой, все выражение заключается в ^(…)*$.

Ответ 2



Вот: ^((20|30|45) гв|(?!гв).)*$

Ответ 3



Обязательно ли присутствие числа перед "гв"? Если нет, то ищите все вхождения (?\d+)\w+гв в строке - а потом уже вне регулярки проверяйте найденную группу count по списку разрешенных значений. Если число перед "гв" обязательно, используйте регулярку (?\d*)\w+гв.

Для чего нужен тег <meta-data> в манифесте?

#android


Для чего конкретно нужен тег  в манифесте?
Я понял что для каких-то дополнительных данных. Но можно поподробнее?
Желательно привести пример.
    


Ответы

Ответ 1



Элемент определяет пару "имя-значение" для элемента дополнительных произвольных данных, которыми можно снабдить родительский компонент. Составляющий элемент может содержать любое число элементов . Используют в паре имя/значение для работы с каким-то API, например для использования сервисов Google Play, нужно прописать теги:

Ответ 2



Еще meta-data используется для навигации по back stack'у активити. И, например, в обработчике кнопки назад на actionbar'е (android.R.id.home): if (NavUtils.getParentActivityName(getActivity()) != null) { NavUtils.navigateUpFromSameTask(getActivity()); } Так навигация будет в соответствии с рекомендациями гугля.

Ответ 3



Почитайте здесь: http://blog.iangclifton.com/2010/10/08/using-meta-data-in-an-androidmanifest/ В частности может быть использован для хранения данных которые могут быть необходимы каждому activity в приложении. Это особенно полезно для таких вещей, как ключи API.

Разбор записи в файле задач cron

#linux #bash #cron


Вот строка:

# every hour
0 * * * *  /usr/bin/php  -d memory_limit=500M  -f [wwwpath]cron/cron-hour.php > /dev/null 2>&1


Что я уже нашел:


0 * * * * формат времени из сайта просто видно что означает.
/usr/bin/php указывает обработчик
-d определяет INI php из параметром memory_limit=500M
-f приступает к обработке файла
[wwwpath]cron/cron-hour.php место, откуда берётся файл
> меняем вывод результата


и далее — темнота. Пожалуйста, растолкуйте с 6-го пункта включительно, как дальше
работает интерпретатор?
    


Ответы

Ответ 1



Что за магическое something > /dev/null 2>&1? Как вы уже правильно заметили, > перенаправляет поток. Цитируя статью I/O Redirection: COMMAND_OUTPUT > # Redirect stdout to a file. # Creates the file if not present, otherwise overwrites it. # Перенаправляет stdout в файл # Создает файл, если он не существует, в противном случае, перезаписывает Обратите внимание, > перенаправляет только stdout, но помимо него есть еще два потока: stdin и stderr. Последний нас интересует больше всего. У каждого потока есть свой дескриптор: stdin: 0 stdout: 1 stderr: 2 Соответственно, нам осталось перенаправить куда-нибудь в укромное место поток stderr. Это можно сделать с помощью команды 2>. В данном случае, мы перенаправляем его в поток stdout, что эквивалентно 2>&1: M>&N # "M" is a file descriptor, which defaults to 1, if not set. # "N" is another file descriptor. # "M" - дескриптор файла. По умолчанию - 1 # "N" - дескриптор файла, в который будет организовано перенаправление.

Ответ 2



/usr/bin/php -d memory_limit=500M -f [wwwpath]cron/cron-hour.php > /dev/null 2>&1 Это одна-единственная команда баша. > /dev/null означает, что вывод будет записываться в файл /dev/null (специальный файл, который всегда пуст) - то есть дескриптор STDOUT (или просто 1) будет открытым файлом /dev/null 2>&1 означает, что STDERR (2) будет просто дубликатом STDOUT (1) Короче говоря, и обычный вывод, и вывод ошибок не будет нигде отображаться и не будет никуда записываться.

Можно ли реализовать будильник который сработал бы даже если девайс выключен?

#java #android


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


Ответы

Ответ 1



Некоторые android-устройства могут включаться самостоятельно по будильнику. Например, у Huawei это реализовано, но такую функцию должен реализовать производитель на аппаратном уровне и уровне драйверов системы. Программно, на любом android-устройстве, сторонним разработчиком, реализовать такое невозможно. Если производителем данная функция поддерживается, то устройство будет включаться по будильнику из полностью выключенного состояния без дополнительных действий со стороны стороннего разработчика, как и в случае с включенным устройством, если не поддерживается - повлиять на это сторонний разработчик никак не может.

Ответ 2



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

Ответ 3



Это не возможно. Если устройство выключено, то оно выключено.

Ответ 4



Вы что тут с ума что ли сошли? Если телефон выключен, то нет питания, микросхемы не работают, ось не фунциклирует, программы никакие не работают - это невозможно. А то что после перезагрузки работает будильник это в общем то несложно реализовать. Есть специальный бродкаст который рассылается по окончании перезапуска устройства android.intent.action.BOOT_COMPLETED, для его ловли нужен пермишен: - так что достаточно посадить на этот BroadcastReceiver и все.

Способы чтения xml файла

#c_sharp #xml


Какие способы чтения xml файла существуют в C#, кроме XmlDocument, XmlDocumentXPatch
и XmlReader ? 

update: Мне нужен способ чтения от элемента к элементу, и допустим вывод их на консоль,
при этом xml большие, поэтому первые два способа использовать нельзя.

update2: вот что получилось набросать, проблема в генерации полноценного запроса
Insert, учитывая вложенность, сейчас просто для примера добавляется 1 элемент

while (xml.Read())
    {
       if (xml.NodeType.ToString() == "Element")
             {                
                if (xml.IsEmptyElement != true)
                    {
                        myStack.Push(xml.Name);
                    }
              }
        else if (xml.NodeType.ToString() == "Text")
              {
                string first = myStack.Peek().ToString();
                myStack.Pop();
                string second = myStack.Peek().ToString();
                myStack.Push(first);
                string cmd = "INSERT INTO " + second + " (" + first + ") VALUES ('"
+ xml.Value + "')";
                SqlCommand command = new SqlCommand(cmd, conn);
                command.ExecuteNonQuery();
               }
        else if (xml.NodeType.ToString() == "EndElement")
               {                    
                    myStack.Pop();
               }
    }

    


Ответы

Ответ 1



Способы чтения xml, существующие в .NET: XmlReader XmlDocument XPathDocument XDocument/XElement XmlSerializer DataContractSerializer / SoapFormatter DataSet.ReadXml / DataTable.ReadXml Последние два пункта только для документов определённой структуры, не произвольной. Добавил их для полноты картины. Если файлы большие, то подходит только первый способ. Если не хочется вручную возиться с запоминанием родителей в переменных, то можно применить следующий подход: считываем регулярно повторяющиеся поддеревья в XElement (или другой класс по нраву). Но это применимо только для файлов с повторяющейся структурой. Допустим, имеется следующий файл: Vasya
Mars New Vasyuki
Petya
Earth Urupinsk
Предполагается, что узлов person много. Таким образом, в память загружается лишь одно такое поддерево за раз. using (var xmlReader = XmlReader.Create("file.xml")) { while (xmlReader.Read()) { if (xmlReader.ReadToFollowing("person")) { XmlReader personSubtree = xmlReader.ReadSubtree(); XElement personElement = XElement.Load(personSubtree); // здесь обрабатываем personElement } } }

Стоит ли void метод отмечать как статический?

#java #ооп


Стоит ли в Java void методы помечать как static, если объекты в данном проекте используются
для хранения определенного состояния между вызовами метода, которое в свою очередь
определяется возвращаемым значением?
    


Ответы

Ответ 1



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

Ответ 2



void или нет - вообще не имеет значения. Если хранимое состояние единственно - используйте для хранения объект-синглтон и вызывайте методы на нем. Использовать при этом статические методы, которые будут внутренне обращаться к синглтону теоретически возможно, но делать так не нужно. Если возможных носителей состояния много - создавайте экземпляры, храните состояние в каждом и на нем же вызывайте методы. Пример - класс Random. static нужно использовать только в случае, если состояния нет и экземпляр ни по каким иным причинам не нужен.

Редактирование дата-фрейма, содержащего NA

#циклы #r


Проблема заключается в следующем:

Имеется дата-фрейм, в котором необходимо заменить NA на значение, содержащееся в
предыдущей строчке.

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


Ответы

Ответ 1



В пакете zoo есть функция na.locf которая делает именно это: > df <- data.frame(a=c(1,NA,2,NA,NA), b=c(1.3,NA,2.4,NA,1.1)) > df a b 1 1 1.3 2 NA NA 3 2 2.4 4 NA NA 5 NA 1.1 > na.locf(df) a b 1 1 1.3 2 1 1.3 3 2 2.4 4 2 2.4 5 2 1.1

Порядок запуска потоков

#c_sharp #многопоточность


Всем привет. Подскажите пожалуйста почему идет запуск методов в потоках именно в
таком порядке. Вот код:

using System;
using System.Threading;
class a 
{
    object o = new object();
    public void Test()
    {
        lock (o)
        {
            Console.WriteLine("Start");
            Monitor.Wait(o);
            Console.WriteLine("Stop");
        }
    }
    public void UnLock()
    {
        lock(o)
        Monitor.Pulse(o);
        Console.WriteLine("Unlock");
        for(int x = 0; x <10; x++)
        {
            Thread.Sleep(500);
            Console.WriteLine(x);
        }
    }
}
class b
{
    static void Main()
    {
        a A = new a();
        Thread t = new Thread(A.Test);
        t.Start();
        Thread t1 = new Thread(A.UnLock);
        t1.Start();
    }
}


Я ожидаю что вначале запустится Test, потом написав слово Start он останавливается,
потом запускается метод UnLock и при вызове в нем Pulse() метод Test не должен продолжать
свое дело, так как Pulse() не снимает блокировку с объекта, однако как только вызывается
Pulse(), то несмотря на заблокированный объект в методе Unlock, метод Test начинает
продолжать свое дело. Почему так?? То есть я ожидаю вывод такой 

Start
Unlock
0....9
Stop


а получается

Start
Unlock
Stop
0....9


То есть видно, что метод Pulse говорит о освобождении объекта блокировки, и не смотря
на то что он не освободился по факту, метод Test продолжает свою работу
    


Ответы

Ответ 1



У вас в коде две проблемы. Первая - неправильный отступ. У вас сейчас на самом деле написано следующее: public void UnLock() { lock(o) { Monitor.Pulse(o); } Console.WriteLine("Unlock"); for(int x = 0; x <10; x++) { Thread.Sleep(500); Console.WriteLine(x); } } как указал Pavel Mayorov, вы освобождаете лок сразу же после вызова Pulse. Вторая - само предположение, что второй поток будет запущен позже. Это многопоточность, и нет никаких гарантий что Test начнет выполнятся до UnLock. Даже починив lock, при определенном положении звезд, вы вполне можете получить вывод: Unlock 0....9 Start и зависание на Wait.

Ответ 2



Сразу после вызова Pulse вы освобождаете блокировку, выходя из блока lock(o) - вот первый поток и продолжает работу.

Ответ 3



Из документации: Поток, который в данный момент владеет блокировкой указанного объекта, вызывает этот метод для сообщения следующему в очереди потоку о блокировке. При получении импульса ожидающий поток перемещается в очередь готовности. Когда поток, вызвавший метод Pulse, освобождает блокировку, следующий поток в очереди готовности (который необязательно является потоком, получившим импульс) получает блокировку. Т.е. поскольку вы берете лок только на вызов метода Pulse(), то Test() продолжает работу сразу после того, как освобождается блокировка в Unlock(). Чтобы исправить это, блокировку надо брать на весь код: public void UnLock() { lock(o) { Monitor.Pulse(o); Console.WriteLine("Unlock"); for(int x = 0; x <10; x++) { Thread.Sleep(500); Console.WriteLine(x); } } } (И логичнее будет вызывать Pulse() после цикла.) Но у вас есть еще одно неверное предположение: что метод Test() будет запущен раньше, чем Unlock(). Это необязательно так. Первым может запуститься метод Unlock().

Вопросы по передаче параметров в Java

#java


Здравствуйте! Пересев с С# узнал, что в Java все параметры передаются по значению. 

1) Ссылка ссылается на имеющийся объект, и если до передачи на него ссылалась одна
ссылка, то теперь их две? 

2) Создаётся новый объект в куче, и в пределах блока кода метода работаешь с новосозданным
объектом. При этом после завершения работы метода, изначальный объект остаётся не изменённым?
Созданный объект в методе уже стал на учёте у сборщика мусора?

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

Вот класс:

class MyClass {

String s;

public MyClass(String s) {
    this.s = s;
}

public static void changeField(MyClass other) {
    other.s = "**********";
}

public static void changeRef(MyClass other) {
    other = new MyClass("----------");
} 


Однако почему-то, метод changeField изменяет объект, в то время как changeRef - нет.

    MyClass obj1 = new MyClass("1");
    MyClass obj2 = new MyClass("2");

    MyClass.changeField(obj1);
    MyClass.changeRef(obj2);

    System.out.println(obj1.s);
    System.out.println(obj2.s);


Вывод исполнения программы: 

**************
2 

    


Ответы

Ответ 1



Как вы сказали, в Java передаётся ссылка на объект(за исключением примитивных классов типа int, long and etc.) при этом, под эту ссылку выдается своя память. В методе changeField происходит изменение самого объекта. И вы видите эти изменения за пределами функции. В методе changeRef происходит создание нового экземпляра класса и ссылку на него записываете в ту область памяти которая была выделена для копии ссылки передаваемого объекта. Таким образом вы не меняете исходную ссылку и исходный объект. И да, при передаче объекта в метод, создаётся дополнительная ссылка, т.е. их становится две, как вы написали в вашем вопросе.

Ответ 2



В java нет передачи по ссылке в том смысле, что члены ссылочных типов вы менять можете, а вот сами ссылки, указывающие на экземпляры этих типов - нет. В C# по сути все точно так же: тот же самый код, что вы написали, будет точно так же работать и там. При вызове changeField вы меняете поле экземпляра, но не сам экземпляр. А при вызове changeRef вы пытаетесь изменить саму ссылку, но ссылки остаются неизменными, так как в метод вы передаете только их копии. Отличие между Java и C# будет в том, что C# с помощью ключевых слов ref и out позволяет менять и сами ссылки на объекты. В java этого нет

Ответ 3



Всетаки букварь по Java прочитать стоит. Все передается по значению. В java нет передачи по ссылке. Вот только MyClass obj1 = new MaClass("1") означает что в obj1 лежит не объект а ссылка на него. В тоже время long val = 1l означает что в val храниться 1, но Long val = new Long(1) - уже будет означать что val храниться ссылка на объект типа Long ( не путать с примитивным типом long) Вот тут подробнее https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html Т.е. разница между Reference types и Primitive Types

Удалить уникальные значения из list

#python #list #count


Подобная тема была, но ответ мне не ясен. Почему удаляет из списка не все значения?

data = [1, 2, 3, 4, 5, 6]
for i in data:
     if data.count(i) == 1:
           data.remove(i)
print data


Печатает [2,4,6]
    


Ответы

Ответ 1



Самое главное, что Вы должны запонить - никогда не изменяйте размер массива во время прохождения по нему. Давайте посмотрим, как изменение размера массива влияет на логику цикла: In [3]: l = list(range(6)) In [4]: for x in l: ...: print(x) ...: l.remove(x) ...: 0 2 4 Взглянем на это через призму замечательных ASCII рисунков: +---+---+---+---+---+---+---+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+---+ ^ x Выведем на печать x и удалим его из списка: # print(0) +---+---+---+---+---+---+ | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+ ^ x Переместимся на следующий элемент, как завещал нам великий Guido van Rossum: +---+---+---+---+---+---+ | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+ ^ x Для закрепления, повторим действия: напечатаетаем, удалим и перейдем на следующую итерацию цикла: # print(2) +---+---+---+---+---+ | 1 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+ ^ x (до перехода) +---+---+---+---+---+ | 1 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+ ^ x (после перехода) Очевидно, что изменяя размер массива во время итерирования по нему, на свет рождается еще одно маленькое зло, которое может привести (и приводит) к ошибкам. Самый короткий рабочий эквивалент данного цикла представил @andreymal: data = [x for x in data if data.count(x) > 1] Но у представленных решений есть один общий недостаток - они имеют квадратичную сложность. In [9]: data = list(range(10000)) In [10]: %timeit [x for x in data if data.count(x) > 1] 1 loops, best of 3: 1.66 s per loop Стандартная библиотека Python предоставляет класс Counter, который подсчитает количество вхождений каждого элемента. Таким образом, скорость получится линейной (строго говоря, амортизированно линейной): In [11]: from collections import Counter In [12]: def f(xs): ....: counter = Counter(xs) ....: return [x for x in xs if counter[x] > 1] ....: In [13]: %timeit f(range(10000)) 100 loops, best of 3: 2.33 ms per loop

Ответ 2



Как писали в предыдущем ответе, массив меняется, а индекс не меняется, по сути получается лишнее смещение на следующий элемент при удалении другого элемента. Когда мне лень мудрить, а список чистить надо, я создаю копию массива: for i in tuple(data): if data.count(i) == 1: data.remove(i) (tuple вместо list, потому что он, говорят, производительнее) Когда мне мудрить не лень, я могу завести отдельный список под удаляемые элементы: rm = [] for i in data: if data.count(i) == 1: rm.append(i) for x in rm: data.remove(i) Когда я вспоминаю про существование генераторных выражений, я пишу вариант-однострочник: data = [x for x in data if data.count(x) > 1] Четвёртый известный мне вариант приведён в другом ответе.

Ответ 3



если добавить печать data = [1, 2, 3, 4, 5, 6] for i in data: print i if data.count(i) == 1: data.remove(i) print data получим 1 3 5 видимо в питоне, когда вы удаляете элемент, индекс остается, и вы шагаете через один. т.е. после удаления надо опять с тем же индексом проверять элемент. Проще всего запусть цикл по убыванию индекса вот так удалим всё (мой первый код на питоне :), наверняка можно красивее) data = [1, 2, 3, 4, 5, 6] i = len(data)-1 while i>=0 : if data.count(data[i]) == 1: data.remove(data[i]) i = i-1 print data

Передача интегральной переменной в функцию: по значению или по ссылке?

#cpp


f(int i) vs f(const int& i)

есть ли смысл в f(const int& i) ?
    


Ответы

Ответ 1



В случае int нет никакого - потому что указатель может быть "длинее". Сам инт обычно 32бита, а указатель может быть от 32 до 64 бит (в зависимости от платформы и компилятора). Потестируйте, я думаю, что разницы не будет, возможно, даже второй вариант окажется медленее. Посмотрим код по факту int f1(int a) { return a*a; } int f2(const int &a) { return a*a; } и результат f1(int): # @f1(int) imull %edi, %edi movl %edi, %eax retq f2(int const&): # @f2(int const&) movl (%rdi), %eax imull %eax, %eax retq код очень похожий, но в первом случае компилятор смог подставить значение сразу с регистра. В втором случае он вставляет ещё загрузку с памяти. Нужно конечно смотреть в мануалы, но если бы это был старый процессор виду 286-386, то первый вариант работал бы быстрее. (да, значние в регистр нужно ещё занести, но компилятор может больше творить). А вот если вместо int сложный объект, с сложным конструктором, выигрыш может быть очень существенный. Ведь нужно копировать объекты, освобождать память и многое другое. В моей практике был случай, когда в функцию передавалось два аргумента, которые были просто int a[4]. Сделав указанную выше оптимизацию, я получил около 20 раз ускорение (да, функция была небольшой и очень часто вызывалась).

Ответ 2



Разумеется, разница есть. Имея const int&, кто угодно может сбросить const при помощи const_cast, и поменять переменную. Пример: #include using namespace std; void f1(int x) { x = 5; } void f2(const int& x) { const_cast(x) = 5; } int main() { int i = 0; cout << "start: " << i << endl; f1(i); cout << "after f1: " << i << endl; f2(i); cout << "after f2: " << i << endl; return 0; } Результат: start: 0 after f1: 0 after f2: 5 С передачей копии таких проблем возникнуть не может.

Ответ 3



Передача переменной по ссылке обладает одним особым свойством: если выполнены условия, при которых ссылка привязывается к передаваемому объекту напрямую, то она сохраняет адресную идентичность объекта. Например int i; void foo(const int &ri) { assert(&i == &ri); } int main() { foo(i); } А уж важна ли вам такая адресная идентичность - это уже вам решать. Если не важна, то никакого смысла передавать скалярные объекты по ссылке нет.

Ответ 4



В объявлении f(const int& i); смысла нет, так как обычно ссылки внутренне передаются как указатели на объект, а sizeof( int * ) может превосходить по величине sizeof( int ) и внутри кода функции для обращения к объекту могут использоваться команды косвенного обращения вместо прямого обращения к локальной переменной, коей является параметр функции. Другое дело, если вы пишете шаблонную функцию с параметром вида const T &, где T в общем случае может быть любым типом, а не только целочисленным, то в этом имеется большой смысл, так как вызов по ссылке позволяет избежать создание временного объекта и, соответственно, вызовов конструкторов и деструкторов. Кроме того пользовательские типы могут быть к тому же некопируемыми.:)

Ответ 5



Формально есть. В первом случае параметр передается по значению (с созданием копии). В случае с константной ссылкой, параметр передается собственно по ссылке, и, следовательно, не создается его копия. Фактическое различие проявляется при передаче аргументов, которые не являются POD-типами, так как исчезают затраты на копирование при использовании способа 2.

Запись образа на флэшку

#ubuntu #iso_образ


Есть ISO-образ Windows 10, Ubuntu 14.04 и флешка на 8Gb. Как записать загрузочную
флешку для установки?

То есть нужна рабочая  и простая утилита, где нужно указать ссылку на образ и куда
записать, и не более..) Поиск ничего рабочего не дал.
    


Ответы

Ответ 1



предуведомление о загрузке образов именно ms/windows с usb-устройств. подготовка такого носителя —- это нетривиальный процесс и «уложить» его в рамки одной программы/скрипта — длительная (и неблагодарная) работа, которую, как вы, вероятно, уже обнаружили, до сих пор никто не проделал. см. ниже обновление. копирование образов как таковых копирование образов в операционной системе gnu/linux осуществляется так же, как и копирование любых других файлов — программой cp. в случае с доступом к физическим устройством эта программа, естественно, должна выполняться с root-овыми привилегиями. например, используя sudo: $ sudo cp /путь/к/файлу/с/образом /dev/блочное-устройство и обратная процедура (с блочного устройства в файл): $ sudo cp /dev/блочное-устройство /путь/к/файлу/с/образом все разделы на блочном устройстве, во избежание проблем, должны быть отмонтированы (то, что в графическом интерфейсе для «флэшек» называется как-нибудь вроде «извлечь устройство», применять в данном случае нельзя — usb-устройство будет логически выключено). посмотреть список примонтированных разделов (и уточнить, куда именно они примонтированы) можно программами df или mount, отмонтировать: $ sudo umount /путь/к/разделу/блочного/устройства или $ sudo umount /путь/к/точке/монтирования определить имя нужного блочного устройства можно по-разному. в случае извлекаемого usb-накопителя это проще делать, просмотрев последние записи кольцевого буфера ядра (сразу после подключения устройства) с помощью программы dmesg. примерный вывод: $ dmesg | tail ... [17614.102720] sd 2:0:0:0: [sdb] Attached SCSI removable disk sdb — в данном случае и есть имя блочного устройства вот это имя и надо подставить в команду: $ sudo cp /путь/к/файлу/с/образом /dev/sdb учтите, что сразу же после завершения этой команды ещё не вся буферизованная информация «сброшена» на устройство. для очистки буферов выполните программу: $ sync после этого usb-устройство можно извлекать. обновление по поводу установочных образов ms/windows проблема здесь заключается не в том, «как бы так хитро записать образ», а в том, что стандартная программа установки ms/windows, после запуска, в поиске остальных файлов, необходимых для продолжения установки, будет просматривать лишь носители, отвечающие следующим требованиям: это либо cd/dvd-устройство, либо устройство, подключенное через интерфейс sata/pata и не являющееся съёмным. т.н. «usb-флэшки» подключаются через интерфейс sata, как и традиционные современные «винчестеры», но, в отличие от «винчестеров», рапортуют о том, что они являются съёмными. посмотреть результат такого рапорта в операционной системе gnu/linux можно в файле /sys/block/имя-устройства/removable. например, так сообщает о себе «usb-флэшка» с именем sdf: $ cat /sys/block/sdf/removable 1 а вот так сообщает о себе «винчестер» (sda): $ cat /sys/block/sda/removable 0 кстати, этот рапорт ничуть не изменится, если «винчестер» подключить не напрямую к sata-контроллеру на материнской плате, а, например, к контроллеру usb через «переходник» usb-sata/pata. для «обхода» подобной логики программы-инсталлятора, как я понимаю, существует три пути (отсортированы по степени реалистичности): записать образ на cd/dvd или на «винчестер» изменить микро-программу внутри «usb-флэшки» так, чтобы она рапортовала о своей «несъёмности» (для некоторых устройств это возможно, но нет никаких гарантий, что устройство при этом не превратится в «кирпич») «пропатчить» программу-инсталлятор так, чтобы она искала необходимые файлы и на съёмных sata/pata-носителях

Ответ 2



Воспользуйтесь утилитой dd dd if=ОБРАЗ_ДИСКА.iso of=/dev/ДИСК

Ответ 3



Тебе нужна утилита UNetbootin. Она очень проста в использовании. Скармливаешь ей образ и делаешь запись. Предварительно можно отформатировать.

Ответ 4



С Windows 7 прокатывал такой вариант: Ставим gparted. Форматируем через него флэшку в NTFS. Не забываем установить на флэшку флаг "boot" через управление флагами во всё том же gparted. Монтируем образ с windows. Просто копируем содержимое на флэшку через cp -r или rsync -avrh или drag'n'drop.

Ответ 5



Воспользуйся программой Unetbootin https://unetbootin.github.io/ Никогда не подводила

Как удаленно установить мое тестовое приложение человеку на iphone?

#ios #установка


Есть ли способ удаленно установить мое приложение человеку на iphone не подключая
его к своему маку? 
    


Ответы

Ответ 1



Конечно. Есть такая штука как diawi. UDID девайса должен быть включен в провижн профайл, под которым ты собираешь билд. После этого ты перетягиваешь собранный ипа файл и провижн профайл в окошко diawi, туда где написано drag files here. Затем жмешь кнопку send. Будет сгенерена ссылка, которую ты отправляешь заказчику. Все что ему нужно - открыть эту ссылку у себя на девайсе и приложение будет установлено. Этот вариант подразумевает что заказчику вообще ни к какому маку можно не подключаться. Из твоего текста нельзя однозначно сделать вывод о чьем маке идет речь. Если ты имеешь в виду свой собственный мак (в то время как заказчик может юзать его (заказчика) мак), то можно просто отправить ему билд и он сможет поставить его себе на девайс через iTunes (разумеется, при условии, что UDID девайса включен в провижн). Но diawi, на мой взгляд, самая удобная и быстрая опция.

Ответ 2



Можно устанавливать приложение на любой девайс даже не зная его UDID. Достаточно e-mail владельца девайса. Больше того, о последующих версиях приложения владелец девайса будет своевременно уведомлен и при желании может ее установить. Это TestFlight. Как видите, это официальная технология, и принадлежит Apple. Очень полезная вещь для тестирования. Инструкции по настройке.