Intersection of 2 sets - c++

I wrote a function in C++ for finding an intersection and union of 2 sets.
I tried this following function:
intersection function:
bool member (int x[10],int s[10])
{
bool result=false;
for (int i=0; i<10; i++)
for (int j=0 ; j<10;j++)
if (x[i]==s[j])
result=true;
return result;
}
int intersection(int s1[10],int s2[10],int s3[10])
{
for ( int i=0 ; i<10 ; i++)
{
if (member(s1,s2)==true)
s3[i]=s1[i];
}
return 0;
}

You can try union and intersection of two sets of user input size as below :
#include<stdio.h>
#include<malloc.h>
void main()
{
int *a, *b, *c, *d, n1, n2, i, j, k=0, l=0, flag=0;
printf("Enter number of elements in A and B : ");
scanf("%d %d",&n1,&n2);
a = (int *)malloc(sizeof(int)*n1);
b = (int *)malloc(sizeof(int)*n2);
c = (int *)malloc(sizeof(int)*((n1>n2)?n1:n2));
d = (int *)malloc(sizeof(int)*(n1+n2));
printf("\nEnter element in set A : ");
for(i=0;i<n1;i++)
{
printf("\nEnter element : ");
scanf("%d",&a[i]);
}
printf("\nEnter elements in set B : ");
for(i=0;i<n2;i++)
{
printf("\nEnter element : ");
scanf("%d",&b[i]);
}
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
if(a[i]==b[j])
{
c[l++]=a[i];
j=0;
break;
}
}
}
for(i=0;i<n2;i++)
d[k++]=a[i];
for(i=0;i<n1;i++)
{
flag=0;
for(j=0;j<n2;j++)
{
if(b[i]==a[j])
{
flag=1;
break;
}
}
if(!flag)
d[k++]=b[i];
}
printf("\n\t A = {");
for(i=0;i<n1;i++)
{
printf("%d",a[i]);
}
printf("}");
printf("\n\t B = {");
for(i=0;i<n2;i++)
{
printf("%d",b[i]);
}
printf("}");
printf("\n\t A U B = {");
for(i=0;i<k;i++)
{
printf("%d",d[i]);
}
printf("}");
printf("\n\t A n B = {");
for(i=0;i<l;i++)
{
printf("%d",c[i]);
}
printf("}");
}

You're copying s1 in s3, one item at a time, if member(s1, s2) return true, that is if it's an intersection between s1 and s2
You should rewrite in this way (caution: not tested)
bool member (int x, int s[10])
{
bool result=false;
for (int j=0 ; (! result) && (j<10);j++)
if (x==s[j])
result=true;
return result;
}
int intersection(int s1[10],int s2[10],int s3[10])
{
int j = -1;
for ( int i=0 ; i<10 ; i++)
{
if (member(s1[i],s2)==true)
s3[++j]=s1[i];
}
// what about other places of s3?
return 0;
}

Related

passing a double pointer boolean array to a function

