C++ Same array - different outputs - c++

I'm trying to read from file (myfile.in) a 2D array. Rows and cols are given.
myfile>>n>>m; //rows and cols
for(int i = 0; i < n; i++) {
for(int j =0; j < m; j++) {
myfile>>tab[i][j];
cout<<tab[i][j]<<" ";
}
cout<<endl;
}
and the output on the screen is as it should be (as it is in file):
1 0 0 0 1 0 1
0 1 1 1 1 0 0
0 0 1 0 1 1 0
0 1 0 0 1 0 0
0 1 0 0 0 1 1
1 1 1 1 0 0 0
0 1 0 0 0 1 1
after that i tryied to print the array separately.
for(int i = 0; i < n; i++) {
for(int j =0; j < m; j++) {
cout<<tab[i][j]<<" ";
}
cout<<endl;
}
and the output is:
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
actually it's showing the last row, why?

According to your comment, you are actually initializing tab to be tab[0][0]. I don't know how come the compiler allows that, but the important thing is that you're writing outside your array bounds, triggering undefined behavior.
Try dynamically allocating your array after reading in n and m:
int n, m;
file >> n >> m;
int **tab = new int* [n];
for(size_t i = 0; i < n; ++i)
{
tab[i] = new int[m];
}
This way you'll always be sure to allocate only as much memory as you need.
Also, don't forget to delete the array when you're done:
for(size_t i = 0; i < n; ++i) delete[] tab[i];
delete[] tab;
As you can see this method tends to add a bit too much unnecessary complexity. An elegant alternative would be using a container such as a std::vector<std::vector<int>>:
using namespace std;
vector<vector<int>> tab;
for(int i = 0; i < n; ++i) {
vector<int> current_row;
for(int j = 0; j < m; ++j) {
int buff;
file >> buff;
current_row.push_back(buff);
}
tab.push_back(current_row);
}

int n=0, m=0; int tab[n][m];
This is not legal C++ for two reasons:
Dimensions of an array must be constant expressions. n and m are not.
You are creating an array of 0 size.
If the constant-expression (5.19) is present, [...] its value shall be greater than zero.
Your compiler is accepting it because it has extensions that accept both of these. Nonetheless, your array has size 0 and so it has no elements. Anything you attempt to write to it will be outside the bounds of the array.
Reading myfile>>n>>m; doesn't automatically change the size of the array. You already declared it as being size 0. Nothing you do will change that.
Instead, you'd be much better off using a standard library container, such as a std::vector, which can change size at run-time. Consider:
myfile >> n >> m;
std::vector<std::vector<int>> tab(n, std::vector<int>(m));
You can then use this tab object in exactly the same way as you have above.

Related

Sort Array of 0 ,1 and 2

What is wrong in my code why it is not giving correct output??
input
84
1 0 1 2 1 1 0 0 1 2 1 2 1 2 1 0 0 1 1 2 2 0 0 2 2 2 1 1 1 2 0 0 0 2 0 1 1 1 1 0 0 0 2 2 1 2 2 2 0 2 1 1 2 2 0 2 2 1 1 0 0 2 0 2 2 1 0 1 2 0 0 0 0 2 0 2 2 0 2 1 0 0 2 2
Its Correct output is:
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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
And Your Code's output is:
0-36092119132636100007056629140-858993460214748364-...
#include<iostream>
#include<algorithm>
using namespace std;
void sortArray(int *arr,int n){
int low=0,mid=1,high=n-1;
while(mid<=high){
if(arr[mid]==1){
mid++;
}
else if(arr[mid]==2){
swap(arr[mid],arr[high]);
high--;
}
else{
swap(arr[mid],arr[low]);
mid++,low++;
}
}
for(int i=0;i<n;i++){
cout<<arr[i];
}
}
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[n];
}
sortArray(arr,n);
}
return 0;
}
The main problem is in your input reading:
for(int i=0;i<n;i++) {
cin>>arr[n];
}
You are reading into arr[n] which is undefined. You want to use i as index:
for(int i=0;i<n;i++) {
cin>>arr[i];
}
Since the array is going to contain only 0, 1, or 2, you can simplify the sorting algorithm, too:
void sortArray(int *arr, size_t n)
{
size_t count[3] = {0};
for (size_t i = 0; i < n; ++i) {
count[arr[i]]++;
}
size_t k = 0;
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < count[i]; ++j)
arr[k++] = i;
}
for (size_t i = 0; i < n; ++i)
std::cout << arr[i] << ' ';
std::cout << endl;
}
Note: you are using a non-standard extension. C++ standard doesn't have VLA (variable length arrays).
Variable length arrays are typically allocated on "stack" and is prone to stack overflow. If length of the array is too big, you will have undefined behaviour. Worse, you can't easily know the "right" size for the array, either. For that reason, VLAs are best avoided. You could use std::vector<int> instead.
you should try a better approach(Textbook approach) i.e to count how many times 0,1 and 2 are occurring and then assigning them in ascending order or please explain what approach you are using in your code.
void sort012(int a[], int n)
{
int count[3]={};
for(int i=0;i<n;i++){
count[a[i]]++;
}
int j=0;
for(int i=0;i<3;i++){
int temp=count[i];
while(temp--){
a[j]=i;
j++;
}
}
}
its an easy and efficient approach in terms of time and space complexity

converting a bitset array to array of ints

