Usage of multidimensional vectors - c++

I was trying to use multidimensional vector and change the values of row and column.
#include<iostream>
#include<vector>
using namespace std;
void changerow(vector<vector<int> > A, int row, int M, int P){
for(int j = 0; j < M; j++){
(A[row - 1])[j] = ((A[row - 1])[j] + P) % 10;
}
}
void changecolumn(vector<vector<int> > A, int column, int N, int P){
for(int i = 0; i < N; i++){
(A[i])[column - 1] = ((A[i])[column - 1] + P) % 10;
}
}
int main(int argc, char* argv[])
{
int T, N, M;
cin >> T >> N >> M;
if((T >= 1 && T <= 10) && (M >= 1 && M <= 100) && (N >= 1 && N <= 100)){
// Logic of the program
vector<vector<int> > A(N, vector<int>(M));
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cin >> (A[i])[j];
}
}
changerow(A,2,M,3);
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cout << A[i][j];
}
}
}
return 0;
}
I don't know how would pass the address of the vector in order to change the element, since only the local copy of the vector gets passed. I am currently reading Thinking in C++ Volume 1 but its not elaborate. Kindly let me know a good source for learning the use of vectors in C++.

Currently, you are passing the vector by value, which means that the callee gets a copy of the vector.
If you wish the changes that the callee makes to be visible to the caller, you need to pass the vector by reference. This is done like so:
void changecolumn(vector<vector<int> >& A, int column, int N, int P){
^ THIS
For a discussion, see Pass by Reference / Value in C++

Related

Replacing defined constant by an integer value in function with matrices

I would like to modify the N-Queens backtracking algorithm by getting the size of the board (N) from the standard input instead of defining N as a constant.
However, I can't match the types at the functions. Should I define some kind of global maximum constant and then work with n?
Here's the code:
#include <iostream>
using namespace std;
bool safe(int N, char mat[][N], int v, int k)
{
int i, j;
for (i = 0; i < v; i++)
if (mat[i][k] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j >= 0; i--, j--)
if (mat[i][j] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j < N; i--, j++)
if (mat[i][j] == 'Q')
return false;
return true;
}
void backtrack(int N, char mat[][N], int v)
{
if (v == N)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << mat[i][j] << " ";
cout << endl;
}
cout << endl;
return;
}
for (int i = 0; i < N; i++)
{
if (safe(N, mat, v, i))
{
mat[v][i] = 'Q';
backtrack(N, mat, v + 1);
mat[v][i] = '-';
}
}
}
int main()
{
int N;
cin >> N;
char mat[N][N];
memset(mat, '-', sizeof mat);
backtrack(N,mat, 0);
return 0;
}
char mat[N][N]; is a Variable Length Array (VLA) which is a non standard extension of some c++ compilers that you should avoid using. If you need run-time allocated memory, consider using a std::vector:
int N{};
std::cin >> N;
std::vector<std::vector<char>> mat(N, std::vector<char>(N, '-'));
will do what you want. You can then pass this to any function using:
void foo(const std::vector<std::vector<char>>& mat); // for read-only
void foo(std::vector<std::vector<char>>& mat); // for read-write
Note: this is potentially less effeccient depending on how memory is allocated. If you need your memory to line up all together, use a 1D vector and access function to get index for you.

Floating Point Error With This Code Can someone help me

i am facing problem with this chinese remainder theoram
i am taking an input.txt file as input
and trying to generate an output.txt file but it says floating point error. when i am running with some specific input at that time it is working but for many test cases it is not working
#include <bits/stdc++.h>
#include <fstream>
#include <iostream>
using namespace std;
int ModInverse(int a, int m)
{
a = a % m;
for(int x = 1; x < m; x++)
if(((a * x) % m) == 1) return x;
}
int findMinX(int num[], int rem[], int k) {
int prod = 1;
for(int i = 1; i <= k; i++) prod *= num[i];
int result = 0;
for(int j = 1; j <= k; j++) {
int y = prod / num[j];
result = result + rem[j] * ModInverse(y, num[j]) * y;
}
return result % prod;
}
int main() {
ifstream infile;
infile.open("input.txt");
int n;
int num[100];
int rem[100];
infile >> n;
for(int i = 0; i < n; i++) infile >> num[i];
for(int i = 0; i < n; i++) infile >> rem[i];
infile.close();
int k = sizeof(num) / sizeof(num[0]);
ofstream myfile;
myfile.open("output.txt");
myfile << findMinX(num, rem, k);
myfile.close();
return 0;
}
These lines:
for(int i = 1; i <= k; i++)
for(int j = 1; j <= k; j++)
will cause i and j to go out of bounds.
Array indexing starts at 0 in C++, so you should use indexes 0 to k-1.
Do this instead:
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++)
Another thing worth checking up is this function:
int ModInverse(int a, int m)
{
a = a % m;
for(int x = 1; x < m; x++)
if(((a * x) % m) == 1) return x;
}
Given the wrong input, it'll exit the loop and return nothing, which causes undefined behaviour. Validate the input and print an error message if the file contains data you can't handle.
Here's an example of an input.txt that makes it crash for me:
5
1 2 3 4 5
2 3 4 5 6
Another cause for concern is that you use k instead of n in your call to the function:
myfile << findMinX(num, rem, k);
This means the function will always work on 100 values. Some of them may be uninitialized, and again, undefined behaviour.

