1
0
forked from kalmar/DALGLI0

changed error handling

This commit is contained in:
Hubert Tylkowski 2018-06-27 11:16:10 +02:00
parent 7522756ff9
commit 8175042b4a
5 changed files with 113 additions and 90 deletions

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Main

View File

@ -4,8 +4,7 @@ import java.util.List;
public class Main { public class Main {
public static void main(String[] args) throws DivisionErrorException, MultiplierNotFoundException { public static void main(String[] args){
//ex input in run console : 2 "1 1 1 0 1" "0 1 1"
int n = Integer.parseInt(args[0]); int n = Integer.parseInt(args[0]);
List<Integer> firstPolynomial = new ArrayList<>(); List<Integer> firstPolynomial = new ArrayList<>();
args[1] = args[1].substring(1, args[1].length()-1); args[1] = args[1].substring(1, args[1].length()-1);
@ -14,6 +13,11 @@ public class Main {
List<Integer> secondPolynomial = new ArrayList<>(); List<Integer> secondPolynomial = new ArrayList<>();
Arrays.asList(args[2].split(",\\s*" )).forEach(factor -> secondPolynomial.add(Integer.valueOf(factor))); Arrays.asList(args[2].split(",\\s*" )).forEach(factor -> secondPolynomial.add(Integer.valueOf(factor)));
PolynomialTask polynomialTask = new PolynomialTask(n, firstPolynomial, secondPolynomial); PolynomialTask polynomialTask = new PolynomialTask(n, firstPolynomial, secondPolynomial);
polynomialTask.printAllValuesToStandardOutput(); System.out.print("[");
System.out.print(polynomialTask.printMultipliedPoly()
+ ", " + polynomialTask.printSubtractedPoly()
+ ", " + polynomialTask.printGcd());
System.out.print("]");
} }
} }

View File

@ -1,134 +1,150 @@
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class PolynomialTask { public class PolynomialTask {
private int n; private int n;
private List<Integer> firstPolynomial; private int[] firstPolynomialAsArray;
private List<Integer> secondPolynomial; private int[] secondPolynomialAsArray;
public PolynomialTask(int n, List<Integer> firstPoly, List<Integer> secondPoly) { public PolynomialTask(int n, List<Integer> firstPoly, List<Integer> secondPoly) {
this.n = n; this.n = n;
this.firstPolynomial = firstPoly; this.firstPolynomialAsArray = parseListToArray(firstPoly);
this.secondPolynomial = secondPoly; this.secondPolynomialAsArray = parseListToArray(secondPoly);
} }
public Integer[] multiplyPolynomials(List<Integer> firstPolynomial, List<Integer> secondPolynomial) { private int[] parseListToArray(List<Integer> polynomial) {
int[] multiplied = new int[firstPolynomial.size() + secondPolynomial.size() - 1]; int[] result = new int[polynomial.size()];
int sizeOfFirstPoly = firstPolynomial.size(); for (int i = 0; i < polynomial.size(); i++) {
int sizeOfSecondPoly = secondPolynomial.size(); result[i] = polynomial.get(i);
}
return result;
}
private int[] multiplyPolynomials(int[] firstPolynomial, int[] secondPolynomial) {
int[] multiplied = new int[firstPolynomial.length + secondPolynomial.length - 1];
int sizeOfFirstPoly = firstPolynomial.length;
int sizeOfSecondPoly = secondPolynomial.length;
for (int i = 0; i < sizeOfFirstPoly; i++) { for (int i = 0; i < sizeOfFirstPoly; i++) {
for (int j = 0; j < sizeOfSecondPoly; j++) for (int j = 0; j < sizeOfSecondPoly; j++)
multiplied[i + j] = (multiplied[i + j] + (firstPolynomial.get(i) * secondPolynomial.get(j))) % n; multiplied[i + j] = (multiplied[i + j] + (firstPolynomial[i] * secondPolynomial[j])) % n;
} }
return Arrays.stream(multiplied).boxed().toArray(Integer[]::new); return multiplied;
} }
public int[] moduloDividePolynomialsReturnQuotient(List<Integer> firstPoly, List<Integer> secondPoly) throws MultiplierNotFoundException, DivisionErrorException { private int[] polyDiv(int[] polyOne, int[] polyTwo) {
int[] quotient = new int[firstPoly.size() + secondPoly.size()]; if (polyOne.length < polyTwo.length) {
int firstPolyDegree = firstPoly.size() - 1; return null;
int secondPolyDegree = secondPoly.size() - 1;
List<Integer> polynomialAfterSubtract = firstPoly;
while (firstPolyDegree >= secondPolyDegree) {
polynomialAfterSubtract = calcQuotient(polynomialAfterSubtract, secondPoly, quotient);
firstPolyDegree = polynomialAfterSubtract.size() - 1;
} }
int firstPolyDeg = polyOne.length - 1;
int[] remainder = new int[polynomialAfterSubtract.size()]; int secondPolyDeg = polyTwo.length - 1;
for (int i = 0; i < polynomialAfterSubtract.size(); i++) { int[] tempArr = new int[polyOne.length];
remainder[i] = polynomialAfterSubtract.get(i); int[] result;
fillTemporaryArray(polyTwo, tempArr);
int tempMultiplier;
int shift = 0;
while (firstPolyDeg >= secondPolyDeg) {
parseNegativeElement(polyOne, firstPolyDeg);
tempMultiplier = findMultiplier(polyOne[firstPolyDeg], polyTwo[secondPolyDeg]);
tempArr = shiftValuesInArray(tempArr, shift);
tempArr = multiplyPolyByNumber(tempArr, tempMultiplier);
tempArr = moduloArray(tempArr);
polyOne = subtractTwoPolynomials(polyOne, tempArr);
firstPolyDeg--;
shift++;
} }
return remainder; result = Arrays.copyOf(polyOne, shift - 1);
return result;
} }
private List<Integer> calcQuotient(List<Integer> firstPoly, List<Integer> secondPoly, int[] quotient) throws MultiplierNotFoundException, DivisionErrorException { private void fillTemporaryArray(int[] polyTwo, int[] tempArr) {
int firstPolyDegree = firstPoly.size() - 1; for (int i = 0; i < polyTwo.length; i++) {
int secondPolyDegree = secondPoly.size() - 1; tempArr[tempArr.length - 1 - i] = polyTwo[polyTwo.length - 1 - i];
if (firstPolyDegree < secondPolyDegree) {
throw new DivisionErrorException();
} }
int quotientCoefficient;
if ((((float) firstPoly.get(firstPolyDegree) / (float) secondPoly.get(secondPolyDegree))) == Math.round(firstPoly.get(firstPolyDegree) / secondPoly.get(secondPolyDegree))) {
quotientCoefficient = firstPoly.get(firstPolyDegree) / secondPoly.get(secondPolyDegree);
} else {
quotientCoefficient = invElem(firstPoly.get(firstPolyDegree), secondPoly.get(secondPolyDegree));
}
quotient[firstPolyDegree - secondPolyDegree] += quotientCoefficient;
List<Integer> newPoly = generatePolyFromIndexAndValue(firstPolyDegree - secondPolyDegree, quotientCoefficient);
Integer[] multipliedPolynomials = multiplyPolynomials(newPoly, secondPoly);
List<Integer> polynomialAfterFirstDivide = new ArrayList<>(Arrays.asList(multipliedPolynomials));
return removeUnnecessaryZeros(subtractTwoPolynomials(firstPoly, polynomialAfterFirstDivide));
} }
private List<Integer> removeUnnecessaryZeros(List<Integer> polynomialAfterSubtract) { private int[] subtractTwoPolynomials(int[] polyOne, int[] polyTwo) {
int amountOfZeros = 0; int[] result = new int[polyOne.length];
for (int i = polynomialAfterSubtract.size() - 1; i >= 0; i--) { for (int i = 0; i < polyOne.length; i++) {
if (polynomialAfterSubtract.get(i) == 0) { result[i] = polyOne[i] - polyTwo[i];
amountOfZeros++;
} else {
break;
}
} }
return result;
polynomialAfterSubtract = polynomialAfterSubtract.subList(0, polynomialAfterSubtract.size() - amountOfZeros);
return polynomialAfterSubtract;
} }
private List<Integer> subtractTwoPolynomials(List<Integer> firstPoly, List<Integer> secondPoly) { private int[] moduloArray(int[] array) {
List<Integer> subtractedPolynomial = new ArrayList<>(Collections.nCopies(firstPoly.size() + secondPoly.size(), 0)); for (int i = 0; i < array.length; i++) {
for (int index = firstPoly.size(); index >= 0; index--) { array[i] = array[i] % n;
if (index < secondPoly.size()) {
subtractedPolynomial.set(index, firstPoly.get(index) - secondPoly.get(index));
parseNegativeElement(subtractedPolynomial, index);
}
} }
return subtractedPolynomial; return array;
} }
private void parseNegativeElement(List<Integer> subtractedPolynomial, int index) { private int[] multiplyPolyByNumber(int[] poly, int multiplier) {
while (subtractedPolynomial.get(index) < 0) for (int i = 0; i < poly.length; i++) {
subtractedPolynomial.set(index, (subtractedPolynomial.get(index) * subtractedPolynomial.get(index)) % n); poly[i] = poly[i] * multiplier;
} }
private List<Integer> generatePolyFromIndexAndValue(int size, int quotientCoefficient) {
List<Integer> poly = new ArrayList<>(Collections.nCopies(size + 1, 0));
poly.set(size, quotientCoefficient);
return poly; return poly;
} }
private int invElem(int a, int b) throws MultiplierNotFoundException { private int[] shiftValuesInArray(int[] array, int amount) {
if (amount == 0) {
return array;
} else {
int[] res = new int[array.length];
System.arraycopy(array, amount, res, 0, array.length - amount);
for (int j = array.length - amount + 1; j < res.length; j++) {
res[j] = 0;
}
return res;
}
}
private void parseNegativeElement(int[] polyOne, int firstPolyDeg) {
while (polyOne[firstPolyDeg] < 0) {
polyOne[firstPolyDeg] = n + polyOne[firstPolyDeg];
}
}
private int findMultiplier(int a, int b) {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (a == (b * i) % n) { if (a == (b * i) % n) {
return i; return i;
} }
} }
return -1;
throw new MultiplierNotFoundException();
} }
public void printAllValuesToStandardOutput() throws DivisionErrorException, MultiplierNotFoundException { public String printMultipliedPoly() {
List<List<Integer>> values = new ArrayList<>(); return Arrays.toString(multiplyPolynomials(firstPolynomialAsArray, secondPolynomialAsArray));
values.add(Arrays.asList(multiplyPolynomials(firstPolynomial, secondPolynomial))); }
values.add(Arrays.stream(moduloDividePolynomialsReturnQuotient(firstPolynomial, secondPolynomial)).boxed().collect(Collectors.toList()));
try { public String printSubtractedPoly() {
values.add(gcd(firstPolynomial, secondPolynomial)); int[] result = polyDiv(firstPolynomialAsArray, secondPolynomialAsArray);
} catch (MultiplierNotFoundException e) { if (result == null) {
return "Division Error";
} else if (result.length == 0) {
return "[0]";
} else {
return Arrays.toString(polyDiv(firstPolynomialAsArray, secondPolynomialAsArray));
} }
System.out.println(values);
} }
private List<Integer> gcd(List<Integer> polyOne, List<Integer> polyTwo) throws MultiplierNotFoundException, DivisionErrorException { public String printGcd() {
if (polyTwo.isEmpty()) return polyOne; int[] gcd = gcd(firstPolynomialAsArray, secondPolynomialAsArray);
List<Integer> poly = Arrays.stream(moduloDividePolynomialsReturnQuotient(polyOne, polyTwo)).boxed().collect(Collectors.toList()); if (gcd == null) {
return gcd(polyTwo, poly); return "Division Error";
} else
return Arrays.toString(gcd);
}
private int[] gcd(int[] firstPoly, int[] secondPoly) {
if (secondPoly.length == 0) {
return firstPoly;
}
if (firstPoly.length >= secondPoly.length) {
return gcd(secondPoly, polyDiv(firstPoly, secondPoly));
} else {
return gcd(secondPoly, polyDiv(secondPoly, firstPoly));
}
} }
} }