Why is this ranged based for loop causing issues with subtraction? - c++

I'm having an issue with a ranged based for loop causing my values to go negative, and I've resolved the issue with a regular for loop but want to understand why it messed up in the first place. You can see from the sample output below that the initial values exist correctly, but then when attempting to subtract from them, they get reset to a default initialized value of 0 I guess?
Broken code:
#include <iostream>
#include <vector>
#define IS_TRUE(x) { if (!(x)) std::cout << __FUNCTION__ << " failed on line " << __LINE__ << std::endl; }
int maximumScore(std::vector<int>& nums, std::vector<int>& multipliers) {
std::vector<int> multRank;
multRank.resize(multipliers.size());
std::cout << "multRank: ";
//ISSUE IS IN THE LOOP BELOW
for (int n : multRank) {
n = multipliers.size();
std::cout << " " << n;
}
std::cout << std::endl;
for (auto i = 0; i < multipliers.size(); ++i) {
for (auto j = 0; j < multipliers.size(); ++j) {
int abs1 = std::abs(multipliers[i]);
int abs2 = std::abs(multipliers[j]);
if (abs1 > abs2) {
multRank[i] = multRank[i] - 1;
std::cout << multRank[i];
}
}
}
std::cout << std::endl << "multRank after: ";
for (int n : multRank) {
std::cout << " " << n;
}
std::cout << std::endl << std::endl;
return 0;
}
void test1()
{
std::vector<int> nums = { 1, 2, 3 };
std::vector<int> multipliers = { 3, 2, 1 };
int test = maximumScore(nums, multipliers);
IS_TRUE(test == 14);
}
int main()
{
std::cout << "Maximum Score from Performing Multiplication Operations\n";
test1();
}
Broken code output:
Maximum Score from Performing Multiplication Operations
multRank: 3 3 3
-1-2-1
multRank after: -2 -1 0
Repaired code:
#include <iostream>
#include <vector>
#define IS_TRUE(x) { if (!(x)) std::cout << __FUNCTION__ << " failed on line " << __LINE__ << std::endl; }
int maximumScore(std::vector<int>& nums, std::vector<int>& multipliers) {
std::vector<int> multRank;
multRank.resize(multipliers.size());
std::cout << "multRank: ";
//ISSUE WAS IN THE LOOP BELOW
for (auto i = 0; i < multipliers.size(); ++i) {
multRank[i] = multipliers.size();
std::cout << " " << multRank[i];
}
std::cout << std::endl;
for (auto i = 0; i < multipliers.size(); ++i) {
for (auto j = 0; j < multipliers.size(); ++j) {
int abs1 = std::abs(multipliers[i]);
int abs2 = std::abs(multipliers[j]);
if (abs1 > abs2) {
multRank[i]--;
std::cout << multRank[i];
}
}
}
std::cout << std::endl << "multRank after: ";
for (int n : multRank) {
std::cout << " " << n;
}
std::cout << std::endl << std::endl;
return 0;
}
void test1()
{
std::vector<int> nums = { 1, 2, 3 };
std::vector<int> multipliers = { 3, 2, 1 };
int test = maximumScore(nums, multipliers);
IS_TRUE(test == 14);
}
int main()
{
std::cout << "Calculate Rank\n";
test1();
}
Repaired code output:
Maximum Score from Performing Multiplication Operations
multRank: 3 3 3
212
multRank after: 1 2 3

The first range based for loop is not using references:
for (int n : multRank) {
n = multipliers.size();
std::cout << " " << n;
}
In this loop, n is a copy of the data in multRank. If you want to be able to modify the data in multRank, you want n to be a reference:
for (int& n : multRank) {
n = multipliers.size();
std::cout << " " << n;
}

Related

How to format output like this

My code is like this so far :
void matrix::print(int colWidth) const
{
cout << getRows() << " x " << getCols() << endl;
cout << "-";
for (unsigned int d = 0; d < getCols(); d++) {
cout << "--------";
}
cout << endl;
for (unsigned x = 0; x < getRows(); x++) {
cout << "|";
for (unsigned y = 0; y < getCols(); y++) {
cout << setw(colWidth) << at(x, y) << " |";
}
cout << endl;
}
cout << "-";
for (unsigned int d = 0; d < getCols(); d++) {
cout << "--------";
}
cout << endl;
}
But the output depends on the colWidth which will be the space between each number printed. So how can I adjust my dashes to be printed like the following no matter the colWidth it should align.
One output should look like this:
Second output is like this:
If the column width is a parameter, you're almost done with your code. Just turn the cout<<"--------" into:
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-');
That code prints a string of dashes, which width is: number of matrix columns, times column width plus 2, plus 1:
Plus 2 because you are appending a " |" to each column.
Plus 1 because you are adding a '|' at the beginning of each row.
You may want to check for empty matrices at the beginning of your print method.
[Demo]
#include <initializer_list>
#include <iomanip> // setw
#include <iostream> // cout
#include <vector>
class matrix
{
public:
matrix(std::initializer_list<std::vector<int>> l) : v{l} {}
size_t getRows() const { return v.size(); }
size_t getCols() const { if (v.size()) { return v[0].size(); } return 0; }
int at(size_t x, size_t y) const { return v.at(x).at(y); }
void print(int colWidth) const
{
std::cout << "Matrix: " << getRows() << " x " << getCols() << "\n";
// +2 due to " |", +1 due to initial '|'
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-') << "\n";
for (unsigned x = 0; x < getRows(); x++) {
std::cout << "|";
for (unsigned y = 0; y < getCols(); y++) {
std::cout << std::setw(colWidth) << at(x, y) << " |";
}
std::cout << "\n";
}
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-') << "\n";
}
private:
std::vector<std::vector<int>> v{};
};
int main()
{
matrix m{{1, 2}, {-8'000, 100'000}, {400, 500}};
m.print(10);
}
// Outputs
//
// Matrix: 3 x 2
// -------------------------
// | 1 | 2 |
// | -8000 | 100000 |
// | 400 | 500 |
// -------------------------

