counting frequency of integers take together - c++

I need to count the frequencies of different integers together in a binary file, how can I do this? I do not wish to convert to string, because that would slow down my program down.. I think...
vector<uint32_t> buf(2);
map<uint32_t, uint32_t> mymap;
if(file.is_open())
{
while (file.read(reinterpret_cast<char*>(&buf[0]), sizeof(uint32_t)*numcols))
{
for(size_t i = 0; i < numcols; ++i)
{
mymap[buf[i]]++; // **---> I need help here**
}
}
}
file.close();
How can I make the key to the map so that it always counts those integers together
Yep.. how many times I see integer pairs consecutively, like how many times (1,2), or (8, 14), or (7,3).
1 2
1 2
7 3
8 14
8 14
8 14
1 2 --> 2 times
7 3 --> 1 time
8 14 --> 3 times
numcols == 2 correct.

One option might be to have the map use pair<uint32_t, uint32_t>s as keys. That way you're explicitly mapping from pairs of uint32_ts to the frequency with which they appear.

Related

Read to array from table in text file, while skipping specific column

I am trying to read the contents of a text file into 2D array in C++. The file contains 125 rows with 21 columns of integers (a table of integers). I'm to read this into an array that is 125 rows of 20 columns, skipping column 21 of the file.
I defined the size of the array with variables, but it just reads column 21 into the next row, ignoring the new line. I need it to start each row in the array at the start of the new line from the file but ignore the last item in the table.
I'm not sure if I'm looking for it to skip column 21, or if I'm looking for it to start reading each column at a new line (or both?)
Text file looks like (is this called a matrix?) and it's number separated by 1 space and \n at end.
(The text file was generated by a program to generate rows of 20 numbers and the sum.)
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
" etc
Other solutions I've found can be difficult for me to understand because people write their variables and functions non-descriptively. Some solutions require advanced methods I'm not supposed to use as well, such as vectors and string manipulation. I have currently learned everything before "pointers" so I can only use solutions I've learned in class. I've learned functions, arrays, search/sort, and basics like operators, loops, variables, etc. I'm not supposed to use vectors for this or string manipulation.
I will (eventually) have to sum the numbers in the array (after I extract the first 20 of each row from the file) so to compare the sum from the array final column to the last integer in each row of the file (which is a sum).
My function is (note: We are using namespace std)
void readArray() {
ifstream infile("tableofintegers.txt");
for (int rowcount = 0; rowcount < ROWS; rowcount++) // row loop
{
for (int colcount = 0; colcount < COLS; colcount++) // column loop
{
infile >> twoDArray[rowcount][colcount]; // read to array
}
}
}
These are variables:
const int ROWS = 125;
const int COLS = 20;
I tried this but got a runtime error
file >> array[row][col];
file.ignore(10, '\n');
The error when I tried file.ignore
C:\path\matrix.exe (process 27316) exited with code -2147483645.
Not only is there an error, but it still "wraps" the read starting line two with the sum (last digit) of line 1.) As you can imagine, as this iterates, it keeps pushing the data over further and further.
I expected for the program to stop reading when it reached the limit of the array columns (20) then continue at the next line, but it didn't. My brain tells me something's not logical about that expectation, yet I have a dissonance or something going on. I can't really wrap my head around it. I also tried file.ignore which I expected would ignore 10 characters after the 20th column up to new line, but it just kicked an error and still wrapped.
Note: I'm printing the array to the console. Here is my code for that.
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
cout << setw(5) << dataArray[row][col];
}
cout << endl;
}

What does this vector array code do? (C++)