I have a double pointer boolean.
I would like to pass this boolean to a function
The code is used for graph theory, to create an adj matrix, check if the graph has cycles or not ...
The problem comes from the cycle function
The function doesn't like the boolean in parameter to check if a graph has a cycle.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
int Cycle(int number_of_vertices ,bool **adj_matrix)
{
bool** adj = new bool*[number_of_vertices];
for(int i=0;i<number_of_vertices;i++)
{
adj[i] = new bool[number_of_vertices];
}
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
adj[i][j] = adj_matrix[i+1][j+1];
}
}
for(int k=0;k<number_of_vertices;k++)
{ // transitiv closure
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
if(adj[i][k]&&adj[k][j])
{
adj[i][j] = true;
}
}
}
}
int count = 0;
for(int i=0;i<number_of_vertices;i++)
{
if(adj[i][i])
{
count++;
}
}
return count;
}
int main()
{
string first_line, second_line;
int initial_extremity, final_extremity, value, number_of_vertices, nombre_arcs;
ifstream fichier("test.txt");
bool** adj_matrix;
int** val_matrix;
vector<int> vertice_names;
if (fichier.is_open())
{
getline(fichier, first_line);
number_of_vertices = atoi(first_line.c_str());
getline(fichier, second_line);
nombre_arcs = atoi(second_line.c_str());
adj_matrix = new bool*[number_of_vertices];
val_matrix = new int*[number_of_vertices];
for (int i=0; i<number_of_vertices;i++)
{
adj_matrix[i] = new bool[number_of_vertices];
val_matrix[i] = new int[number_of_vertices];
for (int j=0; j<number_of_vertices; j++)
{
adj_matrix[i][j] = false;
val_matrix[i][j] = 0;
}
}
while(fichier >> initial_extremity >> final_extremity >> value)
{
adj_matrix[initial_extremity][final_extremity] = true;
val_matrix[initial_extremity][final_extremity] = value;
int c = Cycle(number_of_vertices, adj_matrix);
printf("number of cycles: %d\n\n", c);
if(c!=0)
{
printf("%d --[%d]--> %d\n",initial_extremity,value,final_extremity);
}
else
{
printf("%d --[%d]--> %d\n",initial_extremity,value,final_extremity);
}
if ( find(vertice_names.begin(), vertice_names.end(), initial_extremity) != vertice_names.end() )
{
//nothing
}
else
{
vertice_names.push_back(initial_extremity);
}
if ( find(vertice_names.begin(), vertice_names.end(), final_extremity) != vertice_names.end() )
{
//nothing
}
else
{
vertice_names.push_back(final_extremity);
}
}
fichier.close();
}
else
{
cout << "error while opening the file" << '\n';
cin.get();
}
printf("%d arcs\n",nombre_arcs);
printf("%d vertices\n\n\n",number_of_vertices);
printf("Adj Matrix \n");
printf(" ");
for(int i = 0; i<number_of_vertices; i++)
{
printf("%3d",vertice_names.at(i));
}
printf("\n");
for (int i = 0; i<number_of_vertices; i++)
{
printf("%3d ", vertice_names.at(i));
for (int j = 0; j <number_of_vertices; j++)
{
printf("%3d",adj_matrix[i][j]);
}
printf("\n");
}
printf("\n\n");
sort(vertice_names.begin(), vertice_names.end(), less<int>());
printf("Adj and value matrix\n");
printf(" ");
for(int i = 0; i<number_of_vertices; i++)
{
printf("%3d",vertice_names.at(i));
}
printf("\n");
for (int i = 0; i<number_of_vertices; i++)
{
printf("%3d ", vertice_names.at(i));
for (int j = 0; j <number_of_vertices; j++)
{
if (adj_matrix[i][j])
{
printf("%3d",val_matrix[i][j]);
}
else
{
printf(" ");
}
}
printf("\n");
}
return 0;
}
format of the .txt file:
first line : number of vertices
second : number of arcs
the other lines : Inital Arc Final Arc Value
3
4
0 1 0
1 0 12
1 2 25
2 0 6
By the way, if someone have a better idea to check if a graph has a cycle let me know
Best regards
Looks to me like you are stepping out of bounds in the Cycle function:
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
adj[i][j] = adj_matrix[i+1][j+1]; // i + 1 and j + 1 go out of bounds
}
}
Suppose number_of_vertices is 3. Then the index of the last element is 2. When i = 2, then i + 1 = 3. Out of bounds.

Sorting, how should I cout the round and pass?

