Задать вопрос
  • Тамагочи Френдс имеет два оттенка, как это сделано программно?

    @odissey_nemo
    alfss, цветовые модели бывают разные. Но в почти любой (из достаточно обширных) есть чистые цвета и смешанные на основе их. Для экранов обычно используют модель RGB, где лишь 3 чистых цвета Red, Green, Blue, а серая гамма для неё обеспечивается одинаковыми значениями во всех трёх компонентах, от 0 до 255 (если модель хранит значение цветовой компоненты в байтах, что верно в 99.99% случаев). Тем самым, в RGB у нас может быть только 256 значений серых цветов (от чёрного 0,0,0 до белого 255,255,255). И ещё достаточно много оттенков, почти не отличимых глазом от серых значений.
    В данном случае мы наблюдаем шкалу градаций серого из 3-х вариантов: чёрный (тёмный), серый (промежуточный) и белый(светлый). Возможно, это сделано их целей экономии или по каким-либо иным соображениям.
    Цветными эти серые изображения я бы не стал называть. Ранее (когда была самостоятельная техническая культура и страна) их называли "256 градаций серого". Назвать их серыми цветами тоже можно, но звучит как то не информативно.
    Хранить в коде эти картинки можно как угодно, Зависит это, скорее всего, от контроллера, формирующего картинку. Есть стандартные форматы, известные во всех ОС, на любых процессорах, позволяющие хранить битовые картинки (BMP,PNG,GIF,TIF и т.д.). Но они нужны чисто для хранения на внешних носителях и передачи между компьютерами.
    А в тамагочи разрабы вполне могли обойтись хранящимися в ПЗУ битовыми масками. Тогда проще всего хранить изображение из 3 градаций серого в 2-х битовых маскированых матрицах (2 бита на пиксель, все значения 00,01,10,11). И даже остаётся ещё одно избыточное значение, которое тоже можно куда-либо приспособить, например, как признак отсутствие значения(цвета), как раз это и были бы прозрачные пикселы, формирующие внешнюю форму (маску) объекта.
  • Почему не проверяется ввод с клавиатуры?

    @odissey_nemo
    Да, это фишка Жабы, при == проверяется нечто типа сходства адресов двух строк (объектов), а не сами строки (объекты). Сравнивать таким образом можно (без ухищрений заумных) только переменные примитивных типов.
  • Как защитить Rest API от использования третьими лицами?

    @odissey_nemo
    Сергей Горностаев, это же лениво, да и не нужно, на самом то деле. Денег не несёт, революции не предвидится. Так для чего трудиться? Это Звончук ещё не понял, что буря страстей бурлит в стакане воды, вот и интересуется))
  • Как защитить Rest API от использования третьими лицами?

    @odissey_nemo
    Сергей Горностаев, возможно, потому, что тайные диктатуры уже заложили такие бэкдуры для себя, а вторичным и тоталитарным не дают этим воспользоваться. Впрочем, как и всеми другими своими реальными технологиями. Вот и приходится бедолагам выкручиваться, при этом являясь вторичными к тайным диктатурам, и оттягивая праведный гнев населения на себя. Оттого и так много платят этим самым диктатурам, в валютах тайных, естественно. За унижение платят.
  • Java - как быстро погрузиться?

    @odissey_nemo
    BorLaze, РФ-понятие патриотизма есть чисто местное явление, возбуждаемое искусственно. На Украине можно найти много сходства с этим явлением, кстати. В основном в официальных источниках.
    Отдельным людям, для спокойствия, лучше обходиться без этого понятия вообще, пока дело происходят в рамках пост-СССР, по кр. мере.
  • Как расположить кнопки друг за другом в ряд?

    @odissey_nemo
    Был бы это Swing, то было бы просто - использовать FlowLayout и всё.
  • Как динамически из java кода генерировать xml из xsd?

    @odissey_nemo
    xsd служит для контроля xml файлов. Теоретически, его можно пытаться использовать и для генерации псевдо-xml, которые пройдут проверку этим самым xsd. Но таких средств не знаю. Хотя написать подобный код возможно. В качестве упражнения для понимания xsd - вполне интересная и полезная задача!
  • Как перевести дату в секундах с рождества Хр. перевести в календарную дату?

    @odissey_nemo
    Stalker_RED, это марсиане, не иначе. А паренёк работает на их контору, переводит с марсианского языка программирования (он там один, устоялся за 10 000 марсианских лет) на java (он самый похожий). Правильный выбор!
  • Как на java сделать, генератор случайных букв и чисел?

    @odissey_nemo
    Именно так большинство и делает. Наверное, это самое внятное решение.
  • Интересная тема на диплом связанная с алгоритмами?

    @odissey_nemo
    Математики в генных маловато, ПМСМ. Больше алгоритмики, скорее. Но интересные решения сделать можно, уверен. Если найти интересную тему!
  • Как определить масштаб карты, если я знаю сколько метров у меня в 1 см?

    @odissey_nemo
    Писать на карте масштаб, не кратный стандартному (1:1000, 1:5 000, 1: 10 000, !:25 000, 1:50 000, 1:100 000, 1:250 000, 1:500 000, 1:1 000 000 и т.д.), не есть комильфо для глаза специалиста.
    Даже если требования стандартов к карте не предъявляются и карта является временной или рабочей, не для распространения, всё равно масштаб стараются сделать таким, чтобы хотя бы несколько последних цифр в нём были нулями. Скажем, 1:66 000 и т.д.
    На компьютерных "картах" лучше просто рисовать отрезок (внизу справа обычно) на экране и надписывать над ним число км на местности, помещающиеся в этом отрезке.
  • Как сделать круглое изображение?

    @odissey_nemo
    dimasik100200, я имел в виду, что растры хранятся только в виде прямоугольных матриц пикселов. А круглыми при просмотре их делают прозрачные пикселы в углах этих самых матриц)
  • Как сделать круглое изображение?

    @odissey_nemo
    Наверное, стоит написать "как сделать его выглядящим круглым". Круглых изображений не бывает в виртуальном мире, только в физическом :o(. А товарищи всё сказали правильно: нужна прозрачная маска в растре, которая сформирует круглый образ из прямоугольного растра. Давно не работал с изображениями, поэтому сказать ничего конкретного не смогу.
  • Какую сортировку применять?

    @odissey_nemo
    longclaps: Обострённая чувствительность - преходяща. Но только со временем. Ну какая зависть, уважаемый longclaps? Я подсознательно восхищён тем, как Вы быстро решили стандартными средствами не тривиальную (по кр. мере для меня) задачу. Если всё было сделано Вами вручную, с нуля - готов публично признаться в Вашем превосходстве в этой области.
  • Какую сортировку применять?

    @odissey_nemo
    artshelom: Абсолютно нормальное решение. Отвечающее задаче. Что и требовалось. Честно говоря, на скорость его не тестировал. Если интересно, протестирую. Но думаю, это лучше сделает автор, как лицо заинтересованное.

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

    Фишка же современных (ПМСМ) собеседований в том, что сегодня на них ищут людей, знающих конкретные технологии, а не тех, которые способны реально мыслить в новых, неизвестных условиях. Что-то типа роботов, настроенных на конкретные операции. Не делаешь эту, новейшую операцию? Ты плохой робот, нам тебя не надо. От тебя нет немедленной отдачи, что есть наша основная цель.

    В целом это объективно оправдано в условиях перехода на индус-кодирование. Люди теперь - винтики, которых легко вывинтить и выбросить. И ими в таких условиях много легче командовать и эксплуатировать. И они не скрипят при быстром ввинчивании-вывинчивании :o). Всё - ПМСМ. Успехов!
  • Какую сортировку применять?

    @odissey_nemo
    package test;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.nio.charset.Charset;
    import java.nio.file.Paths;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Comparator;
    
    /**
     * Created by nemo_odissey on 10.07.2017 12:45 for
     * <a href="https://toster.ru/q/440261?utm_source=email_notifications&utm_medium=email&utm_content=mention&utm_campaign=notifications#comment_1428657" >Какую сортировку применять?</a>.
     */
    public class JapanEditor
    {
        /**
         * Class to store vocabulary item and make it comparable only  lexicographically
         */
        public static class WordItem implements Comparable
        {
            public String word;
            public int count;
    
            public WordItem( String word, int count )
            {
                this.count = count;
                this.word = word.split( "/",0 )[0];
            }
    
            @Override
            public int compareTo( Object obj )
            {
                return this.word.compareTo( ((WordItem)obj).word );
            }
    
            public int compareByFrequency( Object obj )
            {
                return this.count - ((WordItem)obj).count;
            }
        }
    
        /**
         * Сортирует и извлекает из массива source начиная с индекса pos1 и до индекса pos2 (не включая его самого) максимальные элементы,
         * по размеру массива result или меньше.
         * @param maxLen максимальный размер массива с максимальными элементами
         * @param dstList {@link ArrayList} для размещения результатов работы. Если {@code null}, то  будет создан внутри. Очищается перед работой и заполняется результатами
         * @param source исходный массив
         * @param pos1 начальный индекс массива source
         * @param pos2 конечный инидекс в массиве source (не включается в сортировку)
         * @return {@link ArrayList} (не может быть {@code null})
         */
        public static final ArrayList<WordItem> partialSort( int maxLen, ArrayList<WordItem> dstList, WordItem[] source, int pos1, int pos2 )
        {
            if ( dstList == null )
                dstList = new ArrayList<WordItem>( 10 );
            else
                dstList.clear();
            dstList.add( source[ pos1++ ] );
            // Проверим все слова с префиксом на предмет их частоты и отберём до 10 самых часто встречающихся
            for( int i = pos1; i< pos2; i++ )
            {
                WordItem item = source[ i ];
                int placeFound = 0;
                int listPos;
                int cmp;
                // Найдём, надо ли вставлять и куда вставить
                for ( listPos = dstList.size() - 1; listPos >= 0; listPos-- )
                {
                    if ( ( cmp = item.compareByFrequency( dstList.get( listPos ) ) ) < 0 ) // нашли элемент из списка проверенных, который больше проверяемого
                        break; // дальше не идём, может сможем добавить в конец списка, если там ещё есть место
                    if (cmp == 0) // по частоте он равен
                        if ( item.compareTo( dstList.get( listPos ) ) > 0 ) // но элемент из списка проверенных оказался меньше лексически
                            break;
                }
                // пытаемся вставить в массив либо на место элемента, который меньше, либо в конец списка, если там ещё есть место
                if ( listPos == (dstList.size()-1) ) // младший элемент списка больше проверяемого элемента, попробуем просто сдобавить в конец
                {
                    if ( dstList.size() < maxLen ) // массив результата ещё не полон, добавляем в конец
                        dstList.add( item );
                    continue; // переходим к следующему элементу
                }
                // нашли, куда вставить
                if ( dstList.size() == maxLen )
                {
                    // массив результата уже полностью заполнен, сразу удаляем нижний,
                    // т.к. он выйдет за разрешённые пределы при вставке нового элемента
                    dstList.remove( maxLen - 1 );
                }
                // вставляем ниже большего элемента, или, если listPos == -1, вместо самого большого
                dstList.add( listPos + 1, item );
            }
            return dstList;
        }
    
        /**
         * Обработки ошибок НЕТ
         * @param args путь_к_файлу_с_данными, где хранится задание
         * @throws IOException
         */
        public static void main( String[] args ) throws IOException
        {
            long start = System.nanoTime();
            BufferedReader brd  = java.nio.file.Files.newBufferedReader( Paths.get( args[ 0 ] ), Charset.forName( "utf-8" ) );
            // читаем число слов
            int wordCnt = Integer.parseInt( brd.readLine() );
            WordItem[] wordArr = new WordItem[wordCnt];
            // Читаем все слова и их частоты
            for(int i = 0; i < wordCnt; i++)
            {
                String word = brd.readLine();
                String[] elems = word.split( " " );
                wordArr[ i ] = new WordItem( elems[0], Integer.parseInt( elems[1] )  );
    //            wordArr[ i ] = new WordItem( word.toLowerCase(), freq );
            }
    
            // сортируем массив словаря
            Arrays.sort( wordArr );
    
            // считываем и обрабатываем каждый префикс один за другим
            int prefCnt = Integer.parseInt( brd.readLine() );
            System.out.printf( "Счётчик слов %d, счётчик префиксов %d\n", wordCnt, prefCnt );
            System.out.printf( "Словарь считан и отсортирован за %,f млс.\n\n",  1e-9 * (System.nanoTime() - start) );
            int summaryWordCount = 0;
            WordItem prefixItem = new WordItem( "", 1 );
            ArrayList<WordItem> list = new ArrayList<>( 11 );
            for(int i = 0; i < prefCnt; i++)
            {
                String prefix = brd.readLine().trim();
                prefixItem.word = prefix;
                int pos1 = Arrays.binarySearch( wordArr, prefixItem ); // if positive, point to a word in vocabulary started from prefix or equal to it
                if ( pos1 < 0) // no precise prefix value found in vocabulary
                    pos1 = -(pos1 + 1); // pos1 to the first element starting from prefix
                if ( pos1 >= wordCnt) // префикс отсутствует в словаре
                    continue;
    
                System.out.printf( "     ~ %s\n", prefix );
    
                if ( wordArr[pos1].word.startsWith( prefix ) ) // Если префикс есть, ищем последнюю его позицию в словаре
                {
                    char nextLastChar = prefix.charAt( prefix.length() - 1 );
                    prefixItem.word = prefix.substring( 0, prefix.length() -1 ) + (++nextLastChar); // готовим следующую не строку
                    int pos2 = Arrays.binarySearch( wordArr, pos1, wordCnt, prefixItem );  // ищем последнее вхождение префикса в словаре
                    if ( pos2 < 0)
                        pos2 = -pos2 -1;
                    if ( pos2 > wordCnt)
                        pos2 = wordCnt;
                    summaryWordCount += pos2 - pos1;
                    list = partialSort( 10, list, wordArr, pos1, pos2 );
                    for( WordItem item: list )
                        System.out.printf( "%6d %s\n", item.count, item.word );
                }
            }
            brd.close();
            System.out.printf( ">>> Длительность обработки %,f сек., средний размер выборки по каждому префиксу %d\n",  1e-9 * (System.nanoTime() - start), summaryWordCount / prefCnt);
        }
    }
  • Какую сортировку применять?

    @odissey_nemo
    longclaps: artshelom:

    Посмотрел и я, критик строгий, на творение творца названием из этого списка антонимов. Мне лично импонирует 7-й номер.

    Скажу сразу - мне лично творение понравилось. Кратко, мощно, грамотно. Быстрее моего "древнего" подхода практически на порядок (хэш - 4-5 секунд. двоичный -22 секунд). Не уверен, что код создан без Инет-поиска, но сути это не меняет.

    Есть небольшое примечание к коду longclaps: всё таки при отборе префиксов по эталону идёт не вставка, а сортировка вставкой, но т.н. частичная. Есть и микро замечание: при одинаковой мощности найденных префиксов они не сортируются лексикографически, как записано в условиях задачи. Поправить очень легко, при желании.

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

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

    И обнаружил интересные вещи! Оказывается, число элементов в рабочей хэш-таблице оказалось ... ровно 150 000!!! Т.е. равно всему числу тестовых слов! Что невероятно, если тестовая последовательность слов создавалась без вытаскивания синтетических "слов" из той же хэш-таблицы. Ведь в хэш-таблицу попадали все (ВСЕ) префиксы, созданные из элемента словаря. Казалось бы, в общем случае, число хэш-ключей должно равняться числу исходных слов умноженных на среднюю длину слова. Но нет! Число уникальных ключей равно числу слов! А все слова состоят из 3 символов (a, b и c) в разных комбинациях. Синтетика!

    Решил, для начала, попробовать выборку, приближенную к реальности. Взял словарь Лебедева к браузеру Opera, что был под рукой (см. в архиве по ссылке). В нём было 142 000 русских слов, что близко к величине тестового словаря (150 000). Префиксы и их длины сгенерировал случайным отбором, общим числом, заданным в тесте (15 000).

    Провёл эксперимент. Результаты были ожидаемы, хотя и не кардинальны: двоичный поиск сработал чуть быстрее, а хэш медленнее, 5-6 секунд вместо 3-4. И, что логично, хэш-таблица резко выросла в размерах, стала около 500 000 вместо 150 000 ранее. И создавалась она теперь раза в два дольше, чем осуществлялась сортировка массива.

    На этом уже можно было бы ставить точку. С резюме: хэш-таблица по любому сработала много быстрее двоичного поиска. Но ведь заело!

    Стал разбираться в алгоритме longclaps. Удивило использование простой частичной сортировки вставкой. Решил опробовать. Это же сортировка, а сортировкам и противопоставлялся поиск по хэш-таблице. Это же наше, сортировщиков, всё!

    Ранее (см. переписку ) думал и утверждал, что тип сортировки при поиске всех соответствующих префиксу слов не должен бы влиять на общую длительность алгоритма. Реализовал в своём алгоритме чудо от longclaps, и - новое чудо! Алгоритм заработал за время сопоставимое с хэш-поиском!!! Т.е. те же секунды!

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

    Можно оптимизировать память и дальше. Скажем, использовать общий массив символов, куда считать весь файл, а слова и префиксы хранить в Java 8 Segment (avax.swing.text.Segment), легко переносимый в более ранние версии. Тогда не будет отдельных строк вообще ни в словах, ни в префиксах. Можно отказаться от объектов вообще, сортировать только индексы. Но это уже сильно затуманит код.

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

    Исправленный Java код комментарием ниже. И в нём есть одна логическая неувязочка, которую уже лень устранять.
  • Какую сортировку применять?

    @odissey_nemo
    artshelom: Посмотрел. Понравилось. Сделано классически, без оптимизации. Вполне возможно, более универсальное.

    Исправил свой код. На моём Lenovo ThinkPad T4400 работает 22-24 секунды с выводом или без вывода, разница полсекунды. Быстрее с этим подходом уже не сделаешь. Надо думать дальше, в сторону укладки данных в другом виде, сразу готовом к выдаче. Или многопоточность. Интересно сравнить массив и дерево на этом тесте.

    На другом компьютере вполне может срабатывать за 5-10 секунд.
    Кстати, средний размер набора слов, содержащего префикс, 3750 слов. Что не тривиально, наверное. Т.е. тест - вырожденный. И набор букв какой-то... японский, 3 буквы)))
  • Какую сортировку применять?

    @odissey_nemo
    artshelom: binarySearch возвращает либо чётко самый ПЕРВЫЙ индекс со словом, совпадающим с префиксом, либо, если нет такого, то отрицательное значение самого раннего индекса, куда надо вставить наше искомое значение минус единица. Т.е. если возращено -1, то вставлять можно было бы в самое начало списка (индекс 0), -2 в индекс 1 и т.д., по возрастанию. На деле это значит, что binarySearch возвращает всегда точную позицию самого ранней позиции префикса в лексикографически отсортированном массиве (-1). Или укажет за границу массива (-array.length() -1).

    Итак, самая первая позиция префикса найдена точно! Или префикса вообще нет! Если он есть, берём до 10 первых лексикографических, начинающихся с искомого префикса. Т.к. сортировать можно либо лексикографически, либо по мощности (частоте). Для поиска по префиксу подходит только лексикографическая сортировка, естественно.

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

    Из интереса возьму Вашу тестовую выборку и завтра проверю. Спасибо за тренировку :o)

    P.S. Ошибки возможны, тестировал на выборке в 10 слов и 5 префиксов. Это к слову о пользе тестирования.
    P.P.S. Ошибка понятно, не учёл, если префикс лексикографически выше последнего слова в словаре. Это надо обрабатывать, как пустой результат, т.е. пропускать и переходить дальше, да!
  • Почему hashset добавляет одинаковые объекты?

    @odissey_nemo
    Arti-Jack: хорошо. Может, кто ещё наткнётся и будет не зря. Ничто не Земле не проходит бесследно)))