how to print on the same line inside function, avoid flush

I want to display a progress bar however putting the printing code inside a separate function seems to invoke an std::flush as each time the progress bar is printing in a new line. This did not happen when the code was used inline
The code:
#include <iostream>
#include <unistd.h>
void load(int curr, int total) {
std::cout << "\n[";
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << "=";
else if (i == pos) std::cout << ">";
else std::cout << " ";
}
std::cout << "]" << int(float(curr)/(float)total * 100.0) << " %\r";
std::cout.flush();
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i,5);
}
std::cout << std::endl;
return 0;
}
What it does:
[> ]0 %
[==========> ]20 %
[====================> ]40 %
[==============================> ]60 %
[========================================> ]80 %
[==================================================]100 %
What it's supposed to do: print all on the same line
The first line in your function outputs \n, which is what makes it print on a new line every iteration.
Fix:
#include <iostream>
void load(int curr, int total) {
std::cout << '[';
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << '=';
else if (i == pos) std::cout << '>';
else std::cout << ' ';
}
std::cout << ']' << int(float(curr)/(float)total * 100.0) << " %\r" << std::flush;
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i, 5);
}
std::cout << '\n';
}

terminate called after throwing an instance of 'std::out_of_range' in C++

I am new to C++ and learning data structures. In the below code I am getting an "out of range warning", and do not understand what I am doing wrong.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers{100,-1,2,4,55,78,3};
int temp {};
int pass {};
pass = numbers.size();
for(int i {0} ;i<pass-1;i++){
for(int j {0} ; j<pass-1-i ; j++){
if(numbers.at(j) > numbers.at(j+1)){
temp = numbers.at(j);
numbers.at(j)=numbers.at(j+1);
numbers.at(j+1)=temp;
}
}
}
cout << numbers.at(0) << endl;
cout << numbers.at(1) << endl;
cout << numbers.at(2) << endl;
cout << numbers.at(3) << endl;
cout << numbers.at(4) << endl;
cout << numbers.at(5) << endl;
cout << numbers.at(6) << endl;
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
return 0;
}
It seems like you may not understand how std::vectors work.
You have only declared 7 elements in your vector which means you can only go up to the index 6. This is because std::vector's indices start at 0. This is true for std::array as well.
vector<int> numbers{100,-1,2,4,55,78,3};
However, in your code you have put these two statements:
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
which doesn't work because like I mentioned you can only go up to index 6.
You should also consider using a for loop like the comments mention above. It is more simple to use and is less work.
For example eith a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers{ 100,-1,2,4,55,78,3 };
int temp{};
int pass{};
pass = numbers.size();
for (int i{ 0 }; i < pass - 1; i++) {
for (int j{ 0 }; j < pass - 1 - i; j++) {
if (numbers.at(j) > numbers.at(j + 1)) {
temp = numbers.at(j);
numbers.at(j) = numbers.at(j + 1);
numbers.at(j + 1) = temp;
}
}
}
std::cout << "v = { ";
for (int i = 0; i < numbers.size(); i++) {
std::cout << numbers.at(i) << ", ";
}
std::cout << "}; \n";
return 0;
}
Output:
v = { -1, 2, 3, 4, 55, 78, 100, };

Which are the best methods for speeding up the algorithm based on vector search?

