Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Hints 1. Not explicitly included in the C implementation of the FRACTION ADT are several Java class concepts described in Chapters #8 and #9. You

image text in transcribed

Hints

1. Not explicitly included in the C implementation of the FRACTION ADT are several Java class concepts described in Chapters #8 and #9. You should decide what to do about each of the following

a) An override of the toString() method (inherited from the class Object) that is called implicitly whenever a FRACTION object appears in the code where a String is needed. (Note See Section 9.6 for a discussion of the class Object. There are several other Object methods that should also be considered including clone(), equals(), and finalize(). finalize() is discussed below.)

b) A finalize() method called by the garbage collector to perform termination housekeeping for an object just before the objects memory is reclaimed. (Note finalize() is akin to a C++ destructor ~FRACTION() and the ADTs DestructFRACTION() method).

c) A no-argument constructorin addition to constructors that take one or more argumentsto ensure that an application can instantiate a FRACTION object with default values.

d) Accessor (get) and mutator (set) methods to provide application program read/write access to private-access FRACTION instance variables.

2. The FRACTION ADT utility functions SetSign() and Reduce() are used to be defined in C using the static prefix to denote private accessibility (static C functions had file scope) and should not be confused with static-versus-non-static definition of C++ member functions and Java methods. Just for fun, consider defining SetSign() as a static method and Reduce() as a non-static method in your Java implementation of the class FRACTION. Both utility functions should be defined in Java with private accessibility for the same reason that the FRACTION ADT implementation used to define them as static functions. Confusing, right?!

3. How does Java express the const-ness of method parameters? Answer final almost works (smile)! Read carefully

