交换数组的部分
Swapping sections of an array
我被要求制作一个函数来交换数组中的两个部分。
像这样,
array[] = {1 , 2, 5, 7, 8, a , b, c}
| |
sections: First Second
签名是void reverse_reg(int *arr, int s, int k, int j)
其中arr
是数组,s
是第一节的第一个索引,k
是第一节的最后一个索引j
表示第二部分的结尾,开始是 k
(因为 C 中的索引从 0 开始)
到目前为止我有这样的东西,
void reverse_reg(int *arr, int s, int k, int j)
{
for (int i = s; i < j; i++)
{
if (i > k / 2) /* swap the rest */
{
swap(&arr[i], &arr[j - i + 1]); /* this is wrong */
}
else
{
swap(&arr[i], &arr[k + i + 1]);
}
}
}
我已经测试了 else
块,到目前为止它成功交换了第二部分,产生了,
result:
a b c 7 8 1 2 5
尽管如此,我还没有找到交换第二部分的方法,因为 if
块产生了一些完全错误的东西(这是有道理的),这让我认为最初的逻辑错误。有什么提示吗?
如果有帮助,我调用函数的方式是,reverse_reg(arr, 0, 4, 8);
结果数组应该是:
result:
a b c 1 2 5 7 8
正如@EugeneSh. 所指出的,一个简单的方法是反转每个部分,然后反转整个数组。它可以像这样简单:
void swap(int* i, int* j) {
int k = *i;
*i = *j;
*j = k;
}
void reverse(int arr[], int len) {
for (int i = 0; i < len / 2; i++) {
swap(arr + i, arr + len - i - 1);
}
}
void reverse_reg(int* arr, int s, int k, int j) {
// you use last index of initial section while I need index of second one
++k;
reverse(arr + s, k - s);
reverse(arr + k, j - k);
reverse(arr + s, j - s);
}
"12578abc"
"abc12578"
假设 array
声明为 unsigned char array[8];
,这可以是对 64 位整数的循环操作。使用旋转函数,我们可以将 "abc"
向左移动,将 "12578"
向右移动,然后合并它们的结果:
uint64_t rot_left_64(uint64_t num, int n)
{
return (num << n) | (num >> (64 - n));
}
uint64_t num = 0x01020507080a0b0c;
num = rot_left_64(num , 8 * 5);
printf("%016llX\n", n); //output 0x0A0B0C0102050708
我被要求制作一个函数来交换数组中的两个部分。
像这样,
array[] = {1 , 2, 5, 7, 8, a , b, c}
| |
sections: First Second
签名是void reverse_reg(int *arr, int s, int k, int j)
其中arr
是数组,s
是第一节的第一个索引,k
是第一节的最后一个索引j
表示第二部分的结尾,开始是 k
(因为 C 中的索引从 0 开始)
到目前为止我有这样的东西,
void reverse_reg(int *arr, int s, int k, int j)
{
for (int i = s; i < j; i++)
{
if (i > k / 2) /* swap the rest */
{
swap(&arr[i], &arr[j - i + 1]); /* this is wrong */
}
else
{
swap(&arr[i], &arr[k + i + 1]);
}
}
}
我已经测试了 else
块,到目前为止它成功交换了第二部分,产生了,
result:
a b c 7 8 1 2 5
尽管如此,我还没有找到交换第二部分的方法,因为 if
块产生了一些完全错误的东西(这是有道理的),这让我认为最初的逻辑错误。有什么提示吗?
如果有帮助,我调用函数的方式是,reverse_reg(arr, 0, 4, 8);
结果数组应该是:
result:
a b c 1 2 5 7 8
正如@EugeneSh. 所指出的,一个简单的方法是反转每个部分,然后反转整个数组。它可以像这样简单:
void swap(int* i, int* j) {
int k = *i;
*i = *j;
*j = k;
}
void reverse(int arr[], int len) {
for (int i = 0; i < len / 2; i++) {
swap(arr + i, arr + len - i - 1);
}
}
void reverse_reg(int* arr, int s, int k, int j) {
// you use last index of initial section while I need index of second one
++k;
reverse(arr + s, k - s);
reverse(arr + k, j - k);
reverse(arr + s, j - s);
}
"12578abc"
"abc12578"
假设 array
声明为 unsigned char array[8];
,这可以是对 64 位整数的循环操作。使用旋转函数,我们可以将 "abc"
向左移动,将 "12578"
向右移动,然后合并它们的结果:
uint64_t rot_left_64(uint64_t num, int n)
{
return (num << n) | (num >> (64 - n));
}
uint64_t num = 0x01020507080a0b0c;
num = rot_left_64(num , 8 * 5);
printf("%016llX\n", n); //output 0x0A0B0C0102050708