20fe63bd5f
Fixed Bug with splitLines argument, works now, arrays (mostly?) replaced with linked lists
306 lines
11 KiB
Java
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;
|
|
}
|
|
|
|
|
|
}
|
|
}
|