Dynamic Arrays and user input c++

I'm writing a program for my C++ class that takes the user input for the size of a int and char array, fills the arrays with random values (numbers 0-100, letters A-Z) then sorts, reverses, and displays both arrays.
For the most part the program works and I understand the logic I used here, but...
After running and debugging the code multiple times. I noticed that when the arrays were being filled with values, the first element, even though it was actually being given a value, it would not print the assigned value it was given in ascending order, but would in a descending order? I don't understand this at all.
NOTE: I have to use template functions for the sorting, reversing and display of the arrays.
template <class T>
void sort(T *arr, int a) {
T temp;
for (int i = 0; i < a; i++) {
for (int j = a; j > 0; j--) {
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
template <class T>
void reverse(T *arr, int a) {
T temp;
for (int i = 0; i < a / 2; i++) {
temp = arr[i];
arr[i] = arr[a - i];
arr[a - i] = temp;
}
}
template <class T>
void display(T *arr, int a) {
for (int i = 0; i < a; i++) {
cout << arr[i] << ", ";
}
cout << endl;
}
template<class T>
void save(T *arr, int a) {
sort(arr, a);
display(arr, a);
reverse(arr, a);
display(arr, a);
}
int main() {
int x, y;
cout << "Please enter a number for an array of data type \"int\"" << endl;
cin >> x;
cout << "Please enter a number for an array of data type \"char\"" << endl;
cin >> y;
int *arr1 = new int[x];
char *arr2 = new char[y];
for (int i = 0; i < x; i++)
cout << (arr1[i] = rand() % 100 + 1);
srand(time(nullptr));
for (int i = 0; i < y; i++)
cout << (arr2[i] = rand() % 26 + 65);
system("cls");
save(arr1, x);
save(arr2, y);
delete[]arr1;
delete[]arr2;
system("pause");
return 0;
}
You are using the complete length here:
save(arr1, x);
save(arr2, y);
So in reverse
arr[i] = arr[a - i];
arr[a - i] = temp;
you need to -1 on the length or you'll get an invalid index when i == 0
arr[i] = arr[a - 1 - i];
arr[a - 1 - i] = temp;
Like R Sahu says, in sort
for (int j = a; j > 0; j--) {
you need to -1 because a is the length which will be an invalid index.
for (int j = a-1; j > 0; j--) {
As a side note, you can declare Temp t inside of the for loop in reverse and inside of the if in sort because it is only used in those scopes.
EDIT:
Also I overlooked, in sort you need to change
j>0
to
j >= 0
that way you access the first element of the array as well.
You have a off-be-one error in couple of places.
for (int j = a; j > 0; j--) {
is incorrect. a is an invalid index for the array. Change that line to use j = a-1:
for (int j = a-1; j > 0; j--) {
You have a similar, off-by-one, error in reverse. Instead of
arr[i] = arr[a - i];
arr[a - i] = temp;
you need to use:
arr[i] = arr[a - i - 1];
arr[a - i - 1] = temp;
Your implementation of sort is not correct. I don't want to get into the algorithmic details here but changing the order of the values used for j seems to fix the problem.
for (int i = 0; i < a; i++) {
for (int j = i+1 ; j < a ; j++) {
// The swapping code.
}
}
You are using bubble sort that is O(n^2) time complexity. Consider using faster algorithm. If you don't want to implement it on your own, use sort() function. It's complexity is about O(n log n), which is very good.
http://www.cplusplus.com/reference/algorithm/sort/
#include <iostream>
#include <algorithm>
using namespace std;
bool comp(int i1, int i2) { // comp function is to compare two integers
return i1 < i2;
}
int main() {
int x[30];
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x[i];
}
sort(x, x + n, comp); // if you don't provide comp function ( sort(x, x+n) ), sort() function will use '<' operator
for (int i = 0; i < n; i++) {
cout << x[i] << " ";
}
return 0;
}

Program seems to skip 'if' statement

I'm attempting to create a program that will multiply 3 not equal values from vector 1 ('V1'), and write in vector 2 ('V2'). I'm using 3 'for' loops and an integer that counts vector 2's value's number. But program skips the 'if' statement.
#include <vector>
#include<fstream>
#include<iostream>
#include <algorithm>
using namespace std;
void earase(vector<int> V2, unsigned int z){
V2.erase(V2.begin() + z);
}
void main(){
unsigned int N;
unsigned int z = 0;
vector<int> V1;
vector<int> V2;
int input;
ifstream file1;
file1.open("input.txt");
file1 >> N;
for (unsigned int i = 0; i < N; i++){
file1 >> input;
V1.push_back(input);
}
file1.close();
for (unsigned int i = 0; i < V1.size(); i++){
for (unsigned int j = 0; j < V1.size(); j++){
for (unsigned int k = 0; k < V1.size(); k++){
V2.push_back(V1[i] * V1[j] * V1[k]);
if (i == j || i == k || j == k || (i == k ) && k==j)
{
void earase(vector<int> V2, unsigned int z);
}
z++;
}
}
}
sort(V2.begin(), V2.end());
ofstream file2;
file2.open("output.txt");
file2 << V2.back();
file2.close();
}
Here is the input.txt file
4
1 2 3 4
After finishing the program sorts the vector 2 and writes the last number in vector 2 in 'output.txt' but it writes values that will come only if multiply the same value from vector 1, 3 times.
I think the problem is in 'if' statement, and 'z' integer, is there any more efficient way to do this?
Non equal positions is trivial, no test required (assuming you want each combination only once):
for (unsigned int i = 0; i < V1.size(); i++){
for (unsigned int j = 0; j < i; j++){
for (unsigned int k = 0; k < j; k++){
V2.push_back(V1[i] * V1[j] * V1[k]); } } }
If for some reason, you wanted all each combination multiple times (as if you had gone through all N cubed possibilities skipping only duplicate positions) just go through the above simple way and push each multiple times.
The body of your if is actually something quite different than you expect:
if (i == j || i == k || j == k || (i == k ) && k==j)
{
void earase(vector<int> V2, unsigned int z); // <<<<<<<
}
You're not calling earase. Instead, you're declaring a function called earase. If you want to call the function, call it:
if (i == j || i == k || j == k || (i == k ) && k==j)
{
earase(V2, z);
}
By the way you could have easily checked that with some debugging output (like std::cout << "if entered"; after/before earase). However, keep in mind that this won't actually change V2.

How can I properly add and access items to a multidimensional vector using loops?

I have this program that is trying to determine how many unique items are within some intersecting sets. The amount of input entirely depends on the the first value n, and then the amount of sets entered afterward. For example, if I start with entering n = 2, I am expected to enter 2 integers. The program then determines how many intersections there are between n items (this is like choosing 2 items from n items). This goes on as k increments. But that's kind of beyond the point. Just some background info.
My program adapts correctly and accepts the proper amount of input, but it stops working properly before the first for loop that is outside of the while loop. What I have tried to do is make a vector of integer vectors and then add every other row (when index starts at 0 AND index starts at 1). But I am guessing I have constructed my vectors incorrectly. Does anybody see an error in my vector logic?
#include <iostream>
#include <vector>
using namespace std;
int fact (int m) {
if (m <= 1)
return 1;
return m * fact(m - 1);
}
int comb (int n, int k) {
return fact(n)/(fact(n-k)*fact(k));
}
int main() {
int n = 0;
int k = 2;
int sum = 0;
int diff = 0;
int final = 0;
vector <vector <int> > arr;
cin >> n;
while (n > 0) {
vector <int> row;
int u;
for (int i = 0; i < n ; ++i) {
cin >> u;
row.push_back(u);
}
arr.push_back(row);
n = comb(row.size(), k);
k++;
}
for (int i = 0; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
sum += arr[i][j];
for (int i = 1; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
diff += arr[i][j];
final = sum - diff;
cout << final;
return 0;
}
for (int i = 0; i < arr.size(); i+=2)
^
You want to do i+=2 or i=i+2, else the value of i is never changed, leading to an infinite loop.