我正在尝试创建一个程序来生成随机测试用例。我有一个有序的字符串数组(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'ed和数组一样,所有元素都打印得很好。任何想法都出错了?
答案 0 :(得分:4)
认为你应该只交换指针,而不是字符串内容本身。 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--;
}
答案 1 :(得分:1)
我相信他们的代码中存在一些问题:
您将size
传递给randomize()
,但您从未使用过它。最好这样做:
size_t x = rand() % size;
size_t y = rand() % size;
而不是将64
的大小值硬编码到这些行中。
由于您正在交换指针,因此无需创建临时缓冲区和strcpy()
指针。你可以简单地交换指针本身。我建议只使用这样的函数:
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}
答案 2 :(得分:0)
您的代码存在的一个问题是,x
和y
可能是相同的数字,而strcpy
时您strcpy(list[x], list[y]);
自身char**
。 Afaik,这不能保证有效。
(虽然我相信您的实际问题可能与您填充输入QStringList filenames = QFileDialog::getOpenFileNames(this,"",QDir::currentPath() );
的方式有关。无法验证,因为现在缺少信息)