Our professor told us to make our program cout the round and pass of the sorting algorithm.. What should I do then?
https://qph.is.quoracdn.net/main-qimg-21f7faf7e69c3317661f5f959008e031?convert_to_webp=true
Like this one ^
Bubble sort code
#include <stdio.h>
int main()
{
int array[100], n, c, d, swap;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (array[d] > array[d+1]) /* For decreasing order use < */
{
swap = array[d];
array[d] = array[d+1];
array[d+1] = swap;
}
}
}
printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%d\n", array[c]);
return 0;
}
Is this right??? --->
#include<stdio.h>
int main()
{
int a[100],c[100],b,n,i,temp;
printf("\t\t\tBUBBLE SORT\n");
printf("Enter total numbers : ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter %d number : ",i+1);
scanf("%d",&a[i]);
c[i]=a[i];
}
printf("\n");
for(i=0;i<n;i++)
{
for(int j=0;j<n-1;j++)
{
b=0;
if(a[j]<a[j+1])
{ b++;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
if(b!=0)
{
for(int k=0;k<n;k++)
{
printf("%d ",a[k]);
}
printf("\n");
}
}
}
printf("\nAssending order By Bubble sort\n\t");
for(i=0;i<n;i++)
{
printf("%d ",c[i]);
}
return 0;
}
This is just simple step by step bubble sort problem.
just make two functions as bubble_asc(), bubble_desc()
and call it from the main function().
int main() {
...
bubble_asc();
bubble_desc();
...
}
void bubble_asc() {
...
do step by step bubble sort with ascending order here.
for(~~~~~) {
for(~~~~~~) {
if(array[a] < array[b])
....
}
}
print arrays here..
}
void bubble_desc() {
...
do step by step bubble sort with descending order here.
for(~~~~~) {
for(~~~~~~) {
if(array[a] > array[b])
....
}
}
print arrays here..
}

C++: Fast algorithm for finding minimum sum of cycle edges

