C++ pushing back a string by value in a vector - c++

I'm doing some algorithmics problem and I'm having trouble with managing functions, vectors and strings in C++.
I have to find a concrete path in a matrix and for that, I need to have all the different paths, so I decided to use a function. This function will check where to continue to search. Here is the code of the function:
vector<string> get_all_paths(string actual, int rows, int columns, int col_actual, int row_prev) {
vector<string> solutions;
int row_actual = (rows+row_prev-1)%rows;
for (int i = 0; i < 3; i++) {
cout << col_actual << " " << row_actual << "\n";
//cout << (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) << " " << dp[row_actual][col_actual] << "\n";
if( (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) == dp[row_actual][col_actual] ) {
if (col_actual > 0) {
//cout << "--" << actual << " " << row_actual << "\n";
string branch = actual + to_string(row_actual+1) + " ";
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
//cout << ".." << actual << "\n";
} else {
//cout << actual << " " << row_actual << "\n";
cout << actual << "\n";
string branch = actual.c_str();
branch += to_string(row_actual+1);
cout << branch << "\n";
solutions.push_back( branch );
break;
}
}
row_actual = (row_actual+1)%rows;
}
for(auto i : solutions) cout << "--" << i << "\n";
return solutions;
}
And here is the call to the method:
vector<string> solutions;
for (int i = 0; i < rows; i++) {
if (dp[i][cols-1] == min_path) {
cout << "................\n";
solutions = get_best_path( (to_string(i+1)+" "), rows, cols, cols-2, i);
for(auto i : solutions) {
reverse(i.begin(), i.end());
cout << i << "\n";
}
cout << "xxxxxxxxxxxxxxx\n";
}
}
The thing is that I'm getting three paths for a given example, which is correct, but they are all the same string, which is the last path or the last change done in variable branch.
Maybe I'm mixing a lot of concepts and maybe this has been answered a lot of times, but I've searched this and got nothing.
EDIT: I'm not getting three paths from the function, just the last one, but when printing inside the function the paths i do have three inside that function all with the same value, sorry about that.
EDIT2: The idea of the problem is to find the minimum cost path in a given matrix and, if there are more than 1, the one that is the smallest lexicographically. So given a matrix:
5 4
9 1 9 9
1 9 9 9
9 9 9 9
1 1 1 1
9 9 1 9
My approach is to use dp as a matrix with the dynamic programming results and then i try to recreate all the paths in the function above.
In this case, the dp matrix is:
9 2 11 12
1 10 11 20
9 10 11 12
1 2 3 4
9 10 3 12
And so, the best paths are:
4 4 4 4
4 5 4 4
2 1 5 4
And the one correct is the last one.
Inside my function i do get the different paths and i add them to the vector of results, but then i lose them when searching for more.
Thanks for the time if you have read this :D!

Well I think the problem is here
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
because that assignment replaces any solutions you might have found so far. Instead you should append any solutions returned to any that you've found so far. In other words something like this
vector<string> tmp = get_best_path(branch, rows, columns, col_actual-1, row_actual);
solutions.insert(solutions.end(), tmp.begin(), tmp.end());
But this is just intuition, I haven't tested anything.

Related

How to find Row and columns from box number on chessboard?

Example: chessboard has 64 fields, starting from 1 in top uppermost left box,
row 2, column 2 means its 10th box,
row 4, column 2 means its 26th box .....so on
Formula, trick to determine Row_column no from box number or vice versa?
I guess you mean that you have 8 boxes on each row?
This might do the trick:
#include <iostream>
#include <cmath>
const int totalNrOfBoxes = 64;
const float nrOfRows = std::sqrt(totalNrOfBoxes);
std::pair<int, int> getRowAndColumn(int boxNumber) {
int rowNumber = std::ceil(boxNumber / nrOfRows);
int columnNumber = (boxNumber - 1) % (int) nrOfRows; // we do -1 to avoid getting 0 when the boxNr is 8 or 16 or 32 for example
columnNumber += 1; // we add one number to the column number because we removed one from the box number
return std::make_pair(rowNumber, columnNumber);
}
int main()
{
std::pair<int, int> rowAndColumn = getRowAndColumn(11);
std::pair<int, int> rowAndColumn2 = getRowAndColumn(64);
std::pair<int, int> rowAndColumn3 = getRowAndColumn(1);
std::pair<int, int> rowAndColumn4 = getRowAndColumn(34);
std::pair<int, int> rowAndColumn5 = getRowAndColumn(7);
std::cout << rowAndColumn.first << " " << rowAndColumn.second << std::endl;
std::cout << rowAndColumn2.first << " " << rowAndColumn2.second << std::endl;
std::cout << rowAndColumn3.first << " " << rowAndColumn3.second << std::endl;
std::cout << rowAndColumn4.first << " " << rowAndColumn4.second << std::endl;
std::cout << rowAndColumn5.first << " " << rowAndColumn5.second << std::endl;
}
gives us the following output:
2 3
8 8
1 1
5 2
1 7
So basically what we do to determine the row number, is to divide the given box number by the number of rows, and take the ceil (finds the closest integer not less than n) out of that. Example: 26 / 8 = 3.25. We know that 26 is on the 4th row, so we need to take the closest integer not less than 3.25 which is 4.
For the column number we take the remainder. So for example with 12 it would return 4. The problem is that we start counting boxes at 1, so 16 % 8 would return 0, while we do want to get a value of 8. So that is why we say boxNumber - 1 (15 % 8 which returns 7) and add 1.