Having difficulty finding an explanation to this.
What does this code do? I understand it creates an array of vector but that's about it.
How can I print the vector array and access elements to experiment with it?
#define MAXN 300009
vector<int>dv[MAXN];
int main()
{
for(int i=1;i<MAXN;i++)
for(int j=i;j<MAXN;j+=i)
dv[j].push_back(i);
}
The code is easy enough to instrument. The reality of what it ends up producing is a very simple (and very inefficient) Sieve of Eratosthenes. Understanding that algorithm, you'll see what this code does to produce that ilk.
Edit: It is also a factor-table generator. See Edit below.
Instrumenting the code and dumping output afterward, and reducing the number of loops for simplification we have something like the following code. We use range-based-for loops for enumerating over each vector in the array of vectors:
#include <iostream>
#include <vector>
#define MAXN 20
std::vector<int>dv[MAXN];
int main()
{
for(int i=1;i<MAXN;i++)
{
for(int j=i;j<MAXN;j+=i)
dv[j].push_back(i);
}
for (auto const& v : dv)
{
for (auto x : v)
std::cout << x << ' ';
std::cout << '\n';
}
}
The resulting output is:
1
1 2
1 3
1 2 4
1 5
1 2 3 6
1 7
1 2 4 8
1 3 9
1 2 5 10
1 11
1 2 3 4 6 12
1 13
1 2 7 14
1 3 5 15
1 2 4 8 16
1 17
1 2 3 6 9 18
1 19
Now, note each vector that only has two elements (1 and an additional number). That second number is prime. In our test case those two-element vectors are:
1 2
1 3
1 5
1 7
1 11
1 13
1 17
1 19
In short, this is a very simple, and incredibly inefficient way of finding prime numbers. A slight change to the output loops to only output the second element of all vectors of length-two-only will therefore generate all the primes lower than MAXN. Therefore, using:
for (auto const& v : dv)
{
if (v.size() == 2)
std::cout << v[1] << '\n';
}
We will get all primes from [2...MAXN)
Edit: Factor Table Generation
If it wasn't obvious, each vector has an ending element (that not-coincidentally also lines up with the subscripts of the outer array). All preceding elements make up the positive factors of that number. For example:
1 2 5 10
is the dv[10] vector, and tells you 10 has factors 1,2,5,10. Likewise,
1 2 3 6 9 18
is the dv[18] vector, and tells you 18 has factors 1,2,3,6,9,18.
In short, if someone wanted to know all the factors of some number N that is < MAXN, this would be a way of putting all that info into tabular form.

Counting ways of breaking up a string of digits into numbers under 26

