C++ string push_back function not working - c++

I am trying to generate strings with {0, 1, 2} using an integer queue to store numbers until I am ready to check if they are binary numbers. I am starting with single digits and then appending them to get longer and longer number strings. So the order I am trying to get is 0, 1, 2, 00, 01, 02, 10, 11, 12, 20, 21, 22, 000, 001, 002, 010, 011, 012 e.t.c. The problem I am having though is that when I dequeue an integer from my queue, turn it into a string and try to append it with {0, 1, 2} using s.push_back(app), nothing is appended. Below is my code and output.
int main()
{
string s; //holds strings of numbers that come from the int queue
bool isBin; //holds the boolean value returned from recognizer
int count=0; //while loop counter to not go over 20 iterations
Queue myQ; //queue created to hold all values generated
int numHolder; //holds values dequeued from int queue to be turned into string
myQ.enQueue(0);//queue 3 initial values to work with
myQ.enQueue(1);
myQ.enQueue(2);
while(count<=20)//while loop doesnt go over 20 iterations of binary numbers
{
numHolder=myQ.deQueue();//holds int values dequeued from queue
s=to_string(numHolder);//converts the int from queue to a string
/* isBin=recognizer(s);//send the string to the recognizer
if(isBin==true)
{
cout<<s<<endl;//prints string if it is binary number
count++;//increment counter because string was binary
}*/
for(int i=0; i<3; i++)//this loop adds 0 then 1 then 2 to the end of each dequeued string
{
char app = i;
s.push_back(app);//this is where string is appended with 0 1 or 2
cout<<s<<endl;
int newNum=stoi(s);//new appended string is turned into integer
myQ.enQueue(newNum);//new integer is put into queue
s.pop_back();//pops back the string so other numbers can be created with the original dequeued string
}
count++;
}
// }// end of while
}// end of main
output:
0
0
0
1
1
1
2
2
2
0
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
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 can tell by the output it has the right order for the first characters but nothing is being appended to them because the string push_back function is not working. Please help!

char app=i stores the characters whose binary value is 0 1 and 2, not the characters '0', '1' and '2'.
Try char app = '0'+i;
In C/C++ char is both a number type and the traditional way to store a single character. The conversion from int just treats char like a number type.

Related

How to shuffle values in an array and store shuffled values into different arrays with AVX

Thanks in advance for the help. I need to be able to perform the following shuffle pattern in an array with uint16_t data. My unprocessed array will look like the following
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
I have transformed my unprocessed data into the format below with _mm512_permutexvar_epi16
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
and then store the contents of the AVX register into 4 different arrays, this is the part I'm unsure on the best way to do.
next eight values of arrayofZero's 0 0 0 0 0 0 0 0
next eight values of arrayofOne's 1 1 1 1 1 1 1 1
next eight values of arrayofTwo's 2 2 2 2 2 2 2 2
next eight values of arrayofThree's 3 3 3 3 3 3 3
I need to loop through my unprocessed data and populate the arrayofZero's with all the 0 values and so on and so forth with my 1, 2, and 3 values.
NOTE: my actual data is not hardcoded 0, 1, 2, 3. It is calculated data that I need to put the
1st value in the 1st array,
2nd value in the 2nd array,
3rd value in the 3rd processed data array,
and 4th value in the 4th processed data array
that pattern repeats for the entire unprocessed data array. Such that after all processing is done
1st Array holds all the 0 values
2nd Array holds all the 1 values
3rd array holds all the 2 values
4th array holds all the 3 values
I have been looking at _mm512_permutexvar_epi16 to get my unprocessed data into the format.
Below is the code that I have started.
#include <immintrin.h>
#include <array>
#include <iostream>
int main()
{
alignas(64) std::array<uint16_t, 128> unprocessedData;
alignas(64) std::array<uint16_t, 32> processedData0, processedData1, processedData2, processedData3;
alignas(64) constexpr std::array<uint16_t, 32> shuffleMask {
0, 4, 8, 12, 16, 20, 24, 28,
1, 5, 9, 13, 17, 21, 25, 29,
2, 6, 10, 14, 18, 22, 26, 30,
3, 7, 11, 15, 19, 23, 27, 31,
};
//prepare sample data
for (uint16_t i {0}; i < unprocessedData.size(); i+=4)
{
unprocessedData[i] = 0;
unprocessedData[i+1] = 1;
unprocessedData[i+2] = 2;
unprocessedData[i+3] = 3;
}
for (size_t i {0}; i < unprocessedData.size(); i+=32)
{
auto v {_mm512_loadu_epi16(&unprocessedData[i]) };
_mm512_storeu_epi16(&unprocessedData[i],
_mm512_permutexvar_epi16(_mm512_load_si512((__m512i*)shuffleMask.data()), v));
//Somehow Store values 0-7 of permuted array into processedData0
//Store values 8-15 of permuted array into processedData1
//Store values 16-23 of permuted array into processedData2
//Store values 24-31 of permuted array into processedData3
}
return 0;
}

