305 lines
11 KiB
Java
305 lines
11 KiB
Java
package de.janchristiangruenhage.math.addition;
|
|
|
|
import de.janchristiangruenhage.exceptions.FeatureNotImplementedYetException;
|
|
import de.janchristiangruenhage.math.Number;
|
|
|
|
public class Addition {
|
|
private String[] addends;
|
|
private int splitLines;
|
|
private String result;
|
|
private int resultLength;
|
|
private boolean cutResult;
|
|
private String resultCarry;
|
|
private boolean calculated;
|
|
|
|
/**
|
|
* Constructs a new <tt>Addition.</tt>
|
|
*
|
|
* @param addends The Addends
|
|
* @param splitLines After how many lines an additional Result will be calculated
|
|
* @param resultLength How many digits the result should have, for overflow or a carry
|
|
* see cutResult
|
|
* @param cutResult If the result should be cut
|
|
*/
|
|
public Addition(String[] addends, int splitLines, int resultLength, boolean cutResult) {
|
|
this.addends = addends;
|
|
this.splitLines = splitLines;
|
|
this.resultLength = resultLength;
|
|
this.cutResult = cutResult;
|
|
}
|
|
|
|
/**
|
|
* Creates an easily readable Addition and returns it.
|
|
*
|
|
* @return String representation of the Calculation
|
|
*/
|
|
public String printCalculation() {
|
|
if (calculated) {
|
|
return result;
|
|
}
|
|
if (splitLines != 0) {
|
|
//decides whether the Addition has to be split before Calculation
|
|
throw new FeatureNotImplementedYetException();
|
|
//Throws new Feature not Implemented Yet Exception
|
|
//return splitAndPrint();
|
|
//splits and prints the calculation, not working yet
|
|
} else {
|
|
return print();
|
|
//just prints the calculation
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates an easily readable Addition and returns it.
|
|
* This is used if the Addition doesn't have to be split anymore
|
|
*
|
|
* @return String representation of the Calculation
|
|
*/
|
|
private String print() {
|
|
int maximum = 0;
|
|
//Variable for the Maximum Length of a Addend String
|
|
String[] shortenedAddends = new String[addends.length];
|
|
for (int i = 0; i < addends.length; i++) {
|
|
shortenedAddends[i] = addends[i].substring(1).trim();
|
|
//The substring for removing the plus symbol at the beginning, the trimming for removing unnecessary spaces
|
|
maximum = (shortenedAddends[i].length() > maximum) ?
|
|
//Checks whether the length of the i-th String is higher than the maximum variable
|
|
shortenedAddends[i].length() : maximum;
|
|
//Assigns the maximum the correct value, the string length if its bigger, itself otherwise
|
|
}
|
|
result = "";
|
|
//Constructs the new String where the result will be saved in
|
|
String carries = "0";
|
|
//Constructs the new String where the carries will be saved in
|
|
int carry = 0;
|
|
//New variable for the carry at the point of the calculation
|
|
for (int i = 0; i < maximum; i++) {
|
|
AdditionColumn additionColumn = new AdditionColumn(shortenedAddends, carries, carry, i).invoke();
|
|
//Method-Object for calculating a single column of the addition
|
|
carries = additionColumn.getCarries();
|
|
//Get the carries string from the Method-Object
|
|
carry = additionColumn.getCarry();
|
|
//Get the carry from the Method-Object
|
|
}
|
|
String retVal = "";
|
|
//Construct the retVal String where the calculation wil be put into
|
|
for (String addend : shortenedAddends) {
|
|
retVal = addAddend(retVal, addend);
|
|
//Adds the addend to the retVal string in a new line
|
|
}
|
|
for (int i = 0; i < addends[0].length(); i++) {
|
|
retVal += " ";
|
|
//Adds a line of spaces
|
|
}
|
|
retVal += "\n";
|
|
//Adds a new line
|
|
while (carries.length() > 0 && carries.charAt(0) == '0') {
|
|
carries = carries.substring(1, carries.length());
|
|
//removes leading zeroes from the carries string
|
|
}
|
|
if (cutResult && carries.length() > resultLength) {
|
|
carries = "("
|
|
+ carries.substring(0, carries.length() - resultLength)
|
|
+ ")"
|
|
+ carries.substring(carries.length() - resultLength);
|
|
//adds braces around the cut part of the result, if wanted
|
|
}
|
|
while (carries.length() < addends[0].length() - 1) {
|
|
carries = " " + carries;
|
|
//elongates the carries string with spaces
|
|
}
|
|
carries = "+" + carries;
|
|
//adds the plus symbol to the carries string
|
|
retVal += carries + "\n";
|
|
//adds the carries string to the retVal string in a new line
|
|
for (int i = 0; i < addends[0].length(); i++) {
|
|
retVal += "_";
|
|
//draws a line
|
|
}
|
|
retVal += "\n";
|
|
//adds new line
|
|
if (cutResult && result.length() > resultLength) {
|
|
resultCarry = result.substring(0, result.length() - resultLength);
|
|
//cuts the carry from the result
|
|
result = "("
|
|
+ resultCarry
|
|
+ ")"
|
|
+ result.substring(result.length() - resultLength);
|
|
//adds braces around the carry
|
|
}
|
|
while (result.length() <= addends[0].length() - 1) {
|
|
result = " " + result;
|
|
//elongates the result string
|
|
}
|
|
retVal += result;
|
|
//adds the result to the retVal string
|
|
retVal += "\n\n\n\n";
|
|
//adds four new lines after the calculation
|
|
calculated = true;
|
|
//sets calculated to true, that the result doesn't have to be recalculated if it is needed again
|
|
return retVal;
|
|
}
|
|
|
|
private String addAddend(String retVal, String addend) {
|
|
String addendCopy = addend;
|
|
while (addendCopy.length() > 0 && addendCopy.charAt(0) == '0') {
|
|
addendCopy = addendCopy.substring(1, addendCopy.length());
|
|
//cuts leading zeroes
|
|
}
|
|
if (addendCopy.length() == 0) {
|
|
return retVal;
|
|
//skips the addend, if it is zero and therefore an empty line
|
|
}
|
|
if (cutResult && addend.length() > resultLength) {
|
|
addendCopy = "("
|
|
+ addend.substring(0, addend.length() - resultLength)
|
|
+ ")"
|
|
+ addend.substring(addend.length() - resultLength);
|
|
//adds braces around the cut part of the addend
|
|
}
|
|
while (addendCopy.length() < addends[0].length() - 1) {
|
|
addendCopy = " " + addendCopy;
|
|
//elongates the addend with spaces
|
|
}
|
|
addendCopy = "+" + addendCopy;
|
|
//adds a plus symbol in front of the addend
|
|
retVal += addendCopy;
|
|
//adds the addend to the retVal string
|
|
retVal += "\n";
|
|
//adds a new line to the retVal string
|
|
return retVal;
|
|
}
|
|
|
|
// /**
|
|
// * TODO: Not Working ATM
|
|
// * <p>
|
|
// * Creates an easily readable Addition and returns it.
|
|
// * This first splits the Additions and then calls their printCalculation() Method
|
|
// * it is therefore an indirect recursion, since this method is only called by the
|
|
// * printCalculation() Method.
|
|
// *
|
|
// * @return String representation of the Calculation
|
|
// */
|
|
// private String splitAndPrint() {
|
|
// int numberOfAdditions = (addends.length - splitLines) / (splitLines - 1) + 1;
|
|
// if (addends.length - splitLines - numberOfAdditions * (splitLines - 1) != 0) {
|
|
// numberOfAdditions += 1;
|
|
// }
|
|
// Addition[] additions = new Addition[numberOfAdditions];
|
|
// String[] carries = new String[numberOfAdditions - 1];
|
|
// for (int i = 0; i < additions.length; i++) {
|
|
// copyAddends(additions, carries, i);
|
|
// }
|
|
// String retVal = "";
|
|
// for (Addition addition : additions) {
|
|
// retVal = addition.printCalculation() + retVal;
|
|
// }
|
|
// return retVal;
|
|
// }
|
|
|
|
// //TODO: Not Working ATM
|
|
// private void copyAddends(Addition[] additions, String[] carries, int i) {
|
|
// if (i == 0) {
|
|
// String[] addends = new String[splitLines];
|
|
// System.arraycopy(this.addends, 0, addends, 0, splitLines);
|
|
// additions[i] = new Addition(addends, 0, resultLength, cutResult);
|
|
// carries[i] = additions[i].calcResult().getResult();
|
|
// } else {
|
|
// String[] addends = new String[splitLines];
|
|
// addends[0] = carries[i - 1];
|
|
// System.arraycopy(this.addends, splitLines + (i - 1) * (splitLines - 1), addends, 1, splitLines - 1);
|
|
// additions[i] = new Addition(addends, 0, resultLength, cutResult);
|
|
// if (i < carries.length) {
|
|
// carries[i] = additions[i].calcResult().getResult();
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// /**
|
|
// * Getter for the Result
|
|
// *
|
|
// * @return the Result
|
|
// */
|
|
// private String getResult() {
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Calculates the Result, but doesn't return the result, it returns itself instead.
|
|
// *
|
|
// * @return Itself
|
|
// */
|
|
// private Addition calcResult() {
|
|
// printCalculation();
|
|
// return this;
|
|
// }
|
|
|
|
/**
|
|
* Getter for the ResultCarry, which is the Carry of the Result
|
|
*
|
|
* @return the ResultCarry
|
|
*/
|
|
public String getResultCarry() {
|
|
return resultCarry;
|
|
}
|
|
|
|
/**
|
|
* The Class <tt>AdditionColumn</tt> represents one Column of the Addition
|
|
*/
|
|
private class AdditionColumn {
|
|
private String[] shortenedAddends;
|
|
private String carries;
|
|
private int carry;
|
|
private int i;
|
|
|
|
/**
|
|
* Constructs a new <tt>AdditionColumn</tt>
|
|
*
|
|
* @param shortenedAddends The Addend Strings,
|
|
* without additional spacing and the plus symbol
|
|
* @param carries The String of Carries
|
|
* @param carry The Carry for this column
|
|
* @param i which column of the Addends should be used
|
|
*/
|
|
public AdditionColumn(String[] shortenedAddends, String carries, int carry, int i) {
|
|
this.shortenedAddends = shortenedAddends;
|
|
this.carries = carries;
|
|
this.carry = carry;
|
|
this.i = i;
|
|
}
|
|
|
|
/**
|
|
* Getter for the Carries
|
|
*
|
|
* @return the carries
|
|
*/
|
|
public String getCarries() {
|
|
return carries;
|
|
}
|
|
|
|
/**
|
|
* Getter for the Carry
|
|
*
|
|
* @return the Carry
|
|
*/
|
|
public int getCarry() {
|
|
return carry;
|
|
}
|
|
|
|
public AdditionColumn invoke() {
|
|
Number resultNum = new Number(0);
|
|
for (String addend : shortenedAddends) {
|
|
if ((addend.length() - i - 1) >= 0) {
|
|
resultNum.add(Number.parseNumber(addend.charAt(addend.length() - i - 1)));
|
|
}
|
|
}
|
|
resultNum.add(new Number(carry));
|
|
carry = resultNum.getCarry();
|
|
Number carryNum = new Number(carry);
|
|
carries = carryNum.getNumber() + carries;
|
|
result = resultNum.getNumber() + result;
|
|
return this;
|
|
}
|
|
}
|
|
}
|