Страницы

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

четверг, 28 ноября 2019 г.

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

#android #циклы #простые_числа


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

Из требований было:


  Напишите программу, которая возвращает наибольшее число палиндром, которое
  является произведением двух простых пятизначных чисел, а также возвращает
  сами сомножители.
  Простое число - это натуральное число, которое делится нацело только на 1 и
  на себя само (2, 3, 5, 7, 11, …)
  Палиндром – строка, которая читается одинаково в обоих направлениях
  (например ABBA)


Сам принцип поиска простых чисел мне понятен. Использовать массивы было нецелесообразно
потому  решето Эратосфена и аналоги пришлось отбросить - уж очень много памяти сожрало
бы создание массива на такое количество значений.

Потому решил использовать циклы для сопоставления и отсеивания.

Вот код моего андроид-приложения:

MainActivity:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private int maxNum = 99999;
    private int minNum = 10000;

    private int divNumMax = 0;
    private int palind;

    private TextView tv1;
    private TextView tv2;
    private TextView tv3;
    private TextView tv4;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv1 = (TextView) findViewById(R.id.textView1);
        tv2 = (TextView) findViewById(R.id.textView2);
        tv3 = (TextView) findViewById(R.id.textView3);
        tv4 = (TextView) findViewById(R.id.textView4);

        Button btnStart = (Button) findViewById(R.id.button);
        btnStart.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        divNumMax = (int) Math.sqrt(maxNum);

        int fPM;
        int sPM;
        boolean isNotPalind;

        fPM = findMaxPrimeNumber(maxNum);
        sPM = findMaxPrimeNumber(fPM - 2);
        isNotPalind = findPalindrome(fPM, sPM);

        while (isNotPalind) {

            if (sPM <= fPM && sPM > minNum) {
                sPM = findMaxPrimeNumber(sPM - 2);
                isNotPalind = findPalindrome(fPM, sPM);

            } else if (sPM <= minNum) {
                fPM = findMaxPrimeNumber(fPM - 2);
                sPM = fPM;
            }

            tv2.setText("1-st primary number: " + fPM);
            tv3.setText("2-nd primary number: " + sPM);
            tv4.setText("1-st * 2-nd = " + palind);

        }
    }


    private int findMaxPrimeNumber(int maxNumPre) {
        int i;
        int j;
        int z;
        int maxNumNew;

        for (i = maxNumPre; i >= minNum; i = i - 2) {

            for (j = 3; j <= divNumMax; j++) {

                z = i % j;

                if (z == 0 && j <= divNumMax) {
                    break;

                } else if (z != 0 && j == divNumMax) {
                    maxNumNew = i;
                    return maxNumNew;

                }
            }

        }
        return 10000;
    }


    private boolean findPalindrome(int firstPrime, int secondPrime) {

        int resultOfMath = firstPrime * secondPrime;

        String ltrResult = Integer.toString(resultOfMath);
        String rtlResult = new StringBuffer(ltrResult).reverse().toString();

        if (ltrResult.equals(rtlResult)) {

            palind = resultOfMath;
            return false;

        } else {
            return true;
        }
    }
}


Скриншот полученного результата на эмуляторе:



Ломаю голову где ошибся, что упустил. Не прошу делать за меня ТЗ, но не хочу оставлять
позади какую-то неразобранную проблемму.
    


Ответы

Ответ 1



Ваше целое несколько раз завернулось вокруг максимального значения int - 2,147,483,647. Проверьте: 99923 * 87541 = 8 747 359 343 А также: На какую цифру должно заканчиваться произведение Ваших двух простых чисел?

Ответ 2