Curious division result

How can this code...
vector<double> _pc;
vector<int> _documentClassIds;
[...]
someMemberFunction(vector<int> const & documentIds) {
cout << "_pc[0] = "<< _pc[0]<<endl;
cout << "_pc[1] = "<< _pc[1]<<endl;
cout << "documentIds.size() = " << documentIds.size()<<endl;
// Normalize
for (auto documentId : documentIds)
_pc[_documentClassIds[documentId]] =
_pc[_documentClassIds[documentId]] / documentIds.size();
cout << "_pc[0] = "<< _pc[0]<<endl;
cout << "_pc[1] = "<< _pc[1]<<endl;
}
produce this output?
_pc[0] = 3
_pc[1] = 3
documentIds.size() = 6
_pc[0] = 0.0138889
_pc[1] = 0.0138889
I'm not sure what you think the problem is.
You have six document IDs, so your for loop runs six times. Each time it runs, it divides one of your _pc array values by six.
Since 0.0138888... is 3 divided by 216 (6^3), the calculations seem correct.
It's obvious that the selection of which _pc array entry to divide is equally distibuted so that each gets divided three times, so each ends up as:
(((3 / 6) / 6) / 6) => 0.013888...

Values not written to vector

I'm trying to read pairs values from a file in the constructor of an object.
The file looks like this:
4
1 1
2 2
3 3
4 4
The first number is number of pairs to read.
In some of the lines the values seem to have been correctly written into the vector. In the next they are gone. I am totally confused
inline
BaseInterpolator::BaseInterpolator(std::string data_file_name)
{
std::ifstream in_file(data_file_name);
if (!in_file) {
std::cerr << "Can't open input file " << data_file_name << std::endl;
exit(EXIT_FAILURE);
}
size_t n;
in_file >> n;
xs_.reserve(n);
ys_.reserve(n);
size_t i = 0;
while(in_file >> xs_[i] >> ys_[i])
{
// this line prints correct values i.e. 1 1, 2 2, 3 3, 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
if(i + 1 < n)
i += 1;
else
break;
// this line prints 0 0, 0 0, 0 0
std::cout << xs_[i] << " " << ys_[i] << std::endl;
}
// this line prints correct values i.e. 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
}
The class is defined thus:
class BaseInterpolator
{
public:
~BaseInterpolator();
BaseInterpolator();
BaseInterpolator(std::vector<double> &xs, std::vector<double> &ys);
BaseInterpolator(std::string data_file_name);
virtual int interpolate(std::vector<double> &x, std::vector<double> &fx) = 0;
virtual int interpolate(std::string input_file_name,
std::string output_file_name) = 0;
protected:
std::vector<double> xs_;
std::vector<double> ys_;
};
You're experiencing undefined behaviour. It seems like it's half working, but that's twice as bad as not working at all.
The problem is this:
xs_.reserve(n);
ys_.reserve(n);
You are only reserving a size, not creating it.
Replace it by :
xs_.resize(n);
ys_.resize(n);
Now, xs[i] with i < n is actually valid.
If in doubt, use xs_.at(i) instead of xs_[i]. It performs an additional boundary check which saves you the trouble from debugging without knowing where to start.
You're using reserve(), which increases capacity (storage space), but does not increase the size of the vector (i.e. it does not add any objects into it). You should use resize() instead. This will take care of size() being 0.
You're printing the xs_[i] and ys_[i] after you increment i. It's natural those will be 0 (or perhaps a random value) - you haven't initialised them yet.
vector::reserve reserve space for further operation but don't change the size of the vector, you should use vector::resize.