Use the final keyword (sicshould be described as a reserved wordsee Note below) liberally to communicate your intent. The final keyword has more than one meaning (1) a final class cannot be extended; (2) a final method cannot be overridden; and (3) final fields [instance variables], parameters, and local variables cannot change their value once set. [Note Technically speaking, a keyword can also be used as a programmer identifier to name variables, constants, modules et cetera, whereas a reserved word is reserved or set aside to be used solely by the programming language for its intended use. C, C++, and Java have reserved words like if, then, int, switch, case, for, break, et cetera. See http://en.wikipedia.org/wiki/Reserved_word for more details.]

In the last case, value for primitives is understood in the usual sense, while value for objects means the objects identity, not its state. Once the identity of a final object reference is set, it can still change its state, but not its identity (that is, you cannot re-point the object reference to some other object). Declaring primitive fields as final automatically ensures thread-safety for that field. [Note We will learn about threads when we study Chapter #23 Concurrency) later in the semester.]

Some programmers habitually declare parameters as final, since this is almost always the desired behavior. [Why does this idea make sense?] Others find this verbose, and of little real benefit. [What do you think?]

Consistently using final with local variables (when appropriate) can be useful as well. It brings attention to the non-final local variables, which usually have more logic associated with them (for example, result variables, accumulators, loop variables, et cetera). Many find this verbose. A reasonable approach is to occasionally use final for local variables, but only if there is some unusual condition, whereby making final explicit can call attention to at least one non-final local variable in the method; this serves to quickly distinguish the non-final local variables from the others.

Finl-ly, using final, (1) clearly communicates your intent; (2) allows the compiler and the Java virtual machine (JVM) to perform minor optimizations; and (3) clearly flags items that are simpler in behavior. final says, If you are looking for complexity, you wont find it here.

Based on http://www.javapractices.com/topic/TopicAction.do?Id=23 on February 7, 2015.

4. (Continuing 3) Both C++ and Java allow non-static class functions to refer to the object that called the class function by using the reserved word this. C++ treats this as a pointer-to the object and Java treats this as a reference to the object. How does Java express the const-ness of the implied parameter this? Answer Dr. Hanna was not able to find a way to express const-ness for this! After reading Hints 3 and 4, he has despaired of finding a way to guarantee the const-ness of objects that are referenced by method parameters! Do you consider this limitation a design-flaw of the Java programming language?!

5. The following Java code is necessary to pass the predefined System.out stream to the method OutputFRACTION().

// FRACTION.java code

import java.io.*;

//---------------------------------------------------------

public void OutputFRACTION(PrintStream OUT)

//---------------------------------------------------------

{

OUT.printf("%c%d/%d",((this.sign == -1) ? '-' : '+'),this.N,D);

}

// Problem16.java

System.out.printf("LHS = ");

LHS.OutputFRACTION(System.out);

System.out.printf(" ");

6. The following Java code is necessary to pass a programmer-defined Scanner object named IN to the method InputFRACTION().

// FRACTION.java code

//---------------------------------------------------------

public void InputFRACTION(Scanner IN)

//---------------------------------------------------------

{

this.N = IN.nextInt();

IN.skip(" / ");

this.D = IN.nextInt();

SetSign();

Reduce(this);

}

// Problem16.java code

import java.util.Scanner;

Scanner IN = new Scanner(System.in);

System.out.printf("LHS? "); LHS.InputFRACTION(IN);

7. (Continuing 6) The following Java code works to translate the C code, but requires the user of the program to type a space on either side of the forward slash. A real kludge! Can you find a better way? (Note A kludge is a workaround or quick-and-dirty solution that is clumsy (inelegant, difficult) to extend and hard to maintain, yet an effective and quick solution to a problem.)

this.N = IN.nextInt();

IN.skip(" / ");

this.D = IN.nextInt();

// C code

fscanf(IN,"%d/%d",&fraction->N,&fraction->D);

8. (Continuing 7) Late breaking news! Daniel Cyrus (Spring, 2015) suggested the use of the Scanner method useDelimiter(). Setting the delimiters used by a Scanner object is analogous to the library function strtok() use of delimiters to support tokenizing in C programs. The String literal "[/\\s]" is a regular expression that sets the delimiters to be used when scanning the IN stream for the next integer to the forward slash character and whitespace characters. IN.reset() resets the set of delimiters to its default value. IN.skip("\\s*/\\s*") then skips 0 or more whitespace characters, a single forward slash, and 0 or more whitespace characters.

//---------------------------------------------------------

public void InputFRACTION(Scanner IN)

//---------------------------------------------------------

{

IN.useDelimiter("[/\\s]");

this.N = IN.nextInt();

IN.skip("\\s*/\\s*");

this.D = IN.nextInt();

IN.reset();

SetSign();

Reduce(this);

}

9. If you plan to translate the following C code for SumOfFRACTION() into Java code, you must add a parameter-less constructor for FRACTION as shown below. What does the highlighted line in the added FRACTION constructor mean?

// C code

FRACTION fraction;

fraction.N = LHS->sign*LHS->N*RHS->D + RHS->sign*RHS->N*LHS->D;

fraction.D = LHS->D*RHS->D;

// Java code

FRACTION fraction = new FRACTION();

fraction.N = this.sign*this.N*RHS.D + RHS.sign*RHS.N*this.D;

fraction.D = this.D*RHS.D;

//---------------------------------------------------------

public FRACTION()

//---------------------------------------------------------

{

this(1,5);

}

10. SetSign() (which strips the negative signs out of N and D, stores them in sign, then ensures N and D are both non-negative) and Reduce() (reduce the fraction N/D to its lowest form) are used to normalize (or canonicalize) a FRACTION object. However, SetSign() does not always work correctly on an already-normalized FRACTION! Why?! You should be able to convince yourself, though, that Reduce() does always work correctly on an already-normalized FRACTION.

Notes

(1) Idempotence (term was introduced by Benjamin Peirce) is the property of certain operations that can be applied multiple times without changing the result beyond the initial application. For example, abs(x) == abs(abs(x)) = abs(abs(abs(x))), but x++ x++,x++ Is SetSign() idempotent?

(2) In Computer Science, when representing mathematical objects in a computer, there are usually many different ways to represent the same object. A canonical form is a representation such that every object has a unique representation. Thus, the equality of two objects can easily be tested by testing the equality of their canonical forms. Often the distinction between canonical and normal form is made; a canonical form specifies a unique representation for every object (so it is a syntactic and semantic concept), whereas a normal form simply specifies the objects form, without the requirement of uniqueness (so it is strictly a syntactic concept).

Taken from http://en.wikipedia.org/wiki/Canonical_form on February 9, 2015

//---------------------------------------------------------

// FRACTION header

// Fraction.h

//---------------------------------------------------------

#ifndef FRACTION_H

#define FRACTION_H

typedef struct

{

int sign; /* sign = -1 (negative), = +1 (non-negative) */

int N; /* (N)umerator */

int D; /* (D)enominator */

} FRACTION;

//---------------------------------------------------------

// Public Operations

//---------------------------------------------------------

void ConstructFRACTION(FRACTION *fraction,const int N,const int D);

FRACTION SumOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS);

FRACTION DifferenceOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS);

