- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正试图找出如何正确地读入和存储C.txt文档中的迷宫。这个迷宫的最大大小是40x40“立方体”。读完后,我将需要解决它,通过放置路径从左下角到右下角与*。我习惯于使用二维数组,但这个问题一直困扰着我,因为我不知道如何跟踪行和列,如果它们不完全均匀,或者我甚至不知道如何准确地在每个“立方体”的中间打印一个*。我读过其他由1和0组成的迷宫的例子,甚至所有的迷宫都是为墙壁设计的,这样可以很容易地读入和跟踪,但不需要像这样输入。在解决第一个迷宫后,我需要在同一个文本文件上读取其他迷宫,第一个迷宫将由一个双空格分隔。下面是其中一个迷宫的示例:
+---+---+---+---+---+
| | |
+---+ + + + +
| | | | | |
+ + + + +---+
| | | | |
+ + + +---+ +
| | | |
+ +---+---+ + +
| | |
+---+---+---+---+---+
/* Read in a grid as parameter of max 120x120 to account for '+' and'-' */
int readLine(int grid2D[120][120])
{
int row = 0;
int col = 0;
int isNewLine = TRUE;
/* Loop through while getchar does not equal EOF */
while ((c = getchar()) != EOF)
{
/* Check for foreign characters, return FALSE if found */
if ((c != '+') || (c != '-') || (c != '|') || (c != ' '))
{
/* If c = \n , avoid tripping error, and do nothing */
if(c == '\n'){}
else
errorFree = FALSE;
}
/* If character is a '+' '-' or '|', it is a wall, set to -1 to
use int's for wall tracking */
else if (row%2 == 0)
{
if(c == '|')
{
grid2D[row][col] = -1;
col++;
}
}
else if((c == '+') || (c == '-'))
{
grid2D[row][col] = -1;
col++;
}
else
{
if(c == '\n')
{
col = 0;
row++;
}
}
isNewLine = TRUE;
return isNewLine;
}
+---+
,另一边是a
|
)
最佳答案
针对您在评论中提出的问题,确定行和列的大小是非常直接的。当您使用fgets
从文件中读取数组的一行时,可以使用strlen()
来确定字符数(但请注意,它还包含'\n'
字符-因此您需要减去一个-这可以与从结尾处修剪'\n'
结合使用)
读取第一行并计算'\n'
后,设置一个变量来保存数组中的字符数(列)。由于您知道数组是多维数据集,因此可以将第一行的长度与读取的每一行的长度进行比较,以验证所有行具有相同数量的列。
在循环和处理每一行的输入时,您只需保留一个行计数器,当您完成读操作时,该计数器将保存数组中的行数。
有两种方法可以处理阵列的存储。您可以声明一个足够大的数组来容纳最大的预期迷宫(同时保持它足够小以适合堆栈256x512
在Linux和Windoze上都是安全的),也可以动态地为列和行分配存储空间,根据需要使用realloc()
来分配额外的存储空间。(在那里你可以处理迷宫的大小直到你的计算机的内存限制-但是它确实增加了复杂性)
你对我的数组的“困惑”是可以理解的,例如11x21
这一切都源于终端上的字符大约是宽字符的两倍。因此,要打印字符的“立方体”,需要的列数大约是行数的两倍。这根本不是问题。如果对列和行的读取进行了正确的编码,并且让变量跟踪列和行的数量,那么差异就只不过是代码在几个变量中跟踪的数字。
下面是一个简短的例子来解决您在读取未知数或行和列到固定最大值时遇到的绊脚石。(而不是动态分配和重新分配——我们可以稍后再讨论)。要做到这一点,我们#define
一个最大列数的常数,然后知道我们需要1/2个行数,
#include <stdio.h>
#include <string.h>
#define MAXC 512 /* declare consts for max NxN you can handle */
#define MAXR (MAXC + 1) / 2
#define
和
row
以及行和列的总数(
col
)以及声明一个数组来保存迷宫就很简单了。如果文件名是第一个参数,则可以打开文件(如果没有参数,则默认从
nrow, ncol
读取)。在这两种情况下,您都可以验证是否打开了一个流以供读取,例如。
size_t row = 0, col = 0, nrow = 0, ncol = 0;
char a[MAXR][MAXC+1] = {""}; /* delcare and initialize array */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
a[MAXR][MAXC] = {""};
之后),并使用它与每行的字符数进行比较,以验证是否有立方体。在读取行时,还需要保护数组边界,这样就不会试图在数组中存储超过要保存行数的行,因此对
stdin
和
'\n'
进行简单的检查将强制执行该限制,例如。
while (row < MAXR && fgets (a[row], MAXC, fp)) {
size_t len = strlen (a[row]); /* get length of row */
if (len && a[row][len-1] == '\n') /* validate it fits in array */
a[row][--len] = 0; /* remove trailing '\n' char from end */
else if (len == MAXC) {
fprintf (stderr, "error: row exceeds %d chars.\n", MAXC);
return 1;
}
if (!row) /* if 1st row - set expected ncol for each row */
ncol = len;
if (ncol != len) { /* validate all other rows against 1st */
fprintf (stderr, "error: unequal columns (%lu) on row (%lu)\n",
len, row);
return 1;
}
/* your code goes here - example just outputs array */
for (col = 0; col < ncol; col++)
putchar (a[row][col]);
putchar ('\n');
row++; /* advance row counter when done processing row */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
nrow = row; /* save the total number of rows */
row < MAXR
和
fgets (a[row], MAXC, fp)
值,为您提供
nrow
数组。我将留给您的路径逻辑,但我确实想提供一个如何将路径中的
ncol
替换为
nrow x ncol
的示例。下面的操作只针对每个可能的路径字符执行约束,即每个
' '
都有一个相邻的空间(您可以根据需要进行调整)。这里我们只循环
'*'
并在数组中的每个字符上嵌套一个循环。
'*'
语句内部条件的简单添加来处理,例如。
/* you can make multiple passes over the array to determine your path.
* below is just an example of replacing the spaces in the path with
* asterisks.
*/
puts ("\nreplacing path spaces with asterisks\n");
for (row = 0; row < nrow; row++) {
for (col = 0; col < ncol; col++) {
/* if adjacents and current ' ', replace with '*' */
if (col && col < ncol - 1 && /* col > 0 && col < ncol-1 */
/* next checks adjacent and current all ' ' */
a[row][col-1] == ' ' && a[row][col] == ' ' &&
a[row][col+1] == ' ')
a[row][col] = '*'; /* if conditions met, set element '*' */
putchar (a[row][col]);
}
putchar ('\n');
}
0 -> nrow-1
个字符的迷宫,您可以执行如下操作:
#include <stdio.h>
#include <string.h>
#define MAXC 512 /* declare consts for max NxN you can handle */
#define MAXR (MAXC + 1) / 2
int main (int argc, char **argv) {
size_t row = 0, col = 0, nrow = 0, ncol = 0;
char a[MAXR][MAXC+1] = {""}; /* delcare and initialize array */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (row < MAXR && fgets (a[row], MAXC, fp)) {
size_t len = strlen (a[row]); /* get length of row */
if (len && a[row][len-1] == '\n') /* validate it fits in array */
a[row][--len] = 0; /* remove trailing '\n' char from end */
else if (len == MAXC) {
fprintf (stderr, "error: row exceeds %d chars.\n", MAXC);
return 1;
}
if (!row) /* if 1st row - set expected ncol for each row */
ncol = len;
if (ncol != len) { /* validate all other rows against 1st */
fprintf (stderr, "error: unequal columns (%lu) on row (%lu)\n",
len, row);
return 1;
}
/* your code goes here - example just outputs array */
for (col = 0; col < ncol; col++)
putchar (a[row][col]);
putchar ('\n');
row++; /* advance row counter when done processing row */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
nrow = row; /* save the total number of rows */
/* you can make multiple passes over the array to determine your path.
* below is just an example of replacing the spaces in the path with
* asterisks.
*/
puts ("\nreplacing path spaces with asterisks\n");
for (row = 0; row < nrow; row++) {
for (col = 0; col < ncol; col++) {
/* if adjacents and current ' ', replace with '*' */
if (col && col < ncol - 1 && /* col > 0 && col < ncol-1 */
/* next checks adjacent and current all ' ' */
a[row][col-1] == ' ' && a[row][col] == ' ' &&
a[row][col+1] == ' ')
a[row][col] = '*'; /* if conditions met, set element '*' */
putchar (a[row][col]);
}
putchar ('\n');
}
return 0;
}
0 -> ncol-1
$ ./bin/array2dread <dat/arrmaze.txt
+---+---+---+---+---+
| | |
+---+ + + + +
| | | | | |
+ + + + +---+
| | | | |
+ + + +---+ +
| | | |
+ +---+---+ + +
| | |
+---+---+---+---+---+
replacing path spaces with asterisks
+---+---+---+---+---+
| * * * | * * * * * |
+---+ * + * + * + * +
| * | * | * | * | * |
+ * + * + * + * +---+
| * | * | * | * * * |
+ * + * + * +---+ * +
| * * * | * | * * * |
+ * +---+---+ * + * +
| * * * * * * * | * |
+---+---+---+---+---+
关于c - 在数组中读取迷宫文件的数组,立方体大小不均,多余字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52461768/
我的服务层有如下方法 public ModuleResponse GetModules(ModuleRequest request) { var response = new ModuleRe
我构建的工具栏与大多数工具栏一样,minHeight 设置为 actionBarSize: 但是,如果我删除这个属性,就完全没有区别了。工具栏保持其 actionBarSize,即使我删除菜单并将
我已经为 SVG 和剪辑路径苦苦挣扎了一段时间。 我正在尝试创建一个三 Angular 形剪辑路径,它将覆盖照片以给顶部一个“三 Angular 形”边缘。 我试图实现与照片完全相同的效果,但三 An
我有一个带有 2 个索引的 PostgreSQL 表。其中一个索引涵盖了 website_id 和 tweet_id 列,是一个唯一的 B 树索引。第二个索引只覆盖 website_id 列,是一个非
我是一名优秀的程序员,十分优秀!