I am trying to solve the Euler question 419
So far, I think I managed to build an algorithm to find the answer. Or at least it gives the correct result for first 40 step. But I need to compute 1,000,000,000,000th step. Solving first 40 step (with my algorithm) takes about 3-4 seconds. And bigger the iteration number increases, computation time increases as well. I don't think my computer can solve 1,000,000,000,000 iteration in a year.
What I do is simply using temporary vectors for both sequential number counting(form_1 and form_2) and keeping the calculated the result for each iteration(testVec). Here is my code below:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>
std::vector<int> form_1;
std::vector<int> form_2;
std::vector<int> testVec;
void showVec(std::vector<int>& vec)
{
//
for (unsigned long int i = 0; i < vec.size(); i++)
{
//
std::cout << vec[i] << std::endl;
}
}
void resFin(int start, int stop, std::vector<int>& vec)
{
//
for (unsigned long int i = 0; i < vec.size(); i++)
{
//
if (i == 0)
{
//
form_1.push_back(vec[0]);
//std::cout << "form_1 pushed " << vec[0] << std::endl;
}
else
{
//
if (i != vec.size() - 1)
{
//
if (vec[i] == vec[i - 1])
{
//
form_1.push_back(vec[i]);
//std::cout << "form_1 pushed " << vec[i] << std::endl;
}
else
{
//
form_2.push_back(form_1.size());
form_2.push_back(vec[i - 1]);
form_1.clear();
form_1.push_back(vec[i]);
}
}
else
{
//
if (vec[i] == vec[i - 1])
{
//
form_1.push_back(vec[i]);
//std::cout << "form_1 pushed " << vec[i] << std::endl;
form_2.push_back(form_1.size());
//std::cout << "form_2 pushed " << form_1.size() << std::endl;
form_2.push_back(vec[i - 1]);
//std::cout << "form_2 pushed " << vec[i - 1] << std::endl;
form_1.clear();
}
else
{
//
form_2.push_back(form_1.size());
//std::cout << "form_2 pushed " << form_1.size() << std::endl;
form_2.push_back(vec[i - 1]);
//std::cout << "form_2 pushed " << vec[i - 1] << std::endl;
form_2.push_back(1);
//std::cout << "form_2 pushed " << 1 << std::endl;
form_2.push_back(vec[i]);
//std::cout << "form_2 pushed " << vec[i] << std::endl;
form_1.clear();
}
}
}
}
vec.clear();
for (unsigned long int k = 0; k < form_2.size(); k++)
{
//
vec.push_back(form_2[k]);
//std::cout << "vec pushed " << form_2[k] << std::endl;
}
//showVec(vec);
if (start + 1 != stop)
{
//
form_1.clear();
form_2.clear();
std::cout << "recursed to " << start + 1 << std::endl;
resFin(start + 1, stop, vec);
}
}
void stepFind(int stop, std::vector<int>& vec)
{
//
resFin(1, stop, vec);
}
void trimmVec(std::vector<int>& vec)
{
//
int a = 0;
int b = 0;
int c = 0;
for (unsigned long int i = 0; i < vec.size(); i ++)
{
//
switch (vec[i])
{
case 1:
a++;
a = a % 1073741824;
break;
case 2:
b++;
b = b % 1073741824;
break;
case 3:
c++;
c = c % 1073741824;
break;
default:
break;
}
}
std::cout << "a is " << a << "; b is " << b << "; c is " << c << std::endl;
}
int main()
{
//
testVec.push_back(1);
testVec.push_back(1);
stepFind(39, testVec);
//showVec(testVec);
trimmVec(testVec);
getchar();
return 0;
}
I think no one ought to wait more than a few hours to solve euler problems right? So I am doing something wrong here. So, are there such methods existed to minimize computing time, especially in vectors inside searching(I think this consumes the time most)?

How to reset a static struct inside a function

So let's say I have a function
struct coinTypes {
int tenP = 0;
int twentyP = 0;
int fiftyP = 0;
};
coinTypes numberOfCoins(int coins)
{
static coinTypes types;
// incrementing structs values
}
Let's say I have used this function for some time, and values in coinTypes struct are no longer 0. Then I decided to use this function for another purpose and I need the values to be 0 again. Is there any way to reset coinTypes struct?
Unless you are just misunderstanding what the keyword static does (you probably are), this is what you are asking for:
run online
#include <iostream>
struct britishCoins {
int tenP;
int twentyP;
int fiftyP;
};
britishCoins& getCoins () {
static britishCoins coins {0, 0, 0};
return coins;
}
void resetCoins () {
getCoins() = {0, 0, 0};
}
britishCoins numberOfCoins(int coins)
{
britishCoins& result = getCoins();
result.tenP += coins / 10;
//...
return result;
}
int main () {
std::cout << numberOfCoins(0).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
resetCoins();
std::cout << numberOfCoins(0).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
std::cout << numberOfCoins(10).tenP << std::endl;
return 0;
}
Prints:
0
1
2
3
4
0
1
2
3
4
If you just want to convert int coins into britishCoins without storing it's value inside the function it's simple:
run online
#include <iostream>
struct britishCoins {
int tenP;
int twentyP;
int fiftyP;
};
britishCoins numberOfCoins(int coins)
{
britishCoins result;
result.fiftyP = coins / 50;
coins %= 50;
result.twentyP = coins / 20;
coins %= 20;
result.tenP = coins / 10;
return result;
}
int main () {
for (int i = 0; i < 3; ++i) {
britishCoins coins = numberOfCoins(130);
std::cout << coins.fiftyP << "*50 + " << coins.twentyP << "*20 + " << coins.tenP << "*10" << std::endl;
}
return 0;
}
output:
2*50 + 1*20 + 1*10
2*50 + 1*20 + 1*10
2*50 + 1*20 + 1*10
Dont use static in this case. Try to use:
Class Coin with object params coinType, couinNumber for example.