Большая целочисленная арифметика на Java - домашнее задание - PullRequest
1 голос
/ 01 декабря 2011

Так что это домашнее задание, и я работаю над ним около 10 часов. Я просто хотел бы несколько советов, чтобы увидеть, где я иду не так. Поэтому мое задание - по сути сделать калькулятор для больших целых чисел, и мой профессор предоставил скелет. Функции, которые он попросил нас написать, - это вычитание, деление, умножение, возведение в степень (x ^ n) и меньшая функция. Я почти уверен, что мои функции lessThan и multiply работают правильно, но, возможно, нет, в любом случае, моя работа ниже, и я опишу свои проблемы позже:

public class Calc {

//
// main
//
// Parses the command-line arguments as an integer
// operation, packages the operands as digit arrays,
// calls the appropriate calculator function, and 
// then outputs the result.
//
public static void main(String[] args) {
if (args.length == 3) {
    int[] input1 = construct(args[0]);
    int[] input2 = construct(args[2]);
    if (args[1].equals("plus")) {
    int[] result = plus(input1,input2);
    putln(result);
    } else if (args[1].equals("minus")) {
    int[] result = minus(input1,input2);
    putln(result);
    } else if (args[1].equals("times")) {
    int[] result = times(input1,input2);
    putln(result);
    } else if (args[1].equals("div")) {
    int[] result = div(input1,input2);
    putln(result);
    } else if (args[1].equals("power")) {
    int[] result = power(input1,input2);
    putln(result);
    } else if (args[1].equals("less")) {
    boolean result = lessThan(input1,input2);
    TextIO.putln(result);
    } else if (args[1].equals("equal")) {
    boolean result = equal(input1,input2);
    TextIO.putln(result);
    } else {
    TextIO.putln("Invalid binary operation.  Try using +, -, +, /, ^, <, or =.");
    }
} else if (args.length == 2) {
    int[] input = construct(args[0]);
    // it must be a unary operation
    if (args[1].equals("!")) {
    int[] result = factorial(input);
    TextIO.putln(result);
    } else {
    TextIO.putln("Expected factorial operation!");
    }
} else {
    TextIO.putln("Invalid input.  Try either a binary operation or factorial.");
}
}


//
// plus
//
// Computes the sum of two digit arrays,
// represented as a digit array.
//
public static int[] plus(int[] a, int[] b) {

// Determine the result's maximum length.
//
int alen, blen, len;
alen = length(a);
blen = length(b);
if (alen > blen) {
    len = alen + 1;
} else {
    len = blen + 1;
}

// Allocate an array of digits with that length.
//
int[] c = new int[len];

// Compute the sum of the digits, working from
// least to most significant.
//
int carry = 0;
for (int i = 0; i < len; i = i+1) {
    int sum = carry;
    if (i < alen) {
    sum = sum + a[i];
    }
    if (i < blen) {
    sum = sum + b[i];
    }
    c[i] = sum % 10;
    carry = sum / 10;
}

// Trim off the leading 0s.
//
return trim(c);
}

// INCOMPLETE
//
// minus
//
// Computes the difference of two digit arrays,
// represented as a digit array.
//
// You can assume that the first operand is 
// larger than the second one.
//
public static int[] minus(int[] a, int[] b) {
    if(equal(a,b))
    {
        int [] zero = new int [1];
                zero[0] = 0;
        return zero;
    }
    else{

    int c = 0;

    int lb = length(b);
    while(lb > c)
        {
            b[c] = (b[c]) * (-1);
            c++;
        }
    return plus(a,b);
    }
}


// INCOMPLETE
//
// times
//
// Computes the product of two digit arrays,
// represented as a digit array.
//
// HINT: use repeated addition.  You might need
//       to write lessThan first.
//
// BONUS: perform this using the schoolbook 
//        method.
//
public static int[] times(int[] a, int[] b) {
    int len;
        if(length(a) > length(b))
            len = length(a) + 1;
        else
            len = length(b) + 1;
        int[] c = new int[len];
        int[]counterArray;
        if(lessThan(a,b))
        {
            counterArray = new int[length(b)];
            counterArray[length(b)-1] = 1;
        }
        else
        {
            counterArray = new int[length(a)];
            counterArray[length(a)-1] = 1;
        }

        int[] counterTwo = new int[1];
        counterTwo[0] = 1;
        while(lessThan(counterArray,a))
            {
        c = plus(c,b);
        counterArray = plus(counterArray, counterTwo);
            }
        return plus(c,b);
}

// INCOMPLETE
//
// div
//
// Computes the quotient of two digit arrays,
// represented as a digit array.
//
public static int[] div(int[] a, int[] b) {
    int[] counter = zero();
    boolean value = true;
    if(lessThan(a,b))
        return zero();
    else {
        while(value)
        {
            a = minus(a,b);
            counter = plus(counter,one());
            if(lessThan(b,a))
                value = false;

        }
        return counter;
    }

/**boolean checker = false;
int[] c = new int[length(a)];
for(int i = 0; i < length(a); i++)
{
    c[i] = 0;
}
int counter = 0;
while (!checker)
{
    if(equal(a,c))
    {
        checker = true;

    }
    else if(lessThan(a,c))
    {
        checker = true;
    }
    else if (lessThan(c,a))
    {
        c = plus(c,b);
        counter++;
    }
}
return construct("" + (counter));*/
}

// 
// factorial
//
// Computes the factorial of a digit array,
// as a digit array.
//
public static int[] factorial(int[] a) {
int[] count = one();
int[] product = one();
while (lessThan(count,a) || equal(count,a)) {
    product = times(product,count);
    count = plus(count,one());
}
return product;
}

// INCOMPLETE
// 
// power
//
// Computes the p-th power of a digit array x, 
// where p is also given as a digit array.  The
// result is calculated as a digit array.
//
public static int[] power(int[] x, int[] p) {
    int pl = length(p);
    int[] checker = new int[1];
    checker[0] = 0;
    int[] adder = new int[1];
    adder[0] = 0;
    if ((p[pl - 1] % 2) == 0)
        {
            while(equal(checker,p) == false)
            {
                adder = plus(square(x),adder);
                p = minus(p,construct("" + 2));
            }
            return adder;
        }
    else
    {
        int[] checkertwo = new int[1];
        checkertwo[0] = 1;
        while(equal(checkertwo,p) == false)
        {
            adder = plus(square(x), adder);
            p = minus(p,construct("" + 2));
        }
        return times(adder,x);
    }
}

public static int[] square(int[] x)
{
    return times(x,x);
}

//
// equal
//
// Returns whether or not two digit arrays 
// represent the same number.
//
public static boolean equal(int[] a, int[] b) {
int[] ta = trim(a);
int[] tb = trim(b);
if (ta.length != tb.length) {
    return false;
} else {
    for (int i = a.length-1; i >= 0; i = i-1) {
    if (a[i] != b[i]) {
        return false;
    }
    }
    return true;
}
}

// INCOMPLETE
//
// lessThan
//
// Returns whether or not one digit array
// represents a number less than another.
//
public static boolean lessThan(int[] a, int[] b) {
boolean value = false;
a = minus(a,construct(""+0));
b = minus(b,construct(""+0));
if(length(b) > length(a))
{
    value = true;
}
else if(length(a) == length(b))
{
    boolean c = false;
    int counter = 0;
    while(counter < length(a))
        {
        c = false;
            if(a[counter] > b[counter])
            {
                c = true;
                value = false;
            }
            if(!c)
                value = true;
            counter++;
        }
}
else
    value = false;
return value;

}

// * * * * * * * * * * * * * * * * * * * * * * * * 
//
// These are helper functions that can be used in 
// the above code.
//

//
// construct
//
// Converts a string that consists of decimal digits
// into an array of those digits.
//
public static int[] construct(String digits) {
int len;
int[] a;

len = digits.length();
a = new int[len];

// Copy each digit of the string into
// the digit array, but as integers 
// rather than characters.

for (int i = len-1; i >= 0; i = i-1) {

    // get the i-th digit
    char c = digits.charAt(i);

    // check if it is a valid digit
    if (c >= '0' && c <= '9') {
    a[len-1-i] = (int)(c-'0');
    } else {
    // treat nondigits as 0 digits
    a[len-1-i] = 0;
    }
}

// trim off leading 0s
return trim(a);
}

//
// zero
//
// returns the digits representing 0
//
public static int[] zero() {
return construct("0");
}

//
// one
//
// returns the digits representing 0
//
public static int[] one() {
return construct("1");
}

//
// trim
//
// Takes an array of integer digits representing an integer,
// one that may have leading 0 digits, and constructs an 
// array with no leading digits.
//
public static int[] trim(int[] a) {
int len = length(a);

int[] b;
// build an array of that length
b = new int[len];

// set the digits
for (int i=0; i<len; i++) {
    b[i] = a[i];
}

return b;
}

// 
// put
//
// Outputs an array of digits, from most- to least-
// significant, excluding any leading 0s.
//
public static void put(int[] a) {
int len = length(a);

for (int i = len-1; i >= 0; i = i-1) {
    TextIO.put(a[i]);
}
}

// 
// putln
//
// Outputs an array of digits, from most- to least-
// significant, excluding any leading 0s, followed by
// a carriage return.
//
public static void putln(int[] a) {
put(a);
TextIO.putln();
}

// 
// length
//
// Counts the number of digits in a digit array
// excluding leading 0s.
//
public static int length(int[] a) {
int len = a.length;

// figure out the number's real length
while (len > 0 && a[len-1] == 0) {
    len = len - 1;
}
if (len == 0) {
    return 1;
} else {
    return len;
}
}

}

