У меня проблема с кодом, который я пишу, который должен взять список ящиков разного размера и упаковать их в один большой контейнер.
Основной метод, который должен реализовывать решение, называется fillContainerBox()
. У меня есть базовое c вложенное выражение if, которое будет работать для упаковки первых нескольких коробок, но код не выполняется, когда необходимо распаковать более 1 коробки.
/**Container Box Class which sorts using recursion
*
* @author Richard McCormick
*/
public class ContainerBoxClass extends java.lang.Object
{
private static int CLEAR_BOX = 102;
private static int FILL_BOX = 101;
private static final char DEFAULT_FIELD_CHAR = 45;
private static final int MAX_NUM_BOXES = 26;
private static final int NO_BOXES_AVAILABLE = -1;
private BoxClass[] boxList = new BoxClass[MAX_NUM_BOXES];
private char[][] containerBoxField;
private int containerBoxHeight = 0;
private int containerBoxWidth = 0;
private int numBoxesAvailable = 0;
//Shows what you are doing
private boolean displayFlag = false;
/**Default constructor class
* @param initBoxHeight - Height of container
* @param initBoxWidth - Width of container
*/
ContainerBoxClass(int initBoxHeight, int initBoxWidth)
{
containerBoxHeight = initBoxHeight;
containerBoxWidth = initBoxWidth;
containerBoxField = new char[containerBoxWidth][containerBoxHeight];
//Populates field with empty values
for (int y = 0; y < containerBoxHeight; y++)
{
for (int x = 0; x < containerBoxWidth; x++)
{
containerBoxField[x][y] = DEFAULT_FIELD_CHAR;
}
}
displayFlag = false;
}
/**Adds a new box to list of boxes
* @param boxWidth
* @param boxHeight
* @return success
*/
public boolean addBoxToList(int boxWidth, int boxHeight)
{
//Initialize return
boolean success = false;
//Checks that there is room
if (numBoxesAvailable < MAX_NUM_BOXES)
{
//Creates a new box
BoxClass tempBox = new BoxClass(boxWidth, boxHeight);
tempBox.unsetUsedState();
//Increments available boxes
boxList[numBoxesAvailable] = tempBox;
numBoxesAvailable++;
//Success
success = true;
}
return success;
}
/**Checks location to see if box will fit
*
* @param testLocation - Point class
* @param testBox - Box class
*
* @return fits - Boolean indicator
*/
private boolean checkForFitInField(PointClass testLocation, BoxClass testBox)
{
boolean fits = false;
//Dimensions of testBox
int testWidth = testBox.getWidth();
int testHeight = testBox.getHeight();
//Position of test point
int testLocX = testLocation.getXPos();
int testLocY = testLocation.getYPos();
System.out.println("Test location: " + testLocX + " " + testLocY);
//Booleans to see if box is out of bounds or not
boolean inBoundsX = ((testLocX + testWidth) < containerBoxWidth);
boolean inBoundsY = ((testLocY + testHeight) < containerBoxHeight);
//If size fits within the container at desired location
if (inBoundsX && inBoundsY)
{
int numOccupied = 0;
//Iterates through location to determine if empty
for (int ycounter = testLocY; ycounter < (testLocY + testHeight); ycounter++)
{
for (int xcounter = testLocX; xcounter < (testLocX + testWidth); xcounter++)
{
//If there is something in location bounds, location not empty
if (containerBoxField[xcounter][ycounter] != DEFAULT_FIELD_CHAR)
{
numOccupied++;
}
}
}
if (numOccupied == 0)
{
fits = true;
}
}
return fits;
}
/**Displays the items in box
*
*/
public void displayField()
{
String row;
//Prints field from top down, to preserve order/location
for (int height = containerBoxHeight - 1; height >= 0; height--)
{
//Clears row each iteration
row = "";
//Iterates through columns in row
for (int width = 0; width < containerBoxWidth; width++)
{
//Checks to see if location is empty or not
if (containerBoxField[width][height] != DEFAULT_FIELD_CHAR)
{
row += " X ";
}
else
{
row += " " + DEFAULT_FIELD_CHAR + " ";
}
}
System.out.println(row);
}
System.out.println("===================================");
}
/**Fills a location in container box with a given box
*
* @param boxLocation - Location to pack box
* @param fillBox - Box to be packed
* @param clearFlag - Indicates if box is to be packed or removed
*/
public void fillBoxLocation(PointClass boxLocation, BoxClass fillBox, int clearFlag)
{
//Sets the starting and end positions for X-Axis
int xstart = boxLocation.getXPos();
int xend = xstart + fillBox.getWidth();
//Sets the starting and end positions for Y-Axis
int ystart = boxLocation.getYPos();
int yend = ystart + fillBox.getHeight();
//Output for testing
System.out.println("Attempting to fill box of size: " + fillBox.getWidth() + " " + fillBox.getHeight());
System.out.println("At location: " + xstart + " " + ystart);
//Iterates through each row
for (int ycounter = ystart; ycounter < yend; ycounter++)
{
//Iterates through each column
for (int xcounter = xstart; xcounter < xend; xcounter++)
{
//If clearFlag is set to fill box
if (clearFlag == FILL_BOX)
{
//Fill box
containerBoxField[xcounter][ycounter] = (char)FILL_BOX;
fillBox.setUsedState();
}
//Otherwise, erase box
else if (clearFlag == CLEAR_BOX)
{
containerBoxField[xcounter][ycounter] = (char)DEFAULT_FIELD_CHAR;
fillBox.unsetUsedState();
}
}
}
}
/**Attempts to fill the container class with boxes
*
* @return success - Boolean value indicating operation success
*/
public boolean fillContainerBox()
{
boolean success = false;
int currentBoxIndex = 0;
int previousBoxIndex = -1;
BoxClass currentBox;
BoxClass previousBox = new BoxClass();
PointClass currentLocation;
PointClass previousLocation = new PointClass();
while (findNextUnusedBoxIndex(0) != NO_BOXES_AVAILABLE)
{
currentBoxIndex = findNextUnusedBoxIndex(0);
currentBox = boxList[currentBoxIndex];
currentLocation = findNextOpenLocation();
BoxClass nextBox = boxList[currentBoxIndex + 1];
if (checkForFitInField(currentLocation, currentBox))
{
fillBoxLocation(currentLocation, currentBox, FILL_BOX);
PointClass nextLoc = new PointClass();
nextLoc = findNextOpenLocation();
if (checkForFitInField(nextLoc, nextBox) != true)
{
fillBoxLocation(currentLocation, currentBox, CLEAR_BOX);
fillBoxLocation(currentLocation, nextBox, FILL_BOX);
}
}
previousLocation = currentLocation;
previousBox = currentBox;
if (displayFlag)
{
displayField();
}
}
return success;
}
/**Finds the next open location in the container box
*
* @return openLocation - PointClass object containing first open location
*/
private PointClass findNextOpenLocation()
{
//Instantiates return variable as empty PointClass
PointClass openLocation = new PointClass();
//Boolean value which indicates whether location has been found
boolean hasLocation = false;
//Iterates through each row
for (int ycounter = 0; ycounter < containerBoxHeight; ycounter++)
{
//Iterates through each column
for (int xcounter = 0; xcounter < containerBoxWidth; xcounter++)
{
//If item at current location is empty, and no item has yet been found
if (containerBoxField[xcounter][ycounter] == DEFAULT_FIELD_CHAR && hasLocation == false)
{
//Set current location as first open location
openLocation.setXPos(xcounter);
openLocation.setYPos(ycounter);
//Indicate that location has been found
hasLocation = true;
}
}
}
//Return the open location
return openLocation;
}
/**Finds the next unused box in boxList, starting at provided index
*
* @param startAtIndex - Index to begin searching at
* @return indexFinal - Index of first unused box
*/
private int findNextUnusedBoxIndex(int startAtIndex)
{
//Sets up return and internal vars
int indexFinal = NO_BOXES_AVAILABLE;
int counter = startAtIndex;
//Iterates through available boxes
while (counter < numBoxesAvailable)
{
//If box has already been used, skip and increment
if (boxList[counter].isUsed())
{
counter++;
}
//Otherwise, return unused box index & terminate
else
{
indexFinal = counter;
counter = numBoxesAvailable;
}
}
//Return unused box index
return indexFinal;
}
/**Sets display flag
*
* @param setState - Boolean value to set displayFlag to
*/
public void setDisplayFlag(boolean setState)
{
//If display flag is not already equal to set state
if (setState != displayFlag)
{
//Set new flag state
displayFlag = setState;
}
}
}
Пожалуйста, извините за мой грязный код. Я пытался найти решение, но не нашел его.