2017-02-14 61 views
0

我试图创建一个程序来生成随机测试用例。我有一个字符串数组(char **),它们是有序的,我想随机化它们。我的方法是随机选择两个元素并交换它们。不过,我不断收到段错误,似乎错过了一些知识。交换字符串数组中的元素

样本阵列(64个元素):{"1 2 3", "3 2 1", "4 5 6".....}

char ** randomizeOrder(char ** list, int size){ 

    char temp[6]; 
    temp[5] = '\0'; 

    srand(time(NULL)); 
    int count = 64; 
    int x, y; 
    while(count > 0){ 
     fprintf(stderr, "Starting...\n"); 
     x = rand() % 64; 
     y = rand() % 64; 

     strcpy(temp, list[x]); 
     fprintf(stderr, "Copying %s from Y to X\n", list[y]); 
     strcpy(list[x], list[y]); 
     fprintf(stderr, "Copying %s from temp to Y\n", temp); 
     strcpy(list[y], temp); 
     count--; 
    } 

    return list; 

} 

这似乎在最初的几个元件工作,然后开始读取垃圾。元素与数组一样是malloc,所有元素都打印得很好。任何想法最新怎么了?

+1

这是怎么排列声明并填充? –

+2

如果您只是切换字符串,我不确定为什么您需要'strcpy'。你可以交换指针,这应该更容易。 –

+0

该数组是malloc'd,每个元素都是malloc'd,然后使用sprinf写入数值。 http://pastebin.com/aRsAB8Wg – DAnsermino

回答

3

认为你应该交换指针,而不是字符串内容本身。 A char**当然只是一个指针数组。

应该是这样的:

while(count > 0){ 
    x = rand() % 64; 
    y = rand() % 64; 

    char* tmp = list[x]; 
    list[x] = list[y]; 
    list[y] = tmp; 
    count--; 
} 

如果你想成为非常聪明的你可以使用this trick

代码的
while(count > 0){ 
    x = rand() % 64; 
    y = rand() % 64; 

    list[x] |= list[y]; 
    list[y] |= list[x]; 
    list[x] |= list[y]; 

    count--; 
} 
+0

我不认为'char **'是一个指针数组。指针数组通常类似于'char * arr []'。 'char **'只是一个指向指针的指针。 – RoadRunner

+0

用你的第二个片断,你会认为指针的行为和整数一样,不一定必须是真的。 – alk

+0

[在C中,指针和数组之间有非常紧密的联系。事实上,它们或多或少都是同一件事!](https://www.le.ac.uk/users/rjm1/cotter/page_59.htm) –

0

的一个问题是,它可能有xy为相同的号码,并且当strcpy(list[x], list[y]);时您是strcpy。 Afaik,这不能保证工作。

(虽然我相信你的实际问题,可能对你如何填充输入char**做无法验证,因为它是缺乏信息了。)

1

我相信他们的一些问题在你的代码:

  • 您将size传递给randomize(),但您从不使用它。这将更好地做到:

    size_t x = rand() % size; 
    size_t y = rand() % size; 
    

    而不是硬编码的64大小值到这些行。

  • 由于您正在交换指针,因此它们不需要创建临时缓冲区和指向它的指针。你可以简单地交换指针本身。我建议只使用一个功能是这样的:

    void swap(char **s1, char **s2) { 
        char *temp = *s1; 
        *s1 = *s2; 
        *s2 = temp; 
    } 
    

    那么你可以简单地传递swap(&list[x], &list[y]);交换你的指针。我不相信你的功能randomize()需要返回char**。如果仅仅是void,那将更容易。

下面是一些测试代码,显示这一点:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#define ARRAYSIZE(x) (sizeof x/sizeof x[0]) 

void randomize(char **list, size_t size); 
void print_list(char **list, size_t size); 
void swap(char **s1, char **s2); 

int main(void) { 
    char *list[] = {"1 2 3", "3 2 1", "4 5 6", "6 5 4", "7 8 9", "9 8 7"}; 

    printf("Original list:\n"); 
    print_list(list, ARRAYSIZE(list)); 

    randomize(list, ARRAYSIZE(list)); 

    return 0; 
} 

void randomize(char **list, size_t size) { 
    size_t x, y; 

    srand(time(NULL)); 

    for (size_t i = 0; i < size; i++) { 
     x = rand() % size; 
     y = rand() % size; 

     swap(&list[x], &list[y]); 

     printf("Swapping list[%zu] and list[%zu]:\n", x, y); 
     print_list(list, size); 
    } 
} 

void print_list(char **list, size_t size) { 

    printf("{"); 
    for (size_t i = 0; i < size-1; i++) { 
     printf("%s, ", list[i]); 
    } 
    printf("%s}\n\n", list[size-1]); 
} 

void swap(char **s1, char **s2) { 
    char *temp = *s1; 
    *s1 = *s2; 
    *s2 = temp; 
} 

随机输出:

Original list: 
{1 2 3, 3 2 1, 4 5 6, 6 5 4, 7 8 9, 9 8 7} 

Swapping list[0] and list[4]: 
{7 8 9, 3 2 1, 4 5 6, 6 5 4, 1 2 3, 9 8 7} 

Swapping list[4] and list[1]: 
{7 8 9, 1 2 3, 4 5 6, 6 5 4, 3 2 1, 9 8 7} 

Swapping list[0] and list[1]: 
{1 2 3, 7 8 9, 4 5 6, 6 5 4, 3 2 1, 9 8 7} 

Swapping list[3] and list[3]: 
{1 2 3, 7 8 9, 4 5 6, 6 5 4, 3 2 1, 9 8 7} 

Swapping list[2] and list[1]: 
{1 2 3, 4 5 6, 7 8 9, 6 5 4, 3 2 1, 9 8 7} 

Swapping list[4] and list[1]: 
{1 2 3, 3 2 1, 7 8 9, 6 5 4, 4 5 6, 9 8 7}