I am trying to switch cols and rows of a 2D array by using a temp array and replace original array with temp using std::copy at the end. But std::Copy copying only first row and rest are showing same old values in original array. Also the statement array = {}; is not clearing indexes to 0.
// Clear array to 0 (issue: This has no effect at all)
array[arrayRowSize][arrayColSize] = {};
// Copy array (issue: only first row is copied, rest of original still has old values)
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
Can anyone take a look at my code and tell me what I am doing wrong ? Please add some details about how it actually work, and suggest if there is anything we can improve.
#include <iostream>
#include <cstdint>
using namespace std;
bool IsIntegerInputValid (int16_t arrayData, int8_t arrayLimit)
{
// Entered input is a non-digit, negative number or > arrayLimit ?
if ( cin.fail() || arrayData < 0 || arrayData > arrayLimit )
{
// Clear error flag and input buffer
cin.clear();
cin.ignore();
cout << "Invalid input, Please try again" << endl;
return false;
}
return true;
}
int main()
{
const uint8_t kMaxArraySize = 10;
int16_t array[kMaxArraySize][kMaxArraySize] = {};
int16_t arrayRowSize = 0;
int16_t arrayColSize = 0;
// Get array size
while (1)
{
cin >> arrayRowSize;
if ( IsIntegerInputValid ( arrayRowSize, kMaxArraySize) )
{
while (1)
{
cin >> arrayColSize;
if ( IsIntegerInputValid ( arrayColSize, kMaxArraySize) )
{
break; // Got valid size
}
}
break; // Got valid size
}
}
// Get array input
for (int i = 0; i < arrayRowSize; ++i)
{
for (int j = 0; j < arrayColSize; ++j)
{
cin >> array[i][j];
if ( !IsIntegerInputValid (array[i][j], kMaxArraySize) )
{
--i; // Try again
}
}
}
// Copy rows to cols and cols to rows
int16_t tempArray[kMaxArraySize][kMaxArraySize] = {};
for (int i = 0; i < arrayColSize; ++i)
{
for (int j = 0; j < arrayRowSize; ++j)
{
tempArray[i][j] = array[j][i];
cout << tempArray[i][j] << ' ';
}
cout << endl;
}
array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)
// Copy array (issue: only first row is copied, rest of original still has old values)
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
return 0;
}
Thanks
array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)
This accesses the table element at next out of bounds row of array and next out of bounds column of that row (if the row had any column that werent out of bounds). The behaviour is undefined. The last index that can be accessed is array[arrayRowSize - 1][arrayColSize - 1]. Assigning to an element out of bounds does nothing along the lines of clearing the array.
To set all elements of an array to zero, I would use:
std::memset(array, 0, sizeof array);
That said, you're about to overwrite all values, so this appears to be pointless.
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
This assumes that the lines are stored contiguously in memory. And if that were true, this would work just fine. However, since you've allocated A large array, and use only part of each row, there are unused parts of the rows between.
An example: You allocate a 7x7 array, then use only a 3x3 array within it. The memory layout could be following:
|-----| <- a row
AAAXXXXBBBXXXXCCCX...
|-------| <- first 9 elements
A represents first row, B represents second ...
X represents unused part of the array.
Now, if you copy 9 contiguous elements as if they were all elements of your array, you would get AAAXXXXBB, which contains plenty of unused elemnets, and not all of used elements.
Since your rows are not contiguous, you must copy each row separately. Or you could copy the entire array including the unused portions.
The copy doesn't work because sizes of your aray is not the same as kMaxArraySize.
copy tries to copy array as one dimensional array. but in your case 2d array coverted to 1d can have a lot of zeros inside.
if you've choosen size 3, 3 the your array will be like :
1 2 3 0 0 0 0 0 0 0
4 5 6 0 0 0 0 0 0 0
7 8 9 0 0 0 0 0 0 0
......
for 1d representation it will look like:
1 2 3 0 0 0 0 0 0 0 4 5 6 0 0 0 0 0 0 0 7 8 9 0 0 0 0 0 0
but copy will take only 9 first records.
Related
My code prints 1 at every position except the first column. I want it to print 1 at certain specific places (r, c) where r is the row and c is the column. Also, can anybody tell me how do I initialize the 2-D array with 0 at every index?
I have tried to reset the values of r and c to zero but nothing changes.
int main()
{
int T;
cin>>T;
while(T--)
{
vector <long long int>R;
vector <long long int>C;
long long int N, M, K, r, c, i, j, k; // N -> rows, M -> columns
cin>>N>>M>>K;
long long int arr[N][M];
cout<<K<<endl;
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
arr[i][j] = 0;
}
}
for(k=0; k<K; k++)
{
cin>>r>>c;
arr[r][c] = 2;
r = 0; c = 0;
}
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
Input:
1 4 4 9 1 4 2 1 2 2 2 3 3 1 3 3 4 1 4 2 4 3
Some remarks:
Firstly, C-Style Array sizes must be known at compile time for standard C++, so you can't read them from cin (this is a GCC extension).
So if you need an array with a size known only at runtime, I suggest std::vector.
Additionally, in C++ it is common practice to define the loop variable inside the scope of the for-loop, like so:
for (int i = 0; i < N ++i)
This keeps the surrounding scope cleaner. An array or struct can be initialized to zero in C++ with the following uniform initialization syntax:
SomeStruct x{}; // All members are default initialized (e. g. for built-in types: 0)
SomeType myArray[N][M]{}; // All elements are default initialized
A comment like this
// N -> rows, M -> columns
is really just saying you should be naming your variables rows/cols and not N/M. Make your code self-documenting ;)
I would not recommend using std::endl when you want a line-break, as it also flushes the buffer, which when writing to files could
have serious performance implications (for console output it's no problem). It is better practice to use '\n' for line-breaks and use std::flush explicitly if you need it.
I've omitted the outer while loop and made Rows/Columns constant for simplicity. With std::vector you should use Rows*Cols as size in a
1D array and then map a position (i,j) to the 1D index with the formula:
arr2D[i][j] = arr1D[i*Cols + j];
If you choose to let the user specify rows/cols and use
std::vector<int> vec(rows*cols);
As your array.
int main()
{
constexpr int rows{3};
constexpr int cols{3};
int numUserValues{};
cin >> numUserValues;
int arr[rows][cols]{};
cout << numUserValues << '\n';
for(int k=0; k<numUserValues; k++)
{
int r{};
int c{};
if (cin>>r>>c && r>=0 && r<rows && c>=0 && c<cols) {
arr[r][c] = 2;
}
}
for(int i=0; i<N; i++)
{
for(int j=0; j<M; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<'\n';
}
return 0;
}
Your program is very user-unfriendly, since you have no prompts at all (e.g. cout << "Enter number of rows: ";, but this is my test-run, as you can see all elements are zero except for the ones I specified:
$ ./test
5
5
0 0
1 1
2 2
0 1
0 2
2 2 2
0 2 0
0 0 2
Your question is hard to answer, because you say "I want to print 1 at position ...", while your code says arr[r][c] = 2; ;)
"My code prints 1 at every position except first column", would mean for a 5x5:
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
Which is simply not the case and thus false information.
I want it to print 1 at certain specific places (r, c) where r is the row and c is the column
You are doing this:
cin>>r>>c;
arr[r][c] = 2;
when the input is "1 4", which invokes Undefined Behavior (UB), because you go out of range, since the 2D array you have is of 4x4 dimensions, thus you would need to do something like this instead:
arr[r - 1][c - 1] = 1;
since arrays are zero indexed. I changed 2 to 1, since this is what you asked for.
I have tried to reset the values of r and c to zero but nothing changes.
This has no actual effect, since r and c are going to be overwritten upon next input.
I am a beginner programmer and I need some assistance.
I need to write a program that reads an array of 10 numbers from a user, then scans it and figures out the most common number/s in the array itself and prints them. If there is only one number that is common in the array, only print that number. But, if there's more than one number that appears more than once, print them also in the order they appear in in the array.
For example- 1 2 3 3 4 5 6 7 8 9 - output would be 3
For- 1 2 3 4 1 2 3 4 5 6 - output would be 1 2 3 4
for- 1 1 1 1 2 2 2 3 3 4 - output would be 1 2 3
Now, the problem I've been running into, is that whenever I have a number that repeats more than twice (see third example above), the output I'm getting is the number of iterations of the loop for that number and not only that number once.
Any assistance would be welcome.
Code's attached below-
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int array [10], index, checker, common;
main ()
{
for (index=0; index<10; index++)
{
cin >> array [index];
}
for (index=0; index<10; index++)
{
int tempcount=0;
for (checker=(index+1);checker<10;checker++)
{
if (array[index]==array[checker])
tempcount++;
}
if (tempcount>=1)
cout << array[index]<<" ";
}
return 0;
}
Use appropriate data structures for the task.
Create a std::unordered_map that maps value to number_of_occurrences, and make a single pass over the input data.
Then create another map from number_of_occurrences to value. Sort it, in descending order. Report the first value, plus any additional ones that occurred as many times as the first did.
The reason you are having problems is that anytime a number appears two times or more it will print out. A solution is that you create another variable maxCount, then find the maximum times a number appears. Then loop through the array and print out all the numbers that appears the maximum amount of times.
Hope this helps.
Jake
Rather than writing you a solution, I will try to give you some hints that you can hopefully use to correct your code. Try to keep track of the following things:
Remember the position of the first occurrence of each distinct number in the array.
Count the number of times each number appears
and combine the two to get your solution.
EDIT:
int array[] = {1, 2, 3, 4, 1, 2, 3, 4, 5, 6};
int first [11], cnt[11];
for(int i = 0; i < 11; i++){
first[i] = -1;
cnt[i] = 0;
}
int max = 0;
for(int i = 0; i < 10; i++){
cnt[array[i]]++;
if(max < array[i]) max = array[i];
}
for(int i = 0; i <= max; i++){
if(cnt[i] > 1 && first[i] == -1) {
printf(" %d", i);
first[i] = i;
}
}
You could do something like this. At any index in the array look for previous occurences of that element. If you find that that it is the first occurence of that element, you only need to look if there is an occurence of that element ahead in the array.
Lastly display the element whose frequency(here num) would be greater than 1.
for (int i = 0; i < 10; i++)
{
int presentBefore = 0;
for (int j = 0; j < i; j++) //if any previous occurence of element
{
if (array[i] == array[j]) presentBefore++;
}
if (presentBefore == 0)//if first occurence of the element
{
int num = 1;
for (int j = i + 1; j < 8; j++)// if occurences ahead in the array
{
if (array[i] == array[j]) num++;
}
if(num>1)cout<<array[i]<<" ";
}
}
Here is another solution using STL and std::set.
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
int main()
{
int array[12] = { 1, 2, 3, 1, 2, 4, 5, 6, 3, 4, 1, 2 };
std::set<int> dupes;
for (auto it = std::begin(array), end = std::end(array); it != end; ++it)
{
if (std::count(it, end, *it) > 1 && dupes.insert(*it).second)
std::cout << *it << " ";
}
return 0;
}
Prints:
1 2 3 4
I will try to explain how this works:
The original array is iterated from start to finish (BTW as you can see it can be any length, not just 10, as it uses iterators of beginning and end)
We are going to store duplicates which we find with std::count in std::set
We count from current iterator until the end of the array for efficiency
When count > 1, this means we have a duplicate so we store it in set for reference.
std::set has unique keys, so trying to store another number that already exists in set will result in insert .second returning false.
Hence, we print only unique insertions, which appear to be in the order of elements appearing in the array.
In your case you can use class std::vector which allows you to Erase elements, resize the array...
Here is an example I provide which produces what you wanted:
1: Push the values into a vector.
2: Use 2 loops and compare the elements array[i] and array[j] and if they are identical push the the element j into a new vector. Index j is always equal to i + 1 in order to avoid comparing the value with itself.
3- Now you get a vector of the repeated values in the temporary vector; You use 2 loops and search for the repeated values and erase them from the vector.
4- Print the output.
NB: I overloaded the insertion operator "<<" to print a vector to avoid each time using a loop to print a vector's elements.
The code could look like :
#include <iostream>
#include <vector>
std::ostream& operator << (std::ostream& out, std::vector<int> vecInt){
for(int i(0); i < vecInt.size(); i++)
out << vecInt[i] << ", ";
return out;
}
int main() {
std::vector< int > vecInt;
//1 1 1 1 2 2 2 3 3 4
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(3);
vecInt.push_back(3);
vecInt.push_back(4);
std::vector<int> vecUniq;
for(int i(0); i < vecInt.size(); i++)
for(int j(i + 1); j < vecInt.size(); j++)
if(vecInt[i] == vecInt[j])
vecUniq.push_back(vecInt[j]);
std::cout << vecUniq << std::endl;
for(int i = 0; i < vecUniq.size(); i++)
for(int j = vecUniq.size() - 1 ; j >= 0 && j > i; j--)
if(vecUniq[i] == vecUniq[j])
vecUniq.erase(&vecUniq[j]);
std::cout << vecUniq << std::endl;
std::cout << std::endl;
return 0;
}
The input: 1 2 3 3 4 5 6 7 8 9
The output: 3
The input: 1 2 3 4 1 2 3 4 5 6
The output: 1 2 3 4
The input: 1 1 1 1 2 2 2 3 3 4
The output: 1 2 3
For this problem, you can use a marking array that will count the number of times you a digit is visited by you, it's just like counting sort. let's first see the program :
#include <iostream>
using namespace std;
int print(int a[],int b[])
{
cout<<"b :: ";
for (int index=0;index<10;index++)
{
cout<<b[index]<<" ";
}
cout<<endl;
}
int main ()
{
int a[10],b[11], index, checker, common;
for (index=0; index<10; index++)
{
cin >> a [index];
b[index] = 0;
}
b[10] =0;
for (index=0;index<10;index++)
{
b[a[index]]++;
if (b[a[index]] == 2)
cout<<a[index];
//print(a,b);
}
return 0;
}
As you can see that I have used array b as marking array which counts the time a number is visited.
The size of array b depends upon what is the largest number you are going to enter, I have set the size of array b to be of length 10 that b[11] as your largest number is 10. Index 0 is of no use but you need not worry about it as it will be not pointed until your input has 0.
Intially all elements in array in b is set 0.
Now assume your input to be :: 1 2 3 4 1 2 3 4 5 6
Now value of b can be checked after each iteration by uncommenting the print function line::
b :: 0 1 0 0 0 0 0 0 0 0 ....1
b :: 0 1 1 0 0 0 0 0 0 0 ....2
b :: 0 1 1 1 0 0 0 0 0 0 ....3
b :: 0 1 1 1 1 0 0 0 0 0 ....4
b :: 0 2 1 1 1 0 0 0 0 0 ....5
b :: 0 2 2 1 1 0 0 0 0 0 ....6
b :: 0 2 2 2 1 0 0 0 0 0 ....7
b :: 0 2 2 2 2 0 0 0 0 0 ....8
b :: 0 2 2 2 2 1 0 0 0 0 ....9
b :: 0 2 2 2 2 1 1 0 0 0 ....10
In line 5 you can b's at index 1 has value 2 so it will print 1 that is a[index].
And array a's element will be printed only when it is repeated first time due to this line if(b[a[index]] == 2) .
This program uses the idea of counting sort so if you want you can check counting sort.
I am trying to create a dynamically allocated array and print it's contents in C++. Although my code is producing incredibly strange output when I print.
int main() {
int* arr;
arr = new int [1200];
memset(arr, 5, 1200);
for (int i = 0; i < 1200; i++)
printf("%d ", arr[i]);
std::cout << '\n';
return 0;
}
Mixing the cout and printf was just because I was playing around with the code. All the proper includes are in my file.\
Here is the output:
84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 1285 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I have no idea how this was produced.
EDIT:
Thank you everyone for the answers. I now understand what my code does and why the output looks the way that it look.Great answers.
memset(arr, 5, 1200);
If you scribble a whole bunch of 5'a on a piece of paper and then try to read the paper, you'll get back things like "5555". 84215048 in hex is 0x05050505.
Don't manipulate arrays of data as if they were raw chunks of memory unless you know exactly what you're doing.
Your code is setting each byte in the first part of the array, to 5. With a modern C++ compiler as of 2014 each int is 4 bytes or 8 bytes, with each byte 8 bits (although on some computers it can be 16 bits per byte). Assuming 8 bits per byte and 4 bytes per int you'd get the value ((5×256 + 5)×256 + 5)×256 + 5 =
C:\> set /a ((5*256 + 5)*256 + 5)*256 + 5
84215045
C:\> _
Here's how to do your program in the most natural way in C++:
#include <iostream>
#include <vector>
using namespace std;
auto main() -> int
{
vector<int> arr( 1200, 5 );
for( int x : arr ) { cout << x << ' '; }
cout << '\n';
}
Consider 84215045 byte by byte in hex and you will understand what happened:
84215045 = 05050505 (hex)
memset initializes every byte to 5, but an integer is 4-byte long in your case. Also, memset expects the size in bytes of the memory region to fill, which is not 1200, but 1200 * sizeof (int), which in your case appears to be 4800. This explains the trailing zeroes as well.
You might initialize every element to 5 using a loop:
arr = new int [1200];
for (int i = 0; i < 1200; ++i) arr[i] = 0;
or with pointers:
arr = new int[1200];
for (int *cur = arr, *end = arr + 1200; cur < end; ++cur) *cur = 0;
Finally, consider doing away with direct allocation of arrays with new and using STL containers like std::vector if possible.
Given a matrix, if a cell contains 0, then we have make entire row and column corresponding to the cell as 0. For example, if
1 2 3
M = 0 4 5
4 2 0
then the output should be
0 2 0
0 0 0
0 0 0
The method I thought is as follows
Make auxiliary arrays row[] and col[]. If a cell(i,j) contains 0 then, mark row[i] and col[j] as 0.(Initially row[] and col[] contains all 1s).
Again traverse the whole matrix, if for cell(i,j), either of row[i] or col[j] is 0, then put cell(i,j) as 0.
This takes O(m*n) time and O(m+n) space.
How to optimize it further specially in terms of space.Any suggestions for improving time complexity are also welcomed.
Aha, this is an old question.
Use one boolean variate(isZeroInFirstRow) saving if first row has zero element(s) or not and one boolean variate(isZeroInFirstCol) saving if first column has zero element(s) or not.
Then, traverse the whole matrix. If cell(i,j)==0, then set cell(0,j) and cell(i,0) to 0.
Traverse the first row of the matrix. If cell(0,j)==0, then set all elements in column(j) to 0.
Traverse the first column of the matrix. If cell(i,0)==0, then set all elements in row(i) to 0.
If isZeroInFirstRow==true, set all elements in row(0) to 0.
If isZeroInFirstCol==true, set all elements in column(0) to 0.
You can solve this in O(1) space. One solution is to iterate on the matrix, for each 0 you see, you fill the corresponding row/col with some character, 'X' for example.
When you finish, you should have something like that:
X 2 X
M= 0 X X
X X 0
Then you iterate again on the matrix and replace each 'X' with 0 to get:
0 2 0
M= 0 0 0
0 0 0
If you are concerned with storage you may think of using some sparse matrix storage formats to store the resulting matrix, and then free the original dense input.
An example of what I am proposing may be the following (implementing COO format) which should take O(M*N) time:
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstddef>
using namespace std;
int main()
{
constexpr size_t M = 3;
constexpr size_t N = 3;
int matrix[M][N] = {
{1, 2, 3},
{0, 4, 5},
{4, 2, 0}
};
vector<size_t> markedRows;
vector<size_t> markedColumns;
// Search for zeroes
for (size_t ii = 0; ii < M; ++ii) {
for(size_t jj = 0; jj < N; ++jj) {
if (matrix[ii][jj] == 0) {
markedRows.push_back (ii);
markedColumns.push_back(jj);
}
}
}
// Sort columns (rows are ordered by construction)
sort(markedColumns.begin(),markedColumns.end());
// Eliminate duplicates
markedRows.erase (unique(markedRows.begin() ,markedRows.end()) ,markedRows.end() );
markedColumns.erase(unique(markedColumns.begin(),markedColumns.end()),markedColumns.end());
// Construct COO matrix format
vector<size_t> irow;
vector<size_t> icol;
vector<int> val;
for (size_t ii = 0; ii < M; ++ii) {
for(size_t jj = 0; jj < N; ++jj) {
if ( ( find(markedRows.begin() ,markedRows.end() ,ii) == markedRows.end() ) &&
( find(markedColumns.begin(),markedColumns.end(),jj) == markedColumns.end() )
) {
irow.push_back(ii);
icol.push_back(jj);
val.push_back (matrix[ii][jj]);
}
}
}
// FROM HERE YOU NO LONGER NEED MATRIX, AND YOU CAN FREE THE STORAGE
// Print non zero entries
for( size_t ii = 0; ii < irow.size(); ++ii) {
cout << "A["<<irow[ii]<<","<<icol[ii]<<"] = "<<val[ii]<<endl;
}
return 0;
}
You can use your algorithm without allocating and auxiliary row or column by searching the matirx for a row that contains no zeros and a column that contains no zero elements.
If either of these searches fails, then the resulting matrix will all zeros, so your work is done by simply setting all elements to zero.
Otherwise, use the row and colum you found as the bookkeeping row and column you mentioned, setting the corresponding element to zero as you find zeros in the remainder of the matrix. Once that pass is done you walk the bookkeeping row, setting the matix columns to zeros for any zero found in the bookkeeping row, similarly for the aux column.
Here is an algorithm can do it in O(M*N) time and O(1) space : -
Find the max element in the matrix .
Mat[i][j] = max - Mat[i][j] for all (i,j)
Notice that Mat[i][j] will only have positive values.
Use negetive values as sentinels and Mat[i][j] = max as zeros.
Retrieve original values as Mat[i][j] = max - Mat[i][j]
Simple and easy answer:
<2 nested loop> to search through all columns and rows you find any cell = 0 through all column and set it to zeros through all row and set it to zeros. let me know if it not clear to record video for it.
Int main()
{
//example matrix dimension rows(r=6) * columns (c=3)
int r = 6;
int c = 3;
int matrix[r][c];
for(int i=0; i<r; ++i){
for(int j=0 ; j < c ; ++j){
if(matrix[i][j] == 0){
for(int ii=0; ii<r; ++ii){
Matrix[ii][j] = 0 ;
}
for(int jj=0; jj<c; ++jj){
Matrix[i][jj] = 0 ;
}
}
}
}
}
I'm trying to work with vectors of vectors of ints for a sudoku puzzle solver I'm writing.
Question 1:
If I'm going to access a my 2d vector by index, do I have to initialize it with the appropriate size first?
For example:
typedef vector<vector<int> > array2d_t;
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid;
readAPuzzle(grid);
}
Will seg fault. I assume this is because it is trying to access elments of grid that have not yet been initialized?
I've swapped out grid's declaration line with:
array2d_t grid(9, vector<int>(9, 0));
And this seems to get rid of this seg fault. Is this the right way to handle it?
Question 2:
Why is it that when I try to read into my grid from cin, and then print out the grid, the grid is blank?
I'm using the following code to do so:
void printGrid(array2d_t grid)
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
cout << grid[i][j] + " ";
}
cout << endl;
}
}
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid(9, vector<int>(9, 0));
printGrid(grid);
readAPuzzle(grid);
printGrid(grid);
}
And I attempt to run my program like:
./a.out < sudoku-test
Where sudoku-test is a file containing the following:
3 0 0 0 0 0 0 0 0
5 8 4 0 0 2 0 3 0
0 6 0 8 3 0 0 7 5
0 4 1 0 0 6 0 0 0
7 9 0 0 2 0 0 5 1
0 0 0 9 0 0 6 8 0
9 3 0 0 1 5 0 4 0
0 2 0 4 0 0 5 1 8
0 0 0 0 0 0 0 0 6
The first call to printGrid() gives a blank grid, when instead I should be seeing a 9x9 grid of 0's since that is how I initialized it. The second call should contain the grid above. However, both times it is blank.
Can anyone shed some light on this?
Q1: Yes, that is the correct way to handle it. However, notice that nested vectors are a rather inefficient way to implement a 2D array. One vector and calculating indices by x + y * width is usually a better option.
Q2A: Calculating grid[i][j] + " " does not concatenate two strings (because the left hand side is int, not a string) but instead adds the numeric value to a pointer (the memory address of the first character of the string " "). Use cout << grid[i][j] << " " instead.
Q2B: You are passing the array by value (it gets copied) for readAPuzzle. The the function reads into its local copy, which gets destroyed when the function returns. Pass by reference instead (this avoids making a copy and uses the original instead):
void readAPuzzle(array2d_t& grid)