I have an undirected weighted graph and want to find the minimum sum of all cycles edges.
That means if I have no cycle, the answer is 0.
If I have one cycle the answer is the minimum edge weight of that cycle.
And if I have more than one cycle it's the sum of those minimum weights.
My algorithm I implemented, uses some kind of Prims algorithm.
I just add the heaviest edges and when a cycle would be formed the weight is summed to the answer value instead.
I thought it is correct as all my test cases show the right answer.
But somewhere has to be an error, I just couldn't find it yet.
struct connection {
int a, b, cost;
bool operator<(const connection rhs) const {
return cost < rhs.cost || (cost == rhs.cost && (a < rhs.a || (a == rhs.a && b < rhs.b)));
}
};
int n, m, researchers; // Amount of vertices, edges
std::list<connection> *adj; // Array of adjancency lists
std::list<int> *used;
std::set<connection> priorityQ;
void addEdge(int v, int w, int cost) {
connection temp;
temp.a = v;
temp.b = w;
temp.cost = cost;
adj[v].push_back(temp);
temp.a = w;
temp.b = v;
adj[w].push_back(temp);
}
bool isUsed(int u, int v) {
for (std::list<int>::iterator it = used[u].begin(); it != used[u].end(); ++it) {
int te = *it;
if (te == v) return true;
}
return false;
}
void expand(int u) {
for (std::list<connection>::iterator it = adj[u].begin(); it != adj[u].end(); ++it) {
connection v = *it;
if (isUsed(u, v.b)) continue;
used[v.b].push_back(u);
used[u].push_back(v.b);
priorityQ.insert(v);
}
}
void PrimR(int u, bool added[]) {
added[u] = true;
expand(u);
}
// Prim algorithm
void Prim(int u, bool added[]) {
added[u] = true;
expand(u);
while (priorityQ.size() > 0) {
connection now = *priorityQ.rbegin();
priorityQ.erase(*priorityQ.rbegin());
if (added[now.b]) {
researchers += now.cost;
}
else {
PrimR(now.b, added);
}
}
}
int main()
{
int t;
// loop over all test cases
scanf("%d ", &t);
for (int i = 1; i <= t; i++) {
// read input nodes n, connections m
scanf("%d %d", &n, &m);
adj = new std::list<connection>[n];
//read connections and save them
for (int j = 0; j < m; j++) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
addEdge(a - 1, b - 1, c);
}
researchers = 0;
// Use of prim with heaviest edges first
bool *added = new bool[n];
used = new std::list<int>[n];
for (int j = 0; j < n; j++) {
added[j] = false;
}
for (int j = 0; j < n; j++) {
if (!added[j]) {
Prim(j, added);
}
}
// print desired output
printf("Case #%d: %d\n", i, researchers);
delete[] adj;
delete[] added;
delete[] used;
}
return 0;
}
Do you know what I'm doing wrong?
I didn't consider, that between two nodes there could be multiple connections.
My following code solves this:
struct connection {
int a, b, cost, id;
bool operator<(const connection rhs) const {
return cost < rhs.cost || (cost == rhs.cost && id < rhs.id);
}
};
int n, m, researchers; // Amount of vertices, edges
std::list<connection> *adj; // Array of adjancency lists
std::set<connection> priorityQ;
void addEdge(int v, int w, int cost, int id) {
connection temp;
temp.a = v;
temp.b = w;
temp.cost = cost;
temp.id = id;
adj[v].push_back(temp);
temp.a = w;
temp.b = v;
adj[w].push_back(temp);
}
void deleteEdge(int v, int w, int id) {
for (std::list<connection>::iterator it = adj[v].begin(); it != adj[v].end(); ++it) {
if ((*it).id == id) {
adj[v].erase(it);
break;
}
}
for (std::list<connection>::iterator it = adj[w].begin(); it != adj[w].end(); ++it) {
if ((*it).id == id) {
adj[w].erase(it);
break;
}
}
}
void expand(int u) {
for (std::list<connection>::iterator it = adj[u].begin(); it != adj[u].end(); ++it) {
connection v;
v.a = (*it).a < (*it).b ? (*it).a : (*it).b;
v.b = (*it).a < (*it).b ? (*it).b : (*it).a;
v.cost = (*it).cost;
v.id = (*it).id;
priorityQ.insert(v);
}
}
void PrimR(int u, bool added[]) {
added[u] = true;
expand(u);
}
// Prim algorithm
void Prim(int u, bool added[]) {
added[u] = true;
expand(u);
while (priorityQ.size() > 0) {
connection now = *priorityQ.rbegin();
priorityQ.erase(*priorityQ.rbegin());
deleteEdge(now.a, now.b, now.id);
if (added[now.b] && added[now.a]) {
researchers += now.cost;
}
else if (added[now.b]) {
PrimR(now.a, added);
}
else if (added[now.a]) {
PrimR(now.b, added);
}
}
}
int main()
{
int t;
// loop over all test cases
scanf("%d ", &t);
for (int i = 1; i <= t; i++) {
// read input nodes n, connections m
scanf("%d %d", &n, &m);
adj = new std::list<connection>[n];
//read connections and save them
for (int j = 0; j < m; j++) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
addEdge(a - 1, b - 1, c, j);
}
researchers = 0;
// Use of prim with heaviest edges first
bool *added = new bool[n];
for (int j = 0; j < n; j++) {
added[j] = false;
}
for (int j = 0; j < n; j++) {
if (!added[j]) {
Prim(j, added);
}
}
// print desired output
printf("Case #%d: %d\n", i, researchers);
delete[] adj;
delete[] added;
}
return 0;
}
You can use Floyd-Warshall algorithm.
The Floyd-Warshall algorithm finds shortest path between all pairs of vertices.
And this shortest path to (u,u) -> (u,u) is the answer you're finding after considering every possible vertex u.
The algorithm run time is O(n^3).

Merge sort for an array of strings in c++

I have a vector of strings named "values". I want to merge sort them but I kept getting bus error or segmentation error. I know the errors are from the merge_sort function but I don't know how to fix it. Any ideas?
int main()
{
int p=1,q=values.size()/2,r=values.size();
merge_sort(values,p,r);
for (unsigned int i = 0; i < values.size(); i++)
{
cout << values[i] << endl;
}
}
}
void merge_sort(vector<string> a,int p,int r)
{
int q;
if(p<r)
{
q=r/2;
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}
void merge(vector<string> a,int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
string L[n1+1];
string R[n2+1];
for(int i=0;i<n1;i++)
{
L[i]=a[p+i-1];
}
for(int j=0;j<n2;j++)
{
R[j]=a[q+j];
}
L[n1]="ZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
R[n2]="ZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
int i=0, j=0;
for(int k=0;k<r;k++)
{
if(L[i]<=R[j])
{
a[k]=L[i];
i++;
}
else
{
a[k]=R[j];
j++;
}
}
}

Find all possible arrays of size n constructed with all possible combinations of elements from another array in all possible orders?

For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.