решето работает отлично, ранее искал все простые числа в диапазоне 0- 10 000 000 ушло примерно 15 секунд на планшете. главное правильно написать алгоритм. возможно я не верно понял ваш алгоритм (прошу исправить меня) почему второй цикл идет по увеличению параметра, а не от большего к меньшему? for (j = 3; j <= divNumMax; j++) { есть нюанс: рассмотрим ту же задачу, но в диапазоне 0-15, пока отбросим условие палиндрома (здесь оно не играет роли). a = 13; b = 2; a*b = 26 но есть и другие простые числа произведение которых даст значительно больше результат? 11*13 > 26

Ответ 3



Вот правильный ответ на задачу, также встречал на собесе: палиндром - 999949999 множитель1 - 33211 множитель2 - 30109 Реализовал алгоритм так: Метод поиска наибольшего палиндрома (на входе список простых чисел) static void palindrome(ArrayList primeNumbers) { long palindrome = 0; long multiplier1 = 0; long multiplier2 = 0; for (int j = 0; j < primeNumbers.size(); j++) { for (int k = 0; k < primeNumbers.size(); k++) { long i = (long) primeNumbers.get(j) * (long) primeNumbers.get(k); if (palindromeCheck(i)) { if (i > palindrome) { palindrome = i; multiplier1 = primeNumbers.get(j); multiplier2 = primeNumbers.get(k); } } } } System.out.println("palindrome = " + palindrome + "\nmultiplier1 = " + multiplier1 + "\nmultiplier2 = " + multiplier2); } Метод поиска простых чисел (на входе максимальное и минимальное значения из проверяемого диапазона чисел): static ArrayList eratosthenesPrimeNumbers(int max, int min) { ArrayList primeNumbers = new ArrayList<>(); boolean[] array = new boolean[max]; for (int i = 2; Math.pow(i, 2) <= max; i++) { if (!array[i]) { for (int j = (int) Math.pow(i, 2); j < max; j += i) { array[j] = true; } } } for (int i = max - 1; i >= min; i--) { if (!array[i]) { primeNumbers.add(i); } } return primeNumbers; } Проверка на то, что найденное число является палиндромом (на входе проверяемое число): static boolean palindromeCheck(long i) { char[] palindrome = String.valueOf(i).toCharArray(); int fromBegin = 0; int fromEnd = palindrome.length - 1; while (fromBegin < fromEnd) { if (palindrome[fromBegin] == palindrome[fromEnd]) { fromBegin++; fromEnd--; } else return false; } return true; } Да и еще забыл написать, что эти методы надо вызывать :) У меня это сделано так: public class Main { static final int MAX_MULTIPLIER = 99999; static final int MIN_MULTIPLIER = 10000; public static void main(String[] args) { ArrayList primeNumbers2 = new ArrayList<>(eratosthenesPrimeNumbers(MAX_MULTIPLIER, MIN_MULTIPLIER)); palindrome(primeNumbers2); } и дальше реализация методов...

Ответ 4



Немного вник в алгоритм. По моему, он работает неправильно уже здесь: while (isNotPalind) { if (sPM <= fPM && sPM > minNum) { sPM = findMaxPrimeNumber(sPM - 2); isNotPalind = findPalindrome(fPM, sPM); } else if (sPM <= minNum) { fPM = findMaxPrimeNumber(fPM - 2); sPM = fPM; } } Получается ты выведешь первый встречный палиндром, но нет гарантии, что он будет максимальный. Возьмем отвлеченный от этого пример прогонки от 10 до 1 возможных произведений всех чисел. По твоему алгоритму идем по 1-му кругу: 10*10, 10*9 , 10*8, 10*7.... <- и сразу выводим первый попавшийся палиндром далее второй круг: 9*9, 9*8, 9*7... <- или уж тут сразу выводим первый попавшийся палиндром далее третий: 8*8, 8*7, 8*6... И так далее... Допустим на 1-ом круге 10*2 - это палиндром (гипотетически!) Также допустим на 2-ом круге 9*8 - это тоже палиндром (гипотетически!) Но твоя программа выведет 10*2 (несмотря на то что 9*8 больше чем 10*2) То есть первое попавшееся - это не вариант. Надеюсь автор меня понял и поправит если я не прав.

Ответ 5



условие задачи подразумевало произведение двух простых пятизначных чисел. алгоритм работает для двух, трех, четырехзначных чисел. но в упор отказывается работать для 5-ти. в чем тут ошибка? public class Palindrome { private static final boolean reverse(long value) { String str = String.valueOf(value); return str.equals(new StringBuilder(str).reverse().toString()); } private static final boolean isPrime(int n) { int i; for (i = 2; i <= n / 2; i++) { if (n % i == 0) { return false; } } return true; } public static void main(String[] args) { int i = 0; int maxPrimeNumber = 99971; int minPrimeNumber = 10007; outer: for (i = maxPrimeNumber; i >= minPrimeNumber; i--) { for (int j = maxPrimeNumber; j >= minPrimeNumber; j--) { if (isPrime(i) && isPrime(j)) { long product = j * i; if (reverse(product)) { System.out.printf("%d * %d = %d%n", i, j, product); break outer; } } } } } }

Как сверстать блок с линиями отходящими от центральной картинки?

#html #css #вёрстка #svg #адаптивная_верстка


Возможно, кто-то сталкивался с подобными блоками?



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

UPD1: Сложность заключается в верстке линий, отходящих от центральной картинки, в
верстке блоков текста ничего сложного для меня нет.
    


Ответы

Ответ 1



Вариант с применением двух изображений При этом решение используется pattern для добавления второго круглого изображения в центре. Решение адаптивно, вёрстка не сломается при изменении размера окна браузера и при просмотре на любом гаджете. Фоновое изображение добавляется с помощью команды: Затемняется командой - opacity="0.45" Позиционируется координатами - x и y Изображение полностью заполняет родительский блок
и может быть вставлено, как самостоятельный элемент в любое место веб страницы. Круглое изображение добавляется поверх фонового изображения с помощью Ниже полный код приложения: .container { width:100%; height:100%; } .s0{ fill:none; stroke-width:2; stroke:#45228B; }
Быстрый старт Низкая стоимость входа в бизнес Система обучения вашего персонала и помощь в его подборе Простая, проверенная бизнес модель Бизнес - любимое дело
Вариант с применением фильтров Если выбранное изображение устраивает вас по содержанию, но в связи с требованиями дизайна нужно сменить цвет оттенка фона или цвет фигур, то совсем не обязательно дорабатывать картинку в фотошопе, можно её перекрасить с помощью комбинации фильтров: feflood, feComposite, feBlend Техника применения этих фильтров подробно объясняется в топике на нашем сайте #1 Вариант с покраской фигур В фильтре применяется оператор mode="lighten" .container { width:100%; height:100%; } .s0{ fill:none; stroke-width:2; stroke:#D57700; }
Быстрый старт Низкая стоимость входа в бизнес Система обучения вашего персонала и помощь в его подборе Простая, проверенная бизнес модель Бизнес - любимое дело
#2 Вариант с покраской фона В фильтре применяется оператор mode="darken" .container { width:100%; height:100%; } .s0{ fill:none; stroke-width:2; stroke:#E1E1E1; }
Быстрый старт Низкая стоимость входа в бизнес Система обучения вашего персонала и помощь в его подборе Простая, проверенная бизнес модель Бизнес - любимое дело


Ответ 2



Надеюсь работники офисов не будут на меня в обиде за беззлобную шутку-картинку, демонстрирующую их тяжкий повседневный труд. Это скорее сочувствие. Может быть вы улыбнетесь, глядя на эту картинку и вам станет легче переносить самодура-начальника в повседневности. Чтобы получить адаптивное приложение, которое будет работать во всех современных браузерах, необходимо выполнить следующие шаги: Загружаем выбранную картинку в векторный редактор и устанавливаем размеры svg полотна равные ширине и высоте растрового изображения В векторном редакторе с помощью инструмента - Рисовать кривые Безье добавляем нужные контуры линий для размещения поясняющего текста Сохраняем файл в формате SVG и прогоняем его через оптимизатор для получения чистого кода без лишнего кода от Inkscape Чтобы получить центральную, круглую часть изображения более светлую по сравнению с остальным фоном изображения, применяем комбинированную маску, где центральный круг имеет атрибут fill="white", что делает его полностью прозрачным. rect имеет более темную закраску fill="#978300", поэтому фон будет затемненным. Добавляем текст Ниже полный код: .container { width:100%; height:100%; } .s0{ fill:none; stroke-width:2; stroke:#45228B; }
Быстрый старт Низкая стоимость входа в бизнес Система обучения вашего персонала и помощь в его подборе Простая, проверенная бизнес модель
Та же техника реализации с другой картинкой: .container { width:100%; height:100%; } .s0{ fill:none; stroke-width:2; stroke:#45228B; }
Быстрый старт Низкая стоимость входа в бизнес Система обучения вашего персонала и помощь в его подборе Простая, проверенная бизнес модель


Ответ 3



Вот SVG вариант. Я умышленно ставлю вьюбокс наполовину в отрицательную область (viewbox="-100 -100 200 200"), чтобы координата 0,0 была в центре картинки, так легче из головы брать точки для полилиний без дополнительной арифметики. hello row 1 row 2

Ответ 4



Вариант с помощью псевдоэлемента и CSS. Вместо after можно использовать SVG элемент. .title { position: relative; width: 300px; border-bottom: 1.5px solid black; padding: 5px 10px; } .title::after { position: absolute; right: 16px; bottom: -69px; width: 100%; height: 1.5px; background-color: black; transform: translateX(100%) rotate(25deg); content: ""; }
lorem ipsum


Как узнать размер базы данных PostgreSQL?

#база_данных #postgresql


Есть база PostgreSQL base, пользователь postgres. Как одной командой, не используя
скриптов, получить размер базы?    


Ответы

Ответ 1



Войти в интерактивный терминал: $ sudo -u postgres psql Выполнить запрос: # select pg_database_size('base');

Ответ 2



В человеческом виде размер базы покажет обёртка pg_size_pretty SELECT pg_size_pretty( pg_database_size( 'sample_db' ) ); pg_size_pretty ---------------- 36 GB Таким же макаром можно посмотреть и размер таблицы (с индексами) SELECT pg_size_pretty( pg_total_relation_size( 'table' ) ); pg_size_pretty ---------------- 6341 MB Если нужно без индексов, тогда запрос другой: # SELECT pg_size_pretty( pg_relation_size( 'table' ) ); pg_size_pretty ---------------- 1341 MB

Нейронные сети на Python для “чайника” [закрыт]

#python #книги #нейронные_сети


Часто встречаю такое понятие, как нейронные сети и, учитывая еще и тот факт, что
потихоньку изучаю Python, то возникла потребность "что-то эдакое" попробовать самому
написать, но более менее встречающаяся литература в сети, слишком "тверда и не по зубам"
для меня. А ведь так захватывающе - попробовать!
Вопрос: есть ли ресурс, где есть простенькие примеры на Python, для "блондинки с
чайником в руках"? В общем буду признателен всем, кто может посодействовать.    


Ответы

Ответ 1



Есть куча книг по машинному обучению и нейронным сетям. Machine Learning: an Algorithmic Perspective - пример того, что Вам нужно. И почему у нас принято только о нейронных сетях вспоминать? Но в этой книге есть среди прочих пример реализации нейронной сети на Python. Посмотрите пост на хабре с практическим примером. Вам полезно ещё познакомиться с numpy. Есть Python-библиотеки, в которых много чего уже написано. Например, всем известный PyBrain. Еще некоторые: ffnet neurolab PyNN pylibneural Есть хорошая библиотека машинного обучения, которую использую сам, но она не содержит нейронных сетей.

Ответ 2



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

Ответ 3



Для начинающих появился бесплатный курс на Stepic Нейронные сети в данном курсе используется язык python.

Лучший метод оценки производительности труда программиста? [закрыт]

#работа #производительность


Вариант 1. Количество строк кода в единицу времени. Плохой вариант. Все равно что
измерять готовность самолета по его массе. Не учитывает китайский стиль.
Вариант 2. Работает/не работает. Слишком примитивно, не учитывает оптимизацию. Бомбейская
школа программистов была здесь.
Вариант 3. Программист или его коллега сами оценивает работу друг друга исходя из
собственного опыта. Зависит от программиста. Не объективно, но может принести результат
или дело кончится холиваром.
Вариант 4. Оценка бесполезна для процесса и не стоит тратить на нее время.
Вариант 5. Быстрая микроценка проделанной за день работы. Не дает общей картины.
Кто каким образом делает это? Я использую вариант 5 + вариант 1 без учета копипаста,
китайского кода и с учетом комментариев, получается около 5-20 кБайт в день в зависимости
от части над которой идет работа. Какие еще есть варианты?    


Ответы

Ответ 1



Вариант 6. Ежедневные 5-минутные тесты/головоломки для программистов. Вроде заданий из инструментальных тестов на навыки. Особенно с утра. Плюсы: объективная оценка хотя бы состояния человека перед началом дня; прокачка мозга на програмирование, при регулярном ежедневном применении польза будет немала. Минусы: где брать тесты, постоянно новые, интересные, адекватные работе и навыкам. Возможно, тесты придётся покупать; метрика оторвана от контекста работы.

Ответ 2



Хорошей общеизвестной метрики нет (и вряд ли может быть), но никто не мешает вам установить локальную для себя метрику продуктивности. Вы же подсознательно знаете, сделали вы сегодня больше, чем вчера, или меньше. Метрика производительности такого рода имеет смысл только в контексте проекта, а не разработчика. Рекомендую ознакомиться с информацией по поводу Теории Ограничений и по поводу ее распространения на Agile процессы. Фактически, вашим вариантом номер 5 вы частично переизобрели Daily Scrum Meeting.

Ответ 3



В нашей команде уже достаточно давно используется следующая схема: Команда разделена на группы по 3-4 человека, в каждой группе есть главный (обычно более опытный сотрудник). Его задачи: раздача и контроль выполнения заданий, он тесно связан с процессом разработки (практически каждой задачи в его группе), поэтому в курсе прогресса review документации и кода оценка качества выполнения задач и эффективности членов его группы. Тесное взаимодействие людей одной группы практически гарантирует адекватные оценки со стороны лидера группы. Лидеры групп репортят менеджеру команды. Последний не занимается решением технических вопросов, это обязанности "лидеров групп", его основные обязанности - это решение организационных вопросов. т.е. наша схема склоняется к варианту 3

Ответ 4



Абсолютную шкалу построить невозможно. Не существует идеального программиста, ритм работы которого на любой задаче был бы оптимальным с точки зрения как скорости разработки, так и качества кода. Но это не значит, что производительность вообще не поддаётся измерению. Я использую для этого относительную метрику. Перед началом каждого участка работы я, исходя из опыта, делаю более-менее реалистичные предположения о том, когда закончу, а после сравниваю их с реально затраченным временем. Если в процессе не возникло никаких форс-мажоров, но была существенная задержка, то значит производительность была низкой. Количество лишних часов красноречиво говорит о том, насколько низкой. Но бывает и наоборот. Задача решается быстрее, чем планировалось, и при этом я ясно понимаю, что решил задачу именно так, как и планировал - ничего в процессе не упростил. В этом случае я делаю вывод о том, что мне нужно пересмотреть собственные представления о своих возможностях в лучшую сторону - в действительности я круче, чем думаю о себе.

Как починить android.os.NetworkOnMainThreadException

#java #android #faq


Здравствуйте.  Пытаюсь сделать POST запрос на ajax страницу с помощью HttpURLConnection.
Сильно не пинайте, я только сегодня начал практиковать Java и Android. Тестю на API
22 (Intel x86). В обычном хроме та же страница нормально загружается. Logcat:

03-24 10:23:26.842 4679-4679/? I/art: Late-enabling -Xcheck:jni
03-24 10:23:27.402 4679-4679/com.gobonus.gobonus D/AndroidRuntime: Shutting down VM
03-24 10:23:27.427 4679-4679/com.gobonus.gobonus E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.gobonus.gobonus, PID: 4679    
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gobonus.gobonus/com.gobonus.gobonus.WelcomeActivity}:
android.os.NetworkOnMainThreadException

    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420)
    at android.app.ActivityThread.access$900(ActivityThread.java:154)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5294)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
    at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
    at libcore.io.IoBridge.connect(IoBridge.java:122)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
    at java.net.Socket.connect(Socket.java:882)
    at com.android.okhttp.internal.Platform.connectSocket(Platform.java:174)
    at com.android.okhttp.Connection.connect(Connection.java:152)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:106)
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:217)
    at com.gobonus.gobonus.Request.(Request.java:65)
    at com.gobonus.gobonus.WelcomeActivity.onCreate(WelcomeActivity.java:15)
    at android.app.Activity.performCreate(Activity.java:5990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420) 
    at android.app.ActivityThread.access$900(ActivityThread.java:154) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5294) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
    at 


