Pass array as argument - c++

I have an array:
int *BC_type_vel;
BC_type_vel = new int [nBou+1];
and a function:
void BC_update (const int type[], float X[]) {
for (int i=1; i<=nBou; ++i) {
if (type[i] == 1) {
std::cout << i << " " << type[i] << " " << BC_type_vel[i] << std:: endl;
for (int e=PSiS[i]; e<PSiE[i]; ++e) {
X[e] = X[elm[e].neigh[0]];
}
}
}
}
I call it as:
BC_update(BC_type_vel,U);
It gives output as:
1 1 0
2 1 0
3 1 0
4 1 1
5 1 0
So why the function argument does not copy values properly?

I tried following code with gcc:
int *BC_type_vel;
int nBou = 10;
void BC_update (const int type[]) {
for (int i=1; i<=nBou; ++i) {
if (type[i] == 1)
std::cout << i << " " << type[i] << " " << BC_type_vel[i] << std:: endl;
}
}
int main () {
int i;
BC_type_vel = new int [nBou+1];
for (i=1; i<=nBou; ++i) {
if (i%2 == 0)
BC_type_vel[i] = i;
else
BC_type_vel[i] = 1;
}
BC_update(BC_type_vel);
return 0;
}
and it gives the expected results:
1 1 1
3 1 1
5 1 1
7 1 1
9 1 1
So the problem is somewhere else in your code. You need to provide us with the rest of it.

Related

Can someone help me understanding this recursion code

I am currently having hard time to understand this code because I'm not pro in recursion. So, I wanna someone to explain the logic behind this.
#include <iostream>
using namespace std;
void fun(int n){
if(n==0){
return;
}
for (int i = 0; i < 5; i++) {
cout<<n<<" ";
fun(n-1);
}
}
int main()
{
fun(5);
return 0;
}
Output-
https://ideone.com/ZvLGih
I understood the output up to 5 4 3 2 1 then when the base condition hits then after I'm not able to understand the logic.
Assuming that i < 5 is a typo and should have been i < n, it works exactly like this completely non-recursive program:
void fun0()
{
return;
}
void fun1()
{
for (int i = 0; i < 1; i++) {
cout << 1 << " ";
fun0();
}
}
void fun2()
{
for (int i = 0; i < 2; i++) {
cout << 2 << " ";
fun1();
}
}
void fun3()
{
for (int i = 0; i < 3; i++) {
cout << 3 << " ";
fun2();
}
}
void fun4()
{
for (int i = 0; i < 4; i++) {
cout << 4 << " ";
fun3();
}
}
void fun5()
{
for (int i = 0; i < 5; i++) {
cout << 5 << " ";
fun4();
}
}
int main()
{
fun5();
}
or this program that only has a main:
int main()
{
for (int i = 0; i < 5; i++) {
cout << 5 << " ";
for (int i = 0; i < 4; i++) {
cout << 4 << " ";
for (int i = 0; i < 3; i++) {
cout << 3 << " ";
for (int i = 0; i < 2; i++) {
cout << 2 << " ";
for (int i = 0; i < 1; i++) {
cout << 1 << " ";
}
}
}
}
}
}
Understanding recursion is difficult to do when you get to more than two levels of recursion. It's impossible to keep all of the recursive calls in your mind at one time, so the best way to understand it would be to work through the base cases. Look for patterns between calling fun(1), fun(2), and fun(3).
fun(1):
1 1 1 1 1
fun(2):
2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1
fun(3):
long string of numbers you can view in your compiler
It looks like it just prints a number n, followed by 5 iterations of the number n-1, along with all of the iterations of n-k down to k=n. So for fun(3) it would begin:
3 2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 3

Print 5 line at a time

