#java #деление #большие_числа
Нужно написать класс который бы делил одно число на другое, выводя деление в столбик.
Деление целочисленное. Если остался остаток, просто вывести его в последней строке,
если остается ноль его не выводим. Пример результата, который должен вернуться:
Мой код:
public class LongDivUtil {
private String result = "";
private int remDiv = 0;
private int quotient;
private int dividend;
private int divider;
private int[] numbersDividend;
private String[] numbersOfDividendInStrVal;
public LongDivUtil(int dividend, int divider) {
this.dividend = dividend;
this.divider = divider;
this.numbersOfDividendInStrVal = (dividend + "").split("");
this.numbersDividend = new int[numbersOfDividendInStrVal.length];
for (int i = 0; i < numbersOfDividendInStrVal.length; i ++){
numbersDividend[i] = Integer.parseInt(numbersOfDividendInStrVal[i]);
}
}
public void executeDivision(){
System.out.println("execute");
System.out.println(this.dividend + "|" + this.divider);
/////////////////////////////////////////////////////////////////
int tmpInt = numbersDividend[0];
boolean isContinue = false;
for (int i = 0; i < numbersOfDividendInStrVal.length || isContinue; i++) {
if (tmpInt >= divider) {
quotient = tmpInt / divider;
result += quotient;
remDiv = tmpInt % divider;
isContinue = false;
System.out.println("result = " + result);////////////////
System.out.println("remDiv = " + remDiv);//////////////
if (remDiv != 0 && i != numbersOfDividendInStrVal.length - 1){//1
tmpInt = Integer.parseInt((remDiv + "") + (numbersDividend[i] + ""));
System.out.println(tmpInt);
continue;
}
if (i < numbersOfDividendInStrVal.length -1){//2
tmpInt = numbersDividend[++i];
isContinue = true;
}
continue;
} else {
if (tmpInt == 0){//4
result += tmpInt;
if (i < numbersOfDividendInStrVal.length){
tmpInt = i;
}
isContinue = false;
continue;
}
if (tmpInt < divider){
tmpInt = Integer.parseInt(numbersOfDividendInStrVal[i] + numbersOfDividendInStrVal[++i]);
isContinue = true;
continue;
}
}
}
/////////////////////////////////////////////////////////////
System.out.println("out");
}
}
В нете, часто встречающийся вопрос, но ничего не находил в рекомендациях. Пока пишу
сам, но получается, мягко говоря, не очень. Кто ни будь сталкивался с подобным?
Ответы
Ответ 1
Код стоит подправить, но представленный пример показывает основные принципы, которые необходимо реализовать. public class LongDivUtil { private int dividend; private int divider; private int n; private StringBuffer dividendSB; private StringBuffer result=new StringBuffer(""); private StringBuffer firstSplitedString; private StringBuffer secondSplitedString; private StringBuffer print=new StringBuffer(""); public LongDivUtil(int dividend, int divider) { this.dividend = dividend; this.divider = divider; result=new StringBuffer(""); this.dividendSB=new StringBuffer(Integer.toString(this.dividend)); } public void printSomeCharSomeTimes(String s,int n){ for (int i = 0; i=this.divider;i++){ print.append("\n"+t.toString()+this.getLeftDividendNumber()); count(); print.append("\n"+t.toString()+n*divider); t.append(" "); } if (this.dividend!=0) result.append("."); int numberOfDigits=5; while(this.dividend!=0&&numberOfDigits!=0){ for (int i =0;dividend 0){ result.append("0"); } } count(); numberOfDigits--; } return result; } public int getLeftDividendNumber(){ int i=1; while (Integer.parseInt(Integer.toString(this.dividend).substring(0, i)) Ответ 2
Смысл в том что в классе сначала реализуется конвейер деления. Каждый этап добавляется в строку результата. Потом сторка модифициреутся для отображения красивого деления в столбик. На входе главного метода два числа(делимое и делитель), на выходе получаем строку - полную отрисовку деления в столбик. Метод легко тестируется. public class Division { private StringBuilder result = new StringBuilder(); private StringBuilder quotient = new StringBuilder(); private StringBuilder reminder= new StringBuilder(); public String makeDivision(int dividend, int divisor) { if (divisor == 0) { throw new IllegalArgumentException("Divisor cannot be 0, division by zero"); } dividend = Math.abs(dividend); divisor = Math.abs(divisor); if (dividend < divisor) { return "" + dividend + "/" + divisor + "=0"; } String[] digits = String.valueOf(dividend).split(""); Integer reminderNumber; Integer multiplyResult; Integer divisorDigit = calculateDigit(divisor); Integer mod; for (int i = 0; i < digits.length; i++) { reminder.append(digits[i]); reminderNumber = Integer.parseInt(reminder.toString()); if (reminderNumber >= divisor) { mod = reminderNumber % divisor; multiplyResult = reminderNumber / divisor * divisor; String lastReminder = String.format("%" + (i + 2) + "s", "_" + reminderNumber.toString()); result.append(lastReminder).append("\n"); String multiply = String.format("%" + (i + 2) + "d", multiplyResult); result.append(multiply).append("\n"); Integer tab = lastReminder.length() - calculateDigit(multiplyResult); result.append(makeDivider(reminderNumber, tab)).append("\n"); quotient.append(reminderNumber / divisor); reminder.replace(0, reminder.length(), mod.toString()); reminderNumber = Integer.parseInt(reminder.toString()); } else { if (i >= divisorDigit) { quotient.append(0); } } if (i == digits.length - 1) { result.append(String.format("%" + (i + 2) + "s", reminderNumber.toString())).append("\n"); } } modifyResultToView(dividend, divisor); return result.toString(); } private String makeDivider(Integer reminderNumber, Integer tab) { return assemblyString(tab, ' ') + assemblyString(calculateDigit(reminderNumber), '-'); } private void modifyResultToView(Integer dividend, Integer divisor) { int[] index = new int[3]; for (int i = 0, j = 0; i < result.length(); i++) { if (result.charAt(i) == '\n') { index[j] = i; j++; } if (j == 3) { break; } } int tab = calculateDigit(dividend) + 1 - index[0]; result.insert(index[2], assemblyString(tab, ' ') +"│" + quotient.toString()); result.insert(index[1], assemblyString(tab, ' ') +"│" + assemblyString(quotient.length(), '-')); result.insert(index[0], "│" + divisor); result.replace(1, index[0], dividend.toString()); } private int calculateDigit(int i) { return (int) Math.log10(i) + 1; } private String assemblyString(int numberOfSymbols, char symbol) { StringBuilder string = new StringBuilder(); for (int i = 0; i < numberOfSymbols; i++) { string.append(symbol); } return string.toString(); } } пример результата: _10210│5 10 │---- -- │2042 _21 20 -- _10 10 -- 0 Пример теста: Division division = new Division(); @Test public void shouldMakeDivision() { String expected = "_14789│20\n" + " 140 │---\n" + " --- │739\n" + " _78\n" + " 60\n" + " --\n" + " _189\n" + " 180\n" + " ---\n" + " 9\n"; assertEquals(expected, division.makeDivision(14789, 20)); }
Комментариев нет:
Отправить комментарий