Главная страница
Навигация по странице:

  • Практическая 3.1. Тема

  • Наследование Практическая 4.0. Тема

  • Цель

  • Задача: Реализуйте ту же иерархию классов, но сделав некоторые классы абстрактными.Решение

  • Практическая 4.2. Тема

  • Задача: Реализуйте ту же иерархию классов, но использовав интерфейсы.Решение

  • Абстрактные классы и интерфейсы Практическая 6.0. Тема; конвертер температурЦель; конвертер температурЗадача

  • Практическая 6.1. Тема

  • Решение: /*** StringBuilder с поддержкой операции undo* java.lang.StringBuilder — класс с модификатором final

  • Практические Мацука. Основы программирования на. Net и Java


    Скачать 131.13 Kb.
    НазваниеОсновы программирования на. Net и Java
    Дата30.01.2023
    Размер131.13 Kb.
    Формат файлаdocx
    Имя файлаПрактические Мацука.docx
    ТипРешение
    #912697
    страница2 из 3
    1   2   3
    Тема: двоичный поиск

    Цель: двоичный поиск

    Задача:

    Напишите метод, который проверяет, входит ли в массив заданный элемент или нет.

    Используйте перебор и двоичный поиск для решения этой задачи.

    Сравните время выполнения обоих решений для больших массивов (например, 100000000 элементов).

    Решение:

    /*

    Просто перебираем, пока не найдет.

    Если ничего не найдём, вернём -1

    */

    public static int bruteForce(double[] array, double key) {

    for (int i = 0; i < array.length; i++) {

    if (array[i] == key)

    return i;

    }

    return -1;

    }

    /*

    Двоичный поиск

    */

    public static int binarySearchRecursively(double[] sortedArray, double key) {

    return binarySearchRecursively(sortedArray, key, 0, sortedArray.length);

    }

    /**

    * Вспомогательный метод для {@link #binarySearchRecursively(double[], double)}

    *

    * Будем делить отрезок пополам, но не копировать, а просто "сдвигать границы",

    * и вызывать этот же метод рекурсивно. Для этого используем low и high

    *

    * @param sortedArray сортированный массив

    * @param key искомое значение

    * @param low от какого значения ищем

    * @param high до какого значения ищем

    * @return индекс элемента

    */

    private static int binarySearchRecursively

    (double[] sortedArray, double key, int low, int high) {

    int middle = (low + high) / 2; // середина

    if (high < low) { // больше делить нечего

    return -1;

    }

    if (key == sortedArray[middle]) { // если нашёлся

    return middle;

    } else if (key < sortedArray[middle]) { // ищем в левой половине

    return binarySearchRecursively(

    sortedArray, key, low, middle - 1);

    } else {

    return binarySearchRecursively( // ищем в правой половине

    sortedArray, key, middle + 1, high);

    }

    }

    // Вспомогательный метод для тестов

    private static double[] generateRandomArray(int length) {

    double[] array = new double[length];

    for (int i = 0; i < array.length; i++) {

    array[i] = Math.random();

    }

    return array;

    }

    public static void main(String[] args) {

    double[] array = generateRandomArray(100000000);

    Arrays.sort(array); // нужно сначала отсортировать

    /*

    Строго говоря,

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

    лучше использовать benchmarks

    см. https://habr.com/ru/post/349914/

    Но масштаб будет понятен

    */

    long time = System.currentTimeMillis(); // текущее время, unix-time

    bruteForce(array, 0.5);

    System.out.println(System.currentTimeMillis() - time);

    time = System.currentTimeMillis();

    binarySearchRecursively(array, 0.5);

    System.out.println(System.currentTimeMillis() - time);

    }

    Практическая 3.1.

    Тема: найти корень уравнения

    Цель: найти корень уравнения

    Задача:

    Найдите корень уравнения

    cos(x^5) + x^4 - 345.3 * x - 23 = 0

    на отрезке [0; 10] с точностью по x не хуже, чем 0.001. Известно, что на этом промежутке корень единственный.

    Используйте для этого метод деления отрезка пополам (и рекурсию).

    Решение:

    // вспомогательный метод

    public static double func(double x){

    return Math.cos(Math.pow(x, 5)) + Math.pow(x, 4) - 345.3 * x - 23;

    }

    // решить уравнение

    public static double solve(double start, double end){

    if(end - start <= 0.001){

    return start;

    }

    double x = start + (end - start) / 2;

    if(func(start) * func(x) > 0){

    return solve(x, end);

    } else {

    return solve(start, x);

    }

    }

    public static void main(String[] args) {

    System.out.println(solve(0, 10));

    }

    Замечание: если мы хотим добиться нужной точности не по x, по y, то условие в методе следует переписать:

    if(Math.abs(func(start)- func(end)) <= 0.001){

    return start;

    }

    Маленькая хитрость: учитывая, что множество значений double конечно (есть два соседних значения, между которыми нет ни одного значения double), условие выхода из рекурсии переписать так:

    double x = start + (end - start) / 2;

    if(x == end || x == start){

    return x;

    }

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

    Наследование

    Практическая 4.0.

    Тема: реализовать иерархию классов, описывающую трёхмерные фигуры

    Цель: реализовать иерархию классов, описывающую трёхмерные фигуры

    Задача:

    Реализуйте иерархию классов:



    Класс Box является контейнером, он можем содержать в себе другие фигуры. Метод add() принимает на вход Shape. Нужно добавлять новые фигуры до тех пор, пока для них хватаем места в Box (будем считать только объём, игнорируя форму. Допустим, мы переливаем жидкость). Если места для добавления новой фигуры не хватает, то метод должен вернуть false.

    Решение:

    class Shape {

    private double volume;

    public Shape(double volume) {

    this.volume = volume;

    }

    public double getVolume() {

    return volume;

    }

    }

    class SolidOfRevolution extends Shape {

    private double radius;

    public SolidOfRevolution(double volume, double radius) {

    super(volume);

    this.radius = radius;

    }

    public double getRadius() {

    return radius;

    }

    }

    class Ball extends SolidOfRevolution { // конкретный класс

    public Ball(double radius) {

    super(Math.PI * Math.pow(radius, 3) * 4 / 3, radius);

    }

    }

    class Cylinder extends SolidOfRevolution { // конкретный класс

    private double height;

    public Cylinder(double radius, double height) {

    super(Math.PI * radius * radius * height, radius);

    this.height = height;

    }

    }

    class Pyramid extends Shape{

    private double height;

    private double s; // площадь основания

    public Pyramid(double height, double s) {

    super(height * s * 4 / 3);

    this.height = height;

    this.s = s;

    }

    }

    class Box extends Shape {

    private ArrayList shapes = new ArrayList<>();

    private double available;

    public Box(double available) {

    super(available);

    this.available = available;

    }

    public boolean add(Shape shape) {

    if (available >= shape.getVolume()) {

    shapes.add(shape);

    available -= shape.getVolume();

    return true;

    } else {

    return false;

    }

    }

    }

    public class Main {

    public static void main(String[] args) {

    Ball ball = new Ball(4.5);

    Cylinder cylyinder = new Cylinder(2, 2);

    Pyramid pyramid = new Pyramid(100, 100);

    Box box = new Box(1000);

    System.out.println(box.add(ball)); // ok

    System.out.println(box.add(cylyinder)); // ok

    System.out.println(box.add(pyramid)); // failed

    }

    }

    Чтобы к этой задаче не возвращаться, далее описывается еще несколько вариаций этой задачи.

    Практическая 4.1.

    Тема: реализовать иерархию классов, описывающую трёхмерные фигуры — 2

    Цель: реализовать иерархию классов, описывающую трёхмерные фигуры — 2

    Задача:

    Реализуйте ту же иерархию классов, но сделав некоторые классы абстрактными.

    Решение:

    abstract class Shape {

    public abstract double getVolume();

    }

    abstract class SolidOfRevolution extends Shape {

    protected double radius;

    public SolidOfRevolution(double radius) {

    this.radius = radius;

    }

    public double getRadius() {

    return radius;

    }

    }

    class Ball extends SolidOfRevolution { // конкретный класс

    @Override

    public double getVolume() {

    return Math.PI * Math.pow(radius, 3) * 4 / 3;

    }

    public Ball(double radius) {

    super(radius);

    }

    }

    class Cylinder extends SolidOfRevolution { // конкретный класс

    private double height;

    public Cylinder(double radius, double height) {

    super(radius);

    this.height = height;

    }

    @Override

    public double getVolume() {

    return Math.PI * radius * radius * height;

    }

    }

    class Pyramid extends Shape {

    private double height;

    private double s; // площадь основания

    public Pyramid(double height, double s) {

    this.height = height;

    this.s = s;

    }

    @Override

    public double getVolume() {

    return height * s * 4 / 3;

    }

    }

    class Box extends Shape {

    private ArrayList shapes = new ArrayList<>();

    private double available;

    private double volume;

    public Box(double available) {

    this.available = available;

    this.volume = available;

    }

    public boolean add(Shape shape) {

    if (available >= shape.getVolume()) {

    shapes.add(shape);

    available -= shape.getVolume();

    return true;

    } else {

    return false;

    }

    }

    @Override

    public double getVolume() {

    return volume;

    }

    }

    public class Main {

    public static void main(String[] args) {

    Ball ball = new Ball(4.5);

    Cylinder cylyinder = new Cylinder(2, 2);

    Pyramid pyramid = new Pyramid(100, 100);

    Box box = new Box(1000);

    System.out.println(box.add(ball)); // ok

    System.out.println(box.add(cylyinder)); // ok

    System.out.println(box.add(pyramid)); // failed

    }

    }

    Практическая_4.2._Тема'>Практическая 4.2.

    Тема: реализовать иерархию классов, описывающую трёхмерные фигуры — 3

    Цель: реализовать иерархию классов, описывающую трёхмерные фигуры — 3

    Задача:

    Реализуйте ту же иерархию классов, но использовав интерфейсы.

    Решение:

    interface Shape extends Comparable{

    double getVolume();

    @Override

    default int compareTo(Shape other) {

    return Double.compare(getVolume(), other.getVolume());

    }

    }

    abstract class SolidOfRevolution implements Shape {

    protected double radius;

    public SolidOfRevolution(double radius) {

    this.radius = radius;

    }

    public double getRadius() {

    return radius;

    }

    }

    class Ball extends SolidOfRevolution { // конкретный класс

    @Override

    public double getVolume() {

    return Math.PI * Math.pow(radius, 3) * 4 / 3;

    }

    public Ball(double radius) {

    super(radius);

    }

    }

    class Cylinder extends SolidOfRevolution { // конкретный класс

    private double height;

    public Cylinder(double radius, double height) {

    super(radius);

    this.height = height;

    }

    @Override

    public double getVolume() {

    return Math.PI * radius * radius * height;

    }

    }

    class Pyramid implements Shape {

    private double height;

    private double s; // площадь основания

    public Pyramid(double height, double s) {

    this.height = height;

    this.s = s;

    }

    @Override

    public double getVolume() {

    return height * s * 4 / 3;

    }

    }

    class Box implements Shape {

    private ArrayList shapes = new ArrayList<>();

    private double available;

    private double volume;

    public Box(double available) {

    this.available = available;

    this.volume = available;

    }

    public boolean add(Shape shape) {

    if (available >= shape.getVolume()) {

    shapes.add(shape);

    available -= shape.getVolume();

    return true;

    } else {

    return false;

    }

    }

    @Override

    public double getVolume() {

    return volume;

    }

    public ArrayList getShapes() {

    return shapes;

    }

    }

    public class Main {

    public static void main(String[] args) {

    Ball ball = new Ball(4.5);

    Cylinder cylyinder = new Cylinder(2, 2);

    Pyramid pyramid = new Pyramid(100, 100);

    Box box = new Box(1000);

    System.out.println(box.add(ball)); // ok

    System.out.println(box.add(cylyinder)); // ok

    System.out.println(box.add(pyramid)); // failed

    // Sorting:

    ArrayList shapes = box.getShapes();

    Collections.sort(shapes); // sorted by Volume!

    }

    }

    Абстрактные классы и интерфейсы

    Практическая 6.0.

    Тема; конвертер температур

    Цель; конвертер температур

    Задача:

    Напишите класс BaseConverter для конвертации из градусов по Цельсию в

    Кельвины, Фаренгейты, и так далее. У класса должен быть метод convert, который

    и делает конвертацию.

    Решение:

    interface Converter {

    double getConvertedValue(double baseValue);

    }

    class CelsiusConverter implements Converter {

    @Override

    public double getConvertedValue(double baseValue) {

    return baseValue;

    }

    }

    class KelvinConverter implements Converter {

    @Override

    public double getConvertedValue(double baseValue) {

    return baseValue + 273.15;

    }

    }

    class FahrenheitConverter implements Converter {

    @Override

    public double getConvertedValue(double baseValue) {

    return 1.8 * baseValue + 32;

    }

    }

    public class Main {

    public static void main(String[] args) {

    double temperature = 23.5;

    System.out.println("t = " +

    new CelsiusConverter().getConvertedValue(temperature));

    System.out.println("t = " +

    new KelvinConverter().getConvertedValue(temperature));

    System.out.println("t = " +

    new FahrenheitConverter().getConvertedValue(temperature));

    }

    }

    Дополнительно можно попросить реализовать фабричный метод, как-то так:

    interface Converter {

    double getConvertedValue(double baseValue);

    public static Converter getInstance(){

    Locale locale = Locale.getDefault();

    String[] fahrenheitCountries = {"BS", "US", "BZ", "KY", "PW"};

    boolean isFahrenheitCountry =

    Arrays.asList(fahrenheitCountries).contains(locale.getCountry());

    if(isFahrenheitCountry){

    return new FahrenheitConverter();

    } else {

    return new CelsiusConverter();

    }

    }

    }

    Практическая 6.1.

    Тема: Stringbuilder с поддержкой операции undo

    Цель: Stringbuilder с поддержкой операции undo

    Задача:

    Напишите свой класс StringBuilder с поддержкой операции undo. Для этого делегируйте все методы стандартному StringBuilder, а в собственном классе храните список всех операций для выполнения undo(). Это будет реализацией шаблона «Команда».

    Решение:

    /**

    * StringBuilder с поддержкой операции undo

    * java.lang.StringBuilder — класс с модификатором final,

    * поэтому нет наследования, используем делегирование.

    */

    class UndoableStringBuilder {

    private interface Action{

    void undo();

    }

    private class DeleteAction implements Action{

    private int size;

    public DeleteAction(int size) {

    this.size = size;

    }

    public void undo(){

    stringBuilder.delete(

    stringBuilder.length() - size, stringBuilder.length());

    }

    }

    private StringBuilder stringBuilder; // делегат

    /**

    * операции, обратные к выполненным.

    * То есть при вызове append, в стек помещается

    * операция "delete". При вызове undo() она

    * будет выполнена.

    */

    private Stack actions = new Stack<>();

    // конструктор

    public UndoableStringBuilder() {

    stringBuilder = new StringBuilder();

    }

    /**

    see {@link java.lang.AbstractStringBuilder#reverse()}

    После того, как сделан reverse(),

    добавляем в стек операций обратную — тоже reverse().

    Далее таким же образом.

    */

    public UndoableStringBuilder reverse() {

    stringBuilder.reverse();

    Action action = new Action(){

    public void undo() {

    stringBuilder.reverse();

    }

    };

    actions.add(action);

    return this;

    }

    public UndoableStringBuilder append(String str) {

    stringBuilder.append(str);

    Action action = new Action(){

    public void undo() {

    stringBuilder.delete(

    stringBuilder.length() - str.length() -1,

    stringBuilder.length());

    }

    };

    actions.add(action);

    return this;

    }

    // ..... остальные перегруженые методы append пишутся аналогично (см. выше)......

    public UndoableStringBuilder appendCodePoint(int codePoint) {

    int lenghtBefore = stringBuilder.length();

    stringBuilder.appendCodePoint(codePoint);

    actions.add(new DeleteAction(stringBuilder.length() - lenghtBefore));

    return this;

    }

    public UndoableStringBuilder delete(int start, int end) {

    String deleted = stringBuilder.substring(start, end);

    stringBuilder.delete(start, end);

    actions.add(() -> stringBuilder.insert(start, deleted));

    return this;

    }

    public UndoableStringBuilder deleteCharAt(int index) {

    char deleted = stringBuilder.charAt(index);

    stringBuilder.deleteCharAt(index);

    actions.add(() -> stringBuilder.insert(index, deleted));

    return this;

    }

    public UndoableStringBuilder replace(int start, int end, String str) {

    String deleted = stringBuilder.substring(start, end);

    stringBuilder.replace(start, end, str);

    actions.add(() -> stringBuilder.replace(start, end, deleted));

    return this;

    }

    public UndoableStringBuilder insert(int index, char[] str, int offset, int len) {

    stringBuilder.insert(index, str, offset, len);

    actions.add(() -> stringBuilder.delete(index, len));

    return this;

    }

    public UndoableStringBuilder insert(int offset, String str) {

    stringBuilder.insert(offset, str);

    actions.add(() -> stringBuilder.delete(offset, str.length()));

    return this;

    }

    // ..... остальные перегруженные методы insert пишутся аналогично (см. выше)......

    public void undo(){

    if(!actions.isEmpty()){

    actions.pop().undo();

    }

    }

    public String toString() {

    return stringBuilder.toString();

    }

    }

    Практическая 6.2.

    1   2   3


    написать администратору сайта