FRACTION ProductOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS);

FRACTION QuotientOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS);

void InputFRACTION(FRACTION *fraction,FILE *IN);

void OutputFRACTION(const FRACTION *fraction,FILE *OUT);

//---------------------------------------------------------

// Private (Utility) Operations

//---------------------------------------------------------

//int GCD(const int x,const int y);

//void SetSign(FRACTION *fraction);

//void Reduce(FRACTION *fraction);

#endif

//---------------------------------------------------------

// FRACTION function definitions

// Fraction.c

//---------------------------------------------------------

#include

#include

#include

#include ".\Fraction.h"

//---------------------------------------------------------

void ConstructFRACTION(FRACTION *fraction,const int N,const int D)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

fraction->N = N;

fraction->D = D;

SetSign(fraction); Reduce(fraction);

}

//---------------------------------------------------------

FRACTION SumOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

FRACTION fraction;

fraction.N = LHS->sign*LHS->N*RHS->D + RHS->sign*RHS->N*LHS->D;

fraction.D = LHS->D*RHS->D;

SetSign(&fraction); Reduce(&fraction);

return( fraction );

}

//---------------------------------------------------------

FRACTION DifferenceOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

FRACTION fraction;

fraction.N = LHS->sign*LHS->N*RHS->D - RHS->sign*RHS->N*LHS->D;

fraction.D = LHS->D*RHS->D;

SetSign(&fraction); Reduce(&fraction);

return( fraction );

}

//---------------------------------------------------------

FRACTION ProductOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

FRACTION fraction;

fraction.N = LHS->sign*LHS->N * RHS->sign*RHS->N;

fraction.D = LHS->D * RHS->D;

SetSign(&fraction); Reduce(&fraction);

return( fraction );

}

//---------------------------------------------------------

FRACTION QuotientOfFRACTIONs(const FRACTION *LHS,const FRACTION *RHS)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

FRACTION fraction;

fraction.N = LHS->sign*LHS->N * RHS->sign*RHS->D;

fraction.D = LHS->D * RHS->N;

SetSign(&fraction); Reduce(&fraction);

return( fraction );

}

//---------------------------------------------------------

void InputFRACTION(FRACTION *fraction,FILE *IN)

//---------------------------------------------------------

{

void SetSign(FRACTION *fraction);

void Reduce(FRACTION *fraction);

fscanf(IN,"%d/%d",&fraction->N,&fraction->D);

SetSign(fraction);

Reduce(fraction);

}

//---------------------------------------------------------

void OutputFRACTION(const FRACTION *fraction,FILE *OUT)

//---------------------------------------------------------

{

fprintf(OUT,"%c%d/%d",((fraction->sign == -1) ? '-' : '+'),fraction->N,fraction->D);

}

//---------------------------------------------------------

void SetSign(FRACTION *fraction)

//---------------------------------------------------------