Why are addresses of vector elements not consecutive when assigned using push_back()?

Please look at the small test code + output provided below. It seems that when using push_back() on an std::vector within a loop, C++ allocates the memory at 'random' addresses, and then re-copies the data into consecutive memory addresses after the loop is finished.
Is this to do with the fact that the size of the vector is not known before the loop?
What is the correct way of doing what I do in the test code? Do I have to assign the pointers in another loop after the first one exits? Note that I cannot define the size of the vector before the first loop, because in reality it is actually a vector of class objects that require initialization.
Thank you for your help.
std::vector<int> MyVec;
std::vector<int *> MyVecPtr;
for (int i = 0; i < 10; i++)
{
MyVec.push_back(i);
MyVecPtr.push_back(&MyVec.back());
std::cout << MyVec.back() << " "
<< &MyVec.back() << " "
<< MyVecPtr.back() << " "
<< *MyVecPtr.back() << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < MyVec.size(); i++)
{
std::cout << MyVec[i] << " "
<< &MyVec[i] << " "
<< MyVecPtr[i] << " "
<< *MyVecPtr[i] << std::endl;
}
0 0x180d010 0x180d010 0
1 0x180d054 0x180d054 1
2 0x180d038 0x180d038 2
3 0x180d03c 0x180d03c 3
4 0x180d0b0 0x180d0b0 4
5 0x180d0b4 0x180d0b4 5
6 0x180d0b8 0x180d0b8 6
7 0x180d0bc 0x180d0bc 7
8 0x180d140 0x180d140 8
9 0x180d144 0x180d144 9
0 0x180d120 0x180d010 25219136
1 0x180d124 0x180d054 0
2 0x180d128 0x180d038 2
3 0x180d12c 0x180d03c 3
4 0x180d130 0x180d0b0 4
5 0x180d134 0x180d0b4 5
6 0x180d138 0x180d0b8 6
7 0x180d13c 0x180d0bc 7
8 0x180d140 0x180d140 8
9 0x180d144 0x180d144 9
If you know how many insertions you will be performing, you should use reserve() on your vector accordingly. This will eliminate the need for any resizing it would otherwise perform when the capacity is exceeded.
MyVec.reserve(10);
for (int i = 0; i < 10; i++)
{
MyVec.push_back(i);
//...

Converting base 10 to 12, having trouble adding alphabet characters recursivly

I'm having trouble using recursion to add letters to a base 10 - base 12 conversion. How would I go about adding letters into my function? I was thinking about adding an if statement in, but i have no idea where and how to go about this. pointers are appreciated Thanks!
Given a count from 1 to 12:
Dec 1 2 3 4 5 6 7 8 9 10 11 12
Duo 1 2 3 4 5 6 7 8 9 X E 10
my function:
template<class myType>
myType convertDec(myType number){
if(number == 0)
return number;
//if statement somewhere in here? not sure considering i can't touch the return statement
return (number % 12) + 10*convertDec(number / 12);
}
example ideal output:
65280 = 31940 (works fine)
2147483626 = 4EE23088X (doesnt work!)
#include <iostream>
#include <string>
using namespace std;
string ConvertToDuodecimal(unsigned long long n)
{
if (n < 12)
return string() + "0123456789XE"[n];
return ConvertToDuodecimal(n / 12) + ConvertToDuodecimal(n % 12);
}
int main()
{
cout << ConvertToDuodecimal(0) << endl;
cout << ConvertToDuodecimal(1) << endl;
cout << ConvertToDuodecimal(10) << endl;
cout << ConvertToDuodecimal(11) << endl;
cout << ConvertToDuodecimal(12) << endl;
cout << ConvertToDuodecimal(13) << endl;
cout << ConvertToDuodecimal(65280) << endl;
cout << ConvertToDuodecimal(2147483626) << endl;
return 0;
}
Output (ideone):
0
1
X
E
10
11
31940
4EE23088X
The base is a property of the way a number is displayed and nothing to do with it's internal representation. You need to write a function that prints a normal int using base 12.
a = 12; // A = 12 (in base 10)
printf("%d",a); // Prints a in base 10 (still 12)
printf("%x",a); // Prints a in base 16 (now C)
You code is changing the actual value, which isn't the right thing to do.
(and yes, before the pedants strike, printf isn't good C++...)