所以,这是一个每周一次的学校项目,我已经完全开始工作,但感觉好像我做的那样,可能不是最好的方法之一(甚至是一个好方法) )。我希望你们能帮助优化它/提供更好的解决方案。我已经提交了这个版本,但想知道一个更优化的问题解决方案。
首先,这是问题...
这几乎是万圣节,Linus正在花园里等待大南瓜。不幸的是,由于多样化,今年花园里还有很多其他葫芦,所以他需要你写一个程序告诉他有多少块南瓜和它们有多大。
该计划的输入将是许多不同的花园。每个花园的输入的第一行将是花园的尺寸,r,花园中的行数,以及c,列数,其中0≤r≤40且0≤c≤40。尺寸将是r行,每行有c个字符。这些字符中的每一个都是一个小写字母,表示在广场上种植的葫芦的类型。小写'p'代表南瓜。行数和/或列数为0的花园表示输入结束,不应处理。
示例输入:
10 10
pzzzzzzzzp
pyypzzzzzy
ppppssssyy
ssspssssyy
ssssppssyy
ssssppsspy
zzzzzzsspy
zzzzzzsspy
yyyypzsspy
yyyypppppy
3 4
pppp
pppp
pppp
1 7
zzzzzzz
0 0
对于每个花园,输出花园的数量(第一个输入设置为花园1),花园中南瓜片的数量,以及从最小到最大的南瓜片的大小。如果存在多个给定大小的补丁,请按原样打印大小。使用以下格式:
示例输出:
Garden # 1: 4 patches, sizes: 1 4 8 10
Garden # 2: 1 patches, sizes: 12
Garden # 3: 0 patches, sizes:
注意:即使问题是从文件输入,我们的教授告诉我们通过键盘输入。
我对此的处理方法是将花园放入一个带有x的边框的二维数组中。然后我会用一个函数找到一个南瓜贴片(并返回它的坐标)。然后我会使用另一个函数递归地发现如果南瓜通过上面,下面,左边和右边连接到那个,并返回南瓜贴片的大小。这个函数在找到它时通过用'x'替换它来“删除”每个南瓜。这让我不必担心多次找到南瓜。
所以这是我的代码,非常好的评论,以便你们有希望了解我想要做的事情。
#include <iostream>
#include <fstream>
using namespace std;
const int MAX_ROW = 41;
const int MAX_COL = 41;
char input ();
int checkForPatchSize ( char arr[][MAX_COL], int numOne, int numTwo );
bool findPatch ( char arr[][MAX_COL], int &row, int&col );
void sort ( int arr[], int size);
int main ()
{
int inputNumOne = -1; // Defaulted to -1, First number for Patch Size
int inputNumTwo = -1; // Defaulted to -1, Second number for Patch Size
int i, j; // i, j are indexes for loops, number
int numArr[MAX_ROW][MAX_COL]; // Array for storing Data
int indexGarden = 0;
int index = 1;
while ( inputNumOne != 0 )
{
cin >> inputNumOne; // User inputs Dimension
cin >> inputNumTwo; // Of Garden...
if ( inputNumOne != 0 and inputNumTwo != 0 ) // End case is that both are 0.
{
char pumpkinPatch[MAX_ROW][MAX_COL]; // Array for storing pumpkin patch info.
for ( i = 0; i < inputNumOne+2; i++ )
{
for ( j = 0; j < inputNumTwo+2; j++ )
{
// This if statement surrounds the garden in X's so that I have a border (allows me to not have to worry about test cases.
if ( i == 0 or j == 0 or i == inputNumOne + 1 or j == inputNumTwo + 1 )
{
pumpkinPatch[i][j] = 'x';
}
else // This is the input of the garden into a 2d array.
{
pumpkinPatch[i][j] = input();
}
}
}
int row, col, size, numberOfPatches = 0;
bool foundPatch = true;
index = 1;
while ( foundPatch == true )
{
row = inputNumOne+2; // Because I added a border to the garden
col = inputNumTwo+2; // the size is +2 of what the user input.
foundPatch = findPatch ( pumpkinPatch, row, col ); // Finds the start of a pumpkin patch, and returns the coordinates ( as row and col ).
if ( foundPatch == true ) // If a patch is found....
{
numberOfPatches++; // Increase number of patches
size = checkForPatchSize ( pumpkinPatch, row, col); // find size of particular patch
numArr[indexGarden][index] = size; // put size into data arr (to be printed to screen later).
index++;
}
}
numArr[indexGarden][0] = numberOfPatches; // Put number of patches as first item in each column of data arr.
indexGarden++;
}
}
for ( index = 0; index < indexGarden; index++ ) // Print out Garden Info
{
cout << "Garden # " << index + 1 <<": " << numArr[index][0] << " patches, sizes: ";
int temp = numArr[index][0]; // temp is the number of patches in particular garden.
int tempArr[temp]; // temp array to be used for sorting
int indexTwo;
for ( indexTwo = 0; indexTwo < temp; indexTwo++ )
{
tempArr[indexTwo] = numArr[index][indexTwo+1]; // Transfer sizes into a temp array so that they can be sorted.
}
sort (tempArr, temp); // Sort ( Sorts arr from smalles to larges )
for ( indexTwo = 0; indexTwo < temp; indexTwo++ ) // Output sorted array to screen.
{
cout << tempArr[indexTwo] << " ";
}
cout << endl;
}
}
char input()
{
char letter;
cin >> letter;
return letter;
}
/////////////// findPatch /////////////////////////////////////////////////
// Requirements: a 2D array of garden, and the size of it (row and col). //
// Returns a bool, true if patch is found, false if no patches found. //
// row and col are returned by reference to be the coordinates of one //
// of the pumpkins in the patch. //
///////////////////////////////////////////////////////////////////////////
bool findPatch ( char arr[][MAX_COL], int &row, int&col )
{
int rowIndex = 0;
int colIndex = 0;
while ( arr[rowIndex][colIndex] != 'p' and rowIndex < row )
{
colIndex = 0;
while ( arr[rowIndex][colIndex] != 'p' and colIndex < col )
{
colIndex++;
}
if ( arr[rowIndex][colIndex] != 'p' )
{
rowIndex++;
}
}
if ( arr[rowIndex][colIndex] != 'p' )
{
return false;
}
row = rowIndex;
col = colIndex;
return true;
}
/////////////// checkForPatchSize /////////////////////////////////////////
// Requirements: a 2D array of garden, and the coordinates of the start //
// of a patch. (Gotten from findPatch) //
// Returns an int, which is the size of the patch found //
// All p's or pumpkins are changed to x's so that they are not used //
// multiple times. //
///////////////////////////////////////////////////////////////////////////
int checkForPatchSize ( char arr[][MAX_COL], int numOne, int numTwo )
{
int index = 0;
if ( arr[numOne][numTwo] == 'p' )
{
index++;
arr[numOne][numTwo] = '0';
// Check Above
index += checkForPatchSize ( arr, numOne - 1, numTwo );
// Check to Left
index += checkForPatchSize ( arr, numOne, numTwo - 1 );
// Check Below
index += checkForPatchSize ( arr, numOne + 1, numTwo );
// Check to Right
index += checkForPatchSize ( arr, numOne, numTwo + 1 );
return index;
}
return 0;
}
/////////////// sort //////////////////////////////////////////////////////
// Requirements: an integer array, and the size of it (amount of //
// numbers in it). //
// //
// Sorts an array from smalles to largest numbers //
///////////////////////////////////////////////////////////////////////////
void sort ( int arr[], int size )
{
int index = 0;
bool changeMade = true;
while ( changeMade == true )
{
changeMade = false;
for ( index = 0; index < size - 1; index++ )
{
if ( arr[index] > arr[index+1] )
{
int temp = arr[index];
arr[index] = arr[index+1];
arr[index+1] = temp;
changeMade = true;
}
}
}
}
答案 0 :(得分:0)
好的,在阅读完代码后,我看到了你的方法。一般来说,我会从视角来看待这个问题。实际上,您的代码应该可以正常工作,并且是一个非常优雅的解决方案。算法的唯一缺点是每次移动时它都在同一个补丁上迭代。例如,当它向上移动时,它会向下检查。避免冗余是最佳算法的最可靠标志,但就您部署算法的小规模而言,它不一定是最优的。
在某种程度上,你的代码的递归性质使它非常漂亮,因为它遍历南瓜补丁,就像小火花一样消失,我真的很喜欢。递归是我经常不打扰的事情,主要是因为我不会递归地思考,但是花了一些时间绕过你的算法,我确实看到它在这种情况下的价值。我很乐意看到算法与动态视觉效果一起使用。
至于你的算法的准确性,我无法想象它会以任何方式无法正确计算南瓜,因为它的功能是在算法重复自身的采摘南瓜周围做一个小波,有效地传播通过补丁,直到全部计算。正如我所说,你的算法的唯一缺点是,如果你没有以某种方式将南瓜标记为已找到它(它会检查它被调用的位置),它将陷入无限循环。除此之外,我只能说你已经提出了一个很好的解决方案,你的疑虑几乎完全是错位的。在这方面使用递归算法是一个很好的选择,因为它不需要很长的案例列表来“计数”;它只是跳到相邻的位置,以完全计数返回自己。