com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
    03-24 10:23:27.498 4679-4690/com.gobonus.gobonus W/art: Suspending all threads
took: 26.757ms
Request.java:


package com.gobonus.gobonus;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


public class Request {

    private final String USER_AGENT = "GoBonus Android Client 1.0";
    private final String API_SERVER = "http://192.168.2.21";

    public String Content;


    public Request (String session_token, String uri, String params) {

        String urlParameters  = "session_token="+session_token+"&"+params; // url params
        byte[] postData       = new byte[0];

        System.setProperty("http.agent", USER_AGENT); // user agent truck

        // api = android.os.Build.VERSION_CODES.KITKAT) {
            postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
        }
        else
            postData = urlParameters.getBytes(Charset.forName("UTF-8"));

        int    postDataLength = postData.length;
        URL    url            = null;

        try {
            url = new URL( API_SERVER + uri);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        HttpURLConnection conn= null;
        try {
            conn = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        conn.setDoOutput( true );
        conn.setInstanceFollowRedirects( false );
        try {
            conn.setRequestMethod("POST");
        } catch (ProtocolException e) {
            e.printStackTrace();
        }
        conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty( "charset", "utf-8");
        conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));

        conn.setUseCaches( false );
        try {
            DataOutputStream wr = new DataOutputStream( conn.getOutputStream());
            wr.write( postData );
            conn.connect();
            Content = ConvertData(conn);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    protected String ConvertData (HttpURLConnection url) throws IOException {
        // local variables
        String line;
        StringBuffer text = new StringBuffer();

        InputStreamReader in = new InputStreamReader((InputStream) url.getContent());
        BufferedReader buff = new BufferedReader(in);
        do {
            line = buff.readLine();
            text.append(line + "\n");
        } while (line != null);
        return text.toString();
    }

}



WelcomeActivity.java


package com.gobonus.gobonus;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class WelcomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView WebTest = (TextView) findViewById(R.id.webTest);
        WebTest.setText(new Request("123", "/ajax", "foo=bar").Content);
        setContentView(R.layout.activity_welcome);
    }

    public void LoginGo(View view) {
        Intent intent = new Intent(WelcomeActivity.this, LoginActivity.class);
        startActivity(intent);
    }
}


