Страницы

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

понедельник, 25 ноября 2019 г.

Удаление элемента списка в цикле foreach не бросает ConcurrentModificationException, почему?


Допустим, у меня есть некий ArrayList.

ArrayList list = new ArrayList<>();

for (int i = 0; i < 10; i++)
  list.add((int) (Math.random() * 20));


И я хочу из него удалить все числа больше 10.

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

for (Iterator iterator = list.iterator(); iterator.hasNext(); )
    if (iterator.next() > 10)
        iterator.remove();


Но на мое удивление, корректно работает и вариант:

for (Integer i : list)
    if (i > 10)
        list.remove(i);


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

И, действительно, если будем удалять безусловно, получим как раз ConcurrentModificationException

for (Integer i : list)
      list.remove(i);


Собственно, может кто-нибудь объяснить магию или дать наводку, где можно почитать на эту тему?
    


Ответы

Ответ 1



Видимо вам сказочно повезло: у вас не было элементов, значение которых было больше 10 у вас был элемент, значение которого было больше 10, но он был только один и располагался на предпоследнем месте в списке Давайте рассмотрим работу на более коротком примере. ArrayList list = new ArrayList<>(); list.add(1); list.add(22); list.add(3); Мы добавили три числа. Итак, как работает foreach Он получает итератор. Проверяет на наличие следующего элемента hasNext(). public boolean hasNext() { return cursor != size(); // cursor is zero initially. } Если возвращается true, то берет следующий элемент с помощьюnext(). public E next() { checkForComodification(); try { E next = get(cursor); lastRet = cursor++; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } final void checkForComodification() { // Initially modCount = expectedModCount (our case 5) if (modCount != expectedModCount) throw new ConcurrentModificationException(); } Далее повторяются шаги 2 и 3 пока hasNext() не вернет false. Если удалить элемент из списка, то его размер уменьшится и modCount увеличится. Если удалить элемент во время итерации, то будет выброшено ConcurrentModificationException исключение на строке modCount != expectedModCount. Но что происходит, если удаляется предпоследний элемент? > cursor = 0 size = 3 --> hasNext() успешно и next() тоже без эксепшена > cursor = 1 size = 3 --> hasNext() успешно и next() тоже без эксепшена Когда мы удалим значение 22, то размер уменьшится до 2. > cursor = 2 size = 2 --> hasNext() не успешно и next() пропускается. В других же случаях будет выброшено ConcurrentModificationException из-за modCount != expectedModCount. А в этом единичном случае проверка пройдет на ура.. Вот магия....Или баг....

Ответ 2



Да нечего читать на эту тему. В документации ясно сказано, что для удаления элeментов из коллекции нужно использовать итератор. Тот факт, что в вашем примере вы смогли удалить числа больше 10 обусловлен скорее всего тeм, что там не было таких чисел или было только одно - предпоследнее. Хотя реалиция foreach основана на использовании итератора, но если вы представит что внутри foreach обыкновенный for (int i = 0; i < 10; i++) то я думаю будет очевидно почему нельзя удалять элементы из массива пока вы его обходите в цикле. А вообще, используйте Java 8, и забудьте о проблемах :) List list = new ArrayList(); list.removeIf(e -> e > 10);

Чем отличается __repr__ от __str__?


Возьмем как пример парочку выдуманных классов:

import requests

class A:
    def __init__(self, a="string", b=10, c=["a", "b", "c", 1, 2, 3]):
        # параметр c - произвольной длины
        self.a = a
        self.b = b
        self.c = c

class B:
    def __init__(self, A_object):
        # A_object - объект типа A
        self.neighbor = A_object
        self.session = requests.Session()


1) Как следовало бы написать __repr__ и __str__ для этих классов?

2) Документация говорит о том, что __repr__ - это однозначное представление объект
в виде строки, которое можно использовать, чтобы воссоздать точно такой же объект, 
если это невозможно, то вывести какое-нибудь полезное сообщение. Очень похоже, что требуется сериализовать объект таким образом. В чем же тогда отличие от связки __getstate__, __setstate__? Эти два метода тоже могут запросто строку вернуть и требования у этой строки такие же - однозначное представление объекта. Зачем же дублирование? 

И наоборот, как замену getstate, setstate можно придумать следующее:

def __repr__(self):
    return "A({a}, {b}, {c})".format(a=self.a, b=self.b, c=self.c)


а потом вызывать это:

A1 = A()
A2 = eval(A1.__repr__())


