For an assignment we are suppose to modify a custom BitString class. There are over 10 functions we need to actually write the code for and I am stuck on the very first one. This is the beginning parts to the class along with some of the methods contained that I am trying to use:
public class BitString implements Cloneable {
// An array to hold the bits that make up the bit string.
private boolean bits[];
/**
* A constant that defines the size of the default bit string.
*/
public static final int DEFAULT_SIZE = 8;
/**
* Creates a new, all false, bit string of the given size.
*/
public BitString(int size) {
if (size < 1) throw new IllegalArgumentException("Size must be positive");
bits = new boolean[size];
}
/**
* Creates a new all false bit string of size DEFAULT_SIZE.
*/
public BitString() {
this(DEFAULT_SIZE);
}
/**
* Set the value of a bit string at the given index to true.
*/
public void set(int index) {
bits[index] = true;
}
/**
* Set the value of a bit string at the given index to false.
*/
public void clear(int index) {
bits[index] = false;
}
Below is the method I am working on (The only part that was given is the method and the input types) I can not call bits.set() or bits.clear() or the same operations that they are doing. When compiling I get
Error: Cannot make a static reference to the non-static field bits
on both method calls.
public static BitString decimalToUnsigned(int n, int size) {
//throw new UnsupportedOperationException("This function needs to be completed!");
int result = 0;
int multiplier = 1;
int base = 2;
while(n > 0) {
int remainder = n % base;
n = n / base;
if (remainder == 0) {
//value = false;
try {
//bits.clear(size);
bits[size] = false;
} catch (InsufficientNumberOfBitsException ie) {}
} else {
//value = true;
try {
//bits.set(size);
bits[size] = true;
} catch (InsufficientNumberOfBitsException ie) {}
}
result = result + remainder * multiplier;
multiplier = multiplier * 10;
size--;
}
System.out.println("Result..." + result);
return(bits);
}
Thanks for any help.
We're having to make some assumptions here: the static method is a method on BitString, for instance.
Given that, the method is evidently supposed to create a BitString object, since it returns one. So it should create one of the size you need for the parameters you are dealing with. Since you have the (arbitrary, somewhat silly) restriction of not being allowed to call the set and clear methods, you will need to access the bits variable from within the BitString that you create directly; since the static method is on the BitString class, you can do this:
public static BitString decimalToUnsigned(int n, int size)
{
// ...
BitString bitString = new BitString(size);
// ... loops, logic, etc. all to be put in here; when you're ready to
// access the bits array, use:
bitString.bits[index] = false;
// ...
// then when you're ready to return your BitString object, just:
return bitString;
}
Yes, bits is declared private, but that just means it cannot be accessed from outside the class. The static method is within the class, though it cannot use the member variables since the static method does not operate on an instance (other than one it creates).
See if that can get you through the compilation error and on to your logic.
p.s. I don't think this is a very good assignment; it will get your head around static vs. non-static methods, but I think there are better ways to do that. And saying that you have to use and return a class but you cannot call its methods is hardly a real-world scenario.
In your static method you need an instance of a BitString to put your vales in. This is how I would do it:
public class BitString implements Cloneable {
/** A constant that defines the size of the default bit string. */
public static final int DEFAULT_SIZE = 8;
// an array to hold the bits that make up the bit string
private boolean bits[];
/** Creates a new, all false, bit string of the given size. */
public BitString(int size) {
if (size < 1) {
throw new IllegalArgumentException("size must be positive");
}
bits = new boolean[size];
}
/** Creates a new all false bit string of size DEFAULT_SIZE. */
public BitString() {
this(DEFAULT_SIZE);
}
/** Set the value of a bit string at the given index to true. */
public void set(int index) { // might want to check index bounds
bits[index] = true;
}
/** Set the value of a bit string at the given index to false. */
public void clear(int index) { // might want to check index bounds
bits[index] = false;
}
public String toString() { // one possible implementation, might not want to add leading 0's
StringBuilder buf = new StringBuilder(bits.length);
for (Boolean bit : bits) {
buf.append(bit ? '1' : '0');
}
return buf.toString();
}
public static BitString decimalToUnsigned(int n, int size) {
// throw new UnsupportedOperationException("this function needs to be completed");
// might want to check that size is big enough
// this is the key here: you need an instance of the object that has the bits array inside it
BitString result = new BitString(size);
while (n != 0 && size > 0) {
size--; // use size to index into the BitString
if ((n & 1) == 1) { // % 2 doesn't work well with negative numbers, you have to worry about +-1 then
result.set(size); // set bit if needed
}
n = n >>> 1; // unsigned shift to the next bit
}
return result;
}
public static void main(String[] args) {
// can be invoked with just decimalToUnsigned(42, 10) but I want to make it more clear
BitString example1 = BitString.decimalToUnsigned(42, 10);
System.out.println(example1);
BitString example2 = BitString.decimalToUnsigned(-42, 10); // will treat -42 as unsigned
System.out.println(example2);
BitString example3 = BitString.decimalToUnsigned(-1, 33); // will treat -1 as unsigned giving 32 1's
System.out.println(example3);
}
}
It prints:
0000101010 1111010110 011111111111111111111111111111111
Related
I'm trying to check if a number is a square, and if a number is triangular.
The issue is happening at sqrt(num) which is returning 0 for all numbers I test.
I'm using an online compiler, tried several compilers, so it's not a compiling issue. Tried to declare num as a double and as an int, same results.
I'm new to Java, but not new to programming, I searched online, checked my code several times, everything looks fine, it even worked as expected before adding the variables for checking triangular number, but after declaring the variables checkTri and checkTriSqr, this started to happen. I'm sure this have nothing to do with declaring these variables (almost sure), could anyone please help me understand what's going on here?
import static java.lang.Math.sqrt;
import static java.lang.Math.round;
public class Parent{
public static void main(String[] args){
class Number
{
public int num ;
double numSqr = sqrt(num );
double roundNumSqr = round(numSqr) ;
double checkTri = 8 * num + 1 ;
double checkTriSqr = sqrt(checkTri) ;
public void prinTest()
{
System.out.println(num);
System.out.println(numSqr);
System.out.println(roundNumSqr);
System.out.println(checkTri);
System.out.println(checkTriSqr);
}
public boolean isSqr()
{
if (numSqr == roundNumSqr)
{
return true;
}
else
{
return false;
}
}
public boolean isTriangular(){
if (checkTriSqr * checkTriSqr == checkTri )
{
return true;
}
else
{
return false;
}
}
}
Number number = new Number();
number.num = 350;
number.prinTest();
System.out.println(number.isSqr());
System.out.println(number.isTriangular());
}
}
EDIT: The following screen shot is from the tutorial I'm following, concerning declaring classes within methods!
This:
public int num ;
double numSqr = sqrt(num );
initialises num to 0 upon instance construction (the default value for an integer in the absence of assignment), and numSqr is set immediately afterwards (to zero).
You need to recalculate the sqrt() each time you subsequntly set num (perhaps by providing a method setNum() and recalculating everything within that method)
I wouldn't call your class Number, btw. There's already a Number class in the standard Java class set.
numSqr is created in the constructor, whereas number.num = 350;is declared after the construction of your object.
You can use a constructor like this :
public Numer(int num){
this.num=num;
this.numSqr=sqrt(num)
//.... ... ...
}
You can also use an empty constructor and a setter to set the number attribute :
public void setNumber(int num){
this.num=num;
this.numSqr=sqrt(num)
//.... ... ...
}
The values numSqr, roundNumSqr, etc, are all set at the point of the object's creation, however you don't set num to anything until after the object is created. The result is that, for instance,
At creation:
num = 0
therefore
numSqr = 0
roundNumSqr = 0
etc
Then, you set num = 350
But you don't reset the values of numSqr, etc, so this is still the case:
numSqr = 0
roundNumSqr = 0
You need to make a constructor for this class that takes in the value of num and then sets all of the corresponding values, so that they're only set after num has been set (or, add a "calculate" function that updates all the values).
You can modify in this way and compare with technology you have worked on .
import static java.lang.Math.sqrt;
import static java.lang.Math.round;
public class Number {
public int num = 0;
public void prinTest() {
System.out.println(this.num);
System.out.println(this.getSqrt(this.num));
System.out.println(this.getCheckTri());
}
private double getSqrt(double value) {
return sqrt(value);
}
public boolean isSqr() {
if (this.getSqrt(this.num) == round(this.getSqrt(this.num))) {
return true;
} else {
return false;
}
}
private double getCheckTri() {
return 8 * this.num + 1;
}
public boolean isTriangular() {
if (this.getSqrt(this.getCheckTri()) * this.getSqrt(this.getCheckTri()) == this.getCheckTri()) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Number number = new Number();
number.num = 49;
number.prinTest();
System.out.println(number.isSqr());
System.out.println(number.isTriangular());
}
}
You should read some basic tutorials as you have added class inside main method,which means you need more time to check out the syntax.
The other answers alreade said, that the field num was not set to the input number, and that the other fields were actually evaluated on object creation, and hence zero too.
The purpose however is achieved by simple functions:
public static boolean isSquare(int num) {
int root = (int) Math.round(Math.sqrt(num));
return root*root == num;
}
public static boolean isCubic(int num) {
int root = (int) Math.round(Math.cbrt(num));
return root*root*root == num;
}
This exploits the cubic root.
As a comparison of doubles, a sqrt result and its rounded long value are still imprecise, I prefer to recalculate the original parameter.
public int num ;
double numSqr = sqrt(num);
By default, declared instance integer variables (variables declared inside class body) are initialized with 0 (zero). Hence, your code does nothing but take a square root of zero, which is zero.
I am building a data structure to learn more about java. I understand this program might be useless.
Here's what I want. I want to create a data structure that store smallest 3 values. if value is high, then ignore it. When storing values than I also want to put them in correct place so I don't have to sort them later. I can enter values by calling the add method.
so let's say I want to add 20, 10, 40, 30 than the result will be [10,20,30]. note I can only hold 3 smallest values and it store them as I place them.
I also understand that there are a lot of better ways for doing this but again this is just for learning purposes.
Question: I need help creating add method. I wrote some code but I am getting stuck with add method. Please help.
My Thinking: we might have to use a Iterator in add method?
public class MyJavaApp {
public static void main(String[] args){
MyClass<Integer> m = new MyClass<Integer>(3);
m.add(10);
m.add(20);
m.add(30);
m.add(40);
}
}
public class MyClass<V extends Comparable<V>> {
private V v[];
public MyClass(int s){
this.v = (V[])new Object[s];
}
public void add(V a){
}
}
Here is a rough sketch of the add method you have to implement.
You have to use the appropriate implementation of the compareTo method when comparing elements.
public void add(V a){
V temp = null;
if(a.compareTo( v[0]) == -1 ){
/*
keeping the v[0] in a temp variable since, v[0] could be the second
smallest value or the third smallest value.
Therefore call add method again to assign it to the correct
position.
*/
temp = v[0];
v[0] = a;
add(temp);
}else if(a.compareTo(v[0]) == 1 && a.compareTo(v[1]) == -1){
temp = v[1];
v[1] = a;
add(temp);
}else if(a.compareTo(v[1]) == 1 && a.compareTo(v[2]) == -1){
temp = v[2];
v[2] = a;
add(temp);
}
}
Therefore the v array will contain the lowerest elements.
Hope this helps.
A naive, inefficient approach would be (as you suggest) to iterate through the values and add / remove based on what you find:
public void add(Integer a)
{
// If fewer than 3 elements in the list, add and we're done.
if (m.size() < 3)
{
m.add(a);
return;
}
// If there's 3 elements, find the maximum.
int max = Integer.MIN_VALUE;
int index = -1;
for (int i=0; i<3; i++) {
int v = m.get(i);
if (v > max) {
max = v;
index = i;
}
}
// If a is less than the max, we need to add it and remove the existing max.
if (a < max) {
m.remove(index);
m.add(a);
}
}
Note: this has been written for Integer, not a generic type V. You'll need to generalise. It also doesn't keep the list sorted - another of your requirements.
Here's an implementation of that algorithm. It consists of looking for the right place to insert. Then it can be optimized for your requirements:
Don't bother looking past the size you want
Don't add more items than necessary
Here's the code. I added the toString() method for convenience. Only the add() method is interesting. Also this implementation is a bit more flexible as it respects the size you give to the constructor and doesn't assume 3.
I used a List rather than an array because it makes dealing with generics a lot easier. You'll find that using an array of generics makes using your class a bit more ugly (i.e. you have to deal with type erasure by providing a Class<V>).
import java.util.*;
public class MyClass<V extends Comparable<V>> {
private int s;
private List<V> v;
public MyClass(int s) {
this.s = s;
this.v = new ArrayList<V>(s);
}
public void add(V a) {
int i=0;
int l = v.size();
// Find the right index
while(i<l && v.get(i).compareTo(a) < 0) i++;
if(i<s) {
v.add(i, a);
// Truncate the list to make sure we don't store more values than needed
if(v.size() > s) v.remove(v.size()-1);
}
}
public String toString() {
StringBuilder result = new StringBuilder();
for(V item : v) {
result.append(item).append(',');
}
return result.toString();
}
}
I want to create a class that represents an infinite (2^32 can be considered as infinite) strip on which there are pseudo-random numbers. The interface should be very simple; the constructor should get an instance of Random; and there should be a method to get the random number for an index.
Note that I don't want to store a huge lookup table and precalculate it; I want it to be done on the fly.
public class InfiniteRandomStrip {
public InfiniteRandomStrip(Random r) {
...
}
public int getNumber(int index) {
// magic code here
}
}
Note that the code should pass the following test:
Random seed = new Random(123);
Random seed2 = new Random(123);
InfiniteRandomStrip strip = new InfiniteRandomStrip(seed);
InfiniteRandomStrip strip2 = new InfiniteRandomStrip(seed2);
int first = strip.getNumber(454); // consume the random
if(strip.getNumber(5) == strip2.getNumber(5) )
System.out.println("TEST1 OK");
if(first == strip.getNumber(454) )
System.out.println("TEST2 OK");
I've had no luck finding any example or algorithm for such a random list case. If such a problem has no solution, I will be glad to hear an explanation why.
You could clone the Random object in the getNumber method so that you start at the same seed each time. Then compute nextInt repeatedly until you get to the correct index.
int getNumber(int index) {
Random r = this.seed.clone();
for (int i = 0; i < index - 1; ++i) {
r.nextInt();
}
return r.nextInt();
}
public class InfiniteRandomStrip {
private final long seed;
public InfiniteRandomStrip(Random r) {
this.seed = r.nextLong();
}
public int getNumber(int index) {
return new Random(seed ^ index).nextInt();
}
}
following are the steps of the program I'm trying to make
catch String using Scanner
pass that String to a method in another class
separate characters of that String in to an array using .toCharArray()
copy contents of that array to another array using a for loop
but this array giving me a null pointer exception. what am i doing wrong? (ignore the class naming i know it's stupid but i have to do it this way because my teacher wants it that way)
main class:
import java.util.Scanner;
public class _01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter your name : ");
String name = input.nextLine();
int size = name.length();
_02 process = new _02(size);
process.push(name);
}
}
other class with the array:
public class _02 {
int maxsize;
int top;
char arrayStack[];
public _02(int size) {
maxsize = size;
top = -1;
}
public void push(String letters) {
char temp[]= letters.toCharArray();
for (int c=0;c<temp.length;c++) {
temp[c] = arrayStack[++top];
}
}
}
Your assignment is reversed - you want to assign from temp (right side of assignment) to arrayStack (left side of assignment). Also, you need to initialize arrayStack, e.g. arrayStack = new char[temp.length] - right now it's null.
char arrayStack[]; // this is not initialized.
arrayStack[] = new char[temp.length] // inside the push() method.
Arrays need to be initialized in Java; simply declaring an array yields a field initialized to null. Once you change the class to properly initialize arrayStack, you don't need the maxsize field, since it will be the same as arrayStack.length. You also have your assignment reversed in the push method. Finally, since you have a maximum array size, you might want to avoid throwing an ArrayIndexOutOfBoundsException and instead throw a more semantically meaningful exception, or else simply drop the extra characters or grow the stack (in which case the constructor arg is an initial size). For that, you will need some range checking. Finally, the logic is cleaner if you initialize top to 0 instead of -1 and use top++ instead of ++top (or, better, use the built-in API for copying pieces of an array).
public class _02 {
int top;
char arrayStack[];
public _02(int size) {
arrayStack = new char[size];
top = 0;
}
public void push(String letters) {
char temp[]= letters.toCharArray();
int len = temp.length;
// do some range checking
if (top + len >= arrayStack.length) {
// silently ignore the extra characters
len = arrayStack.length - top;
// an alternative would be to throw a "stack full" exception
// yet another alternative would be to grow the stack
}
// for (int c=0; c<len; c++) {
// arrayStack[top++] = temp[c];
// }
// don't use a loop--use the API!
System.arraycopy(temp, 0, arrayStack, top, len);
top += len;
}
}
I need to modify DataSet to accept Comparable Objects. The tester will not compile and I do not know how to print out the compareTo method. Should I be using an ArrayList for the tester? Thanks ahead of time!
public interface Comparable
{
/**
Compares this object with another.
#param other the object to be compared
#return a negative integer, zero, or a positive integer if this object
is less than, equal to, or greater than, other
*/
int compareTo(Object other);
}
public class DataSetComparable
{
private double sum;
private Object maximum;
private Object minimum;
private int count;
private Comparable comparer;
/**
Constructs an empty data set with a given measurer.
#param aMeasurer the measurer that is used to measure data values
*/
public DataSetComparable(Comparable acomparer)
{
sum = 0;
count = 0;
maximum = null;
minimum = null;
comparer= acomparer;
}
/**
Adds a data value to the data set.
#param x a data value
*/
public void add(Object x)
{
sum = sum + comparer.compareTo(x);
if (count == 0 || comparer.compareTo(maximum) < comparer.compareTo(x))
maximum = x;
if (count == 0 || comparer.compareTo(minimum) > comparer.compareTo(x))
minimum=x;
count++;
}
/**
Gets the largest of the added data.
#return the maximum or 0 if no data has been added
*/
public Object getMaximum()
{
return maximum;
}
/**Gets the smallest of the added data.
*#return the minimum or 0 if no data has been added
**/
public Object getMinimum()
{
return minimum;
}
}
public class String implements Comparable {
private String input;
private int holder;
public String(String aninput){
input= aninput;
holder=0;
}
public String getComparer(){
return input;
}
public String getString(){
return input;
}
public int compareTo(Object other){
String temp= (String) other;
if(input.compareTo(temp)<0){
holder=-1;
}
else if (input.compareTo(temp)== 0) {
holder= 0;
}
else{
holder= 1;
}
return holder;
}
}
public class StringTester{
public static void main (String [] args){
Comparable c = new String();
DataSetComparable data = new DataSetComparable(c);
data.add(new String("Jimmy"));
data.add(new String("Amy"));
data.add(new String("Melissa"));
data.add(new String("Melissa"));
String max = (String) data.getMaximum();
String min = (String) data.getMinimum();
System.out.println("Maximum String = " + max);
System.out.println("Minimum String = " + min);
}
}
More specifically, the error says:
constructor String in class String cannot be applied to given types.
Your code includes this:
public class String implements Comparable {
...
}
Do you realize that there is a standard Java library class called String that gets imported by default into every class? If implement your own class called String you are going to get some very confusing compilation error messages.
I strongly recommend that you change the name of your class to something else; e.g. StringHolder.
Note, technically you could define a class called String. However the rules that Java uses to disambiguate the names of classes are not designed for this use-case ... and you will end up having to refer to java.lang.String by its fully qualified name wherever you use it. And other people reading / modifying your code would find that really awkward / annoying.
It is best to treat the names of classes in the java.lang package as "reserved", and don't define classes with the same (unqualified) name.