Манифест




    
    
    
    
    

    
        
            
                

                
            
        
        
            
        
    




Layout


    

        


Ответы

Ответ 1



Эксепшн NetworkOnMainThreadException говорит о том, что вы используете сетевые запросы в главном потоке, используйте AsyncTask для запуска запроса в отдельном от UI потока. И Метод setContentView, нужно вызывать до того, как будете обращаться к элементам разметки. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_welcome); TextView WebTest = (TextView) findViewById(R.id.webTest); WebTest.setText(new Request("123", "/ajax", "foo=bar").Content); } UPD Пример запроса через AsyncTask. Метод doInBackground выполняется в отдельном от UI потоке, после того, как вы выполнили запрос и получили ответ, ваши данные упадут в onPostExecute, который выполняется уже в потоке UI. Не обращайтесь к потоку UI в doInBackground, вызовет Exception. public class WelcomeActivity extends AppCompatActivity { TextView WebTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_welcome); WebTest = (TextView) findViewById(R.id.webTest); new AsyncRequest().execute("123", "/ajax", "foo=bar"); } class AsyncRequest extends AsyncTask{ @Override protected String doInBackground(String... arg) { return new Request(arg[0], arg[1], arg[2]).Content; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); WebTest.setText(s); } } }

Упаковка ValueType при использовании IEnumerable