3) Та же самая документация говорит, что __str__ - должен вывести красивое, читабельно
информационное сообщение, отражающее объект. Как тогда различить результат этого метода и какое-нибудь полезное сообщение из __repr__?

4) Далеко не всегда можно представить какой-то объект в виде строки. Например, функции
длинные коллекции, другие объекты без str и без repr. Выходит, что в этом случае либ
не выполняется требование __repr__, либо необходимо для всех подобных объектов вывести содержание __dict__, что хранит значение всех-всех методов и переменных. Выглядит это решение плоховато, что же делать?

5) Возвращаясь к документации __repr__ - можно пример ситуации, когда невозможн
однозначно представить объект как строку? Объекты ведь не имеют к квантовому миру никакого отношения - они ВСЕГДА детерминированы, всегда есть набор переменных и набор методов. но не зря же в документации эта строка?

6) А еще есть __format__, который тоже должен возвращать строку...
    


Ответы

Ответ 1



datetime.date хорошо иллюстрирует разницу: >>> from datetime import date >>> date.today() # sys.displayhook() uses repr() by default datetime.date(2016, 6, 13) >>> print(date.today()) # print uses str() here 2016-06-13 repr(obj) возвращает однозначное текстовое представление (representation) объект полезное для отладки, сообщений об ошибках, REPL, которое (иногда) позволяет его (теоретически) восстановить: eval(repr(obj)) == obj. str(obj) возвращает читаемый текст. Для многих объектов имеет смысл определить __repr__( (так как реализация по умолчанию в object.__repr__ не слишком информативна). __str__() имеет смысл определять для объектов, для которых существует «естественное» человеко-читаемое (неспецифичное для Питона) представление (как в примере с датой), например, для логов. Если __str__ не определён, то str() использует repr(). Разные форматы рассчитаны на разного потребителя (человек/программа, Питон/обще назначение). Вот график, иллюстрирующий когда разные форматы удобно использовать: ^ ^ | | Более дружелюбный для человека | +---+ | |str| | +---+ | | +----+ +----+ | |repr| |json| | +----+ +----+ | | +------+ | |pickle| | +------+ | | | Машино-читаемый +---------------------------------> Специфичный для Питона -> Более общий 1) Как следовало бы написать __repr__ и __str__ для этих классов? class A: def __repr__(self): return "A(%r, %r, %r)" % (self.a, self.b, self.c) class B: def __repr__(self): return "" % (self.neighbor, self.session) Объекты B не могут быть восстановлены из repr(). 2) Документация говорит о том, что __repr__ - это однозначное представление объект в виде строки, которое можно использовать, чтобы воссоздать точно такой же объект, если это невозможно, то вывести какое-нибудь полезное сообщение. Очень похоже, что требуется сериализовать объект таким образом. В чем же тогда отличие от связки __getstate__, __setstate__? Эти два метода тоже могут запросто строку вернуть и требования у этой строки такие же - однозначное представление объекта. Зачем же дублирование? pickle (__getstate__/__setstate__) не является человеко-читаемым форматом. Цели ограничения на дизайн другие. То что eval(repr(obj)) иногда работает, ещё не значит что это хорошая идея использовать это вместо pickle.loads(pickle.dumps(obj)) или json.loads(json.dumps(obj)). Основной потребитель repr() это человек. Потребитель pickle.dumps() это как правил программа, например, multiprocessing использует pickle для обмена данными между процессами. 3) Та же самая документация говорит, что __str__ - должен вывести красивое, читабельно информационное сообщение, отражающее объект. Как тогда различить результат этого метода и какое-нибудь полезное сообщение из __repr__? Если вы не видите имя типа, то это не __repr__() (за очевидным исключением констант (Python literals) таких как 'abc', 123). 4) Далеко не всегда можно представить какой-то объект в виде строки. Например функции, длинные коллекции, другие объекты без str и без repr. Выходит, что в этом случа либо не выполняется требование __repr__, либо необходимо для всех подобных объектов вывести содержание __dict__, что хранит значение всех-всех методов и переменных. Выглядит это решение плоховато, что же делать? eval(repr(obj)) это подсказка, а не требование: если объект большой, то очевидн нужно сократить его представление. Во многих случаях, можно использовать многоточие: >>> numpy.arange(10000000) array([ 0, 1, 2, ..., 9999997, 9999998, 9999999]) >>> print(numpy.arange(10000000)) [ 0 1 2 ..., 9999997 9999998 9999999] Ещё раз: потребитель repr()—программист Питона, который видит это представление в REPL или debugger. 5) Возвращаясь к документации __repr__ - можно пример ситуации, когда невозможн однозначно представить объект как строку? Объекты ведь не имеют к квантовому миру никакого отношения - они ВСЕГДА детерминированы, всегда есть набор переменных и набор методов. но не зря же в документации эта строка? Документация говорит про случай, когда eval(repr(obj)) == obj не имеет смысла: >>> object() 6) А еще есть __format__, который тоже должен возвращать строку... Этот специальный метод позволяет типу переопределить как format() себя ведёт, например: >>> "{:%Y-%m-%d}".format(datetime.today()) '2016-06-13' В Питоне 2 есть __unicode__() как __str__(), но unicode возвращает. А ещё __fspath__( (PEP 519) появился. Могут быть другие протоколы, которые возвращают строки (со своим обоснованием).

