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

#java #algorithm #data-structures #big-o #polynomials

Вопрос:

Я знаю, что этот код работает, я просто чувствую, что он немного более громоздкий, чем нужно. Это большая просьба, и она, вероятно, будет отклонена, но, пожалуйста, просто потерпите меня. В основном, я чувствую, что есть лучший способ реализовать мой термин статического класса, но понятия не имею, как это сделать. Я не ожидаю, что кто-нибудь перепишет это, но если у вас есть «эй, попробуйте это вместо этого», пожалуйста, поделитесь!

 import java.util.*;
public class Polynomial implements Iterable<Object>, Comparable<Polynomial> {
    Comparator<Polynomial> compare;
    private Term head = null;
    public Polynomial(String file) {
        Scanner scan = new Scanner(file);
        try{
            while(scan.hasNext()){
                addTerm(scan.nextDouble(), scan.nextInt());
            }
        } 
        catch (Exception ex){
            System.out.println(ex.getLocalizedMessage());
            throw new InvalidPolynomialSyntax("Error: Invalid Polynomial Syntax, check input");
        }
    }
    public void addTerm(double coefficient, int exponent ){
        if (exponent < 0){
            throw new InvalidPolynomialSyntax("Error: Invalid Polynomial Syntax, Negative exponents, check input");
        }
        Term current = head;
        if(current == null){ 
            head = new Term(coefficient, exponent);
            head.next = null;
        } 
        else { 
            while(current.next != null){
                current = current.next;
            }
            current.next = new Term(coefficient, exponent);
        }
    }
    @Override
    public int compareTo(Polynomial otherPoly) {
        Term thisCurrent = this.head;
        Term otherCurrent = otherPoly.head;
        while (thisCurrent != null amp;amp; otherCurrent != null){
            if (thisCurrent.getExponent() != otherCurrent.getExponent()){
                return thisCurrent.getExponent() - otherCurrent.getExponent();
            }
            else if(thisCurrent.getCoefficient() != otherCurrent.getCoefficient()) {
                if(otherCurrent.getCoefficient()> thisCurrent.getCoefficient()){
                    return -1;
                }
                else if(otherCurrent.getCoefficient()< thisCurrent.getCoefficient()){
                    return  1;
                }
            }
            thisCurrent = thisCurrent.getNext();
            otherCurrent = otherCurrent.getNext();
        }
        if (thisCurrent == null amp;amp; otherCurrent == null){
            return 0;
        }
        if (thisCurrent == null){
            return -1;
        }else {
            return  1;
        }
    }
    public int compareExponents(Polynomial poly2) {
        Term thisPolyTerm = this.head;
        Term otherPolyTerm = poly2.head;
        while(thisPolyTerm != null amp;amp; otherPolyTerm != null) {
            if (thisPolyTerm.getExponent() != otherPolyTerm.getExponent()) {
                return thisPolyTerm.getExponent() - otherPolyTerm.getExponent();
            }
            else {
                thisPolyTerm = thisPolyTerm.getNext();
                otherPolyTerm = otherPolyTerm.getNext();
            }
        }
        if(thisPolyTerm == null amp;amp; otherPolyTerm == null){
            return 0;
        }
        if (otherPolyTerm == null){
            return  1;
        }
        else {
            return -1;
        }
    }
    public Polynomial() { 
        compare = (Polynomial poly1, Polynomial poly2) -> poly1.compareExponents(poly2); 
        }
    public Polynomial(Comparator<Polynomial> compare){ 
        this.compare = compare; 
        }
    @Override
    public Iterator<Object> iterator() {
        return new Iterator() {
            private Term current = getHead();
            @Override
            public boolean hasNext() {
                return current != null amp;amp; current.getNext() != null;
            }
            @Override
            public Term next() {
                Term data = current;
                current = current.next;
                return data;
            }
        };
    }
    @Override
    public String toString() {
        StringBuilder expressionBuilder = new StringBuilder();
        //first check head to avoid  1x^3  3x^2
        if (head.coefficient > 0){
            expressionBuilder.append(head.toString());
        }
        else {
            expressionBuilder.append(" - ").append(head.toString());
        }
        for(Term tmp = head.next; tmp != null; tmp = tmp.next) {
            if (tmp.coefficient < 0) {
                expressionBuilder.append(" - ").append(tmp.toString());
            } 
            else {
                expressionBuilder.append("   ").append(tmp.toString());
            }
        }
        return expressionBuilder.toString();
    }
    static class Term{
        private double coefficient;
        private int exponent;
        private Term next;