#c_sharp #массивы #.net


Допустим, имеется некий массив, например:

int[,] array = { { 1, 2, 3 }, { 4, 5, 6 } };


Все массивы реализуют IEnumerable (не generic), таким образом, при использовании
этого интерфейса все элементы будут упакованы?

Вопрос актуален, например, при использовании Linq-операций Cast() или OfType():

Console.WriteLine(string.Join(" " , array.Cast()));

    


Ответы

Ответ 1



Да, ситуация с многомерными массивами довольно печальная. Такой массив реализует IEnumerable, но не реализует IEnumerable. А это означает, что любое использование многомерного массива через "призму" IEnumerable приведет к упаковке каждого элемента, и использование метода Enumerable.Cast - не исключение. Вот простой бенчмарк (на основе BenchmarkDotNet), который показывает, что это действительно так: [MemoryDiagnoser] public class MultidimentionalAarrayTests { private int[,] m_multiArray = {{1, 2}, {3, 4}}; private int[] m_regularArray = {1, 2, 3, 4}; [Benchmark] public int MultiArrayLast() { return m_multiArray.Cast().Last(); } [Benchmark] public int RegularArrayLast() { return m_regularArray.Last(); } } Результат: Method | Mean | Error | StdDev | Gen 0 | Allocated | --------------------------- |------------:|----------:|----------:|-------:|----------:| MultiArrayLast | 1,166.97 ns | 23.229 ns | 51.473 ns | 0.0401 | 132 B | RegularArrayLast | 51.29 ns | 1.250 ns | 3.686 ns | - | 0 B | Мы тут видим кучку аллокаций: в первом случае - упакован каждый элемент, итератор в Cast, итератор в Last. Во втором случае нет аллокаций вообще, поскольку Last проверяет, что последовательность реализует IList (а одномерный массив его реализует) и сразу же возвращает последний элемент. Поскольку многомерные массивы не реализуют обобщенный IEnumerable, то заставить его сделать это самим мы не можем, но мы можем создать метод расширения, чтобы не использовать Enumerable.Cast: public static class MultiDimentionalArrayEx { public static IEnumerable AsEnumerable(this T[,] array) { foreach (var e in array) yield return e; } } Теперь мы можем добавить еще один бенчмарк, чтобы проверить результат: [Benchmark] public int MultiArrayWithAsEnumerable() { return m_multiArray.AsEnumerable().Last(); } И вот окончательный результат: Method | Mean | Error | StdDev | Gen 0 | Allocated | --------------------------- |------------:|-----------:|-----------:|-------:|----------:| MultiArrayLast | 1,115.45 ns | 31.0145 ns | 90.9603 ns | 0.0401 | 132 B | RegularArrayLast | 46.11 ns | 0.1826 ns | 0.1525 ns | - | 0 B | MultiArrayWithAsEnumerable | 161.74 ns | 3.2693 ns | 3.2109 ns | 0.0150 | 48 B | Здесь мы видим, что есть выделение в куче двух итераторов (одного для метода расширения и еще одного для Enumerable.Last), но нет упаковок самих элементов.