Нарушает ли OCP и DIP (из SOLID) принцип YAGNI?


Насколько я понимаю, YAGNI рекомендует нам не выделять абстракцию без необходимости
То есть, если нам не нужен полиморфизм в данный конкретный момент, то нам не следуе
выделять абстракцию, ибо зачем тогда? Однако и OCP, и DIP призывает нас выделить абстракци
здесь же. OCP это советует сделать для того, чтобы если вдруг нам понадобится изменить поведение класса, мы это могли сделать не изменяя тип, просто передав новую реализацию абстракции в тип. DIP же прямым текстом сообщает, что детали должны зависеть от абстракций и не наоборот.

Также выделять абстракцию может заставить необходимость тестирования пользователей типа. Но в рамках java, как я понимаю, такой необходимости нет. 

Так вот, нужно ли выделять абстракцию сразу же? Нужно ли следовать OCP и DIP?
    


Ответы

Ответ 1



Разные принципы проектирования направлены на решение определенной задачи проектирования, и в некоторых случаях они могут противоречить друг другу. Можно сказать, что разные принципы «тянут» дизайн в разные стороны и нужно найт правильный вектор, наиболее полезный в данном конкретном случае: SRP – говорит о простоте решения, OCP – об изоляции компонентов модулей, DIP – о «правильности» отношений между классами, а LSP – о «правильном» полиморфизме. Следование одному принципу может привести к нарушению другого. Так, например, любо наследование можно рассматривать как нарушение SPR, поскольку теперь за одну ответственност (рисование фигур) отвечает целая группа классов. Следование DIP и OCP могут привести к появлению дополнительных «швов», т.е. интерфейсов/базовых классов в системе, что, опять-таки, приведет к нарушению SRP и/или ISP. Но такое отношение между принципами не является фиксированным. Для простого случа выделение иерархии фигур для рисования является нарушением SRP, поскольку «рисование в первой итерации может заключаться в выводе текста на консоль и размазывание этой информаци по нескольким классам будет избыточным. Но по мере усложнения решения, появление иерархии наследования будет оправданной с точки зрения SRP, поскольку сложность отображения каждой отдельной фигуры будет столь высокой, что понятие «ответственности» тоже поменяется. Если вначале «единой ответственностью» было отображение всех фигур, то теперь одна ответственность будет разбита на множество: «отображение круга», «отображение квадрата» и т.п. Принцип YAGNI (You Aren’t Gonna Need It) – это более фундаментальный принцип («принци высшего порядка» или «метапринцип»), который поможет понять, когда следовать принципам/паттернам/правилам, а когда нет. В основе принципа YAGNI лежит несколько наблюдений: Программисты, как и люди в целом, плохо предсказывают будущее. Ни одно гибкое решение не будет достаточно гибким. Эти наблюдения приводят к следующим выводам: попытка создать гибкое решение на ранни стадиях разработки обречено на создание переусложненного решения. Связано это с тем, что на ранних этапах еще не известно, какие именно изменения в системе потребуются, и просто не понятно, где «подстилать солому» для будущих изменений. Поскольку на ранних этапах мы не знаем, какая именно гибкость нужна, мы заложим гибкост не там, где нужно: мы предусмотрим замену слоя доступа к данным, но из-за «дырявых абстракций» мы все равно залочим решение на определенной базе данных, или же такая гибкость просто никогда не понадобиться. Мы создадим «фреймворк» парсинга аргументов командной строки, который будет использоваться в одном приложении, а стоимость прикручивания его в другое приложение будет таким большим, что никто этим заниматься не будет. Хороший дизайн заключается в простоте решения, когда изменения требований ведет к линейным трудозатратам. Проще всего добиться этого путем эволюционного дизайна: мы начинаем с разбиения систем на крупные компоненты, но не занимаемся выделением лишнего. Не нужны базовые классы если сейчас нет хотя бы 2-х-3-х наследников. И даже если такие наследники «могут появиться в будущем», то выделить иерархию типов нужно именно тогда, когда это самое будущее настанет. Принцип YAGNI можно выразить следующим образом: выделение лишних абстракций (и любо другое усложнение) оправдано лишь в том случае, если стоимость их выделения в будущем будет существенно дороже, чем сейчас. Инвестиции в продуманность интерфейса программирования библиотеки (API) – будут оправданны поскольку стоимость внесения изменений очень высока. Стоимость же выделения интерфейса/базового класса приложении является практически одинаковой сегодня или через год. Решение проблемы по мере поступления позволяет сосредоточиться на задачах, актуальных сегодня и позволяет избежать работы, которая может и не понадобиться совсем. P.S. Ну и мне кажется, что у вас не совсем правильное понимание принципов OCP и DIP, которые совсем не сводятся к необходимости применения наследования. Вот несколько статей по теме: Шпаргалка по SOLID принципам Open-Closed Principle Dependency Inversion Principle Критический взгляд на DIP И отдельно, в статье "О принципах проектирования" я рассматриваю примерно то же самое что и в этом ответе: что слепое следование принципам приведет к переусложненному и тяжелому в сопровождении решению.

