Passing map by reference in C++ and mutating its value - dictionary

I am passing map by reference in the canSum function where i am mutating its value and adding pairs but at the end when I iterate over the map I find the value of map has not been updated.
canSum function is a recursive function which takes a number (targetSum) and an array and finds if it is possible to form targetSum by any combinations of number in the array (numbers can be repeated).
#include<iostream>
#include<vector>
#include<map>
using namespace std;
bool canSum(int targetSum,vector<int> a,map<int, bool> &m){
if(!(m.find(targetSum) == m.end()))
return m[targetSum];
if (targetSum == 0)
return true;
if(targetSum<0)
return false;
for (int num : a)
{
if (canSum(targetSum - num, a,m)==true)
{
// m[targetSum] = true;
m.insert(pair<int, bool>(targetSum, true));
return m[targetSum];
}
}
m[targetSum] = false;
return m[targetSum];
}
int main(){
int targetSum, t;
vector<int> a;
map<int, bool> m;
m[0] = true;
cout << "enter target" << endl;
cin >> targetSum;
cout << "enter array, press esc to stop entering"<<endl;
while(cin>>t){
a.push_back(t);
}
for (int j = 0; j < a.size(); j++)
{
cout << a[j]<<" ";
}
cout << endl;
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
return 0;
}
Please help me. Thank you.

The for loop to print the map should be after the function call like.
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
Instead of
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
To see mutations in the map due to the function

Related

Rcpp: Calculation in loop stops with error "Not a matrix"

in an R script I source a cpp file to make some calculations. In that R script, a function defined in the cpp file is called and a matrix and an integer is provided. After a few rounds through the loop it gives the error "Not a matrix" (in line of code resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i));), even though for the rounds before it worked.
R script:
## all together
# rm(list=ls())
library(RcppArmadillo)
library(Rcpp)
sourceCpp("~/test.cpp",verbose = FALSE)
cat("start loop")
for(n in c(45:46)){
cat("\n", n, "\n")
p_m <- matrix(data=rnorm(n^2,1,1),nrow = n, ncol=n)
print(class(p_m))
print(some_function(p_m,nosamples=10))
}
cat("finished")
I start this R script via the command line. R version R-4.1.0. In R-Studio it crashes with a fatal error.
The cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector some_function(NumericMatrix x,int nosamples) {
int ncol = x.ncol();
NumericVector out2(nosamples);
int loops;
int loops2;
double result=0;
NumericVector::iterator it;
double acc = 0;
NumericVector resid(ncol);
NumericVector out(ncol*(ncol-1)/2);
loops2=0;
std::cout << nosamples << std::endl;
std::cout << (ncol-1) << std::endl;
std::cout << ncol*(ncol-1)/2 << std::endl;
while(loops2 < (nosamples)){
std::cout << "loops2:" << std::endl;
std::cout << loops2 << std::endl;
loops=0;
int i;
int j;
for(j=0;j<(ncol-1);++j){
std::cout << " j: " << j << std::endl;
for (i = (j+1); i < (ncol); ++i) {
std::cout << " i: " << i << std::endl;
resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i)); //here it stops
std::cout << " i: " << i << std::endl;
for(int ii=0; ii<ncol;++ii){
acc += resid[i];
}
result=sqrt(acc);
loops += 1;
out[loops] = result;
std::cout << " i: " << i << std::endl;
}
}
std::cout << "loops:" << std::endl;
std::cout << loops << std::endl;
out = out[out > 0];
it = std::min_element(out.begin(), out.end());
out= *it;
std::cout << out << std::endl;
loops2 += 1;
out2[loops2]=out[0];
}
std::cout << "cpp finished" << std::endl;
return(out2);
}
Can someone explain what the problem is about?
Thanks and kind regards
Edit
I adapted some things in the cpp file (shown below) and the error disappeared. First I thought, everything is fine. But when I increase the number of loops, another problem occurs: the function breaks, but no error is shown. It breaks after loop number 543 ("loop2: 543"). At least it does the same in each round of the while loop with the same data.
I adapted the R-script and the ccp file to make this problem (at least on my machine) reproducible.
I know this code seems to be somehow meaningless, but it is part of a bigger program and I wanted to give here a minimum example.
The R script:
## all together
# rm(list=ls())
library(RcppArmadillo)
library(Rcpp)
sourceCpp("~/test.cpp",verbose = FALSE)
cat("start loop")
for(n in c(100:101)){
cat("\n", n, "\n")
p_m <- matrix(data=rnorm(n^2,1,1),nrow = n, ncol=n)
print(class(p_m))
print(some_function(p_m,nosamples=800))
}
cat("finished")
The cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
#include <RcppArmadillo.h>
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::Map;
using Eigen::VectorXd;
typedef Map<VectorXd> MapVecd;
// [[Rcpp::export]]
NumericVector some_function(NumericMatrix x,int nosamples) {
int ncol = x.ncol();
NumericVector out(ncol*(ncol-1)/2);
NumericVector out2(nosamples);
NumericVector out3(ncol*(ncol-1)/2);
NumericVector resid(ncol);
int loops;
int loops2;
double result=0;
double acc = 0;
int show_cout=0;
loops2=0;
std::cout << nosamples << std::endl;
std::cout << (ncol-1) << std::endl;
std::cout << ncol*(ncol-1)/2 << std::endl;
while(loops2 < (nosamples)){
std::cout << "loops2:" << loops2 << std::endl;
loops=0;
int i;
int j;
for(j=0;j<(ncol-1);++j){
// std::cout << " j: " << j << std::endl;
for (i = (j+1); i < (ncol); ++i) {
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i));
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
for(int ii=0; ii<ncol;++ii){
acc += resid[ii];
}
result=sqrt(acc);
loops += 1;
out[loops] = result;
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
}
}
// std::cout << "loops:" << loops << std::endl;
//
out = out[out > 0];
const MapVecd xy(as<MapVecd>(out));
out3=xy.minCoeff();
out2[loops2]=out3[0];
loops2 += 1;
}
std::cout << "cpp finished" << std::endl;
return(out2);
}
Two things here:
Use out[loops++] = result; instead of loops += 1; out[loops] = result; because you were starting at 1, and probably accessing the last element outside of the range of this vector.
Use
for(int ii=0; ii<ncol;++ii){ double eps = x(ii, j) - x(ii, i); acc += eps * eps; }
instead of relying on this resid vector.