I got a simple cout statement below. And I want to print 5 lines at a time (the output below). I am new to C++. The 3 dots just a symbol to see the output
int count = 0;
cout << "Print line:" << endl;
for (int i = 0; i < 10; i++){
cout << i << endl;
count++;
if (count > 6){ //if (count % 6 == 0) this is wrong also btw
cout << i << " ..." << endl;
continue;
}
}
The output of the program above is
Print line:
0
1
2
3
4
5
6
6 ...
7
7 ...
8
8 ...
9
9 ...
Expected output
Print line:
0
1
2
3
4
5
Print line
6
7
8
9
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < 10; i++) {
if (i % 5 == 0)
cout << "Print Line\n";
cout << i << endl;
}
}
for (int i = 0; i < 10; i++){
if (i % 6 == 0)
cout << "Print line:" << endl;
cout << i << endl;
}
You need to first check if each loop satisfies the condition i%6==0 or not and then print the number. If the condition is true, then the line will be printed.
Another way to do this to use an extra loop;
for ( int i = 0; i < 20; i += 6 )
{
for ( int n = i; n < i + 6; n++ )
{
if ( n > 20 ) break;
std::cout << n << std::endl;
}
std::cout << "print line" << std::endl;
}

C++ array with random counts

I am stuck somewhere(have some problem with the random number) and I know it, but can't find where to fix...
Two void functions must be used; void randomNumbers(int numbers[][3], int rowSize), void randomCounts(int numbers[][3], int size, int counts[])
I can't put images to show how it should and does look like in .exe files as I just signed up today ...... Hope this works ;(
Expected Result:
//========================
// 7 6 5
// 2 1 1
// 6 7 2
// 9 3 3
// 8 1 1
//========================
//Ran. Number: 0 1 2 3 4 5 6 7 8 9
//Frequency(Counts): 0 4 2 2 0 1 2 2 1 1
What I DID:
//========================
// 0 0 0
// 0 0 0
// 0 0 0
// 0 0 0
// 0 0 0
// ========================
// Ran. Number: 0 1 2 3 4 5 6 7 8 9
// Frequency(Counts): 001A148D
Code:
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
const int COL = 3;
const int SIZE = 5;
void randomNumbers(int inumbers[][3], int rowSize) {
int num = 0;
for (int i = 0; i < 10; i++) {
num = rand() % 10;
}
}
void randomCounts(int inumbers[][3], int size, int counts[]) {
for (int i = 0; i < 10; i++) {
counts[i]++;
cout << setw(5) << counts[i];
}
}
int main(){
int random[SIZE][COL] = {};
srand((unsigned)time(NULL));
cout << endl;
cout << "==================" << endl;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < COL; j++) {
cout << setw(5) << random[i][j];
if (j == COL - 1) {
cout << endl;
}
}
}
cout << "==================" << endl;
cout << endl;
cout << "Ran. Number: " << setw(5) << "0" << setw(5) << "1" << setw(5) << "2" << setw(5) << "3" << setw(5) << "4" << setw(5) << "5" << setw(5) << "6" << setw(5) << "7" << setw(5) << "8" << setw(5) << "9" << endl;
cout << "Frequency(Counts): " << randomCounts << endl;
return 0;
}
Ok, so why are you getting 0, 0, 0.... Because you never actually call your functions. You initialize your array:
int random[SIZE][COL] = {};
Then you print it here:
cout << setw(5) << random[i][j];
And nowhere in between do you set anything into this array. When you do start calling your functions you will find they don't work, due to copying the input and doing some undefined behaviour. When you have debugged this a bit more, ask a new question.

Why is the ILS_best_p not giving me the vector I want?

