1
0
Fork 0
StringMultiplication/src/de/janchristiangruenhage/math/addition/Addition.java
Jan Christian Grünhage 76f4567346 Initial commit
2016-01-13 18:48:57 +01:00

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;
}
}
}