Need help figuriing out correct syntax to update objects in global scope

I have this code:
int do_transact(ifstream & inFile, list<shared_ptr<Bike>> bikelist, status s)
{
int id, i = 0, size = bikelist.size();
float days;
string str, str2;
char name[50];
list<shared_ptr<Bike>>::iterator it = bikelist.begin();
if (s == NO_STATUS) //performs rental
{
inFile >> id;
inFile >> days;
inFile >> str;
inFile >> str2;
strcpy_s(name, str.c_str());
while (i < size)
{
if (id == (*it)->id_num) // rents bike
{
cout << "vvvvvv PERFORMING RENTAL vvvvvv" << endl << endl;
cout << "The price of this rental will be: $" << (days)*((*it)->cost_per_day) << endl;
strcpy_s((*it)->to_whom, name);
(*it)->rented_code = RENTED;
cout << "Thank you for your business!" << endl << endl;
return 0;
}
i++;
it++;
}
}
}
I am trying to change to_whom and rented_code in the original list, but it is not updating.
What is the syntax I need in order to change these values the way I need?

dynamic arrays c++ Access violation writing location

What is wrong with my code ? I have the error like this.
Unhandled exception at 0x00d21673 in mnozenie_macierzy.exe : 0xC0000005: Access violation writing location 0xcdcdcdcd.
It create the first array and the half to the second. The program multiplies arrays.
Sorry for my English if It isn't correct. I hope you understand me.
#include <iostream>
#include <time.h>
using namespace std;
void losowa_tablica(int **tab1, int **tab2, int a, int b, int c, int d)
{
int i, j;
for(i=0; i<a; i++)
{
cout << endl;
for(j=0; j<b; j++)
{
tab1[i][j]=rand();
cout << "tab1[" << i << "][" << j << "] : \t" << tab1[i][j] << "\t";
}
}
cout << endl;
for(i=0; i<c; i++)
{
cout << endl;
for(j=0; j<d; j++)
{
tab2[i][j]=rand();
cout << "tab2[" << i << "][" << j << "] : \t" << tab2[i][j] << "\t";
}
}
cout << endl << endl;
}
int **mnozenie(int **tab1, int **tab2, int a, int b, int c, int d)
{
int g, suma, i, j;
int **mac=new int*[a];
for(int i=0; i<d; i++)
mac[i]=new int[d];
for(i=0; i<a; i++)
for(j=0; j<d; j++)
{
g=b-1, suma=0;
do
{
suma+=tab1[i][g]*tab2[g][j];
g--;
}while(g!=0);
mac[i][j]=suma;
}
return mac;
}
int main()
{
int a,b,c,d;
cout << "Podaj liczbe wierszy pierwszej macierzy: " << endl;
cin >> a;
cout << "Podaj liczbe kolumn pierwszej macierzy: " << endl;
cin >> b;
cout << "Podaj liczbe wierszy drugiej macierzy: " << endl;
cin >> c;
cout << "Podaj liczbe kolumn drugiej macierzy: " << endl;
cin >> d;
int **tab1=new int*[a];
for(int i=0; i<b; i++)
tab1[i]=new int[b];
int **tab2=new int*[c];
for(int i=0; i<d; i++)
tab2[i]=new int[d];
losowa_tablica(tab1, tab2, a, b, c, d);
if ( b==c )
{
cout << "Mnozenie wykonalne" << endl;
int **mno=mnozenie(tab1, tab2, a, b, c, d);
}
else cout << "Mnozenie niewykonalne" << endl;
system("pause");
}
Your code yields undefined behavior:
int **tab1=new int*[a]; // allocating an array of 'a' elements
for(int i=0; i<b; i++) // if b > a then the next line will eventually yield UB
tab1[i]=new int[b];
int **tab2=new int*[c]; // allocating an array of 'c' elements
for(int i=0; i<d; i++) // if d > c then the next line will eventually yield UB
tab2[i]=new int[d];
int **mac=new int*[a]; // allocating an array of 'a' elements
for(int i=0; i<d; i++) // if d > a then the next line will eventually yield UB
mac[i]=new int[d];
In practice, the above code will most likely perform a memory access violation at some point.

