Nick McCaffery Ответов: 2

Как бы я изменил эти строковые объекты на char


Здравствуйте, В моем задании судоку я должен использовать массивы, но я преобразовал символы arrrays в строковые объекты. Мне было интересно, как я мог бы исправить свой код, чтобы избавиться от st.find и st.end и использовать массивы для сравнения вместо этого.

Что я уже пробовал:

// Program to check whether given sudoku
// board is valid or not
#include <bits/stdc++.h>
using namespace std;

// Checks whether there is any duplicate
// in current row or not
bool notInRow(char arr[][9], int row)
{
    // Set to store characters seen so far.
    set<char> st;

    for (int i = 0; i < 9; i++) {

        // If already encountered before, return false
        if (st.find(arr[row][i]) != st.end())
            return false;

        // If it is not an empty cell, insert value
        // at the current cell in the set
        if (arr[row][i] != '.')
            st.insert(arr[row][i]);
    }
    return true;
}

// Checks whether there is any duplicate
// in current column or not.
bool notInCol(char arr[][9], int col)
{
    set<char> st;

    for (int i = 0; i < 9; i++) {

        // If already encountered before, return false
        if (st.find(arr[i][col]) != st.end())
            return false;

        // If it is not an empty cell,
        // insert value at the current cell in the set
        if (arr[i][col] != '.')
            st.insert(arr[i][col]);
    }
    return true;
}

// Checks whether there is any duplicate
// in current 3x3 box or not.
bool notInBox(char arr[][9], int startRow, int startCol)
{
    set<char> st;

    for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
            char curr = arr[row + startRow][col + startCol];

            // If already encountered before, return false
            if (st.find(curr) != st.end())
                return false;

            // If it is not an empty cell,
            // insert value at current cell in set
            if (curr != '.')
                st.insert(curr);
        }
    }
    return true;
}

// Checks whether current row and current column and
// current 3x3 box is valid or not
bool isValid(char arr[][9], int row, int col)
{
    return notInRow(arr, row) && notInCol(arr, col) &&
           notInBox(arr, row - row % 3, col - col % 3);
}

bool isValidConfig(char arr[][9], int n)
{
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {

            // If current row or current column or
            // current 3x3 box is not valid, return false
            if (!isValid(arr, i, j))
                return false;
        }
    }
    return true;
}

// Drivers code
int main()
{
    char board[9][9];
    for(int i=0;i<9;i++) {
        for(int j=0;j<9;j++) {
            cin>>board[i][j];
        }
    }


    cout << (isValidConfig(board, 9) ? "Solution is good!\n" : "Wrong solution!\n");
    return 0;
}

2 Ответов

Рейтинг:
2

Afzaal Ahmad Zeeshan

Цитата:
Я преобразовал char arrrays в строковые объекты. Мне было интересно, как я мог бы исправить свой код, чтобы избавиться от st.find и st.end и использовать массивы для сравнения вместо этого.
Почему бы вам не попытаться решить ее, "не" преобразуя массивы в строки? Это похоже на то, что вы сами создаете себе проблемы.

Наконец, если вы хотите преобразовать строковую переменную в char[] тогда вы можете попробовать использовать c_str() вызов функции, и это вернет строки в стиле C—массивы символов.

Цитата:
ст.найти и Санкт.конец
Это всего лишь итераторы, и они могут помочь лучше обойти тип контейнера для ваших данных. Действительно, с помощью char[] вам нужно использовать только одно целое значение—int i Кроме того, плохая обработка итераторов также может вызвать ошибки, связанные с указателями в вашем коде, которые трудно исправить для новичка в C++.

Я настоятельно рекомендую вам изучить язык C++ немного больше и понять итераторы и другие языковые конструкции, и я уверяю вас, что они помогут вам в ваших заданиях больше, чем что-либо другое.

Еще одна проблема, которую я обнаружил с вашим кодом, заключалась в использовании set<char>- вы думаете , что а set<char> является ли где-нибудь эквивалентным vector<char> или char[] Наборы будут хранить только уникальные значения и упорядочивать их, как правило, в порядке возрастания на основе ключей. Причина, по которой я указываю на это здесь, заключается в том, что к тому времени, когда вы создаете набор, ваши "дубликаты" значений исчезают.

set - ссылка на C++ [^]


Рейтинг:
2

Stefan_Lang

Есть несколько вопросов, о которых вам следует знать:

1. Не включайте # "bits/stdc++.h" ! Это нестандартное оправдание ленивых программистов для начала работы в C++, которое в конечном итоге укусит вас! Видеть c++ - почему бы мне не #include <bits/stdc++.h>? - переполнение стека[^] для получения дополнительной информации. Научитесь правильно использовать классы STL и связанные с ними заголовки.

2. я не вижу никакой строки в вашем коде. Вы используете наборы. Как указано в решении 1, это не позволит вам размещать повторяющиеся значения в строке. Вообще! Кроме того, если вы специально не скажете иначе, набор будет внутренне упорядочивать все элементы при вставке, разрушая фактический порядок строк судоку! Даже если вы понимаете, как использовать find, это не поможет вам в запуске кода. Вы мог используйте std::string, хотя это не было бы моим первым выбором - см. ниже.

3. I've seen you have repeatedly used the insert method. This method does most certainly not what you intended, and that wouldn't be any different for any other type of container, be it set, string, or vector! 'insert' always means that you make room for a new element at the current position, and shift the rest to the right, making the container grow, and grow, and grow. Sudoku uses a fixed grid. There is no reason at all why you'd want it to grow! Therefore this cannot be correct. Note that most containers do implement the indexing operator[]. Therefore you can access individual elements for reading and writing with an index, exactly like you would do with a C array. Example:

#include <string>
#include <iostream>
int main() {
   std::string my_string = "hello world";
   for (size_t i = 0; i < my_string.size(); ++i)
      std::cout << my_string[i];
   return 0;
}


4. в вашем случае, с фиксированным размером сетки, известным во время компиляции, наиболее подходящим контейнером STL будет std::array, который ведет себя почти точно так же, как массив C, за исключением того, что он несет информацию о размере, экономя ваши усилия по передаче этой информации. Видеть std::массив - cppreference.com[^] для полного описания и некоторых примеров кода.

Обратите внимание, что std::array не имеет метода insert. И по уважительной причине: он не может быть изменен! И это хорошо, потому что вы наверняка не хотите изменять размер сетки судоку на лету!