I would like to store the smallest value of compute_evaluation_function in current_best_eval, and the corresponding vector that gives that smallest value in ILS_best_p, I've succeeded with the current_best_eval, but can't seem to get it for the ILS_best_p even though they're under the same if statement.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <cassert>
#include <ctime>
#include <cmath>
using namespace std;
long int **read_matrix(ifstream &input, long int n);
double ran01(long int *idum);
long int *generate_random_vector(long int n);
unsigned long int compute_evaluation_function(long int n);
void first_2_opt_symmetric (long int n);
void swap(long int pos_1, long int pos_2, long int *);
void perturbation(long int pert_size);
long int *p;//the vector generated from generate_random_vector()
long int **d;//one of the matrices read from file
long int **f;//one of the matrices read from file
long int n;
long int actual_solution_value;
long int new_eval;
long int current_eval;
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
int main()
{
string name;
long int optimum;
ifstream infile;
long int initial_eval;
long int *ILS_best_p;
long int new_vs_current;
new_vs_current = INT_MAX;
long int current_best_eval;
current_best_eval = INT_MAX;
long int new_current_eval;
long int best_eval;
long int improvement;
long int i;
long int j;
infile.open("nug12.dat");
infile >> name;
cout << "Name: " << name << "\n";
infile >> n;
cout << "Rows and Columns: " << n << "\n";
infile >> optimum;
cout << "Optimum solution: " << optimum << "\n";
d=read_matrix(infile, n);
f=read_matrix(infile, n);
cout << endl;
p=generate_random_vector(n);
compute_evaluation_function(n);
cout << endl;
first_2_opt_symmetric (n);
cout << endl;
initial_eval = compute_evaluation_function(n);
cout << endl << endl;
for (i = 0; i < 500; i++) //ILS loop
{
if (new_eval < current_eval)
{
new_vs_current = new_eval;
cout << "iteration 1st = " << i+1 << " " << endl;
}
else if (current_eval < new_eval)
{
new_vs_current = current_eval;
cout << "iteration 2nd = " << i+1 << " " << endl;
}
cout << "iteration = " << i+1 << " " << endl;
cout << " Vector before perturbation = ";
for (j = 0; j < n; j++)
{
cout << p[j] << " ";
}
cout << endl << endl;
cout << endl << "current best eval = " << current_best_eval << endl;
perturbation(3);
cout << endl << endl;
cout << endl << "current best eval = " << current_best_eval << endl;
cout << " Vector after perturbation = ";
for (j = 0; j < n; j++)
{
cout << p[j] << " ";
}
cout << endl << endl;
cout << endl << "current best eval = " << current_best_eval << endl;
first_2_opt_symmetric (n);
new_current_eval = compute_evaluation_function(n);
cout << endl << "current best eval = " << current_best_eval << endl;
cout << endl;
cout << " Vector after local search = ";
for (j = 0; j < n; j++)
{
cout << p[j] << " ";
}
cout << endl << endl;
cout << endl << "current best eval = " << current_best_eval << endl;
cout << " Vector p = ";
for (j = 0; j < n; j++)
{
cout << p[j] << " ";
}
cout << endl << endl;
if (new_current_eval < current_best_eval)
{
new_eval = new_current_eval;
cout << "iteration 3rd = " << i+1 << " " << endl;
}
else if (current_best_eval <= new_current_eval)
{
new_eval = current_best_eval;
cout << "iteration 4th = " << i+1 << " " << endl;
}
if (new_eval < new_vs_current)
{
current_best_eval = new_eval;
cout << "iteration 5th = " << i+1 << " " << endl;
ILS_best_p = p;
}
else if (new_vs_current < new_eval)
{
current_best_eval = new_vs_current;
cout << "iteration 6th = " << i+1 << " " << endl;
ILS_best_p = p;
}
cout << endl << "current best eval = " << current_best_eval << endl;
}
cout << endl << "current best eval = " << current_best_eval << endl;
cout << "ILS best vector = ";
for (i = 0; i < n; i++)
{
cout << ILS_best_p[i] << " ";
}
return 0;
}
long int **read_matrix(ifstream &input, long int n)
{
/*
FUNCTION: read instance matrices
INPUT: instance file name, instance size
OUTPUT: d-matrix and f-matrix
(SIDE)EFFECTS: none
COMMENTS: read the distance matrix and flow matrix
*/
long int i, j;
long int **matrix = new long int *[n];
for (i = 0; i < n; i++)
{
matrix[i] = new long int[n];
for (j = 0; j < n; j++)
{
if( !(input >> matrix[i][j]) )
{
cerr << "Error reading at " << i << j << endl;
exit(1);
}
}
}
return matrix;
}
double ran01(long int *idum)
{
/*
FUNCTION: returns a pseudo-random number
INPUT: a pointer to the seed variable
OUTPUT: a pseudo-random number uniformly distributed in [0,1]
(SIDE)EFFECTS: changes the value of seed
*/
long k;
double ans;
k =(*idum)/IQ;
*idum = IA * (*idum - k * IQ) - IR * k;
if (*idum < 0 )
{
*idum += IM;
}
ans = AM * (*idum);
return ans;
}
long int *generate_random_vector(long int n)
{
/*
FUNCTION: generates a random vector
INPUT: vector dimension
OUTPUT: returns pointer to vector, free memory when vector is not needed anymore
(SIDE)EFFECTS: none
*/
long int i, j, help;
long int *v;
srand(time(0));
long int seed=rand();
v = new long int[ n ];
for ( i = 0 ; i < n; i++ )
{
v[i] = i;
}
for ( i = 0 ; i < n-1 ; i++)
{
j = (long int) ( ran01( &seed ) * (n - i));
assert( i + j < n );
help = v[i];
v[i] = v[i+j];
v[i+j] = help;
}
return v;
}
unsigned long int compute_evaluation_function(long int n)
{
/*
FUNCTION: compute evaluation function
INPUT: pointer to solution
OUTPUT: evaluation function
(SIDE)EFFECTS: none
COMMENTS: none
*/
long int i, j;
unsigned long obj_f_value;
obj_f_value = 0;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
obj_f_value += d[i][j] * f[p[i]][p[j]];
}
}
cout << obj_f_value;
return obj_f_value;
}
void first_2_opt_symmetric (long int n)
{
/*
FUNCTION: first improvement 2-opt local search for symmetric instances
INPUT: pointer to some initial assignment
OUTPUT: none
(SIDE)EFFECTS: initial assignment is locally optimized, dlb is used to increase the search speed, the dlb value is changed to false if item change it's location during perturbation
COMMENT: neighborhood is scanned in random order, use of register for faster computation
*/
long int improvement = 1;
long int improve_item = 0;
long int u, v, i, j, k;
long int tmp;
long int *x;
improvement = 1;
x = generate_random_vector(n);
while (improvement)
{
improvement = 0;
for ( i = 0 ; i < n ; i++ )
{
u = x[i];
improve_item = 0;
for ( j = 0 ; j < n ; j++ )
{
v = x[j];
if (u == v)
continue;
tmp = 0;
for ( k = 0 ; k < n ; k++ )
{
if ( (k != u) && (k != v) )
{
tmp += (d[u][k] - d[v][k]) * (f[p[v]][p[k]] - f[p[u]][p[k]]);
}
}
if (tmp < 0)
{
improvement = 1;
improve_item = 1;
swap (u, v, p);
}
}
}
}
delete []x;
}
void swap(long int pos_1, long int pos_2, long int *p)
{
/*
FUNCTION: swap position of two items in a vector
INPUT: position 1, position 2, pointer to vector
OUTPUT: none
(SIDE)EFFECTS: none
COMMENTS: none
*/
long int tmp;
tmp = p[pos_1];
p[pos_1] = p[pos_2];
p[pos_2] = tmp;
}
void perturbation(long int pert_size)
{
/*
FUNCTION: apply random perturbation
INPUT: pointer to solution, perturbation scheme, perturbation strength, change in perturbation, end perturbation size
OUTPUT: none
(SIDE)EFFECTS: new solution formed from old solution
COMMENTS: none
*/
long int hold_value[n]; //allocate memory for items to be chosen in move/*
int chosen[pert_size]; //*allocate temporary memory to determine items to be moved */*
long int i;
for(i = 0; i < n; i++)
{
hold_value[i] = p[i]; //initialize hold_value with the same value from local search/*
}
int j = n - 1;
int rand_number;
int rand_no;
for(i = 1; i <= pert_size; i++)
{
rand_number = rand();
rand_no = rand_number % j; //choose random number from 1 to size - 1/
chosen[i - 1] = rand_no + i; //copy the value to chosen[i]
j--;
}
long int temp;
for(i = 0; i < pert_size; i++)
{
temp = chosen[i];
swap(i, temp, hold_value); //swap chosen[i] and hold_value[i]; n first item in hold_value[i] is the index array that will be included in perturbation/
}
long int temp1;
long int temp2;
temp1 = p[hold_value[1]];//
temp2 = p[hold_value[0]];
for(i = 0; i < pert_size - 1; i++)
{
p[hold_value[i + 1]] = temp2;
temp2 = temp1;
temp1 = p[hold_value[i + 2]];
}
p[hold_value[0]] = temp2;
actual_solution_value = compute_evaluation_function(n);
new_eval = actual_solution_value;
current_eval = new_eval;
}
This is the file I read from:
Nug12
12
578
0 1 2 3 1 2 3 4 2 3 4 5
1 0 1 2 2 1 2 3 3 2 3 4
2 1 0 1 3 2 1 2 4 3 2 3
3 2 1 0 4 3 2 1 5 4 3 2
1 2 3 4 0 1 2 3 1 2 3 4
2 1 2 3 1 0 1 2 2 1 2 3
3 2 1 2 2 1 0 1 3 2 1 2
4 3 2 1 3 2 1 0 4 3 2 1
2 3 4 5 1 2 3 4 0 1 2 3
3 2 3 4 2 1 2 3 1 0 1 2
4 3 2 3 3 2 1 2 2 1 0 1
5 4 3 2 4 3 2 1 3 2 1 0
0 5 2 4 1 0 0 6 2 1 1 1
5 0 3 0 2 2 2 0 4 5 0 0
2 3 0 0 0 0 0 5 5 2 2 2
4 0 0 0 5 2 2 10 0 0 5 5
1 2 0 5 0 10 0 0 0 5 1 1
0 2 0 2 10 0 5 1 1 5 4 0
0 2 0 2 0 5 0 10 5 2 3 3
6 0 5 10 0 1 10 0 0 0 5 0
2 4 5 0 0 1 5 0 0 0 10 10
1 5 2 0 5 5 2 0 0 0 5 0
1 0 2 5 1 4 3 5 10 5 0 2
1 0 2 5 1 0 3 0 10 0 2 0