Runtime Check Failure #3 - Variable is not initiliazed

I really need some help on this problem. My project is to create a math tutor program with a menu that look like this:
cout << "Select one of the following options" << endl;
cout << "-----------------------------------------" << endl;
cout << "1. [A]dd [+]" << endl;
cout << "2. [S]ubtract [-]" << endl;
cout << "3. [M]ultiply [x]" << endl;
cout << "4. [D]ivide [/]" << endl;
cout << "5. [Q]uit " << endl;
when the user chose add or subtract, the program will generate 2 random numbers and come up with the result. When the user chose multiply or divide, the program will generate the second number again and do the math.
Here is my code
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main()
{ //Introduction to user
cout << "Welcome to Math Tutor. This program is designed to help student" << endl;
cout << "to learn how to do basic math such as addition, subtraction,..." << endl;
cout << endl;
//Declare variables
char choice;
int num1, num2, answer, useranswer, remainder, userremainder;
//Seed 2 random numbers
srand(static_cast<unsigned int>(time(0)));
num1 = rand() % 200 + 800;
num2 = 1 + rand() % 200;
do
{
//Display the menu to user and get user input
cout << "Select one of the following options" << endl;
cout << "-----------------------------------------" << endl;
cout << "1. [A]dd [+]" << endl;
cout << "2. [S]ubtract [-]" << endl;
cout << "3. [M]ultiply [x]" << endl;
cout << "4. [D]ivide [/]" << endl;
cout << "5. [Q]uit " << endl;
cin >> choice;
cout << "Your choice is: " << choice << endl;
//Respond to user's selection
switch (choice)
{
case 'A':
case 'a':
case '1':
case '+':
answer = num1 + num2;
cout << "" << num1 << endl;
cout << "+" << num2 << endl;
cout << "-----" << endl;
cout << "Enter your answer: " << useranswer;
if (answer == useranswer)
{
cout << "Congratulation, Your answer is correct" << endl;
cout << num1;
cout << "+" << num2;
cout << "------" << endl;
cout << answer;
}
else
{
cout << "You answer is not correct" << endl;
cout << "The answer is: " << answer;
}
break;
case 'S':
case 's':
case '2':
case '-':
answer = num1 - num2;
cout << num1;
cout << "-" << num2;
cout << "------" << endl;
cout << "Enter your answer: " << useranswer;
if (answer == useranswer)
{
cout << "Congratulation, Your answer is correct" << endl;
cout << num1;
cout << "-" << num2;
cout << "------" << endl;
cout << answer;
}
else
{
cout << "You answer is not correct" << endl;
cout << "The answer is: " << answer;
}
break;
//Seed the second number again
num2 = 1 + rand() % 10;
case 'M':
case 'm':
case '3':
case 'x':
answer = num1 * num2;
cout << num1;
cout << "x" << num2;
cout << "------" << endl;
cout << "Enter your answer: " << useranswer;
if (answer == useranswer)
{
cout << "Congratulation, Your answer is correct" << endl;
cout << num1;
cout << "x" << num2;
cout << "------" << endl;
cout << answer;
}
else
{
cout << "You answer is not correct" << endl;
cout << "The answer is: " << answer;
}
break;
case 'D':
case 'd':
case '4':
case '/':
answer = (num1 / num2);
cout << " __________" << endl;
cout << num2 << ")" << num1 << endl;
cout << "Enter your answer, both the quotient";
cout << "and the remainder separated by a space: " << endl;
cin >> useranswer >> remainder;
if ((useranswer == answer) && (userremainder = remainder))
{
cout << "Congratulation, Your answer is correct" << endl;
cout << " __________" << endl;
cout << num2 << ")" << num1 << endl;
cout << "The answer is: " << answer << "and the remainder is: " << remainder << endl;
}
else
{
cout << "Sorry. The correct answer is: " << answer << " and the remainder is: " << remainder << endl;
}
case 'Q':
case 'q':
case '5':
cout << "Exiting the program....." << endl;
break;
//Validate user's chocie
default:
{
cout << "Please enter a valid choice" << endl;
cout << "You can enter a number from 1 to 5 or" << endl;
cout << "A letter corresponding to the calculation that you want to do" << endl;
cin >> choice;
cout << "Your choice is: " << choice;
}
}
//Pause the screen
if (choice != 5)
{
cout << endl;
cin.ignore(80, '\n');
cout << "Hit the enter key to continue....\n";
cin.get();
cout << endl;
}
} while (choice != 5);
return 0;
}
your problem is the lines
cout << "Enter your answer: " << useranswer
useranswer is what you wanted the user to input, so change these lines to
cout << "Enter your answer: ";
if(cin >> useranswer) { ... } else { ... } // handle non-integer input too

Why is my program looping infinitely?

My program skips past the option for the user to enter the squareSide and keeps looping.
Code is as follows:
do
{
//Displays menu
cout << "Please select a geometric shape." << endl << endl;
cout << "s:" << setw(10) << "Square" << endl;
cout << "c:" << setw(10) << "Circle" << endl;
cout << "d:" << setw(10) << "Diamond" << endl;
cout << "t:" << setw(10) << "Triangle" << endl;
cout << "e:" << setw(10) << "Exit" << endl << endl;
cin >> letter;
cout << "You selected " << letter << endl;
if (letter != EXIT || letter == EXIT1)
{
if (letter == SQUARE || letter == SQUARE1)
{
int squareSide;
int character;
cout <<"\nPlease enter the ASCII character you would like to use to print your square" << endl;
cin >> character;
cout << "\nPlease enter the length of one side of your square"
<< endl;
cin >> squareSide;
for (int x=0; x < squareSide; x++)
{
for (int y = 0; y < squareSide; y++)
{
cout << character;
}
cout << endl;
}
}
}
} while (letter != EXIT && letter != EXIT1);
return 0;
}
All menu selections have to be char.

Resources