Click here to Skip to main content
15,897,187 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, In my sudoku assignment I am supposed to use arrays but I converted the char arrrays to string objects. I was wondering how I could fix my code to get rid of the st.find and the st.end and use the arrays to compare instead.

What I have tried:

// 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;
}
Posted
Updated 20-Nov-19 21:33pm

Quote:
I converted the char arrrays to string objects. I was wondering how I could fix my code to get rid of the st.find and the st.end and use the arrays to compare instead.
Why don't you try to solve it by "not" converting the arrays to strings? It is like you are creating the trouble for yourself.

Lastly, if you want to convert a string variable to char[] then you can try using c_str() function call, and that will return the C-style strings—the character arrays.

Quote:
st.find and the st.end
These are just the iterators and they can help in better traversing the container type for your data. Indeed, with a char[] you only need to use a single integer value—int i. Not just this, poor handling of iterators can raise pointer-related bugs in your code too, which are difficult to fix for a beginner in C++.

I highly recommend that you explore C++ language a bit more, and understand the iterators and other language constructs, and I assure you they will help you in your assignments more than anything.

One more problem that I found with your code was the usage of set<char>, do you think that a set<char> is anywhere equivalent to vector<char> or char[]? Sets would store only the unique values, and order them, normally in ascending order based on the keys. The reason why I am pointing this here is that by the time you create a set, your "duplicate" values are gone.

set - C++ Reference[^]
 
Share this answer
 
v2
There are several issues that you should be made aware of:

1. Do not #include "bits/stdc++.h" ! This is a non-standard lazy programmers' excuse for getting started in C++ that will eventually bite you! See c++ - Why should I not #include <bits/stdc++.h>? - Stack Overflow[^] for more info. Learn to use the STL classes and associated headers as you should.

2. I don't see any string in your code. You are using sets. As pointed out in solution 1, that will not allow you to place duplicate values in a row. At all! Also, unless you specifically say otherwise, a set will internally order all elements upon insertion, destroying the actual Sudoku row order! Even if you did understand the use of find, it wouldn't help you in getting the code to run. You could use std::string, although that would not be my first choice - see below.

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:
C++
#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. In your case, with a fixed grid-size that is known at compile time, the most suitable STL container would be std::array It behaves almost exactly like a C array, except, it carries the size information, saving you the effort of passing that around. See std::array - cppreference.com[^] for a full description and some example code.

Note that std::array does not have an insert method. And for a good reason: it can't be resized! And that's good, because you most certainly don't want to resize a Sudoku Grid on the fly!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900