Кажется, моя функция минус не работает, по какой-то причине, я не знаю, что случилось. Для меня имеет смысл, что x - y = x + (-y), что я и сделал правильно. Возможно, плюс-функция, написанная моим профессором, плохо с этим работает? Я пытался думать об этом. И я думаю, что эта функция минус является неотъемлемой частью моих функций деления и власти. Мне жаль, что мои записи не ясны, но кто-то может, пожалуйста, просмотреть их и дать мне совет о том, где я испорчен с функцией минус, что наиболее важно, потому что я думаю, что, как только я получу это, чтобы работать правильно, я могу сделать отдых.

Ответы [ 2 ]

0 голосов
/ 01 декабря 2011

Добавьте приведенный ниже код в конец метода plus (в пределах цикла для ).

carry = sum / 10; // existing

if (c[i] < 0) {
   c[i] = c[i] + 10; // Create a positive complement of base 10.
   carry = carry - 1; // Borrowed. (or carry = -1)
}

Без этого исправления, когда цифра второго операнда больше,он вернул бы отрицательное значение, которое в результате выглядело бы как - цифра .Например, 12 + (-8) будет напечатано как 1-6

0 голосов
/ 01 декабря 2011

Этот код не проверен, но он должен работать:

public static int[] minus(int[] a, int[] b) {
    int len = length(a);
    int blen = length(b);

    int[] c = new int[len];

    int carry = 0;
    for (int i = 0; i < len; i = i+1) {

        int sum = a[i] - carry;
        if (i < blen) sum -= b[i];
        if (sum < 0) {
            sum += 10;
            carry = 1;
        } else {
            carry = 0;
        }
        c[i] = sum;
    }
}
...