arrays - 使字符数组向左/向右旋转其单元格 n 次
问题描述
我在这里完全是新人,但我听说过很多关于这个网站的信息,现在我已经被接受了 7 个月的软件开发“训练营”,我正在为即将到来的测试提高我的 C 知识。
我被分配了一个关于我已经通过的测试的问题,但是我没有完成那个问题,这让我很困扰。
问题是用 C 编写一个程序,将字符(char)数组的单元格向左移动 1(对我来说,在哪个方向上并不重要,但问题是向左移动)。而且我还自己承担在执行过程中不要使用临时数组/堆栈或任何其他结构来保存整个数组数据。
所以一个 'string' 或包含 '0' '1' '2' 'A' 'B' 'C' 的字符数组将在使用后变为 '1' '2' 'A' 'B' 'C' '0'功能一次。
写这个没问题,我相信我最终得到了类似的东西:
void ArrayCharMoveLeft(char arr[], int arrsize, int times) {
int i;
for (i = 0; i <= arrsize ; i++) {
ArraySwap2CellsChar(arr, i, i+1);
}
}
如您所见,该功能有些模块化,因为它允许输入单元格需要向左移动或移动的次数。我没有实现它,但这就是我的想法。
据我所知,有3种方法可以做到这一点:
- 循环 ArrayCharMoveLeft 次。这本能地感觉效率低下。
- 在 ArrayCharMoveLeft 中使用递归。这应该类似于第一个解决方案,但我不能 100% 确定如何实现它。
- 这就是我试图弄清楚的方式:循环中没有循环,没有递归,没有临时数组,程序将知道如何将单元格向左/向右移动 x 次而不会出现任何问题。
问题是,在交换数组中的 N 次单元之后,剩余的数组大小 - 有时没有组织。例如:
将 ArrayCharMoveLeft 与我们上面提到的给定数组一起使用 3 作为次将产生 ABC021 而不是 ABC012 的预期值。
我为此运行了以下功能:
int i;
char* lastcell;
if (!(times % arrsize))
{
printf("Nothing to move!\n");
return;
}
times = times % arrsize;
// Input checking. in case user inputs multiples of the array size, auto reduce to array size reminder
for (i = 0; i < arrsize-times; i++) {
printf("I = %d ", i);
PrintArray(arr, arrsize);
ArraySwap2CellsChar(arr, i, i+times);
}
如您所见,for 从 0 运行到数组大小 - 次。如果使用此函数,例如使用包含 14 个字符的数组。然后使用 times = 5 将使 for 从 0 运行到 9,因此单元格 10 - 14 不是按顺序排列的(但其余的是)。
最糟糕的是,剩余的细胞总是保持顺序,但在不同的位置。意思而不是 0123 他们可以是 3012 或 2301... 等等。
我在不同的时间值上运行了不同的数组,但没有找到特定的模式,例如“如果剩余的单元格 = 3,则在剩余的单元格上使用 ArrayCharMoveLeft,时间 = 1)。
它似乎总是 2 个选项中的 1 个:剩余的单元格按顺序排列,或者以不同的值移动。似乎与此类似:time shift+direction to allign 1 0 2 0 3 0 4 1R 5 3R 6 5R 7 3R 8 1R 数字随时间和数组的不同而变化。有人对此有想法吗?即使您在循环中使用递归或循环,我也想听听一个可能的解决方案。对此唯一坚定的规则是不要使用临时数组。
提前致谢!
解决方案
- 使用标准库函数
memcpy
,memmove
等,因为它们非常适合您的平台。 - 使用正确的尺寸类型 -
size_t
不是int
char *ArrayCharMoveLeft(char *arr, const size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
if(ntimes)
{
char temp[ntimes];
memcpy(temp, arr, ntimes);
memmove(arr, arr + ntimes, arrsize - ntimes);
memcpy(arr + arrsize - ntimes, temp, ntimes);
}
return arr;
}
但是您希望它没有临时数组(内存效率更高,性能非常差):
char *ArrayCharMoveLeft(char *arr, size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
while(ntimes--)
{
char temp = arr[0];
memmove(arr, arr + 1, arrsize - 1);
arr[arrsize -1] = temp;
}
return arr;
}
https://godbolt.org/z/od68dKTWq https://godbolt.org/z/noah9zdYY