So I'm in the process of learning how to use algorithms and I'm using the Algorithms Book By Robert Sedgewick to learn how to do this and the question is Exercise 1.3.14 (I would recommend highly if you are wanting to learn this stuff.) Anyway, I'm trying to implement my own resizing algorithm for my ResizingStringArrayQueue and I'm really struggling to get my implementation to work. But before I delve further into this, I would like to ask politely that I am NOT looking for a full solution to my resizing array (I'm trying to learn so need to do this by myself.) However if someone would be able to explain to me why my resizing method is failing to copy itself into a new larger array any help that can be offered would be greatly appreciated.
I would like to emphasise here that I'm focusing on the enque method, and am not working on the deque at this stage so please, no solution to how the deque works, thanks!
So here goes...
This is my implementation for the ResizingStringArrayQueue:
import java.util.Iterator;
public class ResizingArrayQueueOfStrings implements Iterable<String> {
private String[] a = new String[1];
private int n;
private int head;
private int tail;
public boolean isEmpty() { return n==0; }
public int size() {return n; }
public void aPrint() { // temporary method for testing needs deleting
System.out.println("Contents of array: ");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+ " ");
}
}
private void resize(int max) {
String[] temp = new String[max];
for (int i = head; i < tail; i++) {
temp[i] = a[i];
a = temp;
}
}
public void enque(String item) { // something is in the wrong order here
if (tail == a.length) {
System.out.println("Capacity Doubled");
resize(2*a.length);
}
n++;
a[tail++] = item;
}
public String deque() {
if (head == tail/2) {
resize(n);
head = 0;
tail = n;
}
n--;
String item = a[head];
a[head++] = null; // loitering
return item;
}
public Iterator<String> iterator(){
return new ResizingArrayQueueIterator();
}
private class ResizingArrayQueueIterator implements Iterator<String>{
private int i = head;
#Override
public boolean hasNext() {
return i < tail;
}
#Override
public String next() {
// TODO Auto-generated method stub
return a[i++];
}
}
}
And this is a copy of my Main():
public static void main(String[] args) {
// TODO Auto-generated method stub
// EXERCISE 1.3.14
System.out.println("EXERCISE 1.3.14 ");
System.out.println();
ResizingArrayQueueOfStrings queueOfStrings = new ResizingArrayQueueOfStrings();
queueOfStrings.enque("a");
queueOfStrings.enque("b");
queueOfStrings.enque("c");
queueOfStrings.enque("d");
queueOfStrings.enque("e");
System.out.println();
for (String string : queueOfStrings) {
System.out.println(string);
}
System.out.println();
queueOfStrings.aPrint();
}
If you comment out the "enques" for c, d and e the code does what it should if you run it, I get a full queue [a,b]. However, when I get to c, my queue becomes [a,null,c, null] when it should be [a,b,c,null] for some reason it fails to copy the b. So I think the problem lies in the order I'm doing things and its somewhere most likely in the resizing method. I've spent a long time looking at this now and I'm getting to the stage where a second set of eyes would be really helpful. Thank you for your time and patience in advance, I look forward to hearing from you!
In resize, move the statement a = temp out of the for loop.
Related
I've got array. I've got an isFull method, which checks if the array is full, but I don't know how to use this to check if it's full, then if it's not full add to the array, otherwise disregard the add call.
The array should take 10 elements and then not accept any more. After 10 elements, it should 'be full' and disregard any addSpy calls.
How would you implement this?
public class ConcreteSubject extends AbstractSubject {
public int arySize;
private int i = 0;
private static AbstractSpy[] spies;
public ConcreteSubject(int a) {
arySize = a;
spies = new AbstractSpy[a];
}
#Override
public void addSpy(AbstractSpy spy) {
if (spies.length < 10) {
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
public void isFull() {
//1
boolean b = false;
for (int i = 0; i < spies.length; i++) {
if (spies[i] == null) {
b = true;
}
}
if (!b) {
System.out.println("Array is full");
} else {
System.out.println("Array not full");
}
}
public class TestSpies {
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject(10);
AbstractSpy spy = new ConcreteSpy();
AbstractSpy[] spies = new AbstractSpy[10];
cs.addSpy(spy);
cs.addSpy(spy);
cs.addSpy(spy);
cs.isFull();
}
}
spies.length < 10 isn't correct. It should be spies.length > 0 && i < spies.length to make sure that the following assignment spies[i] = spy; is always valid.
void isFull() should be boolean isFull(). Your implementation looks OK, just return b. full is a tricky word because technically an array is always "full". A better adjective would be populated, filled.
Since addSpy isn't filling null gaps but simply adds a spy to the end, isFull could be rewritten to return spies.length == i;.
The simplest way of doing it would be like that:
#Override
public void addSpy(AbstractSpy spy) {
if (!isFull())
{
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
To use that, you should change your isFull method to:
public boolean isFull() {
for (int i = 0; i < spies.length; i++) {
if (spies[i] == null) {
return false;
}
}
return true;
}
Keep a track of the number of filled cells of the array using a variable. And before inserting anything into it, check if the filled cells count strictly less than the size of the array (obviously you want to keep track of the array total size as well).
In my java class, we are using junit test to test our methods. This section introduced using an interface.
this specific method I am having problems on is supposed to search an array at each index, looking for a matching string as the input.
In the junit test I have
void test()
{
MyClassList labTest = new MyClassList("CIS 120", "Fall", "Professor Awesome");
MyStudent george = new MyStudent("George","Lucas", "555-555-5555","george.lucas#starwars.com");
MyStudent gene = new MyStudent("Gene", "Roddenberry","666-666-6666", "gene.roddenberry#startrek.com");
MyStudent jordan = new MyStudent("Jordan" ,"Robberts", "755-555-5555", "jordan.robberts#wheeloftime.com");
labTest.insert(george);
labTest.insert(gene);
labTest.insert(jordan);
System.out.println(labTest.toString());
System.out.println(labTest.contains(george));
System.out.println(labTest.search("George"));
This is the code U have for the method search:
Note
protected MyStudent [] log;
protected int lastIndex = -1;
are global variables
package Lab2;
import java.util.Arrays;
import java.util.Scanner;
import Lab2.ClassListInterFace;
public class MyClassList implements ClassListInterFace {
protected String course;
protected String semester;
protected String teacherLastName;
protected MyStudent[] log;
protected int lastIndex = -1;
public MyClassList(String currCourse, String currSemester, String lastName, int maxSize) {
log = new MyStudent[maxSize];
this.course = currCourse;
this.semester = currSemester;
this.teacherLastName = lastName;
}
public MyClassList( String currCourse, String currSemester, String lastName)
{
log = new MyStudent[100];
this.course = currCourse;
this.semester = currSemester;
this.teacherLastName = lastName;
}
public void insert(MyStudent element) {
lastIndex++;
log[lastIndex] = element;
}
public boolean isFull() {
if (lastIndex == (log.length - 1))
return true;
else
return false;
}
public int size() {
return (lastIndex + 1);
}
public void clear()
{
for (int i = 0; i <= lastIndex; i++)
log[i] = null;
lastIndex = -1;
}
public String getName() {
return teacherLastName;
}
public boolean contains(MyStudent element) {
boolean found = false;
for( int location = 0;location <= lastIndex; location++)
{
if (element.equals(log[location])) // if they match
found = true;
}
return found;
}
public String toString()
{
String message = "Course " + course + "\n Semester " + semester + "\n Proffessor " + teacherLastName + "\n";
for (int i = 0; i <= lastIndex; i++) {
message += log[i].toString();
}
return message;
}
public int search(String x)
{
int answer = 0;
for(int i = 0; i < log.length; i++)
{
if(x.equalsIgnoreCase(log[i]))
answer++;
}
return answer;
}
I got this based off some code that the teacher gave us for reference, and I tweaked it a little.
This looks like something that can be done much more elegantly with a for loop. In my experience, using a more concise control structure designed for things like this can lead to far fewer chances of errors. While I'm not sure what exact issue you are looking for help with, I do notice that if you do find a match, you skip the next element without checking to see if it is also a match.
int location = 0;
while (location <= lastIndex)
{
if (x.equalsIgnoreCase(log[location]))
{ // if they match
answer ++;
location ++; //<-- Here's where you increment twice upon finding a match!
}
location++; //To fix with the smallest number of changes, just put this in an else clause
}
This entire block can be reduced to approximately half the lines and half the variables by changing it up to be a for loop. See below:
for(int i = 0; i < log.length; i++) {
if(x.equalsIgnoreCase(log[i].firstName))
answer++;
}
This is much easier to read, and far less prone to errors. Trying to keep track of an excessive number of variables or dividing out common operations (such as incrementing where you are) is just asking for issues. This four-liner is functionally equivalent to your above code block (aside from the fact it doesn't skip the following entry when it finds a match), yet has far fewer opportunities for a programmer to make a mistake. Always, when you can get away with it, use the control flow structure designed for the task.
I was wondering if anyone would be able to point me in the correct direction in regards to creating my own array list methods. For instance, the current project I am assigned to does not allow for me to use the methods given to me for free like in the following example.
package com.tutorialspoint;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(22);
arrlist.add(30);
arrlist.add(40);
// adding element 25 at third position
arrlist.add(2,25);
// let us print all the elements available in list
for (Integer number : arrlist) {
System.out.println("Number = " + number);
}
}
}
This example shows the add() method. For my project I have to create this method myself and call it from a different file within my package.
I find this as an interesting problem. I am always curious about how things work at the raw level.
If you think about it, an ArrayList is basically just an array that you can expand. So you can either have a really big array (which would take a lot of memory for one ArrayList) or every time you add something, you make a new bigger array and copy the contents and add the new item (which I think the performance is O(N)).
This is my attempt without using any libraries:
public class MyArrayList<T>
{
private T[] asArray;
#SuppressWarnings("unchecked")
public MyArrayList()
{
asArray = (T[]) new Object[0];
}
public void add(T t)
{
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length + 1];
// copy everything over to the new array
for (int i = 0; i < asArray.length; i++)
{
temp[i] = asArray[i];
}
// add the new element
temp[asArray.length] = t;
asArray = temp;
}
public void remove(int index)
{
if (index < 0 || index >= asArray.length) return;
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length - 1];
boolean found = false;
// copy everything over to the new element
for (int i = 0; i < asArray.length; i++)
{
// don't copy if the indices are the same
if (i == index)
{
found = true;
continue;
}
temp[i - (found ? 1 : 0)] = asArray[i]; // it's i - 1 after the removed object so then it doesn't leave a gap and it doesn't go over the array's length
}
asArray = temp;
}
public T get(int index)
{
return asArray[index];
}
}
I am quite proud of this code. :) I consider Short_Teeth's code cheating because the class is a subclass and, well, doesn't add anything. I hope I helped.
This is very easy to understand; However, I explained a little bit in comments.
public class MyArrayList<E extends Object> {
private static int initialCapacity = 5;
private static int currentSize;
private Object[] myArrayList = {}, temp = {};
private static int currentIndex = 0;
public static void main(String[] args) {
MyArrayList arrList = new MyArrayList();
arrList.add("123"); //add String
arrList.printAllElements();
arrList.add(new Integer(111)); //add Integer
arrList.printAllElements();
arrList.add(new Float("34.56")); //add Integer
arrList.printAllElements();
arrList.delete("123");
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
}
public MyArrayList() { //creates default sized Array of Objects
myArrayList = new Object[initialCapacity]; //generic expression
/* everytime I cross my capacity,
I make double size of Object Array, copy all the elements from past myObject Array Object
*/
}
public MyArrayList(int size) { //creates custom sized Array of Objects
myArrayList = new Object[size];
}
public void add(Object anyObj) {
//add element directy
myArrayList[currentIndex] = anyObj;
currentSize = myArrayList.length;
currentIndex++;
if (currentIndex == currentSize) {
createDoubleSizedObjectArray(currentSize);
}
}
//print all elements
public void printAllElements() {
System.out.println("Displaying list : ");
for (int i = 0; i < currentIndex; i++) {
System.out.println(myArrayList[i].toString());
}
}
private void createDoubleSizedObjectArray(int currentSize) {
temp = myArrayList.clone();
myArrayList = new MyArrayList[2 * currentSize]; //myObject pointer big size data structure
// myObject = temp.clone(); //probably I can do this here as well. Need to check this
System.arraycopy(temp, 0, myArrayList, 0, currentSize);
}
void delete(Object object) {
//if already empty
if (currentIndex == 0) {
System.out.println("Already empty!");
return;
}
//you don't need to delete anything. I can simply override the storage
currentIndex--;
}
}
import java.util.ArrayList;
public class MyArrayList<E> extends ArrayList<E>{
private static final long serialVersionUID = -5164702379587769464L;
public void newMethod(){
// No implementation
}
}
This is a class which extends from ArrayList and a method called newMethod() was added to this class.
Below we are calling this newly created method in your case you must implement the add to this newly created method.
public class Hello {
public static void main(String args[]) {
MyArrayList<Integer> myList = new MyArrayList<Integer>();
// It has the ArrayList add() method as this new class extends from ArrayList (all the ArrayList methods are included)
myList.add(2);
// The newly created method in your case you need to implement the add yourself
myList.newMethod();
}
}
This could also be a good link for what you need.
http://www.java2novice.com/java-interview-programs/arraylist-implementation/
I also recomend that you try to implement and solve your problems first and then ask questions about a specific problem, and only after you done a good research about what may be causing this problem (There are lots of resources out there). If you done some research before you asked this question, I'm pretty sure that you would have been able to solve everything on your own.
Hope you find this information useful. Good luck.
This may be a very simple question, but I can't seem to find a suitable answer on Google. I have a class called Player, which has a String array called playerInv with a size of 10.
In my Main Activity Class, I want to run a for loop to determine the first index in the array that is empty (""). I then want to populate that with a new string, and then terminate the loop. How do I do this?
Sorry for the nooby question. Like I said, I've tried Google to no avail!
For Loop:
String playerInvTemp[] = thePlayer.getPlayerInv; ERROR -- cannot resolve getPlayerInv
for (int i=0; i < playerInvTemp.length; i++)
{
if ((!playerInvTemp[i].isEmpty()) || playerInvTemp[i] == null)
{
setPlayerInv("Blood Essence", i); ERROR cannot resolve setPlayerInv
//invText.setText();
Blood = true;
break;
}
}
Player Class:
public class Player {
private int playerPos;
private int playerHP;
private String playerInv[];
Player(int startPos, int startHP, String[] newInventory)
{
playerPos = startPos;
playerHP = startHP;
playerInv = newInventory;
}
public int getPlayerPos() {
return playerPos;
}
public void setPlayerPos(int playerPos) {
this.playerPos = playerPos;
}
public int getPlayerHP(){
return playerHP;
}
public void setPlayerHP(int playerHP){
this.playerHP = playerHP;
}
public String getPlayerInv(int pos)
{
return playerInv[pos];
}
public void setPlayerInv(String playerInv[]) {
for (int i=0; i<10; i++)
{
this.playerInv[i] = playerInv[i];
}
}
public void setPlayerInv(String val, int index)
{
this.playerInv[index] = val;
}
public String getPlayerInv()
{
return this.playerInv; *//this gives error "Incompatible types. Required java.lang.string, found java.lang.string[]"*
}
}
Do this
Add these two method in Player class
public void setPlayerInv(String val, int index)
{
this.playerInv[index] = val;
}
public String[] getPlayerInv()
{
return this.playerInv;
}
then change your for loop like this
String playerInvTemp[] = thePlayer.getPlayerInv();
for (int i=0; i < playerInvTemp.length; i++)
{
if (!playerInvTemp[i].isEmpty()) || playerInvTemp[i] == null)
{
setPlayerInv("Blood Essence", i);
//invText.setText();
Blood = true;
break;
}
}
Bunch of problems here, .length() is not valid for an array, it should be .length.
`for (int i=0; i<thePlayer.getPlayerInv(i).length(); i++)`
You most likely mean null or at least need to check for it, here and you need [] not ():
if (thePlayer.getPlayerInv[i] == "" or theplayer.getPlayerInv[i] == null)
This is all wrong, and as a matter of fact you need to post your code and errors, you have many problems and should start with learning some basics about Java.
Try some beginners tutorials (https://www.google.com/search?q=java+tutorials&ie=utf-8&oe=utf-8). You have a lot of both syntax and logic errors.
Do you run an instance of constructor player()??
I did
Player a=new Player();
a.getPlayerInv(0)
and works fine.
What's the shortest way to get an Iterator over a range of Integers in Java? In other words, implement the following:
/**
* Returns an Iterator over the integers from first to first+count.
*/
Iterator<Integer> iterator(Integer first, Integer count);
Something like
(first..first+count).iterator()
This implementation does not have a memory footprint.
/**
* #param begin inclusive
* #param end exclusive
* #return list of integers from begin to end
*/
public static List<Integer> range(final int begin, final int end) {
return new AbstractList<Integer>() {
#Override
public Integer get(int index) {
return begin + index;
}
#Override
public int size() {
return end - begin;
}
};
}
Edit:
In Java 8 and later you can simply say:
IntStream.range(begin, end).iterator() // returns PrimitiveIterator.OfInt
or if you need the boxed version:
IntStream.range(begin, end).boxed().iterator() // returns Iterator<Integer>
Untested. Mapping that onto "min, count" is left as an exercise for the reader.
public class IntRangeIterator implements Iterator<Integer> {
private int nextValue;
private final int max;
public IntRangeIterator(int min, int max) {
if (min > max) {
throw new IllegalArgumentException("min must be <= max");
}
this.nextValue = min;
this.max = max;
}
public boolean hasNext() {
return nextValue <= max;
}
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Integer.valueOf(nextValue++);
}
public void remove() {
throw new UnsupportedOperationException();
}
}
If you actually want the shortest amount of code, then Bombe's answer is fine. However, it sucks memory for no good reason. If you want to implement it yourself, it would be something like:
import java.util.*;
public class IntegerRange implements Iterator<Integer>
{
private final int start;
private final int count;
private int position = -1;
public IntegerRange(int start, int count)
{
this.start = start;
this.count = count;
}
public boolean hasNext()
{
return position+1 < count;
}
public Integer next()
{
if (position+1 >= count)
{
throw new NoSuchElementException();
}
position++;
return start + position;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
An example using the guava framework. Note that this will not materialize the set (although you have to read the ContiguousSet implementation to verify that).
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.DiscreteDomains;
class RangeIterator {
public Iterator<Integer> range(int start, int length) {
assert length > 0;
Range<Integer> dim_range = Ranges.closedOpen(start, start + length);
DiscreteDomain<Integer> ints = DiscreteDomains.integers();
ContiguousSet<Integer> dim = dim_range.asSet(ints);
return dim.iterator();
}
}
A sample using stream API in java 8:
int first = 0;
int count = 10;
Iterator<Integer> it = IntStream.range(first, first + count).iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Without iterator, it could be:
int first = 0;
int count = 10;
IntStream.range(first, first + count).forEach(i -> System.out.println(i));
Straight-forward implementation of your homework:
List<Integer> ints = new ArrayList<Integer>();
for (int i = 0; i < count; i++) {
ints.add(first + i);
}
It's generally considered good style to pass around Collection and friends instead of Iterator (see this FAQ entry), so I'd recommend something like
public final class IntegerRange implements Set<Integer> {
final LinkedHashSet<Integer> backingList;
public IntegerRange(final int start, final int count) {
backingList = new LinkedHashSet(count, 1.0f);
for (int i=0; i < count; i++) {
backingList.set(i, start + i);
}
}
/** Insert a bunch of delegation methods here */
}
and then just use .iterator() when you need to pass an Iterator to whatever framework you're using.
UPDATE: Obviously, this code isn't lazy. If you can't afford the extra memory overhead of storing (potentially) 2^32-1 Integers, you should use a different solution. Also, nothing about the type guarantees the range will be sorted (even though it is, based on the implementation). If you need to guarantee sorting, you could look into implementing SortedSet and backing it with a TreeSet, but it will take longer to build the range. Honestly, if you are that concerned with getting the details right, it might be worth your effort to look for a library. Tapestry has an internal version, for instance.