Print common elements in an array intersection - c++

Given two arrays - array arr and array art of size n and m respectively. We have to find intersection of arrays
My solution -
#include<iostream>
#include<climits>
using namespace std;
void inputarray(int arr[],int size){
for(int i=0;i<size;i++){
cin>>arr[i];
}
}
void logic(int arr1[],int size1,int arr2[],int size2){
for(int i=0;i<size1;i++){
int element = arr1[i];
for(int j=0;j<size2;j++){
if(element==arr2[j]){
cout<<element;
arr2[j]=INT_MIN;
break;
}
}
}
}
int main(){
int arr1[100];
int arr2[100];
int size1;
cin>>size1;
int size2;
cin>>size2;
inputarray(arr,size1);
inputarray(arr,size2);
logic(arr1,size1,arr2,size2);
}
But for this abovw solution answer is coming wrong.
Answer Coming is -
6
4
1 2 2 2 3 4
2 2 3 3
2233
Expected Answer is -
6
4
1 2 2 2 3 4
2 2 3 3
223
So please tell where is the problem and how can i solve ?

Errors like this one show how important variable naming is...
In the line:
if(ele==arr[j]){
you are mistaking arr with art...

Related

Generate the lexicographically first permutation(recursive backtracking)

The input is a number n, a number m, and an array of size 3*n, whose elements are either 0s or numbers from 1 to n, where 1<=n,m<=30. I need to make an algorithm to generate the lexicographically first permutation of the set{1,...,n}, where every element appears exactly 3 times, where two equal numbers have a minimum ofm different numbers between them. Only the 0s are to be replaced, while any number that isn't 0 has to stay the same.
For example, for n=5, m=1 and the array 1 0 0 0 0 0 3 0 0 0 0 0 0 4 5 the output should be 1 2 1 2 1 2 3 4 3 5 3 4 5 4 5.
I came up with this code. It doesn't output the lexicographically first permutation. It outputs
1 2 3 4 5 1 3 2 3 4 5 1 2 4 5
#include <array>
#include <iostream>
using namespace std;
int counters[100]={3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
bool verify_permutation(int V[], int n, int m){
array<int,100> POZ;
POZ.fill(m);;
for(int i = 1;i<=3*n;i++){
if(V[i]==0)
return false;
for(int j = 1;j<=3*n;j++){
if(POZ[V[j]]<m)
return false;
POZ[V[j]]=0;
for(int k = 1;k<=n;k++){
POZ[k]++;
}
}
}
return true;
}
int j = 1;
void backtracking(int V[], int x, int m, int n){
if(verify_permutation(V,n,m)){
for(int i = 1;i<=3*n;i++)
cout<<V[i]<<' ';
return;
}
for(int i=1;i<=3*n;i++){
if(counters[j]==0)
continue;
if(V[i]!=0){
counters[V[i]]--;
continue;
}
j++;
if(j>n)
j=1;
if(V[i]==0){
counters[j]--;
V[i]=j;
backtracking(V,j,m,n);
counters[j]++;
}
}
return;
}
int main(){
int V[31];
int n,m;
cin>>n>>m;
if(m>=n){
cout<<-1;
return 0;
}
for(int i = 1; i <= 3*n; i++){
cin >> V[i];
}
backtracking(V, 1, m, n);
}
What is wrong with the code?

wrong output for inf=INT_MAX

Below code is for Bellman Ford algorithm and it gives wrong output when I use const int INF=INT_MAX but correct output when I use const int INF=1e9 in line number 3.
Any idea why?
Code:
#include"bits/stdc++.h"
using namespace std;
const int INF=1e9;
int main()
{
int n,m;
cin>>n>>m;
vector<vector<int>> edges;
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edges.push_back({u,v,w});
}
int src;
cin>>src;
vector<int> dist(n,INF);
dist[src]=0;
for(int iter=0;iter<n-1;iter++)
{
for(auto e:edges)
{
int u=e[0];
int v=e[1];
int w=e[2];
dist[v]=min(dist[v],w+dist[u]);
}
}
for(auto i:dist)
{
cout<<i<<" ";
}
}
Sample Input:
5 8
1 2 3
3 2 5
1 3 2
3 1 1
1 4 2
0 2 4
4 3 -3
0 1 -1
0
Expected Output:
0 -1 2 -2 1
Signed integer overflow here w+dist[u]. The simple fix:
dist[v] = static_cast<int>(min(static_cast<long long>(dist[v]), static_cast<long long>(w) + dist[u]));

multiplication table of 1-4

i tried to write a code that shows the multiplication table of 1-4 but in the first attempt(below) it gave me:
1 2 3 4
2 4 6 8
3 6 9 12
4 0
but then sb told me to write it like this and it worked.
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
**Now my question is what was the problem with the 1st one?????
1st version:
#include <iostream>
using namespace std;
main(){
int x[4][4];
for(int i=1;i<5;i++){
for(int j=1;j<5;j++){
x[i][j]=i*j;
cout<<x[i][j]<<" ";
}
cout<<endl;
}
}
2nd:
#include <iostream>
using namespace std;
main(){
int x[4][4];
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
x[i][j]=(i + 1)*(j + 1);
cout<<x[i][j]<<" ";
}
cout<<endl;
}
}
The difference is the starting index.
Arrays begin at 0 position, so you must initialize your i and j from 0.
Otherwise, you could declare your x matrix as [5][5], and you can use i and j starting from 1.
Cheers!!

