Заполнение 2D МАССИВА символами из строки

Я пытаюсь заполнить массив некоторыми выбранными символами из строки. 2 столбца должны оставаться пустыми, но у меня это работает так. Каждый символ должен быть равен количеству строк. Как игра с сортировкой мячей.. Небольшой совет? Спасибо.

void generator(const int rows, const int columns, char field[rows][columns]){  
    // seed
    srand(time(NULL));

    int random_index;

    // choosing empty columns (they'll be by side)
    int clear_column[2];
    // choosing random number in range of columns
    clear_column[0] = rand() % (columns+1);
    // adding +1 index to already choosen number
    clear_column[1] = clear_column[0]+1;
    // if choosen number is equal to number of columns => second empty column will be on the left side
    if ( clear_column[0] == columns)
    {
        clear_column[1] = clear_column[0]-1;
    }

    // variable to store all symbols 
    char store_symbol[10] = "^@#&*+-/$";
    // variable to store used symbols
    int store_index[10] = {0,0,0,0,0,0,0,0,0};
    
    

    // ** i = columns; k = rows

    // loops all columns
    for (int i = 0; i < columns; i++)
    {
        // loops all rows
        for (int k = 0; k < rows; k++)
        {
            // adding empty columns
            if ( i == clear_column[0] || i == clear_column[1])
            {
                field[k][i] = ' ';
            }
            else{
                int got_symbol = 0;
                while (got_symbol == 0)
                {
                    random_index = rand() % rows;

                    if ( store_index[random_index] <= rows)
                    {
                        field[i][k] = store_symbol[random_index];
                        store_index[random_index] += 1;
                        got_symbol = 1;
                        break;
                    }
                    
                }
                
            }
            
        }
        
    }

Вот как это должно выглядеть.

В сторону: вызов srand внутри функции-генератора вызывает недоумение. Может быть безобидно, но проверьте srand() — зачем вызывать его только один раз?

Oka 20.11.2022 17:25
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
1
207
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы исправить потенциальное Undefined Behavior в этой функции, когда rows не равно columns, индексы здесь

field[i][k] = store_symbol[random_index];

Нужно перевернуть

field[k][i] = store_symbol[random_index];

Следующее позволяет rows плюс один из каждого символа в массиве:

if (store_index[random_index] <= rows) {

Измените <= на <, чтобы ограничить количество каждого символа в массиве до максимума rows.

Следующий

int clear_column[2];
clear_column[0] = rand() % (columns+1);
clear_column[1] = clear_column[0]+1;
if (clear_column[0] == columns) {
    clear_column[1] = clear_column[0]-1;
}

Вводит ошибку off-by-one. Если clear_column[0] равно columns, то очищается только последний столбец через clear_column[1] (clear_column[1] = clear_column[0] - 1;).

I никогда не достигнет columns в цикле.

Есть несколько решений для этого:

Убедитесь, что columns > 1 найдите первый столбец в допустимом диапазоне минус один и возьмите следующий столбец.

int clear_column[2] = { rand() % (columns - 1) };
clear_column[1] = clear_column[0] + 1;

Или найдите первый столбец для очистки в пределах допустимого диапазона и отрегулируйте второй в любом направлении:

int clear_column[2] = { rand() % columns };             
clear_column[1] = clear_column[0] + (clear_column[0] == columns - 1 ? -1 : 1);

В стороне: это чаще распределяет пустые столбцы по двум последним столбцам (clear_column[0], будучи columns - 1 или columns - 2, приводит к тому же шаблону.

Или вы можете обернуть второй столбец, чтобы очистить его до начала массива:

clear_column[0] = rand() % columns;
clear_column[1] = (clear_column[0] + 1) % columns;

Или полностью рандомизируйте очищенные столбцы.

int clear_column[2] = { rand() % columns };      
while ((clear_column[1] = rand() % columns) == clear_column[0]);

Однако эти последние два создают разные шаблоны.


Возникла проблема с требованием

Каждый символ должен быть равен количеству строк

Когда количество элементов за вычетом количества пробелов (строк, умноженных на два) не равно квадрату строк, поскольку вы допускаете rows разных символов до rows раз каждый.

Вместо этого вы должны разрешить columns - 2 разных символов до rows раз каждый (или наоборот).


Вот пример вышеупомянутых изменений, примененных к вашей функции:

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

#define SYM "^@#&*+-/$?"
#define MAX_SYM 10
#define def(c, a, i, d) (c > i ? atoi(a[i]) : d)

void generator(const int rows, const int columns, char field[rows][columns])
{
    int clear_column[2] = { rand() % columns };
    clear_column[1] = (clear_column[0] + 1) % columns;

    char store_symbol[MAX_SYM] = SYM;
    int store_index[MAX_SYM] = { 0 };

    for (int i = 0; i < columns; i++) {
        for (int k = 0; k < rows; k++) {
            if (i == clear_column[0] || i == clear_column[1]) {
                field[k][i] = ' ';
                continue;
            }

            while (1) {
                int random_index = rand() % (columns - 2);

                if (store_index[random_index] < rows) {
                    field[k][i] = store_symbol[random_index];
                    store_index[random_index] += 1;
                    break;
                }
            }
        }
    }
}

int main(int argc, char **argv)
{
    int r = def(argc, argv, 1, 4);
    int c = def(argc, argv, 2, 6);

    if (r < 1 || c < 1 || r > MAX_SYM || c > MAX_SYM) {
        fprintf(stderr, "Invalid dimensions %dx%d\n", r, c);
        return EXIT_FAILURE;
    }

    char map[r][c];

    srand((unsigned) time(NULL));
    generator(r, c, map);

    for (int i = 0; i < r; i++) {
        printf("|");
        for (int j = 0; j < c; j++) {
            printf(" %c |", map[i][j]);
        }

        putchar('\n');
    }
}

Другие вопросы по теме