{

if ( ((fraction->N >= 0) && (fraction->D >= 0)) ||

((fraction->N D

fraction->sign = +1;

else

fraction->sign = -1;

fraction->N = abs(fraction->N);

fraction->D = abs(fraction->D);

}

//---------------------------------------------------------

void Reduce(FRACTION *fraction)

//---------------------------------------------------------

{

int GCD(const int x,const int y);

int gcd = GCD(fraction->N,fraction->D);

fraction->N /= gcd;

fraction->D /= gcd;

}

//---------------------------------------------------------

int GCD(const int x,const int y)

//---------------------------------------------------------

{

if ( y == 0 )

return( x );

else

return( GCD(y,x % y) );

}

//---------------------------------------------------------

// Chapter #8, Problem #16

// Problem16.c

//---------------------------------------------------------

#include

#include

#include

#include ".\Fraction.h"

//---------------------------------------------------------

int main()

//---------------------------------------------------------

{

FRACTION r,LHS,RHS;

printf("LHS? "); InputFRACTION(&LHS,stdin);

ConstructFRACTION(&RHS,4,-12);

printf("LHS = "); OutputFRACTION(&LHS,stdout); printf(" ");

printf("RHS = "); OutputFRACTION(&RHS,stdout); printf(" ");

r = SumOfFRACTIONs(&LHS,&RHS);

printf("LHS+RHS = "); OutputFRACTION(&r,stdout); printf(" ");

r = DifferenceOfFRACTIONs(&LHS,&RHS);

printf("LHS-RHS = "); OutputFRACTION(&r,stdout); printf(" ");

r = DifferenceOfFRACTIONs(&RHS,&LHS);

printf("RHS-LHS = "); OutputFRACTION(&r,stdout); printf(" ");

r = ProductOfFRACTIONs(&LHS,&RHS);

printf("LHS*RHS = "); OutputFRACTION(&r,stdout); printf(" ");

r = QuotientOfFRACTIONs(&LHS,&RHS);

printf("LHS/RHS = "); OutputFRACTION(&r,stdout); printf(" ");

r = QuotientOfFRACTIONs(&RHS,&LHS);

printf("RHS/LHS = "); OutputFRACTION(&r,stdout); printf(" ");

system("PAUSE");

return( 0 );

}

Introduction A rational number is any number that can be expressed as the quotient or fraction N/D of two integers, with the denominator D not equal to zero. Since D may be equal to 1, every integer is a rational number The abstract data type, FRACTION (implemented in the C programming language), can be used to represent rational numbers. Problem Convert the C programming language implementation of the FRACTION abstract data type (found in source files Fraction.h and Fraction.c) into a Java class definition and convert the C application program Problem16.c into a Java console application. Sample Program Dialo Command Prompt C:NCOURSES CS2323NCode Chapter8>javac Problem16.java CNCOURSES CS2323NCode Chapter8>java Problemi6 LHS RHS LHS-RHS+2/15 LHSRHS+1/15 RHS/LHS+5/3 C:NCOURSES CS2323NCode Chapter8> Introduction A rational number is any number that can be expressed as the quotient or fraction N/D of two integers, with the denominator D not equal to zero. Since D may be equal to 1, every integer is a rational number The abstract data type, FRACTION (implemented in the C programming language), can be used to represent rational numbers. Problem Convert the C programming language implementation of the FRACTION abstract data type (found in source files Fraction.h and Fraction.c) into a Java class definition and convert the C application program Problem16.c into a Java console application. Sample Program Dialo Command Prompt C:NCOURSES CS2323NCode Chapter8>javac Problem16.java CNCOURSES CS2323NCode Chapter8>java Problemi6 LHS RHS LHS-RHS+2/15 LHSRHS+1/15 RHS/LHS+5/3 C:NCOURSES CS2323NCode Chapter8>

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Expert Performance Indexing In SQL Server

Authors: Jason Strate, Grant Fritchey

2nd Edition

1484211189, 9781484211182

More Books

Students also viewed these Databases questions

Question

Timeline for final evaluation

Answered: 1 week ago

Question

How will it be used?

Answered: 1 week ago