Matlab - Convert Character Vector Into Number Vector?

I'm trying to implement an oscilloscope for a digital input and send it over a serial port for debugging. I have the scope software sending Matlab a string like "000000111111111000000001111111000000". I'd like to plot this. Is there any way for me to split this string into a vector. It doesn't seem Matlab allows you to use strsplit() without a delimiter. I'd rather not bog up the communications with a delimiter between each byte.
With MATLAB's weak typing, this is actually quite easy:
>> str = '000000111111111000000001111111000000'
str = 000000111111111000000001111111000000
>> class(str)
ans = char
>> vec = str - '0'
vec =
Columns 1 through 22:
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
Columns 23 through 36:
0 1 1 1 1 1 1 1 0 0 0 0 0 0
>> class(vec)
ans = double
This subtracts the ordinal value of the character '0' from each character in the string, leaving the numerical values 0 or 1.
You can use sscanf with a single value width:
a = '000000111111111000000001111111000000'
b = sscanf(a, '%1d');
Which returns:
>> b.'
ans =
Columns 1 through 18
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
Columns 19 through 36
0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0
A quick and fast solution is:
data = '000001111111110000000000111111111110000000';
vec = str2double(cellstr(data.').');
It will produce a column vector of numeric values. If you want a row vector as output, just use a single transpose:
vec = str2double(cellstr(data.'));
I'm surprised how difficult this is to do. But here's what I came up with:
str = '000001111111110000000000111111111110000000'; %test string
y = cellfun(#(x) str2num(x), regexp(str,'\d','match'));
plot(y);
regexp() seems to be the only way to go. By default, it return indexes of matches so you need to specify 'match'. Then you end up with a cell array of strings. The only good way to convert this into a numerical array is one item at a time with str2num().
I hope this helps someone else out who is assuming there is a straight forward function as I assumed. And if anyone knows a way to do this without converting my "01...01....01....01....00....00....00....00" stream of bytes into the ascii representations of the binary numbers: "49.....49.....49....49....48....48....48....48", I'd love to hear it.

Reading single lines from file into vector

I have an input file of the following format:
# 1 2 3 4 5 6 7
0 0 0 1
1 0 0 1
2 0 0 1
3 0 0 1
5 0 0 1
6 0 0 1
# 0 0 2 2 4 4 5
0 0 0 1
0 1 0 1
0 2 0 1
0 3 0 1
# 9 10 11 12 13 14 15 16 17 18
0 0 0 1
0 0 1 1
0 0 2 1
0 0 3 1
Each line preceded by a # must be read into its own vector. The entries in between these vectors represent matrices that also must be read into their own matrix.
So from the input file above, what I want to end up having is the following:
knot1 = {1 2 3 4 5 6 7}
cp1= { {0,0,0,1} {1,0,0,1} {2,0,0,1} {3,0,0,1} {5,0,0,1} {6,0,0,1} }
knot2 = {0 0 2 2 4 4 5}
cp2= {{...} {...} {...} {...} }
knot3 = {9 10 11 12 13 14 15 16 17 18}
cp3= {{...} {...} {...} {...} }
Note, each vector is not necessarily the same size! Same goes for the matrices. Also, the number of #vectors and matrices can vary as well.
Here is what I have so far:
ifstream file;
file.open(filename.c_str());
if(file.fail()){
cout << "Cannot open " << filename << endl;
}
int curr_line = 0;
vector<int> knot_locations; //stores the locations of the #vectors
while(!file.eof()){ //loops over input file checking to see where the #vectors are
curr_line++;
string line;
getline(file,line);
if(line[0]=='#'){
knot_locations.push_back(curr_line);
}
}
for(int i=0; i < knot_locations.size(); i++){
file.seekg(std::ios::beg);
for(int i=0; i < knot_locations[i] - 1; ++i){ // this loop skips to the line that contains the #vectors.
file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
}
so now that I am at the line
containing the vector, how can I read
in JUST that SINGLE line into a vector?!
I'm not sure how to turn a string into
a vector of floats. Also, since I know all the
locations of the vectors, I can read everything
else between into the matrices. But again, same
problem. I am not sure how to go about actually
reading these into a numeric array/vector given a line (string)
file.close();
Probably better ways of doing this. Any ideas on how to go about this problem? The key is to be able to read all the vectors marked with a # into their own vector. There can be anywhere between 1-3 of these vectors. And in between each of these vectors is a matrix of unknown rows/columns that also need to be read into their own matrix. What I have above just locates the # marked vectors. Need help on how to read a string line into a numeric array OR a recommendation on a different way to go about this.
Thank you.

int variable not resetting on c++?

So, my program is supposed to receive test inputs like:
3
1 0 1
0 1 1
1 0 1
5
1 1 1 0 0
1 1 0 1 1
1 0 1 0 1
0 1 0 1 0
0 1 1 1 1
3
1 0 0
0 1 0
0 0 1
2
1 1
1 1
0
where the single-valued lines (n) are the size of a NxN matrix located in the following n entries like shown above. If n = 0, the program stops. The output must be the biggest sum amongst the columns of the matrix. So I expect outputs like this:
3
4
1
2
After a lot of effort and wasted time, I managed to get the first output correctly, but I noticed the following ones sometimes summed up and suggested some variable was not being reset. Here's my code:
#include <iostream>
using namespace std;
int pop = 0;
int main() {
int n, i, j, k;
cin >> n;
while (n!=0) {
int alunos[n]={0};
pop = 0;
for (i=0;i<n;i++) {
int array[n]={0};
for (j=0;j<n;j++) {
cin >> array[j];
if (array[j]==1) alunos[j]++;
}
}
for (k=0;k<n;k++) {
if(alunos[k]>pop) pop = alunos[k];
}
cout << pop << endl;
cin >> n;
}
return 0;
}
Noticed that I'm outputting pop(the biggest sum) and resetting it to 0 everytime a new n is given. alunos[n] is an array with the sums of each column (also resetted on every while loop) and array[n] is just an auxiliary array for reading each line of input. My outputs with this are:
3
5
6
8
Thanks in advance!
You cannot use initializers with variable length arrays. Either switch to some sort of container:
std::vector<int> alunos(n);
or fill the array with zeros manually:
int alunos[n];
std::fill(alunos, alunos+n, 0);
Also, ignoring errors is unhealthy. Don't do it.

Copying data file into an array

I have a project for school. They gave me a data file that needs to be in an array of 10*10. This array needs to be an upper triangle, which means that all values of and below the diagonal have to be zero. This data file is the time that a project takes by every stage. It means that every [i][j] represents the time for stage from i to j.
Just to make it more complicated the problem ask you to find the longest time per column and add it to the longest time in the next column.
here is my code so far:
#include <iostream>
#include<iomanip>
#include <fstream>
#include <cmath>
using namespace std;
//Function prototype
int minCompletionTime (int Data[], int numTasks);
int main()
{
//Declaring and initializing variables
int num_Events(0), completion_Time(0);
int startSearch(0), endSearch(0);
const int SIZE(10);
char datch;
//Declaring an array to hold the duration of each composite activity
int rows(0),duration_Data [10];
//Declaring an input filestream and attaching it to the data file
ifstream dataFile;
dataFile.open("duration.dat");
//Reading the data file and inputting it to the array. Reads until eof
//marker is read
while (!dataFile.eof())
{
//Declaring an index variable for the array
//Reading data into elements of the array
dataFile >> duration_Data[rows];
//Incrementing the index variable
rows++;
}
//Taking input for the number of events in the project
cout << "Enter the number of events in the project >>> ";
cin >> num_Events;
//Calling the function to calculate the minimum completion time
completion_Time = minCompletionTime(duration_Data, num_Events);
//Outputting the minimum completion time
cout << "The minimum time to complete this project is " << completion_Time
<< "." << endl;
}
int minCompletionTime (int Data[], int numTasks)
{
int sum=0;
//As long as the index variable is less than the number of tasks to be
//completed, the time to complete the task stored in each cell will be
//added to a sum variable
for (int Idx=0; Idx < numTasks ; Idx++)
{
sum += Data[Idx];
}
return sum;
}
Any help will be appreciated
My data file only has 6 elements that holds this elements: 9 8 0 0 7 5
my data should look like this in order to start doing operations.
0 0 0 0 0 0 0 0 0 0
0 0 9 8 0 0 0 0 0 0
0 0 0 0 7 0 0 0 0 0
0 0 0 0 5 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 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
It is a little confusing. I am sorry. The first and second column should have values of zero and first row the same way. after fifth row should be all zeros as well since it will be filled with more information from other data file.
There are a few ways of solving this problem. Here are 2 very naive ways:
1. Use a 10x10 array:
Read everything in from the data file (dataFile >> data[row][col]).
Have 2 nested loops:
The outer loop iterates over columns.
The inner loop iterates over the rows of that specific column.
Since you have to find the max and the values under the diagonal is zero, you can just be lazy and find the max of each column (you might have trouble if it's a lot larger than 10x10). However, if you want to only go through the rows that are necessary, I'll let you figure it out (it's very simple, don't over think).
2. Only use a 1x10 array:
Initialize the array with the minimal value (0 or -1 should work for you), let's call it the max_row.
Read item by item on each row, and compare it to the value that's stored in the max_row and replace appropriately.
When you're done, just sum up the elements in max_row.