Ответ 2



При использовании необобщённого IEnumerable упаковки, конечно, не избежать. Но компилятор умный, и в некоторых случаях может обойтись без IEnumerable. Важный случай — это если объект, по которому производится перечисление, обладает открытым методом GetEnumerator с подходящей сигнатурой. В этом случае будет использован именно он.* Второй важный частный случай (и именно он у нас имеет место) — это массивы. Компилятор знает, как можно более эффективно обходить массивы, и иногда пользуется этим. Например, вот такая функция static int[,] array = ...; static void Test() { foreach (var val in array) Console.WriteLine(val); } скомпилировалась так, как будто она была написана следующим образом: int[,] array = Program.array; int upperBound = array.GetUpperBound(0); int upperBound2 = array.GetUpperBound(1); for (int i = array.GetLowerBound(0); i <= upperBound; i++) { for (int j = array.GetLowerBound(1); j <= upperBound2; j++) { Console.WriteLine(array[i, j]); } } Для случая Cast, кажется, оптимизатор не пытается улучшить код для массивов, и таки использует Cast. В коде Cast есть проверка на наличие типизированного варианта IEnumerable (и в этом случае упаковки бы не было), но массив его не поддерживает. Так что выполняется итерация по IEnumerable с упаковкой результатов. В последующих версиях языка, возможно, оптимизатор станет умнее (если разработчики сочтут этот случай важным). (Для недоверчивых, вот IL-код: // int[,] array = Program.array; IL_0000: ldsfld int32[0..., 0...] Test.Program::'array' IL_0005: stloc.0 // int upperBound = array.GetUpperBound(0); IL_0006: ldloc.0 IL_0007: ldc.i4.0 IL_0008: callvirt instance int32 [mscorlib]System.Array::GetUpperBound(int32) IL_000d: stloc.1 // int upperBound2 = array.GetUpperBound(1); IL_000e: ldloc.0 IL_000f: ldc.i4.1 IL_0010: callvirt instance int32 [mscorlib]System.Array::GetUpperBound(int32) IL_0015: stloc.2 // i = array.GetLowerBound(0) IL_0016: ldloc.0 IL_0017: ldc.i4.0 IL_0018: callvirt instance int32 [mscorlib]System.Array::GetLowerBound(int32) IL_001d: stloc.3 IL_001e: br.s IL_0048 // jump to outer loop check // loop start (head: IL_0048) // j = array.GetLowerBound(1) IL_0020: ldloc.0 IL_0021: ldc.i4.1 IL_0022: callvirt instance int32 [mscorlib]System.Array::GetLowerBound(int32) IL_0027: stloc.s 4 IL_0029: br.s IL_003f // jump to inner loop check // loop start (head: IL_003f) // array[i, j] IL_002b: ldloc.0 IL_002c: ldloc.3 IL_002d: ldloc.s 4 IL_002f: call instance int32 int32[0..., 0...]::Get(int32, int32) IL_0034: call void [mscorlib]System.Console::WriteLine(int32) // j++ IL_0039: ldloc.s 4 IL_003b: ldc.i4.1 IL_003c: add IL_003d: stloc.s 4 // j <= upperBound2 IL_003f: ldloc.s 4 IL_0041: ldloc.2 IL_0042: ble.s IL_002b // end loop // i++ IL_0044: ldloc.3 IL_0045: ldc.i4.1 IL_0046: add IL_0047: stloc.3 // i <= upperBound IL_0048: ldloc.3 IL_0049: ldloc.1 IL_004a: ble.s IL_0020 // end loop IL_004c: ret Проверяйте!) *Ссылка на документацию: Otherwise, determine whether the type X has an appropriate GetEnumerator method: и только после этого Otherwise, check for an enumerable interface: Это позволяет, в частности, при итерации по List итерировать не по интерфейсу IEnumerator, а по структуре List.Enumerator, и тем самым избежать упаковки этой структуры.