Nested for loops recursion

I looked up in many places and tried to understand how to get arbitrary number of nested for loops via recursion. But what I have understood is clearly wrong.
I need to generate coordinates in an n-dimensional space, in a grid-pattern. The actual problem has different coordinates with different ranges, but to get simpler things right first, I have used the same, integer-stepped coordinate ranges in the code below.
#include <iostream>
using namespace std;
void recursion(int n);
int main(){
recursion(3);
return 0;
}
void recursion(int n)
{
if(n!=0){
for(int x=1; x<4; x++){
cout<<x<<" ";
recursion(n-1);
}
}
else cout<<endl;
}
I want, and was expecting the output to be:
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Instead, the output I'm getting is
1 1 1
2
3
2 1
2
3
3 1
2
3
2 1 1
2
3
2 1
2
3
3 1
2
3
3 1 1
2
3
2 1
2
3
3 1
2
3
I just can't figure out whats wrong. Any help to figure out the mistake or even another way to generate coordinates will be greatly appreciated. Thanks!
Non-recursive solution based on add-with-carry:
#include <iostream>
using namespace std;
bool addOne(int* indices, int n, int ceiling) {
for (int i = 0; i < n; ++i) {
if (++indices[i] <= ceiling) {
return true;
}
indices[i] = 1;
}
return false;
}
void printIndices(int* indices, int n) {
for (int i = n-1; i >= 0; --i) {
cout << indices[i] << ' ';
}
cout << '\n';
}
int main() {
int indices[3];
for (int i=0; i < 3; ++i) {
indices[i] = 1;
}
do {
printIndices(indices, 3);
} while (addOne(indices, 3, 3));
return 0;
}
Recursive solution, salvaged from your original code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void recursion(int n, const string& prefix);
int main(){
recursion(3, "");
return 0;
}
void recursion(int n, const string& prefix)
{
if (n!=0) {
for(int x=1; x<4; x++){
ostringstream os;
os << prefix << x << ' ';
recursion(n-1, os.str());
}
}
else cout << prefix << endl;
}
Per Igor's comment, you need an increment function.
Let's use an std::vector to represent each dimension. That is vector[0] is the first dimension, vector[1] is the second dimension and so on.
Using a vector allows us to determine the number of dimensions without any hard coded numbers. The vector.size() will be the number of dimensions.
Here is a function to get you started:
void Increment_Coordinate(std::vector<int>& coordinates,
int max_digit_value,
int min_digit_value)
{
unsigned int digit_index = 0;
bool apply_carry = false;
do
{
apply_carry = false;
coordinates[digit_index]++; // Increment the value in a dimension.
if (coordinates[digit_index] > max_digit_value)
{
// Reset the present dimension value
coordinates[digit_index] = min_digit_value;
// Apply carry to next column by moving to the next dimension.
++digit_index;
apply_carry = true;
}
} while (apply_carry);
return;
}
Edit 1
This is only a foundation. The function needs to be boundary checked.
This function does not support dimensions of varying sizes. That is left as an exercise for reader or OP.