Find all triplets in an array that sum to a given value.There are duplicates in the array

This is the code I wrote-
void FindTriplet(int arr[], int size, int x) {
sort(arr,arr+size);
for(int i=0;i<size-2;i++)
{
int l=i+1;
int r=size-1;
while(l<r)
{
int sum=arr[i]+arr[l]+arr[r];
if(sum==x)
{
cout << arr[i] << " " << arr[l] << " " << arr[r] << endl;
l++;
r--;
}
else if(sum<x)
{
l++;
}
else
{
r--;
}
}
}
}
The complexity of O(n^3) is not acceptable.
But this code is failing on cases like-
1 1 1 1 where required sum is 3.
Ans. 1 1 1 repeated 4 times
You have do handle duplicates when you found correct sum:
if (sum==x)
{
// skip and count duplicates
const auto oldL = l;
do {
++l;
} while (l <= r && arr[oldL] == arr[l]);
const auto oldR = r;
do {
--r;
} while (l <= r && arr[oldR] == arr[r]);
// resulting count
const auto count = (arr[oldL] == arr[oldR]
? (l - oldL) * (l - oldL - 1) / 2
: ((l - oldL) * (oldR - r)));
for (int j = 0; j != count; ++j) {
std::cout << arr[i] << " " << arr[oldL] << " " << arr[oldR] << std::endl;
}
}
Demo
You'd better make use of STL classes. I wrote some code for you.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
void findTripletSums(const std::vector<int>& arr, int tripleSum)
{
std::map<int,int> arrMap; // counts the number of times the number is repeated
for(auto a : arr)
{
arrMap[a]++;
}
for(auto itrI = arrMap.begin(); itrI != arrMap.end(); ++itrI)
{
int arrI = itrI->first;
if(arrI*3 == tripleSum && itrI->second >= 3)
{
cout << arrI << " " << arrI << " " << arrI << "; ";
return;
}
auto itrJ = itrI;
for(++itrJ; itrJ != arrMap.end(); ++itrJ)
{
int arrJ = itrJ->first;
int complement = tripleSum-arrI-arrJ;
if(complement < itrJ->first)
{
break;
}
if(complement == arrJ)
{
if(itrJ->second >= 2)
{
cout << arrI << " " << arrJ << " " << arrJ << "; ";
}
break;
}
if(arrMap.find(complement) != arrMap.end())
{
cout << arrI << " " << arrJ << " " << complement << "; ";
}
}
}
}
int main()
{
findTripletSums({0,1,3,3,2,4,6}, 7);
cout << "\n";
findTripletSums({1,2,3,4,5,6}, 7);
cout << "\n";
findTripletSums({0,1,1,1,1,2}, 3);
return 0;
}
It prints:
0 1 6; 0 3 4; 1 2 4; 1 3 3;
1 2 4;
0 1 2; 1 1 1;