簡體   English   中英

C:子范圍內的反向數組

[英]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;
    }
}

這是因為你將ilen進行比較,如果它從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM