...

View Full Version : Newbie help with "while" statements.



carlisle
01-09-2012, 08:06 PM
Hello! I'm new to the world of programming and after a few weeks in my Java class have run into some homework trouble. We've been working the the Java Au Naturel book and the current assignment is to:

"Revise the lastEmptySlot method to return the position of the next to- last empty slot. Return the initial position if the executor has less than two empty slots."

I put together something I thought would work, but somewhere I think the "while" statements are messing it up.
Any help would be much appreciated.

Thanks.




public String lastEmptySlot()
{ int count = 0;
String spot = this.getPosition();
String lastEmpty = spot; // in case no later slot is empty

while (this.seesSlot())
{ if (!this.seesCD())
count++;// count number of empty slots
moveOn();
}
if (count < 2)
return lastEmpty;
else {
this.backUp();
while (this.seesSlot())
{ if ( ! this.seesCD()){
lastEmpty = this.getPosition();
break;
}
this.backUp();
}
while (this.seesSlot()){
if ( ! this.seesCD()){
lastEmpty = this.getPosition();
break;
}
this.backUp();
}
return lastEmpty;
}
} //=======================


Also, we use a "Vic" class for setting up all the scenarios in the book (in this case CDs).



// <pre>
// Copy this file in its entirety to a file named Vic.java
// Compile it before trying to compile any program that uses it
// This implementation uses ArrayLists for the sequences of CDs
// It also uses an initializer method to create the tableau before any Vics

import java.util.*;
import java.awt.*;
import javax.swing.*;

