C перемешать 2D массив - PullRequest
0 голосов
/ 07 июля 2019

Хотите перемешать массив * и создать элементы в случайном порядке

Я прочитал Перемешать массив в C , но для int

Я пытаюсь

const char *words = { "one", "two", "three", "four", "five", "six" }; 
for (int i=0; i<6; i++)
{
    int r = (rand() % (6 - i)) + i;

    int temp =  words[i];
    words[i] = words[r];
    words[r] = temp;
}

ошибка, хотя при повторении слов массива

пожалуйста, объясните

Ответы [ 2 ]

4 голосов
/ 07 июля 2019

Как сказано в комментариях, у вас есть несколько проблем

const char *words = { "one", "two", "three", "four", "five", "six" }; 

недопустимо, потому что инициализация (и остальная часть кода) указывает на words - массив, поэтому замените его на

const char *words[] = { "one", "two", "three", "four", "five", "six" }; 
    int temp =  words[i];
    words[i] = words[r];
    words[r] = temp;

слова - это массив const char *, поэтому temp не может быть int , используйте

const char * temp = words[i];

Из этого

  • использовать литерал 6 опасно, используйте sizeof , чтобы учесть любое изменение слов , заменяя 6 на sizeof(words)/sizeof(*words)
  • правильный тип для индекса size_t,
  • чтобы не всегда иметь одинаковые исполнения, используйте srand , например, с текущим временем

Например:

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

int main(void)
{
  const char *words[] = { "one", "two", "three", "four", "five", "six" };
  const size_t nelts = sizeof(words)/sizeof(*words);

  srand(time(NULL));

  for (size_t i=0; i < nelts;  ++i)
  {
    size_t r = (rand() % (nelts - i)) + i;
    const char * temp =  words[i];

    words[i] = words[r];
    words[r] = temp;
  }

  /* show */
  for (size_t i=0; i < nelts;  ++i)
    puts(words[i]);

  return 0;
}

Компиляция и исполнения:

pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra c.c
pi@raspberrypi:/tmp $ ./a.out
four
one
two
five
three
six
pi@raspberrypi:/tmp $ ./a.out
one
three
two
four
five
six
pi@raspberrypi:/tmp $ ./a.out
six
five
two
four
three
one
pi@raspberrypi:/tmp $ ./a.out
three
one
five
four
six
two
1 голос
/ 07 июля 2019

В коде OP есть несколько ошибок и недостатков.

  1. массив строк:
const char *words = { "one", "two", "three", "four", "five", "six" };

Не уверен, как компилятор это читает (если не жалуется). Массив строк C должен быть:

const char *words[] = { "one", "two", "three", "four", "five", "six" };
  1. магическое число
for (int i=0; i<6; i++)

6 - это магическое число , которое считается плохим стилем. Лучше дать ему имя. Еще лучше: значение может быть определено компилятором, который улучшает удобство сопровождения кода:

int n = sizeof words / sizeof *words;
for (int i = 0; i < n; ++i) {
  1. использование rand()
int r = (rand() % (6 - i)) + i;

rand() - генератор псевдослучайных данных с некоторыми ограничениями. Не следует использовать с % n. Для некоторых n с (например, 2) это может привести к довольно неслучайной последовательности. Справочный документ. из rand() дает лучший пример, который я превратил в функцию:

int randomRange(int min, int max)
{
  for (int range = max - min;;) {
    int x = min + rand() / ((RAND_MAX + 1u) / range);
    if (x < max) return x;
  }
}

который называется

int r = randomRange(i, n);
  1. идиоматический своп
int temp =  words[i];

Если тип элементов массива для обмена - const char*, temp также должно быть:

    const char *temp = words[i];
    words[i] = words[j];
    words[j] = temp;

Полный пример кода:

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

int randomRange(int min, int max)
{
  for (int range = max - min;;) {
    int x = min + rand() / ((RAND_MAX + 1u) / range);
    if (x < max) return x;
  }
}

int main(void)
{
  /* an array of strings */
  const char *words[] = { "one", "two", "three", "four", "five", "six" };
  /* let compiler determine size */
  int n = sizeof words / sizeof *words;
  /* shuffle */
  for (int i = 0; i < n; ++i) {
    int j = randomRange(i, n);
    /* idiomatic swap */
    const char *temp = words[i];
    words[i] = words[j];
    words[j] = temp;
  }
  /* print result */
  const char *sep = "";
  for (int i = 0; i < n; ++i) {
    printf("%s%s", sep, words[i]);
    sep = ", ";
  }
  /* done */
  return 0;
}

Выход:

six, three, one, two, four, five

Демонстрация в реальном времени на coliru

...