Линукс после Линуса [закрыт]


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


Ответы

Ответ 1



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

Ответ 2



Автобусы признаны опасными, эта история с Python, тогда была создана Python Softwar Foundation (PSF). Источник Марк Лутц - Программирование на Python. 4-е издание. I том стр. 83 Организации PSF предшествовала организация PSA – группа, которая первоначально была образована в ответ на когда-то давно возникшее в телеконференции Python обсуждение полусерьезного вопроса: «Что будет, если Гвидо попадет под автобус?» В Linux похожая ситуация,есть сообщество которое разрабатывает, а Линус им руководит. Достаточно почитать интервью Линуса за 2012 год,благо их 2-3

Числа, цифры, хексы, буквы и другая каша в голове



  Сколько раз слово "и" встречается в букве "цивилизация"?


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

Итак, как правильно использовать понятия, связанные с числами, и чем они отличаются?
    


Ответы

Ответ 1



Числа Число - это абстрактная единица измерения количества. 1, 2, 1888, 712.4 - всё это числа. -7 - тоже число. Хотя в большинстве языков программирования литеральной записью не обладает. Число представляет собой значение. Оно не обладает ни единицей измерения, ни системой счисления. Строго говоря, нельзя даже говорить, что оно состоит из цифр. Числа в рамках языка программирования К тому, что сказано выше добавляется тип данных, а так же возможность литеральной записи. В памяти число представлено неким набором бинарных данных. Не надо говорить, чт в этом куске памяти лежат хексы. Это просто байты и биты. Шестнадцатеричный дамп куска памяти - это именно дамп, но не число. Например, для Си: 10, 012, 0xa, 0x0A - это разные записи одного и то же числа. 10, 10L, 10.0 - это разные (хотя и равные) числа, поскольку они имеют разный ти данных. Конечно, они могут рассматриваться как одинаковые, если для нас важна величина, а не тип, но с точки зрения компилятора они различаются. Системы счисления Число может быть представлено в виде строки в различных системах счисления. Это по-прежнему одно и то же число, но строковые представления различны. "1111111111", "1010", "14", "A" - это всё представления числа 10 в различных системах счисления (унарная, бинарная, шестиричная и шестнадцатеричная соответственно). Фраза "число в шестнадцатеричной системе счисления" корректна, но неявно подразумевае "текстовое представление числа в шестнадцатеричной системе счисления", т. е. речь далее идёт о строке, а не о числе. Цифры Буква - это один символ в слове, а Цифра - это один символ в строковом представлении числа (по умолчанию - десятичном). Цифра может подразумевать и строковый ("5", "A"), и числовой (5, 10) вариант. Строковый вариант представляет собой выводимый символ, тогда как числовой следует рассматривать как остаток в кольце вычетов. Арифметические операции над цифрами в производить нельзя. Фраза "сложить цифры 5 и 7" некорректна, складывать можно только числа. Однако, в некоторых случаях возможна неявная интерпретация цифр как чисел. Цифры числа Если не оговаривается система счисления, то подразумевается десятичная. Под цифрами числа, как правило, подразумеваются числовой смысл цифр. Т. е. цифры числа - это набор остатков в кольце вычетов по основанию системы счисления который при скалярном умножении на соответствующие степени системы счисления (уже вне кольца) даст оригинальное число. По умолчанию этот набор упорядоченный. В этом контексте можно говорить об арифметических операциях, например "сумма циф числа" - это сумма чисел указанного выше набора. Поскольку речь уже идёт о числах, система счисления более не играет роли - она была нужна только для получения набора. Цифры в строковом контексте Цифра - это любой символ, который относится к соответствующей категории юникода. Можно считать, что он используется для записи чисел в естественных языках (язык программирования не подходят: в записи 0xA - символ A используется как цифра, но в реальности является буквой). В то же время я не могу со стопроцентной гарантией сказать, что любая цифра юникода используется хотя бы в одном естественном языке. PS: В большинстве случаев выше подразумеваются целые числа, однако аналогичная интерпретация возможна и для дробных.