public class Vic
{
private static Stack theStack = new Stack(); // where spare CDs are kept
private ArrayList itsSequence; // its slots
private int itsPos; // 0,1,2,...; 0 is at front
private int itsID; // 1 for first Vic, 2 for...

/* QUERY METHODS */
/** Return the current position as a String value. */
public String getPosition()
{ return itsID + ", " + itsPos;
} //======================

/** Tell whether there is a slot at its position. */
public boolean seesSlot()
{ return itsPos < itsSequence.size();
} //======================

/** Tell whether there is a CD in its current slot. */
public boolean seesCD()
{ if (! seesSlot())
fail ("Can't see a CD where there is no slot!");
return itsSequence.get (itsPos) != null;
} //======================

/** Return the CD that is in its current slot. */
public String getCD()
{ if (! seesSlot())
fail ("There is no slot to get a CD from!");
return (String) itsSequence.get (itsPos);
} //======================

/** Tell whether the stack has any CDs available. */
public static boolean stackHasCD()
{ return ! theStack.isEmpty();
} //======================

/* ACTION METHODS */
/** Move forward to the next slot in the sequence. */
public void moveOn()
{ if (! seesSlot())
fail ("Already at the end of the sequence!");
itsPos++;
trace ("moveOn to slot " + (itsPos + 1));
} //======================

/** Back up to the previous slot in the sequence. */
public void backUp()
{ if (itsPos == 0)
fail ("Already at the front of the sequence!");
itsPos--;
trace ("backUp to slot " + (itsPos + 1));
} //======================

/** Move a CD from the stack to the current slot. */
public void putCD()
{ if (! seesCD() && stackHasCD())
itsSequence.set (itsPos, theStack.pop());
trace ("putCD at slot " + (itsPos + 1));
} //======================

/** Move a CD from the current slot to the stack. */
public void takeCD()
{ if (seesCD())
{ theStack.push (itsSequence.get (itsPos));
itsSequence.set (itsPos, null);
}
trace ("takeCD at slot " + (itsPos + 1));
} //======================

/** Terminate the program with an appropriate message. */
private void fail (String cause)
{ JOptionPane.showMessageDialog (null, "STOPPING: " + cause
+ " (Vic #)" + itsID + ", position =" + itsPos);
System.exit (0);
} //======================

/** Two convenience methods */
public void shiftFromSlotToStack()
{ takeCD();
} //======================

public void shiftFromStackToSlot()
{ putCD();
} //======================

/** Back up to the string position */

public void backUpTo (String someSpot)
{ while (! someSpot.equals (getPosition()))
backUp();
}

/* METHODS THAT USE THE FRAME */
private static String vicSay = "Programmable CD Organizer "
+ " mfd by Jones & Co.";
private static final VicFrame theFrame = new VicFrame();
//////////////////////////////////

public static void say (String message)
{ vicSay = message;
theFrame.repaint();
} //======================

/** Print a trace of the Vic's action. */
private void trace (String message)
{ System.out.println (message + " for Vic #" + itsID);
theFrame.repaint();
pause (500); // half-a-second between actions
} //======================

/** Pause for the specified number of milliseconds. */
private static void pause (int milliseconds)
{ try
{ Thread.sleep (milliseconds);
}
catch (InterruptedException e)
{ // never happens
}
} //======================

/* THE INITIALIZER AND CONSTRUCTOR METHODS */
private static final int MAXSLOTS = 8;
private static final int MINSLOTS = 3;
private static final int MAXVICS = 4;
private static final Random random = new Random();
private static int theMaxVics = random.nextInt (MAXVICS) + 1;
private static ArrayList[] theSeq = new ArrayList[theMaxVics];
private static int theNumVics = 0;
private static final Vic[] theVics = {null, null, null, null};
//////////////////////////////////

/** Initialize individual sequences and stacks. An initializer method
is used because these have to exist before any Vics are created. */

static
{ for (int k = 0; k < theMaxVics; k++)
{ theSeq[k] = new ArrayList();
int numSlots = random.nextInt (MAXSLOTS - MINSLOTS + 1)
+ MINSLOTS;
for (int i = 0; i < numSlots; i++)
{ String it = random.nextInt (2) == 0 ? null
: "" + (char) (i + 'a') + (k + 1);
theSeq[k].add (it);
}
}

//add this code at line 150
for (int i = 0; i < 10; i++)
{
theStack.push ("CD#" + i);// pushes 10 CDs to stack
}

// // start with up to 2 CDs on the stack
// if (random.nextInt (3) > 0) // 2 times out of 3
// { theStack.push ("GarthB");
// if (random.nextInt (2) == 0) // 1 time out of 3
// theStack.push ("LyleL");
// }
} //======================

/** Construct a new Vic. */
public Vic()
{ super();
itsSequence = theNumVics < theMaxVics
? theSeq[theNumVics] : new ArrayList();
itsPos = 0;
itsID = theNumVics + 1;
theVics[theNumVics] = this;
theNumVics++;
trace ("construction");
} //======================

/** Replace random arrangement by user-specified arrangement. */
public static void reset (String[] args)
{ if (args.length > 0 && theNumVics == 0)
{ theMaxVics = Math.min (args.length, MAXVICS);
theSeq = new ArrayList[theMaxVics];
for (int k = 0; k < theMaxVics; k++)
{ theSeq[k] = new ArrayList();
int longest = Math.min (args[k].length(), MAXSLOTS);
for (int i = 0; i < longest; i++)
{ String it = args[k].charAt (i) == '0' ? null
: "" + (char)(i + 'a') + (k + 1);
theSeq[k].add (it);
}
}
}
} //======================

// THE NESTED FRAME CLASS
static class VicFrame extends JFrame
{ private final int SLOT = 75; // between CD slots
private final int EDGE = 10; // leave free at left side
private final int WIDTH = (MAXSLOTS + 2) * SLOT + 2 * EDGE;
private final int DIST = 60; // between CD sequences
private final int SAY = 45; // depth of say's output
private final int TOPSEQ = SAY + DIST; // depth of first seq

public VicFrame()
{ addWindowListener (new Closer());
setSize (WIDTH, TOPSEQ + MAXVICS * DIST + 2 * EDGE);
setBackground (new Color (255, 252, 224)); // a nice cream
setVisible (true); // make it visible to user
} //======================

/** Same as for an applet; called by repaint. */
public void paint (Graphics page)
{ // PRINT THE vicSay MESSAGE AT THE TOP
page.setColor (getBackground());
page.fillRect (EDGE, EDGE, WIDTH - 2 * EDGE,
TOPSEQ + MAXVICS * DIST);
page.setColor (Color.white);
page.fillRect (20, SAY - 20, WIDTH - 40, 20);
page.setColor (new Color (0, 96, 0)); // a light green
page.drawString (vicSay, 25, SAY - 5); // message

// DRAW UP TO FOUR Vic SEQUENCES AND THE STACK
for (int k = 0; k < theMaxVics; k++)
drawSequence (page, k, TOPSEQ + k * DIST);
page.setColor (Color.red);
int y = TOPSEQ + MAXVICS * DIST;
page.drawString ("stack", EDGE, y);
page.fillRect (EDGE, y - 25, 40, 5); // dividing line
for (int k = 0; k < theStack.size(); k++)
page.drawString ((String) theStack.get (k),
EDGE, y - 30 - k * 20);
} //======================

/** Called by VicFrame's paint method. */
private void drawSequence (Graphics page, int index, int y)
{ page.setColor (Color.red);
if (theVics[index] != null)
drawMacMan (page, theVics[index].itsPos, y - 15);
page.setColor (Color.blue);
drawAllCDs (page, y, theSeq[index]);
} //======================

private void drawAllCDs (Graphics page, int y,
ArrayList slots)
{ int atEnd = slots.size();
for (int n = 0; n < atEnd; n++)
{ String it = (String) slots.get (n);
page.drawString (it == null ? "---" : it,
(n + 1) * SLOT + EDGE, y);
}
page.drawString ("END", (atEnd + 1) * SLOT + EDGE, y);
} //======================

private void drawMacMan (Graphics page, int pos, int y)
{ // <x, y> is the lower-left corner of the stick figure
int x = pos * SLOT + EDGE + 78;
page.setColor (Color.black);
page.drawLine (x, y, x + 6, y - 6); // leg
page.drawLine (x + 6, y - 6, x + 12, y); // leg
page.drawLine (x + 6, y - 6, x + 6, y - 18); // body
page.drawLine (x, y - 14, x + 12, y - 14); // arms
page.drawOval (x + 1, y - 28, 10, 10); // head
page.drawLine (x + 4, y - 25, x + 5, y - 25); // eye
page.drawLine (x + 7, y - 25, x + 8, y - 25); // eye
page.drawLine (x + 3, y - 22, x + 9, y - 22); // mouth
} //======================
} // end of VicFrame class

private static class Closer extends java.awt.event.WindowAdapter
{
public void windowClosing (java.awt.event.WindowEvent e)
{ System.exit (0);
} //======================
}
}

// </pre>

Fou-Lu
01-09-2012, 09:00 PM
Assuming that you cannot go from the end to the start, you can shadow the variable instead to limit the work (the datastorage you are using would let you do this, but you don't have a way to access the end from your method). There is no reason to iterate more than once (if I perceive this list properly).



public String lastEmptySlot()
{
String spot = this.getPosition();
String lastEmpty = null;
String shadow = null;
int iEmpty = 0;
while (this.seesSlot())
{
if (!this.seesCD()) // nothing there
{
shadow = lastEmpty;
lastEmpty = this.getPosition();
++iEmpty;
}
this.moveOn();
}
if (shadow == null || iEmpty < 2)
{
shadow = spot;
}
return shadow;
}


Its slightly easier execution wise if you can seek to the end. If that can be done, you can iterate backwards and break the loop or add an additional check once 3 empty slots have been found.

Try that out. Works alright in my head.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum