converting a bitset array to array of ints - c++

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];

Related

How to fill a random position of a size 10 1D array with 1s and 0s the rest

how i fill 10size 1d array randomly 1 and 0 the rest
like 0 0 0 0 0 1 0 0 0 0 or 0 0 0 1 0 0 0 0 0 0 or 0 1 0 0 0 0 0 0 0 0
#include <iostream>
#include<cstdlib>
#include<ctime>
#include<windows.h>
using namespace std;
int main() {
srand(time(NULL));
int x[10] = { 0, }, i;
while (true)
{
Sleep(500);
for (i = 0; i < 10; i++)
{
x[i] = rand() % 1 + 1;
cout << x[i];
}
system("cls");
}
system("pause");
}
I don't want 0 1 0 0 0 1 1 0 1 0 or 0 1 0 1 0 0 1 0 0 1
You are setting a new 1 every time your loop makes a lap. Eventually, you'll have all 1:s.
Either create a new zero-initialized array every loop or set the 1 back to 0 after you've printed the values in the array.
Sleep is not a standard C++ function. Use std::this_thread::sleep_for and std::chrono::milliseconds instead.
I also recommend using the new <random> library that was added in C++11:
Example setting it back to 0 after the result has been printed:
#include <array> // std::array, std::size
#include <chrono> // std::chrono::milliseconds
#include <iostream>
#include <random> // std::mt19937, std::uniform_int_distribution
#include <thread> // std::this_thread::sleep_for
auto& prng() {
// Create a static seeded PRNG to use everywhere in the program
thread_local std::mt19937 instance(std::random_device{}());
return instance;
}
int main() {
std::array<int, 10> x{}; // a nicer array
// Create a distribution for your random numbers to get random numbers
// in the range [0, 10)
std::uniform_int_distribution<unsigned> dist(0, std::size(x) - 1); // [0, 9]
for(int i = 0; i < 100; ++i) { // print 100 of these arrays
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto index = dist(prng()); // get a random index [0, 9]
x[index] = 1; // set the int at index to 1
// print the result
for(int v : x) std::cout << v;
std::cout << '\n';
x[index] = 0; // set it back to 0
}
}
Demo
Instatiate an array of int like int x[10] = {};, in this way you will get an array fill of zeros.
Than you can simply use rand() % 10, it will produce a random number in [0, 9], and it will be the position in the array where the 1 is:
srand(time(NULL));
int x[10] = {};
x[rand() % 10] = 1;
for (int i = 0; i < 10; i++) {
cout << x[i] << endl;
}

C++ Array (disregarding a repeat number)

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.

C++ Same array - different outputs

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.

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)