Binary searching a 2D array to find all the indexes of the key

I am trying to binary search a 2D array which will give me the position of every key in the array, my code is
#include <iostream>
#include <vector>
using namespace std;
vector<pair<int,int> > up;
vector<pair<int,int> > down;
void binsearchd(int **A,int row,int low,int high,int key)
{
int mid=(low+high)/2;
if(low==high&&A[row][mid]!=key)//!(A[row][mid]<=key&&A[row][mid-1]<=key&&A[row-1][mid] <=key&&A[row+1][mid]>key&&A[row][mid+1]>key))
return;
if(A[row][mid]==key)//<=key&&A[row][mid-1]<=key&&A[row-1][mid]<=key&&A[row+1][mid]>key&&A[row][mid+1]>key)
{
down.push_back({row,mid});
return;
}
if(A[row][mid]>key)
binsearchd(A,row,low,mid,key);
else if(A[row][mid]<key)
binsearchd(A,row,mid+1,high,key);
else
{
binsearchd(A,row,low,mid,key);
binsearchd(A,row,mid+1,high,key);
}
return;
}
void searchd(int **A,int lowi,int lowj,int highi,int highj,int key)
{
if(lowi==highi)
{
binsearchd(A,lowi,lowj,highj,key);
return;
}
int midi=(lowi+highi)/2,midj=(lowj+highj)/2;
if(A[midi][midj]==key)//<=key&&A[midi][midj-1]<=key&&A[midi-1][midj]<=key&&A[midi+1][midj]>key&&A[midi][midj+1]>key)
down.push_back({midi,midj});
if(A[midi][midj]>key)
{
searchd(A,lowi,lowj,midi,highj,key);
searchd(A,midi+1,lowj,highi,midj,key);
}
else if(A[midi][midj]<key)
{
searchd(A,midi+1,lowj,highi,highj,key);
searchd(A,lowi,midj+1,midi+1,highj,key);
}
else
{
searchd(A,lowi,lowj,midi,highj,key);
searchd(A,midi+1,lowj,highi,highj,key);
binsearchd(A,midi,lowj,highj,key);
}
return;
}
int main()
{
int row,col;
while(cin>>row>>col&&row){
int **A=new int*[row];
for(int i=0;i<row;++i)
{
A[i]=new int[col];
for(int j=0;j<col;++j)
cin>>A[i][j];
}
int query;
cin>>query;
while(query--)
{
int d;
cin>>d;
//searchu(A,1,1,row+1,col+1,u);
searchd(A,0,0,row,col,d);
int max=-999999999;
//for(vector<pair<int,int> >::iterator itr=up.begin();itr!=up.end();++itr)
//{
for(vector<pair<int,int> >::iterator itr2=down.begin();itr2!=down.end();++itr2)
{
cout<<itr2->first<<" "<<itr2->second<<endl;
}
up.resize(0);
down.resize(0);
}
for(int i=0;i<row+1;++i)
delete A[i];
delete A;
}
}
the problem is it gives segmentation fault on array
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
key=4 and also in most of the time, I tried debugging found the reason of seg fault was binary searching a row 4, which is greater than the no. of row.. but I cant find out how that row can appear because my code divides the row in exactly 2 halves each time and thats how it shoudnt be able to cross the boundary.. Any hint??
Though I am not sure what this code is doing, an obvious oversight may be
searchd(A,0,0,row,col,d);
which should be
searchd(A,0,0,row-1,col-1,d);
This is because in the function binsearchd you reference the array cell A[row][mid]. If you pass it the raw row and col numbers it will index cells which are actually outside the array.
With this fix the code works for me, even though I'm not sure of what its output should be. This is an example output with only input 4:
1 1
0 1
0 1
1 1
0 1
2 1
2 1
3 1
2 1
1 1