Работаю веб-разработчиком (junior). Недавно проходил курс, где попалась олимпиадная задача. Решить ее смог, но решение было далеко от идеала (сверил с решением автора). Ну и задачи подобного формата мне даются сложно. Поможет ли мне олимпиадное программирование в развитии программистких скиллов, если выделю 6-7 часов в неделю? Хипстерские советы типа "Лучше подключись к open source проекту на github" не актуальны. Какую литературу можете посоветовать?
Ответ
Олимпиадное программирование даст вам хорошую эрудицию в алгоритмах и комбинаторике. В целом весьма полезные знания и умения. Задачи, требующие таких знаний, в реальной жизни бывают, но редко, зависит от наукоёмкости предметной области. Сам по себе стиль в котором решаются олимпиадные задачи -- выполнить задачу хоть как, но уложиться в заданное время -- в обычном программировании чаще всего неприемлем: обычно тут нужно решить задачу с должным качеством, включая качество написанного кода, за приемлемое время. Причём важен навык оценки времени на разработку и способность уложиться в заявленное время. Понятность решения часто даже важнее производительности -- потому что если кроме вас в этом никто не разберётся, то всё равно перепишут "как проще". Единственная ситуация в жизни, которая действительно похожа на олимпиадную -- это когда кто-то (чаще всего вы сами) накосячили на проде, и нужно срочно найти решение проблемы и пофиксить. Успешным олимпиадникам на обычных проектах скучно -- мало мест где можно себя проявить, зато море рутины.
У меня есть FrameLayout в который я кладу Button и FrameLayout с целью перекрыть изображением (будущей анимацией, поэтому и FrameLayout) кнопку. Предпросмотр все отображает верно:
Однако, при запуске кнопка перекрывает "FrameLayout":
Вот разметка:
Почему Button перекрывает FrameLayout (хотя с аналогичной... конструкцией, в этой же разметке, такого не было. И как все же расположить FrameLayout поверх Button?
Ответ
Вся соль здесь в таком атрибуте кнопки как android:elevation Кнопка в API > 21 имеет такой атрибут android:stateListAnimator, который по умолчанию ссылается на файл button_state_list_anim_material.xml со следующим содержанием
...
...
Видим что в обычном state_enabled-состоянии атрибут elevation имеет значение @dimen/button_elevation_material, которое равно 2dp Вывод: если мы хотим что бы какое то view перекрывало кнопку, необходимо для него(view!) использовать android:elevation >= 2dp
Когда писал метод в классе, заметил, что компилятор(VS 2015) распознает const и CONST как разные идентификаторы, почему? Есть ли разница? Для чего переопределили const в CONST? пример кода: class A{ public:
void a(CONST int& val);//Будет ругаться, что метод не описан!
}; void A::a(const int& val){}
Ответ
Дело в том, что в исходники часто рассчитаны на компиляцию как в режиме C, так и C++ (например, это так для заголовочных файлов WinAPI). Для этого можно объявить CONST макросом, который раскрывается в const при компиляции C++, и в пустую строку при компиляции C. Это часто используемый в реальности приём. Выдержка из свежего заголовочного файла WinAPI: #ifndef CONST
#define CONST const
#endif
В вашем конкретно случае лучше не заморачиваться, и доопределить CONST #define CONST const
(ну или найти какой-нибудь заголовочный файл, в котором он есть).
Ещё по теме: Зачем Microsoft в WinApi создает свои макросы для имеющихся в языке определений?
Требуется обвернуть картинку индикатором загрузки и менять цвет по мере продвижения индикатора
Ответ
Ну что же, давайте напишем стиль для ProgressBar'а, ведь в конце-концов вы показываете ProgressBar, правильно? Для начала, нам нужен будет конвертер, превращающий угол в геометрию, описывающую наш круглый прогрессбар. Вспомним тригонометрию и в путь! class RoundProgressPathConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
CultureInfo culture)
{
if (values?.Contains(DependencyProperty.UnsetValue) != false)
return DependencyProperty.UnsetValue; var v = (double)values[0]; // значение слайдера
var min = (double)values[1]; // минимальное значение
var max = (double)values[2]; // максимальное var ratio = (v - min) / (max - min); // какую долю окружности закрашивать
var isFull = ratio >= 1; // для случая полной окружности нужна особая обработка
var angleRadians = 2 * Math.PI * ratio;
var angleDegrees = 360 * ratio; // внешний радиус примем за 1, растянем в XAML'е.
var outerR = 1;
// как параметр передадим долю радиуса, которую занимает внутренняя часть
var innerR =
System.Convert.ToDouble(parameter, CultureInfo.InvariantCulture) * outerR;
// вспомогательные штуки: вектор направления вверх
var vector1 = new Vector(0, -1);
// ... и на конечную точку дуги
var vector2 = new Vector(Math.Sin(angleRadians), -Math.Cos(angleRadians));
var center = new Point(); var geo = new StreamGeometry();
geo.FillRule = FillRule.EvenOdd; using (var ctx = geo.Open())
{
Size outerSize = new Size(outerR, outerR),
innerSize = new Size(innerR, innerR); if (!isFull)
{
Point p1 = center + vector1 * outerR, p2 = center + vector2 * outerR,
p3 = center + vector2 * innerR, p4 = center + vector1 * innerR; ctx.BeginFigure(p1, isFilled: true, isClosed: true);
ctx.ArcTo(p2, outerSize, angleDegrees, isLargeArc: angleDegrees > 180,
sweepDirection: SweepDirection.Clockwise, isStroked: true,
isSmoothJoin: false);
ctx.LineTo(p3, isStroked: true, isSmoothJoin: false);
ctx.ArcTo(p4, innerSize, -angleDegrees, isLargeArc: angleDegrees > 180,
sweepDirection: SweepDirection.Counterclockwise, isStroked: true,
isSmoothJoin: false); Point diag1 = new Point(-outerR, -outerR),
diag2 = new Point(outerR, outerR);
ctx.BeginFigure(diag1, isFilled: false, isClosed: false);
ctx.LineTo(diag2, isStroked: false, isSmoothJoin: false);
}
else
{
Point p1 = center + vector1 * outerR, p2 = center - vector1 * outerR,
p3 = center + vector1 * innerR, p4 = center - vector1 * innerR; ctx.BeginFigure(p1, isFilled: true, isClosed: true);
ctx.ArcTo(p2, outerSize, 180, isLargeArc: false,
sweepDirection: SweepDirection.Clockwise, isStroked: true,
isSmoothJoin: false);
ctx.ArcTo(p1, outerSize, 180, isLargeArc: false,
sweepDirection: SweepDirection.Clockwise, isStroked: true,
isSmoothJoin: false);
ctx.BeginFigure(p3, isFilled: true, isClosed: true);
ctx.ArcTo(p4, innerSize, 180, isLargeArc: false,
sweepDirection: SweepDirection.Clockwise, isStroked: true,
isSmoothJoin: false);
ctx.ArcTo(p3, innerSize, 180, isLargeArc: false,
sweepDirection: SweepDirection.Clockwise, isStroked: true,
isSmoothJoin: false);
}
} geo.Freeze();
return geo;
} public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
CultureInfo culture)
{
throw new NotSupportedException();
}
}
Окей, конвертер есть, теперь нам нужен сам стиль. Он несложен, единственный интересный пункт — состояние Indeterminate
Отлично, нам теперь нужно поменять цвета на кастомные, и можно запускать. Обыкновенный:
На данный вопрос уже ответили:
Алгоритм для преобразования диапазона номеров в регулярное выражение
3 ответа
Нужно задать регулярное выражение для диапазона чисел от 1 до 32. Если число больше или меньше нужно возвращать false.
Ответ
Для проверки того, что значение находится в определенном диапазоне лучше привести его к числу и затем проверить. var v = parseInt(value);
if(v>=1 && v=<32)
return true;
return false;
Если очень хочется использовать регулярное выражение, можно использовать следующее /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)$/
Переношу 27тб с одного сервера на другой по ssh: scp -r /home/ root@192.168.0.2:/home2/
Консоль открываю в мозиле (FireSSH), при закрытии вкладки с консолью копирование обрывается, как продолжить копирование с закрытым терминалом?
Ответ
Откройте xterm (или другой терминал) дайте команду в фоновом режиме scp -r /home/ root@192.168.0.2:/home2/ &
Сам вопрос в __DIR__, эта константа указывает на на директорию в которой находится что ?
Ответ
Это директория того файла, в котором в данный момент исполняется код: /var/www/test-app/index.php:
/var/www/test-app/subdir/sub-test.php: __FILE__ аналогичным образом вернет вам путь до исполняемого в данный момент файла (т.е. basename(__FILE__) === __DIR__)
Здравствуйте! У меня такая проблема, когда захожу в File->Project Structure->Project там стоит Gradle Version 2.10, но когда набираю команду в терминале gradle --version то показывает версию 1.4 и Gradle работает именно с этой версией(1.4). В build.gradle прописано
classpath 'com.android.tools.build:gradle:2.0.0'.
Как мне обновить версию Gradle?
Ответ
Команда gradle --version выводит версию градла установленного в системе, при сборке проекта же обычно используется так называемый gradle wrapper, именно его версию вы увидели на странице File->Project Structure->Project. Для работы с ним из консоли перейдите в корневую папку проекта и используйте вместо команды gradle команду gradlew (или если у вас Mac OS или Linux, то ./gradlew).
Есть цикл который выводит из БД инфу. Выводит по очереди.
В одном из полей есть ключевая метка в после, до которой инфу выводить не нужно, а после нее нужно. Чтобы узнать номер этой записи нужно сделать цикл с проверкой положения этой метки и только после этого сделать цикл вывода данных. Метка стоит только в одной записи. И все что до этой записи не нужно выводить.
При простом условии получается что я могу вывести только то что до метки.
И метка может быть а может и не быть Возможноли оптимизировать код чтобы не было двух циклов прохода по выборке из БД?
Ответ
Можно попробовать накапливать информацию для вывода в некоторую переменную до попадания на метку, а после попадания на метку (если таковая будет) очищать значение этой переменной, а уже после окончания цикла выводить накопленную информацию. Схематичный пример (за основу взят сэмпл от @u_mulder ): $output = '';
foreach ($ar as $item) {
if ($item['metka'] == 1) {
$output = '';
}
$output .= $item['value'];
}
echo $output;
Можно это дело вынести в отдельную функцию/метод: function getOutputString(array $data, callable $func, $tagKey = 'metka', $tagValue = 1) {
$output = '';
foreach ($data as $row) {
if ($row[$tagKey] == $tagValue) {
$output = '';
}
$output .= $func($item);
}
return $output;
}
Пример вызова: $ar = [
['metka' => 0, 'value' => 2],
['metka' => 1, 'value' => 3],
['metka' => 0, 'value' => 4],
]; $output = getOutputString($ar, function($row) { return $row['value'];} ); // output: 34
Не могу понять почему у меня в примере ниже результат округляется (ответ 0.0, а не 0.1) public static double addTenPercent(int i) {
double x = i/100;
return x;
} public static void main(String[] args) {
System.out.println(addTenPercent(10));
}
Ответ
Потому что при целочисленном деление результат округляется вниз к целому числу. Нужно написать double(i)/100 или i/100.0
У меня есть бегущая строка с логотипами, но к моменту завершения первого цикла и начала второго, анимация дёргается и встаёт в исходное положение. Не понимаю, как решить эту проблему. Бегущая строка должна быть сделана без использования js и должна быть резиновой.
Javascript крайний вариант. Вот ссылка на мою бегущую строку
Ответ
Прошло много времени с момента публикации вопроса, а я так и не написал решение. Решения оказалось костлявым. Исходя из комментариев пользователя @Утка было решено дублировать список и подогнать параметры анимации так, чтобы новый запуск анимации происходил ровно в тот момент, когда выезжает дубль. Все это с фиксированной шириной списка.
.header_mid {
height: 100px;
}
.header_mid .logo_slide {
padding: 25px 0;
height: 50px;
overflow: hidden;
position: relative;
width:100%;
margin: auto;
}
.loop, .loop-clone {
display: block;
-width: 200%;
width:1510px;
height: 50px;
position: absolute;
overflow: hidden;
}
.loop {
animation: marquee 60s linear infinite;
}
.loop-clone {
animation: marquee-clone 60s linear infinite;
}
.header_mid .logo_slide .logo_item {
height: 50px;
padding: 0 20px;
float: left;
}
@keyframes marquee {
0% { left: 0; }
50% { left: -1510px; }
50.001% { left: 1510px; }
100% { left: 0; }
}
@keyframes marquee-clone {
0% { left: 1510px; }
50% { left: 0; }
100% { left: -1510px; }
}
.header_mid .logo_slide:hover ul,.header_mid .logo_slide .loop-clone ul {
animation-play-state: paused;
}
Я опробовал в интернете множество примеров,но они не показывают на практике,разницу работы одного и того-же кода с применением Volatile и без.Можно ли на персональном компьютере осуществить это,или разницу можно увидеть только при работе сервера с множеством клиентов,которые одновременно используют и изменяют одну и туже переменную через разные потоки?
Ответ
Ну вот вам пример. class Program
{
static bool finish = false; static void Main(string[] args)
{
new Thread(ThreadProc).Start();
int x = 0;
while (!finish)
{
x++;
}
} static void ThreadProc()
{
Thread.Sleep(1000);
finish = true;
}
}
Откомпилируйте Release, запустите из командной строки (не из Visual Studio), увидите, что программа не завершается. Поменяйте код на такой: class Program
{
static bool finish = false; static void Main(string[] args)
{
new Thread(ThreadProc).Start();
int x = 0;
while (!Volatile.Read(ref finish)) // while (!finish)
{
x++;
}
} static void ThreadProc()
{
Thread.Sleep(1000);
Volatile.Write(ref finish, true); // finish = true;
}
}
— этот код будет завершаться. Идея примера честно украдена из ответа Marc Gravell
Пояснение. Многопоточные проблемы с обновлением данных между потоками возникают не только из-за оптимизации на уровне процессора (вид разных процессоров многопроцессорной системы на оперативную память может быть различным), а и из-за оптимизаций компилятора, который имеет право (это важно!) переставлять операции, если только смысл кода в каждом отдельном потоке не меняется. В обычном случае х86-системы с достаточно сильной моделью памяти процессор таких трюков почти не делает, так что проблемы нам с вами видны не так часто, в отличие от программистов на ARM, например. А вот оптимизации компилятора, наоборот, становятся всё агрессивнее и агрессивнее, хотя и в рамках стандарта языка. Право компилятора на изменение внутреннего смысла кода известно как as-if rule: компилятор может производить любой код, если только его побочные эффекты в каждом отдельном потоке оставались те же и в том же порядке. В частности, компилятор имеет право выбросить повторное чтение переменной, если он видит, что она в данном потоке не меняется. Однако некоторые операции (например, Volatile.Read/Write, lock, Thread.Start/Join и т. п.) являются критическими точками, и оптимизации проводятся лишь в блоках между такими точками. В нашем случае оптимизатор смог понять, что переменная finish с точки зрения основного потока не меняется, и выкинул повторное чтение. Имел на это полное право. Когда мы добавили Volatile-операции, то компилятор более не имел права не перечитывать переменную, так что изменения были «замечены».
Ссылки на C# Language Specification (раздел 3.10):
Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. [...] The execution environment is free to change the order of execution of a C# program, subject to the following constraints:
Data dependence is preserved within a thread of execution. That is, the value of each variable is computed as if all statements in the thread were executed in original program order.
Initialization ordering rules are preserved (§10.5.4 and §10.5.5).
The ordering of side effects is preserved with respect to volatile reads
and writes (§10.5.3). [...]
(раздел 10.5.3):
For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the lock-statement (§8.12). These optimizations can be performed by the compiler, by the run-time system, or by hardware.
Установил новую тему для Sublime Text 3 только ради иконок файлов в Sidebar. Но на деле оказалось всё не так радужно.
Как должно быть:
Как у меня:
Да и иконка .sass не та:
То есть Sublime Text не понимает эти типы файлов. И во всех темах есть этот косяк. Главный трабл в том что я специально скачал чистую portable версию, и даже в ней не работает. Да и вообще есть несоответствия с многими иконками. В чём может быть проблема?
Ответ
Во-первых, скачаем выбранную Вами Material Theme, перейдём в папку icons и посмотрим, какая иконка соответствует JavaScript.
Такая, как на Вашем скриншоте. В истории коммитов копаться неохота, однако предположу, что девелоперы сменили иконку, забыв отразить это в скриншотах на заглавной. Если Вам не нравятся предлагаемые разработчиками тем, можете установить вручную в качестве иконки для используемых Вами языков программирования/разметки и прочих файлов любое изображение. Для начала переместим требуемые изображения в какую-нибудь папку. Ссылки на некоторые наборы иконок выложены в данном треде на форуме Sublime Text, мы воспользуемся файлами из Material Theme, пусть для Sass там выбрана на мой взгляд неудачная иконка. Preferences → Browse Paskages... → User. Создаём папку Theme - Default, если она ещё не создана. Название для папки не я придумал, оно обычно используется. Копируем туда всё — или только изображения, которые пригодятся, — из папки icons Material Theme. Preferences → Browse Paskages... → User → Theme - Default → создаём папку Preferences, в которой будут располагаться файлы, о которых зайдёт речь ниже. В один всё у меня вместить не получается, придётся с каждой иконкой связывать отдельный файл с расширением tmPreferences
Ruby В новый файл Ruby.tmPreferences вставляем XML-конструкцию ниже, и сохраняем его: scopesource.rubysettingsiconTheme - Default/file_type_ruby Между вторыми тегами указывается путь к файлу иконки и его имя без расширения.
Sass Предположу, что Вы получили неудовлетворительные результаты, поскольку не подключили отсутствующий по умолчанию в сборке Sublime Text 3 синтаксис Sass. Через Package Control устанавливаем плагин, который в Package Control (имена плагинов в репозиториях, на сайте Package Control и самом Package Control могут отличаться) называется просто Sass Теперь можно связывать sass-файлы с иконками. Создаём файл Sass.tmPreferences и вставляем в него код. scopesource.sasssettingsiconTheme - Default/file_type_sass
Markdown Здесь между первыми тегами недостаточно по аналогии вписать source.markdown или source.md, и такое может случиться для других языков разметки/программирования. Потребуется вставить «область видимости», scope. Как её получить, я очень подробно расписал в данном ответе. Итак, достаём область видимости:
Сколько бы записей в ней не содержалось, нас интересует только первая, text.html.markdown.gfm, которую мы и вставляем в файл Markdown.tmPreferences scopetext.html.markdown.gfmsettingsiconTheme - Default/file_type_markdown
Чтобы не вставлять код каждый раз вручную, рекомендую скачать набор из 70 tm.Preferences файлов для распространённых компьютерных языков
Изображения К примеру, у бинарных, исполняемых файлов или картинок области видимости посмотреть не получится. Чтобы изменить им иконки, необходимо добавить файлы со следующими названиями в папку, где лежит файл активной темы с расширением tmTheme, у меня он располагается по пути Preferences → Browse Paskages... → User file_type_binary.png
file_type_default.png
file_type_image.png
file_type_markup.png
file_type_source.png
file_type_text.png
Из названий понятно для чего они предназначены. Напротив наших изображений теперь будет стоять иконка с названием file_type_image.png
Если сделали всё по данной инструкции, у файлов с соответствующими расширениями в сайдбаре должны появиться вот такие иконки.
Буквально во всех темах, которые мне доводилось увидеть, за редким исключением используются одни и те же иконки. В светлых темах многие из них плохо видны, допустим, тот же оранжевый значок JS на жёлтом фоне.
А иконки, взятые со сторонних сайтов, выглядят не очень красиво. Легко сменить цвета самому можно, например, в GIMP при помощи функции Hue-Saturation. Открываем в этом графическом редакторе файл иконки → Tools → Color Tools → Hue-Saturation, и двигаем слайдеры, — изменение цвета достигается перемещением ползунка Hue
После того, как подобрали колор, яркость и насыщенность, File → Overwrite file_type_%Ваш тип файла%.png
Примеры изменённых мной таким образом иконок: file_type_js.png
file_type_markdown.png
file_type_source.png
file_type_yaml.png
Возможные баги Если вы скачали новую тему или схему, вне зависимости от того, будете ли использовать её или нет, иконки в сайдбаре могут пропасть. В консоли при этом выдаётся примерно следующая ошибка: Errors parsing theme:
Rule is missing a class name
Unable to decode Packages/User/Theme - Default/arrow_down_over.png
pre session restore time: 0.3078
Устраняется проблема в 2 шага:
Ctrl+Shift+P → Package Control: Remove Package → выбираем нашу тему/цветовую схему и удаляем её. Можно сообщить о проблеме разработчику темы/схемы.
У меня портились файлы с расширением tm.Preferences, о которых говорилось выше. Вместо icons/file_type_ruby появлялись кракозябры.
Откройте любой tm.Preferences файл, посмотрите, есть ли там какие-то кракозябры, и если да, то сделайте массовую замену кракозябр на корректные символы в папке, где хранятся tm.Preferences файлы, с помощью поиска Ctrl+Shift+F После данных действий иконки вновь появлялись в моём сайдбаре.
Всем доброго времени суток. Есть телефон, из которого я хотел бы сделать видео-регистратор для моего автомобиля. Програмку то написал, которая будет видео записывать, сохранять и т.д. Но как сделать так, чтобы телефон включался при подключении USB-зарядки, провод которой вставлен в розетку 220B? ROOT доступ полный. Модель телефона - ZTE Blade Q Lux 3G PRO. Android 4.4.2. В интернете читал статьи как это сделать на телефонах Samsung. Как сказано тут в одном из ответов, необходимо изменить содержимое файлов /system/bin/playlpm или /system/bin/lpm, но ни того, ни другого файла в моём телефоне не существует. Насколько я понял принцип, надо найти файл, который запускает анимацию батарейки
и добавить строчки включения системы:
#!/system/bin/sh
/system/bin/reboot
Пробовал менять всё содержимое на эти строки в следующих файлах:
/system/bin/bootanimation
/system/bin/ipod
/system/bin/chcon
Безрезультатно. Может какие-то другие файлы надо изменить? Или вообще в другой папке копаться надо? Подскажите.
Когда попробовал проделать такой трюк с файлом /system/bin/chcon у меня перестала работать кнопка отключения дисплея. То есть, короче, как я включил телефон, так дисплей и работает, не отключается и не реагирует на кнопку выключения. Только после восстановления прежнего файла всё стало нормально после перезагрузки телефона. Так что делаю вывод, что автоматическое включение реализовать возможно. Каждый системный файл действительно запускает скрипты, каждый свой, и отвечает каждый сам за себя. Необходимо лишь понять где нужный файл анимации заряда батареи телефона и где в нём именно надо вписать команду включения.
Ответ
Для того, чтобы телефон запускался при подключении зарядки необходимо выполнить следующие действия.
Скачать и установить на компьютер программу Adb Run. Она необходима для установки соединения с телефоном по USB-проводу.
Скачать и установить на компьютер программу Bootimg. Она необходима для редактирования файла boot.img прошивки телефона. Патч программы должен быть C:\Users\Admin\
Скачать прошивку (ZIP-архив) на компьютер. Из архива достать файл boot.img и положить в папку с программой Bootimg. Открыть системную консоль (Меню пуск -> cmd). Ввести следующую команду: bootimg --unpack-bootimg
Открыть создавшуюся папку initrd, найти в ней файлы init.rc и init.charging.rc. Открыть их. В каждом из них находим строки: service ipod /system/bin/ipod
user root
group root
и после них ниже пишем: class_start core
class_start main
class_start default
Сохраняем и закрываем оба файла. Возвращаемся в консоль. Пишем следующую команду: bootimg --repack-bootimg
Запускаем программу Adb Run. По умолчанию она устанавливается в C:\adb\.
Выбираем пункт 5, затем 0. Телефон должен войти в режим Fastboot. Затем выбираем пункт 1, и затем 1. В консоли должны отобразится как минимум две строки: List of devices attached
0123456789ABCDEF device
Если вы видите только это: List of devices attached
то у Вас могут быть следующие ошибки:
Не включена отладка USB в режиме разработчика
Некорректно подключён USB-провод или, возможно, повреждён
В диспетчере устройств (Правой кнопкой мыши по ярлыку "Мой компьютер"; Свойства; Диспетчер устройств) телефон отображается как неизвестное устройство, например, как на скриншоте здесь
Затем выбираем пункт 5, затем 0. Ждём, когда на экране телефона появится надпись FASTBOOT mode.. или что-то наподобие. Выбираем пункт 7, затем 1, и затем пишем: fastboot flash boot C:\Users\Admin\boot-new.img
Ждём, когда в консоли появится надпись Done... в конце в случае успешной установки boot.img. Затем опять пишем в консоли: fastboot reboot
Закрываем программу Adb Run (консоль). Отключаем телефон от компьютера. После загрузки телефона выключаем его. Подключаем телефон к зарядке 220В, и, в течение 10 секунд телефон сам включится. На этом всё готово. Если у Вас произошли какие-то ошибки или что-то пошло не так, я прошу написать в комментариях. Буду рад помочь!
Я хочу ещё дать людям совет: Если с первой попытки выполнить процедуру не получилось по какой-либо причине, попробуйте ещё несколько раз внимательно выполнить все выше перечисленные действия.
Если версия Android - 4.4 и выше, то могут возникнуть ошибки и, возможно, ничего не получится. Как мне, например, ответила поддержка корпорации ZTE на вопрос "возможно ли хоть как-то реализовать автовключение телефона при..." мне ответили, что видите ли на данном лаунчере такая функция недоступна. И я понял, что решить проблему можно лишь откатом версии Android с 4.4 на 4.2.
Суть в следующем, допустим этот текст находится в div - привет привет привет
привет @привет привет
как узнать позицию от левого верхнего угла div-a, top и left знака "@" в пикселях?
Ответ
На основе ответа на английский вопрос можно узнавать текущее положение курсора, при вводе проверять что именно ввели, если ввели нужны символ - получать координаты курсора и показывать по ним попап. При клике так же проверять координаты курсора и вычислять нужно ли показывать попап. В примере ниже попап показывается, если курсор не далее чем в 5 позициях правее символа @ Пример очень простой, и возможно потребует доработок для использования.
var popup = document.querySelector('#popup');
function getCurrentRange() {
var range = window.getSelection().getRangeAt(0).cloneRange();
range.setStart(range.startContainer, Math.max(0, range.startOffset - 1));
return range;
}
function showPopupAt(range, distance) {
range.setStart(range.startContainer, Math.max(0, range.startOffset - (distance || 0)));
range.setEnd(range.startContainer, range.startOffset + 1);
var rect = range.getBoundingClientRect();
popup.style.display = 'block';
popup.style.left = rect.left + 'px';
popup.style.top = rect.bottom + 'px';
}
function hidePopup() {
popup.style.display = 'none';
}
function toggleByDistance(range) {
var prev = range.startContainer.textContent.lastIndexOf('@', range.startOffset);
var distance = prev != -1 ? range.startOffset - prev : -1;
if (distance < 0 || distance > 5) { //for example
hidePopup();
} else {
showPopupAt(range, distance);
}
}
document.querySelector('[contenteditable]').addEventListener('keyup', function(e) {
var range = getCurrentRange()
if (e.key == '@') {
showPopupAt(range);
} else {
toggleByDistance(range);
}
});
document.querySelector('[contenteditable]').addEventListener('click', function(e) {
toggleByDistance(getCurrentRange());
});
[contenteditable] {
border: 1px solid lightgray;
width: 200px;
height: 200px;
word-wrap: break-word;
white-space: pre-wrap;
}
#popup {
display: none;
position: absolute;
border: 1px solid lightgray;
box-shadow: 2px 2px 3px lightgray;
left: 0;
top: 0;
background-color: white;
}
Хочу сделать кнопку поделится. Когда пользователь будет нажимать на неё, должно высвечиваться следующие. Как это сделать? Также хочется, что бы был определенный тест, например
Приложение name, скачивай от сюда - ссылка.
Ответ
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Приложение name, скачивай от сюда - ссылка");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent,"Поделиться"));
С использованием jQuery $('.td-for-content [align="center"]').remove();
На чистом JS с использованием querySelector var elements = document.querySelectorAll('.td-for-content [align="center"]');
for(var i = 0; i < elements.length; i++){
elements[i].parentNode.removeChild(elements[i]);
}
На чистом JS oldschool var elements = document.getElementsByClassName('td-for-content');
for(var i = 0; i < elements.length; i++){
var childrens = elements[i].getElementsByTagName('div');
for(var j = 0; j < childrens.length; j++){
if(childrens[j].getAttribute('align') === 'center')
childrens[j].parentNode.removeChild(childrens[j]);
}
}
Здравствуйте. Я все пытаюсь реализовать добавление в избранное.
Что у меня на данный момент есть. Список ListView который загружает данные из ресурса string.xml. Обработчик нажатия - при нажатии на пункт списка открывается второе Активити с полным текстом. Также во втором Активити есть кнопка, при нажатии на которую сохраняется с помощью SharedPreferences, номер позиции ListView. В первом Активити сверху есть кнопка избранное при нажатии на которую будут оставаться в активити только те пункты которые добавил в избранное. Так вот я нажал на заголовок списка, открылось второе активити, далее нажимаю на кнопку, сохраняется номер позиции, возвращаюсь в первое активити, теперь нажимаю на кнопку избранное получаю из SharedPreferences, номер позиции. Вопрос как теперь отфильтровать ListView, что бы в списки были только те пункты которые были сохранены в SharedPreferences? Ну и второй вопрос как в SharedPreferences, сохранять несколько пунктов, при нажатии на кнопку. Не знаю правильной ли я вообще пошел дорогой, может это как-то по другому можно было реализовать. Код первого активити со списком public class MainActivity extends AppCompatActivity { ListView listView; // переменная, представляющая экземпляр класса SharedPreferences
SharedPreferences mSettings; // это будет именем файла настроек
public static final String APP_PREFERENCES = "mysettings";
// имя кота
public static final String APP_PREFERENCES_NAME = "Nickname"; TextView tvInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); // получаем экземпляр элемента ListView
listView = (ListView)findViewById(R.id.listView); // инициализирем эту переменную
// в скобках - название вашего файла и стандартное разрешение
mSettings = getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
tvInfo = (TextView)findViewById(R.id.tvInfo); // определяем массив типа String
// заголовок
final String[] catnames = getResources().getStringArray(R.array.cat_names); // два списка которые откроются во втором активити final String[] catnames2 = getResources().getStringArray(R.array.cat_names2);
final String[] catnames3 = getResources().getStringArray(R.array.cat_names3); // используем адаптер данных
final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item, catnames); listView.setAdapter(adapter); // массив количество элементов
final int[] mice = new int [catnames.length]; listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View itemClicked, int position,long id) {
TextView textView = (TextView) itemClicked;
// получаем текст нажатого элемента
String strText = textView.getText().toString(); Intent intent = new Intent(MainActivity.this, LastActivity.class); // получаем пункт нажатого элемента
int intText = position;
String str = Integer.toString(intText);
intent.putExtra("punkt", str); for(int x=0;x} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu); //searchView.setOnQueryTextListener(textChangeListener);
return super.onCreateOptionsMenu(menu);
} // кнопка избранное
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_favorite) {
if(mSettings.contains(APP_PREFERENCES_NAME)) {
// выводим данные в TextView
tvInfo.setText(mSettings.getString(APP_PREFERENCES_NAME, ""));
}
return true;
} return super.onOptionsItemSelected(item);
}
} Второе активити с полным текстом и с кнопкой добавить в избранное public class LastActivity extends AppCompatActivity { TextView textView;
TextView textView2;
TextView textView3;
TextView textView4; String name1;
String name2;
String name3;
String name4; // переменная, представляющая экземпляр класса SharedPreferences
SharedPreferences mSettings;
// это будет именем файла настроек
public static final String APP_PREFERENCES = "mysettings";
// имя кота
public static final String APP_PREFERENCES_NAME = "Nickname"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_last);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); // инициализирем эту переменную
// в скобках - название вашего файла и стандартное разрешение
mSettings = getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE); // находим в коде
textView = (TextView) findViewById(R.id.textView);
textView2 = (TextView) findViewById(R.id.textView2);
textView3 = (TextView) findViewById(R.id.textView3);
textView4 = (TextView) findViewById(R.id.punkt); // получаем Intent извликаем из него объект
Intent intent = getIntent(); // извлекаем из него объект
name1 = intent.getStringExtra("name1");
name2 = intent.getStringExtra("name2");
name3 = intent.getStringExtra("name3");
name4 = intent.getStringExtra("punkt"); // выводим полученные данные
textView.setText(name1);
textView2.setText(name2);
textView3.setText(name3); // кнопка добавить в избранное
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(LastActivity.this, getString(R.string.action_favorite), Toast.LENGTH_LONG).show();
// SharedPreferences.Editor - редактировать
SharedPreferences.Editor editor = mSettings.edit();
// сохраняем его через метод putString() (есть также putLong(), putBoolean() и т.п.)
editor.putString(APP_PREFERENCES_NAME, name4);
// commit() или apply() чтобы изменение вступила в силу
editor.apply();
}
});
}
}
Ответ
Для такой функциональности оптимальным решением будет использование базы данных, которая позволяет делать выборки по условию и предоставляет готовые данные, соответствующие условию, наиболее быстро и оптимально. Создаете таблицу следующей структуры: | _id | name | advanced | favorite | в поле name заносите имена своих котов, поле advanced будет содержать дополнительные сведения (таких полей может быть несколько), поле favorite будет индикатором отметки избранного, в это поле будет записываться определенный признак (например: true) при добавлении этого кота в избранное. Теперь всего два запроса решат вашу проблему легко и правильно.
Выборка всей таблицы по полю name для отображения полного списка имен
Выборка по условию: favorite = true, сформирует список избранного
При клике в списке имен, вы получите ID записи, по которому сможете сделать выборку дополнительных сведений в другом активити
Теперь остается только отправить полученную из БД выборку в адаптер для отображения или заполнить виджеты дополнительными сведениями в активити Стоит заметить, что SharedPreferences вовсе не предназначены для хранения такого рода данных и использование их в таких целях крайне не оправдано. Насчет самой БД от себя рекомендовал бы сразу начать изучать ORM Realm, как наиболее качественный и удобный продукт в данной области, НО! если есть свободное время и нервы, можно потратить его на стандартные классы Android для работы с SQL (SQLiteOpenHelper, Cursor, CursorLoader и др.), учитывая, что это заранее более трудозатратный и мозговыносящий вариант. Варианты различных манипуляций со списками (коллекциями) будут заведомо костыльными для такого рода задачи. UPD По работе с ORM Realm нет каких-то особых исключений, она создана по "правилам" работы СУБД вообще и ORM в частности, то есть общих знаний по работе с базами данных вполне достаточно для ее полномерного использования.
Начальные сведения (которых уже хватит для решения вашей задачи) доступно изложены в кратком руководстве на ресурсе проекта. Здесь есть все основные моменты: поддерживаемые типы данных, создание объекта-модели (RealmObject), запись в БД (CommitTransaction), установление отношений один ко многим и многие ко многим (Relationships), изменение записей, чтение и составление запросов (Queries), работа с результатами запроса (RealmResults) и тд. , кроме того есть готовые сэмплы, где можно посмотреть на использование "в живую". Дополнительно в новостях периодически появляется какая то информация, так же есть серия видео-роликов с уроками по этой ORM. Есть даже какой-то научный доклад на русском языке Полный список доступных классов и методов изложен в API Для работы со списками (ListView и RecyclerView) в API Realm включены классы-адаптеры , там же есть инструкция по подключению в проект и сэмплы с примерами использования. На SoF так же собрана уже достаточно большая база знаний Всего этого вполне достаточно для работы, ключевым моментом здесь, видимо, является понимание работы с базами данных вообще и вот этому нужно научится перед тем, как их использовать, так как это достаточно сложная дисциплина
В данном случае, есть ли какие-то выгоды от использования этого: $(domEl).text()
в сравнении с этим: domEl.textContent
И что из этих двух вариантов является лучшей практикой?
Ответ
Синтетические тесты такие синтетические. Если посмотреть, что именно происходит в методе text getText = Sizzle.getText = function( elem ) {
var node,
ret = "",
i = 0,
nodeType = elem.nodeType; if ( !nodeType ) {
// If no nodeType, this is expected to be an array
while ( (node = elem[i++]) ) {
// Do not traverse comment nodes
ret += getText( node );
}
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
// Use textContent for elements
// innerText usage removed for consistency of new lines (jQuery #11153)
if ( typeof elem.textContent === "string" ) {
return elem.textContent;
} else {
// Traverse its children
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
ret += getText( elem );
}
}
} else if ( nodeType === 3 || nodeType === 4 ) {
return elem.nodeValue;
}
// Do not include comment or processing instruction nodes return ret;
};
можно заметить, что для примера из вопроса будет вызван - тот же самый textContent Также можно отметить, что текст функции унифицирован, чтобы ее можно было вызывать с разными типами аргументов, начиная от массива(коллекции) и заканчивая различными типами узлов: элементы, текстовые узлы и т.д. Таким образом, если в момент написания скрипта есть точная уверенность из какого типа элементов нужно будет брать текст - можно воспользоваться необходимым свойством напрямую, для кода из вопроса - использовать textContent на непосредственно html элементе. Это позволит избежать расходов на вызов конструктора jQuery и соответствующие проверки внутри самой функции. Если же неизвестно для чего будет применяться метод - то лучше воспользоваться методом jQuery.
Есть ли смысл использовать геттеры и сеттеры внутри классов их содержащих?
Ответ
Смотрите. Есть большая разница между использованием сеттера, и использованием ассоциированного поля. Эта разница — в семантике операции. Использование сеттера означает «установить логическое значение свойства, и выполнить все связанные с этим побочные эффекты». Например, если у вас есть несколько связанных полей, это может обновить значения других полей тоже. Если у вас модификация свойства должна отправлять нотификацию подписчикам, нотификация будет отправлена. Использование поля означает «изменить физическое хранилище свойства», тут внимание акцентируется не на логике, а на механизме хранения. Это низкоуровневая операция, и после её выполнения, возможно, вам понадобится выполнить нужные побочные эффекты вручную. Отсюда следует и различие в использовании. Большую часть времени вам нужно присвоение через сеттер: код сеттера позаботится о том, чтобы данные остались в консистентном состоянии, и контракты были выполнены. Но существуют и случаи, когда вам нужно, наоборот, обратить внимание на механику и воспользоваться полем. Типичный случай этого — это ситуация, когда у вас значения двух полей связаны, и сеттер одного свойства должен установить значение и другого свойства тоже. В этом случае он, скорее всего, должен записывать непосредственно в поле связанного свойства, чтобы избежать бесконечной рекурсии. Другой типичный случай — сеттер производит затратную валидацию значения, а вам точно известно, что значение правильное, и вы хотите этой валидации избежать.
То, что в текущей реализации ваш сеттер лишь присваивает значение полю, не так уж и важно. Через некоторое время, с увеличением сложности вашего кода, сеттер может разрастись, и тогда, если вы не пользовались сеттером, вам придётся пересмотреть код класса, чтобы понять, в каком из случаев вам нужен логический (класс остаётся в правильном состоянии), а в каком — физический эффект присвоения (просто значение поля меняется, и всё). Поэтому лучше подумать заранее и установить значение нужной образом.
А с геттером ситуация точно такая же. Единственная разница — геттер реже имеет побочные эффекты. (Но вполне может, например, если у вас ленивое вычисление начального значения свойства.)
Доброго времени суток. Есть MainActivity реализующая интерфейс View.OnClickListener, соответственно есть метод OnClick типа такого: public void onClick(View v) {
if (v.getId()==R.id.btnDel){ //Кнопка Удалить
Button btnDel = (Button) v;
btnDel.setText("Отмена");
btnDel.setOnClickListener(oclBtnDelWhileDel);
Выше по коду я создаю oclBtnDelWhileDel таким: View.OnClickListener oclBtnDelWhileDel = new View.OnClickListener() {
@Override
public void onClick(View v) {
Button btnDel = (Button) v;
btnDel.setText("Удалить");
btnDel.setOnClickListener(this);
}
} ;
Идея в том что метод OnClick класса назначает кнопке слушателя oclBtnDelWhileDel, а oclBtnDelWhileDel назначает слушателем обратно метод OnClick Проблема в том, что при первом нажатии на кнопку, она меняет название на "Отмена" и назначается слушатель oclBtnDelWhileDel. А вот при втором нажатии на кнопку название меняется на "Удалить", а вот слушатель обратно не меняется. Через дебаггер выполняется опять код oclBtnDelWhileDel. Вопрос: не могу понять, почему?.
Ответ
OnClickListener "прикрепляется" к определенной кнопке, и реализует метод обратного вызова (Callback), проще говоря, когда вы нажимаете на кнопку - происходит некоторое действие. Конкретно в вашей реализации очень много некрасивых мест, начиная с объявления кнопки при нажатии на другую кнопку - заканчивая установлением слушателя кнопки внутри реализации onClick другой кнопки. Вы можете просто менять динамически текст на кнопке, и выполнять тот, или иной функционал, допустим: if(btn.getText().equals("Удалить")){ // происходит операция удаления
} else { //операция отмены. }
Написано на коленке, и вероятно, ответ выше помог более по теме, но и этим не пренебрегайте. Зарефакторите код, станет легче.
Если блоки Run в разметке находятся на разных строках, то происходит их разделение пробелом друг от друга. Происходит это потому, что символ переноса строки внутри TextBlock преобразуется в пробел. Решением проблемы становится их размещение в одну строку: Или:
()
Результат в обоих случаях будет без пробелов:
(Text)
После последнего pull'a с гитхаба выскочило из головы создать новую ветку для дальнейшей работы и все коммиты делались в мастер. Сейчас хочу вновь залить проект на гитхаб для проверки и создать pull request. Возможен ли такой путь:
создаю ветку branch1 (так понимаю она будет содержать инфу с последнего коммита мастера)
ее пушу на гитхаб
создаю PR между реповским мастером и только что залитой веткой branch1
Изменения будут видны?
Ответ
Можно оставить на текущем месте (с изменениями) новую ветку: git checkout -b branch1
...и запушить только её git push -u origin branch1
Да, изменения будут видны, если на сервере старый master
На этом этапе уже можно делать pull request.
Но локальный master при этом стоит откатить до состояния на сервере, чтобы избежать сюрпризов при дальнейшей работе. Это можно сделать в любой момент, но лучше всего после отправки branch1 на сервер, чтобы уж точно ничего не потерять. git checkout master
git reset --hard origin/master
Последняя команда принудительно вешает ветку master в указанную точку (origin/master). В таком виде она относительно безопасна, т. к. история не переписывается, а чуть-чуть перемещается в прошлое. Но в общем случае ею можно легко наделать дел и потерять новые коммиты. Поэтому хорошая привычка оставлять на месте, с которого ветка снимается, другую, запасную ветку. Здесь это уже сделано: как раз там лежит branch1
Приветствую.
Возник вопрос, насчет вычисления последовательности схожей с последовательностью чисел Фибоначчи, только в которой каждый член равен сумме трех предыдущих. Последовательность начинается с трех единиц: 1, 1, 1, 3, 5, 9, .... Я хочу находить число этой последовательности по номеру. Номер лежит в пределах от 1 до 10000.
Я изучил последовательность Фибоначчи и нашел несколько формул для вычисления n-ого члена, в частности, формулу Бине(через золотое сечение), и другие. Но я не знаю, как их применить к моей последовательности. Вопрос: как получить формулу для вычисления n-ого члена последовательности без нахождения всех предыдущих членов? Очевидно, что рекурсивный подход для n=10000 не подходит.
UPD: время выполнения программы для любых n не должно превышать 1 секунду.
Ответ
Данный рекурсивный алгоритм нужно переписать итеративно. В этом случае сложность стает O(n), а памяти нужно будет константно (ну почти - числа то увеличиваются). Вот пример, как посчитать и вывести #include
#include
#include
#include using namespace std; mpz_class pp(int n) {
if (n < 1 || n >= 10000000) return 0;
if (n < 3) return 1;
mpz_class a = 1; mpz_class b = 1; mpz_class c = 1;
for (int i = 3; i < n; i++) {
mpz_class t = a + b + c;
c = b; b = a; a = t;
}
return a;
} int main() {
auto t1 = std::chrono::steady_clock::now(); cout << pp(1000000) << endl; auto t2 = std::chrono::steady_clock::now();
auto d_milli = std::chrono::duration_cast( t2 - t1 ).count();
cout << d_milli << endl;
return 0;
}
Вопрос в том, насколько это быстро? Для миллионного элемента на моей машине потребовалось 22секунды. Для 100000 элемента порядка 145мс. Для 10000 элемента это 2-4 мс. И на последок. Как это скомпилировать (на линуксе): g++ -std=c++11 ff.cpp -lgmpxx -lgmp
P.S. нужно не забыть поставить библиотеку gmp. upd решил переписать с ручной реализацией сложения больших чисел. Код сложения не самый оптимальный, но gmp проигрывает всего лишь 6-8 раз. Если переписать с sse, думаю, можно будет вытянуть больше. Но даже для такой простой реализации в лоб, думаю уже не плохо. #include
#include
#include
#include #include
#include
#include #define CLEN 8
#define BASE 100000000 class bi
{
public:
bi()
{
}
bi(std::string data)
{
for (int i = 0; i < data.length(); i+= CLEN) {
int r = std::stoi(data.substr(i, CLEN));
m_digits.push_back(r);
}
}
bi(const bi& data)
{
m_digits = data.m_digits;
} bi(int data)
{
while (data > 0) {
m_digits.push_back(data % BASE);
data = data / BASE;
}
}
bi& operator=(bi data)
{
if (this != &data) {
m_digits = data.m_digits;
}
return *this;
}
friend std::ostream& operator<< (std::ostream& stream, const bi& b); friend bi operator+( const bi& lhs, const bi& rhs );
private:
std::vector m_digits; };
std::ostream& operator<< (std::ostream& stream, const bi& b)
{
for (int i = b.m_digits.size() - 1; i >= 0; i--) {
if (i != b.m_digits.size() - 1) {
stream << std::setfill('0') << std::setw(CLEN);
}
stream << b.m_digits[i];
}
return stream;
}
bi operator+( const bi& lhs, const bi& rhs ) {
bi result;
size_t ls = lhs.m_digits.size();
size_t rs = rhs.m_digits.size();
size_t lm = std::min(ls, rs); result.m_digits.reserve(std::max(ls, rs) + 1);
int p = 0;
for (size_t i = 0; i < lm; i++) {
int c = lhs.m_digits[i] + rhs.m_digits[i] + p;
result.m_digits.push_back(c % BASE);
p = c / BASE;
}
if (ls > rs) {
for (size_t i = lm; i < ls; i++) {
int c = lhs.m_digits[i] + p; result.m_digits.push_back(c % BASE);
p = c / BASE;
}
}
if (rs > ls) {
for (size_t i = lm; i < rs; i++) {
int c = rhs.m_digits[i] + p; result.m_digits.push_back(c % BASE);
p = c / BASE;
}
}
if (p > 0) {
result.m_digits.push_back(p);
}
return result;
} template
T pp(int n) {
if (n < 1 || n >= 10000000) return 0;
if (n < 3) return 1;
T a = 1; T b = 1; T c = 1;
for (int i = 3; i < n; i++) {
T t = a + b + c;
c = b; b = a; a = t;
}
return a;
} template
int test(int n)
{
auto t1 = std::chrono::steady_clock::now(); std::cout << pp(n) << std::endl; auto t2 = std::chrono::steady_clock::now();
auto d_milli = std::chrono::duration_cast( t2 - t1 ).count();
std::cout << d_milli << std::endl;
return d_milli;
} int main()
{
int n = 10000;
int gmp = test(n);
int my = test(n);
std::cout << "gmp = " << gmp << " my = " << my << std::endl;
std::cout << "my/gmp = " << my/gmp << std::endl;
return 0;
}
public static boolean addToGroupMap(K key, V value, Map> checkMap){ assert checkMap!=null;
boolean result = false; Collection vList = checkMap.get(key);
if (vList==null){
checkMap.put(key, new ArrayList(Collections.singleton(value)));
}else {
vList.add(value);
result = true;
}
return result;
}
Думал, что более менее разобрался с дженериками, однако, в упор не понимаю, почему в строке: checkMap.put(key, new ArrayList(Collections.singleton(value))); Компилятор выдает ошибку:
Wrong 2nd argument type. Found: 'java.util.ArrayList', required: '? extends java.util.Collection
Сначала в сигнатуре метода было : K key, V value, Map> checkMap. Однако теперь надо, чтобы в значении мапы была именно коллекция. При этом, нет желания менять в куче кода List<> в checkMap'e на Collection<>, да и почему это надо делать, если лист имплементирует коллекцию? UDP: Также, возникает вопрос. Почему, если заменить в сигнатуре ? extends Collection на ? super Collection, пропадает доступ к методам коллекции? Ведь вроде ? super Collection ограничивает самой коллекцией и ее родителями?
Ответ
Забудем пока про конкретно ваш код и рассмотрим более простой пример. Допустим, есть вот такие классы: // Для демонстрации иерархии типов
class A { }
class B extends A { }
class C extends B { } // Для демонстрации контейнера
class S {
private V value; public V get() { return value; }
public void set(V value) { this.value = value; }
}
Рассмотрим такой контейнер, как S. Каким будет возвращаемое значение для метода get? Этот метод вернет что-то, что является наследником B. То есть, что бы метод get ни вернул - это что-то можно записать в переменную типа B. S s;
B v = s.get(); // Значение типа ? extends B всегда можно записать в переменную типа B
Теперь рассмотрим метод set. Кажется, что все нормально? Но давайте сделаем вот так: S s = new S();
s.set(new B()); // Ошибка - значение типа B не может быть передано как параметр типа C
Здесь я создал конкретный контейнер для примера. Даже если на самом деле используется S - компилятор должен обеспечить корректность кода в любом случае. Теперь рассмотрим такой контейнер как S. Метод set у него можно вызвать с параметром типа B S s;
s.set(new B()); // Значение типа B всегда можно передать как ? super B
А вот метод get нормально вызвать не получится: S s = new S();
B v = s.get(); // Ошибка - попытались значение типа A записать в переменную типа B
В итоге получается, что get-методы требуют отношения extends, а set-методы требуют отношения super. Если вашему коду нужно использовать оба типа методов - придется определять оба отношения одновременно, т.е. оставить просто
У меня активность содержит фрагмент. При нажатии кнопки в этом фрагменте, у меня должны измениться состояния View в макете активности. В активности у меня есть готовый метод, который будет делать это. Но как мне это реализовать, чтобы при нажатии по этой кнопки, вызывался бы метод активности?
Ответ
Объявляешь интерфейс с методами которые тебе необходимо выполнять в
Activity: interface FragmentActions {
void doSomething();
}
Имплементируешь интерфейс в Activity: class MainActivity extend Activity implement FragmentActions {
override void doSomething(){
... Вызываешь свои методы реализованные в активности
}
}
Вызываешь метод во фрагменте: class MainFragment extend Fragment {
private FragmentActions listener;
override void onAttach(Context context){
super.onAttach(context)
listener = (FragmentActions)context;
}
override void onViewCreated(...){
btn.setOnClickListener(()->listener.doSomething())
}
}
Есть класс внутри него есть еще класс который публик, сделал Class cs = new Class()
cs.VnutriClass
не могу так обратится к внутреннему классу вай?
Ответ
Предположим, что у Вас есть некоторый (определенный Вами, а не тот, который java.lang.Class) класс Class с вложенным в него классом VnutriClass, и Вы пытаетесь запустить вот такой код: Class cs = new Class();
cs.VnutriClass;
Здесь Вы создаете объект cs внешнего класса Class и далее пытаетесь обратиться к полю VnutriClass объекта cs класса Class и справедливо получаете ошибку на этапе компиляции, так как в классе Class нет поля VnutriClass. Ваша запись никоим образом не относится к взаимодействию с вложенным классом. Вы пытаетесь обратиться к полю класса. Чтобы обратиться к вложенному классу извне, необходимо этот вложенный класс сделать статическим public class Class {
public static class VnutriClass {};
}
и обращаться к нему через внешний класс: Class.VnutriClass vnutriClass = new Class.VnutriClass();
Если же Вы хотите добавить к внешнему классу поле внутреннего класса, то можно сделать так: public class Class {
private VnutriClass mVnutriClass; public Class() {
mVnutriClass = new VnutriClass();
} VnutriClass getVnutriClass() {
return mVnutriClass;
} public class VnutriClass {};
}
и работать с внутренним классом так: Class cls = new Class();
Class.VnutriClass vnutriClass = cls.getVnutriClass();
Немного теории: В Java, класс, определенный внутри другого класса называется вложенным Существует два типа вложенных классов: статические и нестатические Статический вложенный (static nested) класс – это вложенный класс, определенный с модификатором static. Вложенный статический класс не может непосредственно ссылаться на нестатические члены своего внешнего класса. Нестатический вложенный класс называется внутренним (inner) классом. Внутренний класс имеет доступ ко всем переменным и методам своего внешнего класса и может непосредственно ссылаться на них таким же образом, как это делают остальные нестатические члены внешнего класса. Пример со статическим вложенным классом: public class Outer {
public static class Nested {};
}
Outer.Nested nested = new Outer.Nested();
Пример с внутренним классом: public class Outer {
private Inner mInner; public Outer() {
mInner = new Inner();
} Inner getInner() {
return mInner;
} public class Inner{};
}
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
Не могу найти в Java стандартных механизмов для проверки строк на >, <. Уверен, что где-то они есть...
Ответ
Метод compareTo()
В Java compareTo() получает значение 0, если аргумент является строкой
лексически равной данной строке; значение меньше 0, если аргумент
является строкой лексически большей, чем сравниваемая строка; и
значение больше 0, если аргумент является строкой лексически меньшей
этой строки
Пример: public class Test { public static void main(String args[]) {
String str1 = "Я буду хорошим программистом!";
String str2 = "Я буду хорошим программистом!";
String str3 = "Я буду хорошим дворником!"; int result = str1.compareTo(str2);
System.out.println(result); result = str2.compareTo(str3);
System.out.println(result); result = str3.compareTo(str1);
System.out.println(result);
}
}
Результат выполнения:
0
11
-11
Вот встала такая простая задачка, а с ходу не нашел решения.
Конечно можно и в ручную, но это ж как то не по людски..
Ответ
Найдите список стран в машиночитаемом формате (xml, json, csv).
Добавьте его в приложение как ресурс (Embedded resource)
В приложении: загрузите ресурс через GetType().Assembly.GetManifestResourceStream(...) (вызовите в отладчике GetType().Assembly.GetManifestResourceNames() если есть затруднения с именем ресурса)
Получите из открытого ресурса список стран и передайте его в ItemsSource любым удобным методом (прямым присваиванием или через Binding)
Нужен вот такой треугольник, чтобы тянулся адаптивно. Подскажите, как лучше его сверстать? Я пытался бордерами через before и after, но линии соприкосновения уезжали на некоторых разрешениях. Заранее спасибо.
Начав исследовать такое явление как hash-таблица, я понял, что это некий массив, каждая ячейка которого хранит список, который параметризован двумя типами: ключ и значение. Когда я залез в исходники HashMap, то увидел следующее: transient Node[] table;
Если я все правильно понял, и это и есть хеш-таблица, то почему тогда это одномерный массив? Или я что-то не то нашел, и это не она?
Ответ
Представленный Вами массив является основой для хранения хэш-таблицы. Но кроме этого, каждый элемент такого массива (bucket) содержит ссылку на первый элемент linked list (JDK 7 и ранее), либо ссылку на первый элемент linked list/ссылку на корневой узел balanced tree (JDK 8). В linked list, либо в balanced tree находятся пары, которые попали в одну и ту же корзину. Пример для связного списка:
def A(number) : for item in range(len(number)) :
if number.count(item) < 2 : # определяю уникальный или нет
number[item] *= 0 # превращаю уникальный в ноль for i, elem in enumerate(number) :
if elem == 0 :
del number[i] # если ноль - удаляю
return number
Дан непустой массив целых чисел. Нужно вернуть массив, состоящий только из неуникальных элементов данного массива. Для этого необходимо удалить все уникальные элементы (которые присутствуют в данном массиве только один раз). Нельзя менять оригинальный порядок элементов. Мой код работает, но убирает только первый уникальный элемент, а остальные не трогает.Почему, не знаю, но хотел бы узнать. Если дается [1, 2, 3, 3, 3] , то должно вернуться - [3, 3, 3]. А у меня возвращается - [2, 3, 3, 3].
Ответ
Вот в этом куске for i, elem in enumerate(number) :
if elem == 0 :
del number[i] # если ноль - удаляю
Вы удаляете элементы из того списка, по которому итерируетесь. Так делать нельзя, иначе после удаления элемента цикл будет перескакивать через следующий элемент (потому что после удаления предыдущего он сдвинулся на его место). Поэтому некоторые элементы у вас и не удаляются - в цикле они просто проскальзывают мимо. Вообще, нужно стараться заменять циклы списковыми выражениями там, где это возможно. Например, вашу функцию можно написать в одну строчку: def A(number) :
return [i for i in number if number.count(i) > 1]
Всем привет. Я новичок в программировании и только начинаю многое осваивать(хотя и имею кое-какую подготовку, но считать её хоть сколь-либо серьезной смешно). Знакомлюсь с классами, пытаясь соорудить нечто для работы с матрицами. Код реализации не важен, важно то, что получаю ошибку:
http://prntscr.com/e6y5on
Ключевой вопрос в том, как её исправить. Matrix.h: #ifndef MATRIX_H
#define MATRIX_H class Matrix
{
private:
int m_rows = 1;
int m_cols = 1;
int** m_matrix = new int* [m_rows]; public:
Matrix(int rows, int cols); void SetSize(int rows, int cols);
void Create(); int rows();
int cols(); ~Matrix(); };
#endif
Matrix.cpp: #include
#include
#include "matrix.h" using namespace std; Matrix::Matrix(int rows, int cols)
{
SetSize(rows, cols);
Create();
} void Matrix::SetSize(int rows, int cols)
{
m_rows = rows;
m_cols = cols;
} void Matrix::Create()
{
for (int i = 0; i < m_rows; i++)
m_matrix[i] = new int[m_cols]; cout << "Matrix created with " << m_rows << " rows and " << m_cols <<
" cols." << endl;
}
int Matrix::rows()
{
return m_rows;
} int Matrix::cols()
{
return m_cols;
} Matrix::~Matrix()
{
for (int i = 0; i < m_rows; i++)
delete[] m_matrix[i]; delete[] m_matrix;
cout << "Matrix deleted" << endl;
}
main.cpp: int main()
{
Matrix m(2,2);
return 0;
}
При пошаговой проверке в Visual Studio программа сыплется на удалении внешнего указателя delete[] m_matrix;
Собственно, прошу помочь =)
Ответ
Давайте разбираться. int m_rows = 1;
int m_cols = 1;
int** m_matrix = new int* [m_rows];
Итак, у вас сразу выделяется память и создается матрица 1x1. Поскольку в конструкторе Matrix::Matrix(int rows, int cols)
у вас нет инициализации членов, они инициализированы по умолчанию этой матрицей.
Но что вы делаете дальше? Вы переписываете m_rows и m_cols, и в уже выделенный массив для ОДНОГО указателя записываете их m_rows, т.е. в данном конкретном случае - два. Вот вам и источник ваших неприятностей. Ваша попытка исправить ситуацию - это просто попытка не заметить ошибку. Ни к чему хорошему привести это не может. В следующий раз вы запишете туда их с десяток, и таки засорите память основательнее, только и всего. Вот как по-хорошему должна выглядеть ваша матрица: class Matrix
{
private:
int m_rows;
int m_cols;
int** m_matrix; public:
Matrix(int rows, int cols); void SetSize(int rows, int cols);
void Create(); int rows();
int cols(); ~Matrix(); };
Matrix::Matrix(int rows, int cols)
:m_rows(rows),m_cols(cols)
{
m_matrix = new int*[m_rows];
for (int i = 0; i < m_rows; i++)
m_matrix[i] = new int[m_cols]; cout << "Matrix created with " << m_rows << " rows and " << m_cols <<
" cols." << endl;
} Matrix::~Matrix()
{
for (int i = 0; i < m_rows; i++)
delete[] m_matrix[i]; delete[] m_matrix;
cout << "Matrix deleted" << endl;
}
Задался вопросом, а зачем нужны другие операторы и циклы если есть мощное ключевое слово GoTo? GoTo можно заменить любой цикл, а так же GoTo дает простор для творчества, так как можно называть метки тем, что в голову взбретет . Так же, все равно в конечно итоге красивый код превращается в последовательность GoTO на машинном языке. На мой взгляд GoTo- это, что-то типа Базона Хигса, который считается частицей бога, а GoTo оператор машинного бога.
Ответ
Проблема в том, что код пишется не для компилятора, а для человека. Для ваших коллег и для вас самого через полгода. Безумная мощь оператора goto оборачивается его слабой выразительностью. При помощи goto вы можете выразить именно что всё: и итерирование по списку, и проверку логического условия, и вызов подпрограммы, что угодно. Вам, видя оператор goto, для понимания текста придётся восстанавливать логику каждый раз самому. А это трата времени и мысленных усилий, которые приходится применять каждый раз, когда вам нужно понять, правильный ли код, или, ещё хуже, найти ошибку и исправить её. Так что другие операторы в языках есть для людей, читающих и пытающихся понять логику программы. А компьютеру всё равно, он бы и с одним goto работал, железяка тупая.