Given a string of digits, I wish to find the number of ways of breaking up the string into individual numbers so that each number is under 26.
For example, "8888888" can only be broken up as "8 8 8 8 8 8 8". Whereas "1234567" can be broken up as "1 2 3 4 5 6 7", "12 3 4 5 6 7" and "1 23 4 5 6 7".
I'd like both a recurrence relation for the solution, and some code that uses dynamic programming.
This is what I've got so far. It only covers the base cases which are a empty string should return 1 a string of one digit should return 1 and a string of all numbers larger than 2 should return 1.
int countPerms(vector<int> number, int currentPermCount)
{
vector< vector<int> > permsOfNumber;
vector<int> working;
int totalPerms=0, size=number.size();
bool areAllOverTwo=true, forLoop = true;
if (number.size() <=1)
{
//TODO: print out permetations
return 1;
}
for (int i = 0; i < number.size()-1; i++) //minus one here because we dont care what the last digit is if all of them before it are over 2 then there is only one way to decode them
{
if (number.at(i) <= 2)
{
areAllOverTwo = false;
}
}
if (areAllOverTwo) //if all the nubmers are over 2 then there is only one possable combination 3456676546 has only one combination.
{
permsOfNumber.push_back(number);
//TODO: write function to print out the permetions
return 1;
}
do
{
//TODO find all the peremtions here
} while (forLoop);
return totalPerms;
}
Assuming you either don't have zeros, or you disallow numbers with leading zeros), the recurrence relations are:
N(1aS) = N(S) + N(aS)
N(2aS) = N(S) + N(aS) if a < 6.
N(a) = 1
N(aS) = N(S) otherwise
Here, a refers to a single digit, and S to a number. The first line of the recurrence relation says that if your string starts with a 1, then you can either have it on its own, or join it with the next digit. The second line says that if you start with a 2 you can either have it on its own, or join it with the next digit assuming that gives a number less than 26. The third line is the termination condition: when you're down to 1 digit, the result is 1. The final line says if you haven't been able to match one of the previous rules, then the first digit can't be joined to the second, so it must stand on its own.
The recurrence relations can be implemented fairly directly as an iterative dynamic programming solution. Here's code in Python, but it's easy to translate into other languages.
def N(S):
a1, a2 = 1, 1
for i in xrange(len(S) - 2, -1, -1):
if S[i] == '1' or S[i] == '2' and S[i+1] < '6':
a1, a2 = a1 + a2, a1
else:
a1, a2 = a1, a1
return a1
print N('88888888')
print N('12345678')
Output:
1
3
An interesting observation is that N('1' * n) is the n+1'st fibonacci number:
for i in xrange(1, 20):
print i, N('1' * i)
Output:
1 1
2 2
3 3
4 5
5 8
6 13
7 21
8 34
9 55
If I understand correctly, there are only 25 possibilities. My first crack at this would be to initialize an array of 25 ints all to zero and when I find a number less than 25, set that index to 1. Then I would count up all the 1's in the array when I was finished looking at the string.
What do you mean by recurrence? If you're looking for a recursive function, you would need to find a good way to break the string of numbers down recursively. I'm not sure that's the best approach here. I would just go through digit by digit and as you said if the digit is 2 or less, then store it and test appending the next digit... i.e. 10*digit + next. I hope that helped! Good luck.
Another way to think about it is that, after the initial single digit possibility, for every sequence of contiguous possible pairs of digits (e.g., 111 or 12223) of length n we multiply the result by:
1 + sum, i=1 to floor (n/2), of (n-i) choose i
For example, with a sequence of 11111, we can have
i=1, 1 1 1 11 => 5 - 1 = 4 choose 1 (possibilities with one pair)
i=2, 1 11 11 => 5 - 2 = 3 choose 2 (possibilities with two pairs)
This seems directly related to Wikipedia's description of Fibonacci numbers' "Use in Mathematics," for example, in counting "the number of compositions of 1s and 2s that sum to a given total n" (http://en.wikipedia.org/wiki/Fibonacci_number).
Using the combinatorial method (or other fast Fibonacci's) could be suitable for strings with very long sequences.

Transposing a sparse matrix using linked lists (Traversal problems)

I'm trying to transpose a sparse matrix in c++. I'm struggling with the traversal of the new transposed matrix. I want to enter everything from the first row of the matrix to the first column of the new matrix.
Each row has the column index the number should be in and the number itself.
Input:
colInd num colInd num colInd num
Input:
1 1 2 2 3 3
1 4 2 5 3 6
1 7 2 8 3 9
Output:
1 1 2 4 3 7
1 2 2 5 3 8
1 3 2 6 3 9
How do I make the list traverse down the first column inserting the first element as it goes then go back to the top inserting down the second column. Apologies if this is two hard to follow. But all I want help with is traversing the Transposed matrix to be in the right place at the right time inserting a nz(non zero) object in the right place.
Here is my code
list<singleRow> tran;
//Finshed reading so transpose
for (int i = 0; i < rows.size(); i++){ // Initialize transposed matrix
singleRow trow;
tran.push_back(trow);
}
list<singleRow>::const_iterator rit;
list<singleRow>::const_iterator trowit;
int rowind;
for (rit = rows.begin(), rowind = 1; rit != rows.end(); rit++, rowind++){//rit = row iterator
singleRow row = *rit;
singleRow::const_iterator nzit;
trowit = tran.begin(); //Start at the beginning of the list of rows
trow = *trowit;
for (nzit = row.begin(); nzit != row.end(); nzit++){//nzit = non zero iterator
int col = nzit->getCol();
double val = nzit->getVal();
trow.push_back(nz(rowind,val)); //How do I attach this to tran so that it goes in the right place?
trowit++;
}
}
Your representation of the matrix is inefficient: it doesn't use the fact that the matrix is sparse. I say so because it includes all the rows of the matrix, even if most of them are zero (empty), like it usually happens with sparse matrices.
Your representation is also hard to work with. So i suggest converting the representation first (to a regular 2-D array), transposing the matrix, and convert back.
(Edited:)
Alternatively, you can change the representation, for example, like this:
Input: rowInd colInd num
1 1 1
1 2 2
1 2 3
2 1 4
2 2 5
2 3 6
3 1 7
3 2 8
3 3 9
Output:
1 1 1
2 1 2
3 1 3
1 2 4
2 2 5
3 2 6
1 3 7
2 3 8
3 3 9
The code would be something like this:
struct singleElement {int row, col; double val;};
list<singleElement> matrix_input, matrix_output;
...
// Read input matrix from file or some such
list<singleElement>::const_iterator i;
for (i = matrix_input.begin(); i != matrix_input.end(); ++i)
{
singleElement e = *i;
std::swap(e.row, e.col);
matrix_output.push_back(e);
}
Your choice of list-of-list representation for a sparse matrix is poor for transposition. Sometimes, when considering algorithms and data structures, the best thing to do is to take the hit for transforming your data structure into one better suited for your algorithm than to mangle your algorithm to work with the wrong data structure.
In this case you could, for example, read your matrix into a coordinate list representation which would be very easy to transpose, then write into whatever representation you like. If space is a challenge, then you might need to do this chunk by chunk, allocating new columns in your target representation 1 by 1 and deallocating columns in your old representation as you go.

Permutations with some fixed numbers

How to effectively generate permutations of a number (or chars in word), if i need some char/digit on specified place?
e.g. Generate all numbers with digit 3 at second place from the beginning and digit 1 at second place from the end of the number. Each digit in number has to be unique and you can choose only from digits 1-5.
4 3 2 1 5
4 3 5 1 2
2 3 4 1 5
2 3 5 1 4
5 3 2 1 4
5 3 4 1 2
I know there's a next_permutation function, so i can prepare an array with numbers {4, 2, 5} and post this in cycle to this function, but how to handle the fixed positions?
Generate all permutations of 2 4 5 and insert 3 and 1 in your output routine. Just remember the positions were they have to be:
int perm[3] = {2, 4, 5};
const int N = sizeof(perm) / sizeof(int);
std::map<int,int> fixed; // note: zero-indexed
fixed[1] = 3;
fixed[3] = 1;
do {
for (int i=0, j=0; i<5; i++)
if (fixed.find(i) != fixed.end())
std::cout << " " << fixed[i];
else
std::cout << " " << perm[j++];
std::cout << std::endl;
} while (std::next_permutation(perm, perm + N));
outputs
2 3 4 1 5
2 3 5 1 4
4 3 2 1 5
4 3 5 1 2
5 3 2 1 4
5 3 4 1 2
I've read the other answers and I believe they are better than mine for your specific problem. However I'm answering in case someone needs a generalized solution to your problem.
I recently needed to generate all permutations of the 3 separate continuous ranges [first1, last1) + [first2, last2) + [first3, last3). This corresponds to your case with all three ranges being of length 1 and separated by only 1 element. In my case the only restriction is that distance(first3, last3) >= distance(first1, last1) + distance(first2, last2) (which I'm sure could be relaxed with more computational expense).
My application was to generate each unique permutation but not its reverse. The code is here:
http://howardhinnant.github.io/combinations.html
And the specific applicable function is combine_discontinuous3 (which creates combinations), and its use in reversible_permutation::operator() which creates the permutations.
This isn't a ready-made packaged solution to your problem. But it is a tool set that could be used to solve generalizations of your problem. Again, for your exact simple problem, I recommend the simpler solutions others have already offered.
Remember at which places you want your fixed numbers. Remove them from the array.
Generate permutations as usual. After every permutation, insert your fixed numbers to the spots where they should appear, and output.
If you have a set of digits {4,3,2,1,5} and you know that 3 and 1 will not be permutated, then you can take them out of the set and just generate a powerset for {4, 2, 5}. All you have to do after that is just insert 1 and 3 in their respective positions for each set in the power set.
I posted a similar question and in there you can see the code for a powerset.