1
0
Fork 0
StringMultiplication/src/de/janchristiangruenhage/math/addition/Addition.java
Jan Christian Grünhage 20fe63bd5f Bugfixes
Fixed Bug with splitLines argument, works now,
arrays (mostly?) replaced with linked lists
2016-01-13 22:45:13 +01:00

306 lines
11 KiB
Java

package de.janchristiangruenhage.math.addition;
import de.janchristiangruenhage.math.Number;
import java.util.LinkedList;
public class Addition {
private LinkedList<String> addends;
private int splitLines;
private String printedCalculation;
private String result;
private int resultLength;
private boolean cutResult;
private String resultCarry;
private boolean calculated;
private int lineLength;
/**
* 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
* @param lineLength How long each line should be
*/
public Addition(LinkedList<String> addends, int splitLines, int resultLength, boolean cutResult, int lineLength) {
this.addends = addends;
this.splitLines = splitLines;
this.resultLength = resultLength;
this.cutResult = cutResult;
this.lineLength = lineLength;
}
/**
* Creates an easily readable Addition and returns it.
*
* @return String representation of the Calculation
*/
public String printCalculation() {
if (calculated) {
return printedCalculation;
}
if (splitLines != 0 && splitLines < addends.size()) {
//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
LinkedList<String> shortenedAddends = new LinkedList<>();
for (String addend : addends) {
shortenedAddends.add(addend.substring(1).trim());
//The substring for removing the plus symbol at the beginning, the trimming for removing unnecessary spaces
maximum = (shortenedAddends.getLast().length() > maximum) ?
//Checks whether the length of the i-th String is higher than the maximum variable
shortenedAddends.getLast().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
}
if (carry != 0) {
result = carry + result;
}
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 < lineLength; 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() < lineLength - 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 < lineLength; 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() <= lineLength - 1) {
result = " " + result;
//elongates the result string
}
retVal += result;
//adds the result to the retVal string
retVal += "\n\n";
//adds four new lines after the calculation
printedCalculation = retVal;
//saving the printed calculation for later usage
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() < lineLength - 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() {
LinkedList<Addition> additions = new LinkedList<>();
int carryLine = 0;
while (addends.size() > 0) {
LinkedList<String> addends = new LinkedList<>();
if (carryLine != 0) {
String intermediateResult = additions.getLast().calculateResult();
if (cutResult) {
intermediateResult = intermediateResult.replaceFirst("\\(", "");
intermediateResult = intermediateResult.replaceFirst("\\)", "");
}
addends.add(intermediateResult);
}
for (int i = 0; i < splitLines - carryLine; i++) {
addends.add(this.addends.removeFirst());
if (this.addends.size() == 0) {
break;
}
}
additions.add(new Addition(addends, splitLines, resultLength, cutResult, lineLength));
carryLine = 1;
}
String retVal = "";
for (Addition addition : additions) {
retVal += addition.printCalculation();
}
resultCarry = additions.getLast().getResultCarry();
result = additions.getLast().calculateResult();
return retVal;
}
/**
* Calculator for the Result
*
* @return the Result
*/
private String calculateResult() {
printCalculation();
return result;
}
/**
* 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 LinkedList<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(LinkedList<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;
}
}
}