How would I change an array of bit sets to a 1d array of ints with each element holding only 1 digit in C++. for example, i have bitset<8> bitArray[n], and I want to bit into int binArray[8*n], where binArray holds something like [0],[1],[1],[0],[1],[0] and so forth.
You can use an std::bitset::operator[] to access the specifit bit. Keep in mind though, that [0] means the least significant bit, but we want to store them in the most significant -> least significant order, so we have to use the 7 - j instead of simply j:
#include <iostream>
#include <bitset>
int main()
{
constexpr int SIZE = 5;
std::bitset<8> bitArray[SIZE] = {3, 8, 125, 40, 13};
int binArray[8 * SIZE];
for(int i = 0, index = 0; i < SIZE; ++i){
for(int j = 0; j < 8; ++j){
binArray[index++] = bitArray[i][7 - j];
}
}
}
The binArrays content looks like so (newlines added by me to improve readability):
0 0 0 0 0 0 1 1
0 0 0 0 1 0 0 0
0 1 1 1 1 1 0 1
0 0 0 0 1 1 0 1
Simply construct an array:
std::array<int, 8*n> binArray;
size_t out = 0;
for (const auto& bits : bitArray)
for (size_t ii = 0; ii < n; ++ii)
binArray[out++] = bitArray[ii];

How to write 2D array with diagonally numbers? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
How to write in C++ 2D array with diagonally numbers for
n - size of array (width and height)
x - how many the same number in a row
c - how many numbers must be used
example for
n = 5
x = 2
c = 2
output is:
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
My current code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=-1;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
cout << ++temp_c;
temp_x++;
if(temp_x>x){
temp_x=0;
if(temp_c=c){
temp_c=-1;
}
}
}
cout << endl;
}
}
I will be grateful for your help. :)
But my code return incorrectly number :(
Are you trying to do this?
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=0;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
if(temp_x<x)
{
temp_x++;
cout << temp_c << " ";
continue;
}
temp_c++;
temp_x=0;
if(temp_c>c)
{
temp_c=0;
}
cout << temp_c << " ";
temp_x++;
}
cout << endl;
}
}
Output:
5 2 2
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
5 2 3
0 0 1 1 2
2 0 0 1 1
2 2 0 0 1
1 2 2 0 0
1 1 2 2 0
5 3 2
0 0 0 1 1
1 0 0 0 1
1 1 0 0 0
1 1 1 0 0
0 1 1 1 0
I'd like to propose another algorithm:
Run It Online !
#include <iostream>
#include <vector>
#include <numeric> // iota
using std::cout;
using std::endl;
void fill(const size_t n ///< size of array (width and height)
, const size_t x ///< how many the same number in a row
, const size_t c) ///< how many numbers must be used
{
// generate the sequence of possible numbers
std::vector<int> numbers(c);
std::iota(numbers.begin(), numbers.end(), 0);
//std::vector<int> all(n * n); // for storing the output, if needed
for (size_t i = 0, // element index
k = 0, // "number" index
elements = n * n; // the square matrix can also be viewed as a n*n-long, 1D array
i < elements;
k = (k + 1) % c) // next number (and the modulus is for circling back to index 0)
{
// print the number "x" times
for (size_t j = 0; j < x && i < elements; ++j, ++i)
{
// break the line every "n" prints
if ((i % n) == 0)
{
cout << endl;
}
//all[i] = numbers[k];
cout << numbers[k] << " ";
}
}
cout << endl;
}
int main()
{
fill(5, 2, 2);
}
Output for fill(5, 2, 2)
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0

Two Hard-coded Arrays OF DIFFERENT SIZES into One 2-Dimensional Vector

I realize that if I want "valArray" to populate to the right of "COLUMN 0,0" I should put "[j][1]", however, I keep getting an error when I do that.
OUTPUT:----------------------------------------------------------------------------------------------------------------------------------------------------
55 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 1------------------------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 10 10 11 ----THIS IS ROW 2-----------------------------------------------------------------------------------------------
77 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 3------------------------------------------------------------------------------------------------
88 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 4-----------------------------------------------------------------------------------------
Please advise how to populate correctly, thanks.
#include <iostream>
#include <vector>
#include <Windows.h>
#include <algorithm>
using namespace std;
int main()
{
int typeArray[4] = {55,66,77,88};
int valArray[13] = {1,2,3,4,5,6,7,8,9,10,10,10,11};
// for vector: 4 = LENGTH or NUMBER of ROWS; 13 = WIDTH or NUMBER of COLUMNS;
// 0 = VALUE all cells are initialized to
vector< vector <int> > myVector(4, vector<int> (13,0));
for (int i = 0; i < 4; i++)
{
myVector[i][0] = typeArray[i];
for (int j = 0; j < 13; j++)
{
myVector[1][J] = valArray[j];
}
}
// print vector to screen with 2 ROWS, 3 COLUMNS
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
cout << myVector[i][j] << ' ';
}
cout << '\n';
}
system("Pause");
return 0;
}
One problem is that the loops should be until sizeof(typeArray)/sizeof(typeArray[0]) instead of sizeof(typeArray). Sizeof simply gives you the size of the array in bytes. You need to divide that by the size of each element in order to get the number of elements.
As for how to combine the arrays, I think you have the right idea with the for loop, and simply manually assigning the values.
example psuedo code:
for each element in typeArray
myVector[i][0] = typeArray[i];
myVector[i][1] = valArray[i];
The reason your code is not working is because you are not assigning any values to myVector.
Assuming typeArray and valArray are of the same length and you want to place each in a column, try something like this
for (int j = 0; j < sizeof(typeArray)/sizeof(int); j++)
{
myVector[j][0] = typeArray[j];
myVector[j][1] = valArray[j];
}

How do I work with nested vectors in C++?

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)