У меня есть программа на java скажи как она строит поле Пошагово и оставь комментарии в коде import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

public class GFField {
    
    public static boolean isPrime(int num) {
        if (num < 2) return false;
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) return false;
        }
        return true;
    }

    public static List<Integer> normalizeCoefficients(List<Integer> poly, int p) {
        List<Integer> normalized = new ArrayList<>();
        for (int coeff : poly) {
            normalized.add((coeff % p + p) % p);
        }
        return normalized;
    }

    public static String polyToStr(List<Integer> poly, int p) {
        List<Integer> coeffs = normalizeCoefficients(poly, p);
        StringBuilder terms = new StringBuilder();
        for (int i = coeffs.size() - 1; i >= 0; i--) {
            int coeff = coeffs.get(i);
            if (coeff != 0) {
                if (terms.length() > 0) terms.append(" + ");
                if (i == 0) {
                    terms.append(coeff);
                } else if (i == 1) {
                    terms.append(coeff + "*x");
                } else {
                    terms.append(coeff + "*x**" + i);
                }
            }
        }
        return terms.length() > 0 ? terms.toString() : "0";
    }

    public static List<Integer> generateIrreduciblePoly(int p, int r) {
        // Placeholder: You would need a way to generate irreducibility.
        // This part would require polynomial operations that Java doesn't natively support,
        // or an external library.
        // For simplicity, returning a dummy polynomial.
        List<Integer> irredPoly = new ArrayList<>();
        for (int i = 0; i <= r; i++) {
            irredPoly.add(i == 0 ? 1 : (i == r ? 1 : 0)); // example: x^r + 1
        }
        return normalizeCoefficients(irredPoly, p);
    }

    public static List<List<Integer>> createField(int p, int r) {
        List<Integer> modulusPoly = generateIrreduciblePoly(p, r);
        List<List<Integer>> elements = new ArrayList<>();
        
        for (int i = 0; i < Math.pow(p, r); i++) {
            List<Integer> coeffs = new ArrayList<>();
            for (int j = 0; j < r; j++) {
                coeffs.add((i / (int)Math.pow(p, j)) % p);
            }
            elements.add(normalizeCoefficients(coeffs, p));
        }

        return elements;
    }

    public static List<Integer> modMultiply(List<Integer> poly1, List<Integer> poly2, List<Integer> modulusPoly, int p) {
        // Basic multiplication of polynomials
        int degree1 = poly1.size() - 1;
        int degree2 = poly2.size() - 1;
        int resultDegree = degree1 + degree2;
        
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i <= resultDegree; i++) {
            result.add(0);
        }

        for (int i = 0; i <= degree1; i++) {
            for (int j = 0; j <= degree2; j++) {
                result.set(i + j, (result.get(i + j) + poly1.get(i) * poly2.get(j)) % p);
            }
        }

        // Modulo reduction by modulusPoly (this part is essential)
        // Placeholder: You would need a polynomial division algorithm here
        return normalizeCoefficients(result, p);
    }

    public static List<Integer> findGenerators(List<List<Integer>> elements, List<Integer> modulusPoly, int p) {
        List<Integer> generators = new ArrayList<>();
        Set<List<Integer>> seen = new HashSet<>();
        
        for (List<Integer> candidate : elements) {
            // Ensure candidate is not the zero polynomial
            if (candidate.get(candidate.size() - 1) != 0) {
                seen.clear();
                List<Integer> current = new ArrayList<>();
                current.add(1); // start with 1 polynomial
                
                for (int i = 0; i < elements.size() - 1; i++) {
                    current = modMultiply(current, candidate, modulusPoly, p);
                    if (!seen.add(current)) break; // if seen before
                }
                if (seen.size() == elements.size() - 1) {
                    generators.addAll(seen); // add to generators
                }
            }
        }
        return generators;
    }

    public static void displayResults(int p, int r, List<Integer> modulusPoly, List<List<Integer>> elements, List<Integer> generators) {
        System.out.println("Построение поля GF(" + p + "^" + r + "):");
        System.out.println("Выбран неприводимый многочлен: " + polyToStr(modulusPoly, p));
        System.out.println("\nПоле содержит следующие элементы:");
        for (int i = 0; i < elements.size(); i++) {
            System.out.println("  " + i + ": " + polyToStr(elements.get(i), p));
        }

        System.out.println("\nПорождающие элементы мультипликативной группы:");
        for (List<Integer> generator : generators) {
            System.out.println("\nПорождающий элемент: " + polyToStr(generator, p));
        }
    }

    public static void main(String[] args) {
        System.out.println("Построение конечного поля GF(p^k) и нахождение порождающих элементов мультипликативной группы.");

        Scanner scanner = new Scanner(System.in);
        try {
            System.out.print("Введите простое число p - порядок поля: ");
            int p = scanner.nextInt();
            if (!isPrime(p)) {
                System.out.println("p должно быть простым числом. Введите другое число.");
                return;
            }

            System.out.print("Введите степень расширения r: ");
            int r = scanner.nextInt();
            if (r <= 0) {
                System.out.println("r должно быть положительным числом. Введите другое число.");
                return;
            }

            List<List<Integer>> elements = createField(p, r);
            List<Integer> modulusPoly = generateIrreduciblePoly(p, r);
            List<Integer> generators = findGenerators(elements, modulusPoly, p);

            displayResults(p, r, modulusPoly, elements, generators);

        } catch (Exception e) {
            System.out.println("Ошибка: " + e.getMessage());
        } finally {
            scanner.close();
        }
    }
}