[英]C: reverse array in subrange
我正在嘗試使用此處描述的方法實現左數組旋轉: http : //www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf (在Reversal算法部分下)
當起始索引不為0時,我無法反轉數組。
這是我到目前為止:
void reverse_arr(int *a, int start, int end)
{
int i;
int len = end - start;
//printf("Len pre loop: %d\n", len);
int swap;
for(i = start; i < --len; i++)
{
//printf("start: %d\tlen: %d\n", start, len);
swap = a[i];
a[i] = a[len];
a[len] = swap;
}
}
當起始索引為0時,這很有效,但是當它是其他任何東西時,它永遠不會反轉所有元素。
例如:
int test[] = {1,2,3,4,5,6};
reverse_arr(test, 0, 2); //reverse the first 2 elements of the array
結果: {2,1,3,4,5,6}
是預期的
int test[] = {1,2,3,4,5,6};
reverse_arr(test, 2, 6); //reverse the last 4 elements of the array
結果是: {2,1,4,3,5,6}
這是不可預期的,只有3和4被逆轉。
任何幫助,將不勝感激。
您需要調整交換中的其他下標:
void reverse_arr(int *a, int start, int end)
{
int len = end - start;
for (int i = start; i < --len; i++)
{
int swap = a[i];
a[i] = a[i+len];
a[i+len] = swap;
}
}
您可能還可以使用:
void reverse_arr(int *a, int start, int end)
{
int len = end - start;
end--;
for (int i = start; i < --len; i++, end--)
{
int swap = a[i];
a[i] = a[end];
a[end] = swap;
}
}
#if defined(VERSION1)
static void reverse_arr(int *a, int start, int end)
{
int i;
int len = end - start;
int swap;
for (i = start; i < --len; i++)
{
swap = a[i];
a[i] = a[i+len];
a[i+len] = swap;
}
}
#else
static void reverse_arr(int *a, int start, int end)
{
int i;
int len = end - start;
end--;
for (i = start; i < --len; i++, end--)
{
int swap = a[i];
a[i] = a[end];
a[end] = swap;
}
}
#endif
#define DIM(x) (sizeof(x)/sizeof(x[0]))
#include <stdio.h>
static void print_array(int *array, size_t size)
{
for (size_t i = 0; i < size; i++)
printf(" %d", array[i]);
putchar('\n');
}
static void tester(int lo, int hi)
{
int test[] = {1,2,3,4,5,6};
printf("Before: (%d, %d)\n", lo, hi);
print_array(test, DIM(test));
reverse_arr(test, lo, hi); //reverse the first 2 elements of the array
printf("After: (%d, %d)\n", lo, hi);
print_array(test, DIM(test));
putchar('\n');
}
int main(void)
{
tester(0, 2);
tester(2, 6);
return(0);
}
使用-DVERSION1編譯的結果是否相同:
Before: (0, 2)
1 2 3 4 5 6
After: (0, 2)
2 1 3 4 5 6
Before: (2, 6)
1 2 3 4 5 6
After: (2, 6)
1 2 6 4 5 3
你應該完全放棄len
,而是使用end
。 當你在它時,你也可以放棄i
,並使用start
。 您的代碼將以這種方式變得更具可讀性:
void reverse_arr(int *a, int start, int end)
{
int swap;
while(start < end)
{
swap = a[start];
a[start++] = a[--end];
a[end] = swap;
}
}
這是因為你將i
與len
進行比較,如果它從0開始就沒有問題,但如果從其他任何東西開始則沒有(基數值不同)。
例如,如果要從偏移12開始旋轉三個字符,則因為for
循環在退出狀態開始 ,所以不會發生任何事情。
快速解決方法是在開始循環之前簡單地調整a
,以便它有效地認為(本地值) a
是數組的開頭:
a += start;
for (i = start; i < --len; i++) // No change on this line.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.