Ответ 2



Как не надо использовать слово "цифры": Странные цифры в http ответе Хороший вопрос про chunked encoding, но почему в заголовке цифры, а не числа? Что означают цифры в строке формата? Ширина и точность в формате printf/scanf - это тоже числа. Слова в цифры (один>1) Цифры "десять" в неоговоренной системе счисления не бывает. На самом деле подразумевается преобразование числа прописью к числу Как зашифровать слово в цифры? Ставим цифры в соответствие emeil'у - правда? Assembler. Изменение HEX по ходу программы В памяти по заданному адресу хранятся данные, а не hex.

Как сделать прозрачный текст?


Мне нужно чтобы была кнопка, в которой текст был как фон (т.е. просто "дырявил блок")


    


Ответы

Ответ 1



Две SVG кнопки с прозрачным текстом. Анимация начинается при наведении курсора на цветные полоски слева. Прозрачный текст кнопок реализован при помощи SVG маски. body { background-image: url(https://i.stack.imgur.com/AZ8Hg.jpg); background-repeat: no-repeat; background-size: cover; font-family: verdana, sans-serif; }
Button- Button+


Ответ 2



div#wrapper { position: relative; height: 500px; background: url(http://img-fotki.yandex.ru/get/5807/zzots.6/0_5e7c3_42723e72_XXL.jpg); } div#button { background: white; position: absolute; top: 160px; left: 73px; text-align: center; padding: 15px; font-size: 72px; } div#button span { background: url(http://img-fotki.yandex.ru/get/5807/zzots.6/0_5e7c3_42723e72_XXL.jpg) -73px -160px no-repeat; -webkit-text-fill-color: transparent; -webkit-background-clip: text; display:block; }
КНОПКА
Замечу, что тут два фона: один основной и один - у текста кнопки. Важно в background с текстом поставить тот же фон, на котором кнопка и находитс и сместить её на такое количество пикселей, на котором кнопка смещена относительно основного фона По поводу поддержки браузерами - не могу подсказать, какие версии поддерживают. Самые последние Chrome/FF/Edge - точно работают Поэтому, как мне кажется, лучше такое пока изображать в SVG

Ответ 3



Еще один вариант, но есть проблема с поддержкой браузерами. mix-blend-mode на данный момент не работает в в ie/edge и частично в Safari h1{ background: black; color: white; mix-blend-mode: multiply; }

Алгоритм поиска максимальной суммы непрерывной подпоследовательности


Дана последовательность (массив) целых чисел. Числа могут быть как отрицательны
так и положительные. Предложите самый быстрый алгоритм поиска наибольшей суммы непрерывной последовательности.    


Ответы

Ответ 1



array = list( map( int, raw_input().split() ) ) max_sum = [ 0, ] for x in array: tmp = max_sum[ -1 ] + x if tmp < 0: tmp = 0 max_sum.append( tmp ) print max( max_sum ) http://ideone.com/y3Nwd Соблюдается условие, что последовательность может быть пуста. Работает за O(n).

Ответ 2



Решение - Алгоритм Кадане, кому интересно посмотрите ) думаю лучше уже не придумать...

Ответ 3



Книга «Жемчужины программирования» Джона Бентли (1984) подробно разбирает эту задач (показаны O(n**3), O(n**2), O(n * log n) и наконец O(n) алгоритм). Реализация классического алгоритма Кадане на Питоне: def maxsum(iterable): maxsofar = maxendinghere = 0 for x in iterable: maxendinghere = max(maxendinghere + x, 0) maxsofar = max(maxsofar, maxendinghere) return maxsofar Это O(n) (линейный однопроходной) алгоритм с O(1) (постоянной) памятью: используются только две переменные (для текущей и наибольшей суммы). Пример: >>> maxsum([1, 2, -5, 3, 2, -1, 5, -10, 3, 2]) 9 То же самое на С++: #include template intmax_t maxsum(InputIterator first, InputIterator last) { intmax_t maxsofar = 0, maxendinghere = 0; for ( ; first != last; ++first) { maxendinghere = std::max(maxendinghere + *first, (intmax_t)0); maxsofar = std::max(maxsofar, maxendinghere); } return maxsofar; } Пример: $ g++ -std=c++11 maxsum.cc -o maxsum $ ./maxsum <<<'1 2 -5 3 2 -1 5 -10 3 2' 9 где main(): #include #include int main() { std::istream_iterator numbers(std::cin), eof; std::cout << maxsum(numbers, eof) << std::endl; } Тот же код работает и для явного массива: int main() { int a[] = {1, 2, -5, 3, 2, -1, 5, -10, 3, 2}; std::cout << maxsum(std::begin(a), std::end(a)) << std::endl; }

Ответ 4



Решение за O(n) Чтобы получить максимальную сумму подпоследовательности, заканчивающейся на i-о элементе(обозначим это значение за f(i)), нужно исключить из последовательности с 1-го по i-ый элемент префикс с минимальной суммой. Остается только найти максимум по всем f(i). Реализация на Haskell main = fmap (print . maxsum . map read . words) getLine maxsum xs = let sums = scanl (+) 0 xs in maximum $ zipWith (-) sums $ scanl1 min sums

Ответ 5



Вот такой алгоритм. Переменная maX хранит максимальную последовательность, а переменна maXX хранить непрерывную последовательность на данном шаге, и если она больше максимальной, то переменная maX обновляется. Работает за O(n). Ниже код на C ++: #include #include using namespace std; int massiv[1000]; int maXX,maX; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>massiv[i]; } maXX=massiv[1]; maX=massiv[1]; for(int i=2;i<=n;i++) { maXX=max(maXX+massiv[i],massiv[i]); if (maXX>maX) maX=maXX; } cout<

Ответ 6



Так это массив или последовательность? В последовательности есть зависимость членов Тогда надо просто узнать, убывающая она или возрастающая. Если она убывает, идем с начала до первого нуля или отрицательного. если возрастает, то до идем с конца. Как-то так if (mass[0] > mass[1]) { float sum = mass[0]; for (int i = 1; i < count(mass); i++) if (mass[i] > 0) sum += mass[i]; } else { float sum = mass[count(mass) - 1]; for (int i = count(mass) - 1; i >= 0; i--) if (mass[i] > 0) sum += mass[i]; }

Ответ 7



Пробегаемся от начала массива и на i-ом шаге храним сумму массива с 0 по i-ый элемент а также минимальную сумму к этому шагу, которую мы когда-либо вычисляли до этого и на каждом шаге релаксируем ответ на основе этих двух чисел. int s=0,mins=0,ans=0; for (int i=0;i

Ответ 8



Задача, на самом деле, не совсем логична. Ведь, давайте представим такой массив: int a[16] = {-6,2,5,1,0,3,4,5,8,8,10,9,11,23,14,25}; Ведь его можно разделить всего на две части: первые два числа и все остальное. Пр чем все остальное - есть непрерывная последовательность, сумма элементов которой больш суммы первой подгруппы. Так можно делать с каждым массивом: тупо бить его на две или три части последовательно. Подумайте сами. Задача либо требует уточнений( например, максимальное количество элементов в последовательности ), либо не верна. К примеру, я придумал такой алгоритм( Работа алгоритма производится за линейное время. Это придает алгоритму краткость и понятность. ): (Алгоритм основан на том, что каждое отрицательное значение дает минус в сумме подгруппы ) int sums[16] = {0}; int a[16] = {-6,1,-2,0,1,1,-17,1,0,1,-100,1,1,-1,-1,1}; int n = 0; for(int i = 0;i<16;i++) { if(a[i]>=0) for(int j=n;j<=i;j++) sums[j]+=a[i]; else n=i; } int max = 0; int ind = 0; for(int j=0;j<16;j++) { cout<max) {max = sums[j]; ind=j;} } cout<<"The longest subarray in array begins in "<