        private Term(double c, int e) {
            coefficient = c;
            exponent = e;
            next = null;
        }
        private int getExponent(){
            return this.exponent;
        }
        private double getCoefficient(){
            return this.coefficient;
        }
        private Term getNext(){
            return next;
        }
        @Override
        public String toString(){
            String termString = String.format("%.1f", Math.abs(coefficient));
            if (exponent == 0) { 
                return termString;
            }
            else if(exponent == 1){ 
                return termString   "x";
            } 
            else{
                return termString   "x^"   exponent;
            }
        }
    }
    private Term getHead() {
        return head;
    }
}
 

Весь вспомогательный код ниже
OrderedList.java

 import java.util.*;
public class OrderedList {
    boolean checkSorted(List<T> list){
        boolean isSorted = true;
        for(int i = list.size()-1; i > 0 ; i--){
            T current = list.get(i);
            if(!checkSorted(list, current)){
                isSorted = false;
            }
        }
        return isSorted;
    }
    private static <T extends Comparable<? super T>> 
        boolean checkSorted(List<T> list, T current) {
            T currentValue = list.get(list.indexOf(current));
            T nextValue = list.get(list.indexOf(current) - 1);
            if (nextValue != null) {
                return currentValue.compareTo(nextValue) >= 0; 
            }
            return true;
        }
}
 

Main.java

 import javax.swing.*;
import java.io.*;
import java.util.*;

public class Main {

    private static List<Polynomial> polyList = new ArrayList<>();

    public static void main(String[] args) {
        processPolyList();
    }

    public static ArrayList<String> fromFile() {
        //Create ArrayList and JFileChooser
        ArrayList<String> expressionList = new ArrayList<>();
        JFileChooser chooser = new JFileChooser();
        //Show directories and files
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        //user's current directory
        chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
        int response = chooser.showOpenDialog(null);
        if (response == JFileChooser.APPROVE_OPTION){
            File file = chooser.getSelectedFile();
            try {
                Scanner scan = new Scanner(file);
                if (file.isFile()){
                    while (scan.hasNextLine()){
                        String expression = scan.nextLine();
                        expressionList.add(expression);
                    }
                }
            }
            catch (NoSuchElementException a){
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),"File is empty!");
            }
            catch(FileNotFoundException b){
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),"404 File Not Found!");
            }
        }
        return expressionList;
    }

    public static boolean checkWeakOrder(List<Polynomial> polyList){
        boolean isWeakOrder = true;
        Polynomial previous = polyList.get(polyList.size()-1);
        for(int i = polyList.size()-2; i > 0; i--){

            if (previous.compareExponents(polyList.get(i)) < 0){
                isWeakOrder = false;
            }
        }
        return isWeakOrder;
    }

    public static void processPolyList(){
        try {
            ArrayList<String> a = fromFile();
            for (String element : a) {
                Polynomial p = new Polynomial(element);
                System.out.println(p);
                polyList.add(p);
            }
        }
        catch (InvalidPolynomialSyntax ex){
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),ex.getMessage());
        }

        System.out.println("Strong Ordered: "   OrderedList.checkSorted(polyList));
        System.out.println("Weak Ordered: "   checkWeakOrder(polyList));
    }
}
 

InvalidPolynomialSyntax.java

 public class InvalidPolynomialSyntax extends RuntimeException {
    
    InvalidPolynomialSyntax(String message){
        super(message);
    }
}
 

Комментарии:

1. Вам, вероятно, лучше всего было бы спросить об этом на codereview.stackexchange.com

2. Если вы специально не пишете для разреженных многочленов, было бы гораздо более нормально представлять многочлен в виде простого списка коэффициентов, так что poly.get(i) вы получите коэффициент для x^i. Это List<Double> в вашем случае. Большинство алгоритмов для управления ими (сложение, вычитание, умножение,деление, модуль и т.д.) будут намного проще.

3. @WJS Привет, спасибо за предложение!

4. @MattTimmermans, не могли бы вы рассказать об этом чуть подробнее?