intersection of sets in C++ - c++

i am trying to do simple sets intersection , it works correctly , but when output comes , it shows only memory address or garbage random value , help me ,i applied breakpoints , but it's not working . actually i am new in C++
#include<iostream>
using namespace std;
class set
{
private:
int size;
int *elem;
public:
set()
{
size = 0;
elem = NULL;
}
set(int s);
~set();
set(set &s);
set intersection(set A, int z);
void inputset();
void outputset();
};
set::set(int s)
{
size = s;
elem = new int[s];
}
void set::inputset()
{
int i;
cout << "Enter the set Element" << endl;
for(i = 0 ; i < size ; i++)
{
cin >> elem[i];
}
}
set set::intersection(set A, int z)
{
int i, j, k = 0;
set R(z);
for(i = 0; i < size; i++)
{
for(j = 0; j < A.size; j++)
{
if(elem[i] == A.elem[j])
{
R.elem[k] = A.elem[j];
k++;
break;
}
}
}
return R;
}
set::~set()
{
delete []elem;
}
set::set(set &s)
{
int i;
if(size > 0)
{
delete []elem;
}
size = s.size;
elem = new int[size];
for(i = 0; i < size; i++)
{
elem[i] = s.elem[i];
}
}
void set::outputset()
{
int i;
cout << "The elements of new set is : " << endl;
for(i = 0; i < size; i++)
{
cout << elem[i] << endl;
}
cout << endl;
}
int main()
{
int x, y, z;
char choice;
cout << "Enter sizeof set A" << endl;
cin >> x;
set S1(x);
S1.inputset();
S1.outputset();
cout << "Enter sizeof set B" << endl;
cin >> y;
set S2(y);
S2.inputset();
S2.outputset();
z = x + y;
set S3(z);
cout << "Enter I for intersection" << endl << "Enter U for union" << endl << "Enter D for difference" << endl;
cin >> choice;
switch(choice)
{
case'I':
S3 = S1.intersection(S2, z);
S3.outputset();
break;
default:
cout << "Invalid entry";
}
return 0;
}

There are several ways to check intersections between two sets, if your sets are in arrays, I'd suggest looping one of them and have a check if it's in between the other:
for (int i = 0; i < element1_size; i++) {
for (int u = 0; u < element2_size; u++) {
if (element1[i] == element2[u]) {
cout << "Intersection point : " << element1[i] << endl;
}
}
}

Your copy ctor should be set(const set &s); instead of set(set &s); What you have is a ctor that accepts a reference to set, which is not a copy ctor. So compiler generates default one for you and you have issue returning object by value from method intersection()
Also please fix your code indent, it is not easy to read it.
Also remove following lines from your "copy ctor":
if(size>0)
{
delete []elem;
}
You cannot delete that pointer, your object is not constructed yet.

How about using a map to keep track of the "intersected" elements in much more efficient way. Here is a snippet of what I have in mind:
std::map<int, int> m;
for(int i = 0; i < size; ++i)
m.insert( std::pair<int, int>(elem[i], 1) );
for(int i = 0; i < A.size; ++i)
if(m.count(A[i]) > 0)
R.elem[k++] = A[i]
This way you avoid the nested for-loops, and will be able to compute the intersection with logarithmic time complexity.

Related

Why is an array not returned from the addition operator?

The task is to create 2 variables of the Array class to populate them, output, add and multiply. I created 2 variables of the Array class, after which I wanted to add them, I wrote an addition operator for this, but it does not return an array of sums of the other two arrays
Code:
#include <iostream>
#include <fstream>
#include <string>
void showMenu() {
std::cout << "-------Menu-------" << std::endl <<
"1-Input matrix" << std::endl <<
"2-Print matrix" << std::endl <<
"3-Sum matrix" << std::endl <<
"4-Multiply matrix" << std::endl <<
"0-Exit" << std::endl <<
"------------------" << std::endl;
}
class Array {
public:
Array(const int size) {
this->size = size;
arr = new int[this->size];
}
void fillArr() {
std::cout << "Enter elements of array: ";
for (size_t i = 0; i < size; i++) {
std::cin >> arr[i];
}
}
int getSize() {
return size;
}
int& operator [] (const int index) {
return arr[index];
}
void showArr() {
for (size_t i = 0; i < size; i++) {
std::cout << arr[i] << '\t';
}
std::cout << std::endl;
}
~Array() {
delete[] arr;
}
private:
int size = 0;
int* arr;
};
Array operator + (Array arr1, Array arr2) {
int temp = 0;
if (arr1.getSize() < arr2.getSize())
temp = arr1.getSize();
else temp = arr2.getSize();
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] + arr2[i];
}
tempArr.showArr();
return tempArr;
}
Array operator * (Array arr1, Array arr2) {
int temp = 0;
if (arr1.getSize() < arr2.getSize())
temp = arr1.getSize();
else temp = arr2.getSize();
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] * arr2[i];
}
return tempArr;
}
std::int16_t main() {
int num = 0;
int size1 = 0, size2 = 0;
std::cout << "Enter size of first array: ";
std::cin >> size1;
std::cout << "Enter size of second array: ";
std::cin >> size2;
Array arr1(size1), arr2(size2);
while (true) {
showMenu();
std::cout << "Choice: ";
std::cin >> num;
switch (num) {
case 1:
arr1.fillArr();
arr2.fillArr();
break;
case 2:
arr1.showArr();
arr2.showArr();
break;
case 3: {
Array temp(arr1 + arr2);
temp.showArr();
break;
}
case 4:
(arr1 * arr2).showArr();
break;
}
}
}
I tried to change the array and the operator itself, but nothing came out. Help understand the problem
you need to read up on the rule of 3
here
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] + arr2[i];
}
tempArr.showArr();
return tempArr;
you return a copy of an Array instance. In that case both instances are pointing at the same newed array (arr). The first one to go out of scope (when you exit the operator + function) will delete that data, hence giving you garbage. Then when the second one is destroyed (at the break statement in the menu switch) it tries to delete the same array again., on my machine that errors out
https://en.cppreference.com/w/cpp/language/rule_of_three

read access violation when I tried to implement Depth First Search algorithm in c++

this is my DFS function. I don't know why visited[start_vertex] doesn't work although I allocated the visited array in the main function!
typedef Node** PtP;
void DFS(PtP list, int start_vertex, bool* visited)
{
cout << "the crash under this line";
if (visited[start_vertex])
{
cout << "ignore";
}
visited[start_vertex] = true;
Node* adj = list[start_vertex]; // linked list list[0]
// after this line start_vertex will be adjacency vertex of start vertex
while (adj != NULL)
{
DFS(list, adj->data, visited);
adj = adj->next;
}
}
this is my main function I created an bool array and allocated its by four element and plug in the DFS function
int main()
{
PtP list;
list = new Node * [4];
for (int i = 0; i < 4; i++)
{
list[i] = new Node[4];
list[i] = NULL;
}
for (int i = 0; i < 4; i++)
{
cout << "enter number of vertices adjacency with " << i << ": ";
int temp;
cin >> temp;
addEdge2(list, i, temp);
}
for (int i = 0; i < 4; i++)
{
cout << "list[" << i << "]: ";
traverse(list[i]);
}
bool* visited = new bool[4];
for (int i = 0; i < 4; i++)
{
visited = false;
}
DFS(list, 0, visited);
for (int i = 0; i < 4; i++)
{
cout << "visisted: " << visited[i] << " ";
}
for (int i = 0; i < 4; i++)
{
delete [] list[i];
}
delete [] list;
return 0;
}
and this is my entire program just for test DFS method:
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
};
typedef Node* Ptr;
typedef Node** PtP;
void addFront(Ptr& First, int x)
{
Ptr p;
p = new Node;
p->data = x;
p->next = First;
First = p;
}
void addEdge(PtP &list, int v1, int v2)
{
addFront(list[v1], v2);
addFront(list[v2], v1);
}
void addEdge2(PtP& list, int v, int num_of_adj_vtex)
{
cout << "enter vertices adjacency with " << v << ": ";
int temp;
for (int i = 0; i < num_of_adj_vtex; i++)
{
cin >> temp;
addFront(list[v], temp);
}
}
void traverse(Node* first)
{
Node* p = first;
while (p != NULL)
{
cout << p->data<<" ";
p = p->next;
}
cout << "\n";
}
void DFS(PtP list, int start_vertex, bool* visited)
{
if (visited[start_vertex])
{
cout << "vertex: " << start_vertex << " visited ";
}
visited[start_vertex] = true;
// linked list list[0] after this line start_vertex will be adjaceny vertex of start vertex
Node* adj = list[start_vertex];
while (adj != NULL)
{
DFS(list, adj->data, visited);
adj = adj->next;
}
}
int main()
{
PtP list; //type def node ** ptp
list = new Node * [4];
for (int i = 0; i < 4; i++)
{
list[i] = NULL;
}
for (int i = 0; i < 4; i++)
{
cout << "enter number of vertices adjacency with " << i << ": ";
int temp;
cin >> temp;
addEdge2(list, i, temp);
}
for (int i = 0; i < 4; i++)
{
cout << "list[" << i << "]: ";
traverse(list[i]);
}
bool* visited = new bool[4];
for (int i = 0; i < 4; i++)
{
visited[i] = false;
}
DFS(list, 0, visited);
for (int i = 0; i < 4; i++)
{
cout << "visisted: " << i << " "<< visited[i] << " ";
}
delete [] list;
return 0;
}
Ok, from what I can see, the problem seems to be user input related. The method:
void addEdge2(PtP& list, int v, int num_of_adj_vtex)
{
cout << "enter vertices adjacency with " << v << ": ";
int temp;
for (int i = 0; i < num_of_adj_vtex; i++)
{
cin >> temp;
addFront(list[v], temp); //Here if temp > 3 your later code will fail.
}
}
Requests user input and stores it at the front of the list...whatever is the value of temp, and puts it into the data field.
Later on when you do the DFS method you call the same method recursively:
DFS(list, adj->data, visited);
adj = adj->next;
This depends on what adj->data has stored, from the addEdge2 function. Since you have set the boolean array to a length of 4, that adj->data must be pointing to any value > 3 which would throw the error you mentioned because it is trying to access unallocated memory.
It seems like the code is not wrong, exactly, even though you could probably set some safeguards like making sure the user enters a value from 0 to 3.

How to delete the new array in c++?

I have created a new point function in c++, where I create a new array by Dynamic memory allocation. However, when I want to delete the array in main function, it reports errors like:
'Assessment_1.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\ucrtbased.dll'
'Assessment_1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'.
The thread 0x22dc has exited with code 0 (0x0).
HEAP[Assessment_1.exe]: Invalid address specified to RtlValidateHeap( 00050000, 0005F25C )
Assessment_1.exe has triggered a breakpoint.
The return_array.cpp contains the function in which user inputs the keyboards.
#include<iostream>
#include <conio.h>
using namespace std;
//const static int length = 3;
int* input() {
//static int number[length]; fixed length for input
static int* number_array;
int number_length = 30;
int index = 0;
number_array = new int[number_length];
cout << "enter (ESC) to escape the program!" << endl;
while (_getch() != 27)
{
cout << "Input your number " << index << " elment: " << endl;
cin >> number_array[index];
index = index + 1;
cout << endl;
}
return number_array;
}
The practice.cpp contains the main function and the evaluation function of two vectors. The bug is when I add the delete []vector_1;.
#include <vector>
#include<iostream>
#include"myFunctions.h"
using namespace std;
const static int length = 3;
bool same_vec(vector<int> a, vector<int> b);
void main() {
vector<int> new_vector_1(length);
vector<int> new_vector_2(length);
int* vector_1 = input();
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1;
}
delete []vector_1;
for (int i = 0; i < length; i++) {
cout << " The result of vector_1: " << new_vector_1[i] << endl;
}
int* vector_2;
vector_2 = input();
for (int i = 0; i < length; i++) {
new_vector_2[i] = *vector_2;
vector_2 = vector_2 + 1;
}
delete []vector_2;
for (int i = 0; i < length; i++) {
cout << " The result of vector_2: " << new_vector_2[i] << endl;
}
bool qax = same_vec(new_vector_1, new_vector_2);
if (qax == false) {
cout << "the items are not match!"<<endl;
}
else {
cout << "the items are match!" << endl;
}
}
bool same_vec(vector<int> a, vector<int> b) {
//Evaluate the elements in the two vectors
bool flag = true;
int length_a = a.size();
int length_b = b.size();
vector<bool> new_bool(length_a);
for (int i = 0; i < length_a; i++) {
for (int j = 0; j < length_b; j++) {
if (a[i] == b[j]) {
new_bool[i] = true;
cout << a[i] << " " << b[j] << endl;
break;
}
}
}
for (int i = 0; i < new_bool.size(); i++) {
if (new_bool[i] == false) {
flag = false;
}
}
return flag;
}
And the myFunction.h is my head file.
#pragma once
int* getRandom();
int* input();
Can someone helps to solve the problem? I know one solution is delete the line of delete []vector_1;. The solution may cause memory-leak.
You are changing the address stored in the vector_1 pointer, then trying to delete[] something that no longer corresponds to the pointer returned by the new operator in your input function.
So, instead of this loop:
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1; // This line changes the pointer!
}
delete []vector_1; // And, here, the pointer is NOT what "new" gave you!
Use something like this, instead:
for (int i = 0; i < length; i++) {
new_vector_1[i] = vector_1[i]; // You can use the [] operator on the pointer
cout << *vector_1 << endl;
// vector_1 = vector_1 + 1; // Remove this line, as it's causing the problem!
}
delete []vector_1;
Also, you have exactly the same problem in the loop that deals with the vector_2 pointer - and the same 'fix' will work there, too.
Note: If you don't want to use the [i] index operator, but rather use pointer 'arithmetic', then you can change:
new_vector_1[i] = vector_1[i];
to:
new_vector_1[i] = *(vector_1 + i);
This way, you are adding the value of i to the pointer without changing that pointer.

Odd results after first float entered

I have created a program to take in float values until a non-number is entered. The program will then print the numbers entered like {n0,n1,...,}, as well as sum up the number entered and compute the average.
My problem is after n0 is printed out all the rest of the numbers being printed out are not matching the number entered.
Here is the program:
#include <iostream>
using namespace std;
class ManagedArray
{
float *elements;
int numberOfElements;
public:
ManagedArray(float *ele, int NOE)
: elements(ele), numberOfElements(NOE)
{}
ManagedArray()
{
elements = NULL, numberOfElements = 0; //default constructor
}
int Size();
float get(int index);
void add(float value);
~ManagedArray(); // Destructor
ManagedArray(ManagedArray & ma); // copy constructor
void print(ManagedArray ma);
};
float ManagedArray::get(int index) { return elements[index]; }
int ManagedArray::Size() { return numberOfElements; };
void ManagedArray::add(float value)
{
float * biggerArray = new float[numberOfElements + 1];
if (elements != NULL)
{
// copy the old elements into the biggerArray
for (int i = 0; i < numberOfElements; i++)
{
biggerArray[i] = elements[i];
}
// the old array is not needed anymore, we have a better copy
delete[] elements;
}
// point at the new array
elements = biggerArray;
numberOfElements = numberOfElements + 1;
// put the new number into the last element of the array
elements[numberOfElements - 1] = value;
}
ManagedArray::~ManagedArray() { delete[] elements; }
ManagedArray::ManagedArray(ManagedArray & ma)
{
elements = new float[10]; // put here to get the number of input here
for (int i = 0; i <10; i++) // put here to get the number of input here
{
elements[i] = ma.elements[i];
}
numberOfElements = ma.numberOfElements;
}
void ManagedArray::print(ManagedArray ma)
{
bool hasNumbers = ma.Size() > 0;
if (hasNumbers) {
// print the stored numbers
cout << "Entered numbers: " << endl;
cout << "{";
for (int i = 0; i < ma.Size(); ++i)
{
if (i > 0)
{
cout << ", ";
}
cout << ma.get(i);
}
cout << "}" << endl;
float sum = 0;
for (int i = 0; i < ma.Size(); ++i)
{
sum += ma.get(i);
}
cout << "total: " << sum << endl;
cout << "average: " << (sum / ma.Size()) << endl;
}
else {
cout << "no numbers entered." << endl;
}
}
int main()
{
ManagedArray mArray; // default constructor call for ManagedArray
float userInput;
bool addingNumbersToTheList;
cout << "Keep entering numbers. Enter a non-number to stop." << endl;
do
{
cin >> userInput;
addingNumbersToTheList = !std::cin.fail();
if (addingNumbersToTheList) {
mArray.add(userInput);
}
} while (addingNumbersToTheList);
ManagedArray copy(mArray);
// fix cin after intentionally breaking it above.
if (std::cin.fail())
{
std::cin.clear();
while (std::cin.get() != '\n');
}
copy.print(copy);
copy.print(copy);
cin.get();
return 0;
}
So for instance I enter 1 , 2 , 3 , a
the program would print out {1, -4.22017e+37, 2.89451e+31}
Could someone point out what I am doing wrong with this method?
EDIT: I have fixed the copy constructor. Can someone show me how I would replace
the number 10 with the total of numbers input? in:
elements = new float[10];
and
for (int i = 0; i <10; i++)
I needed to iterate through every possible number in the array with a for loop and an array.
elements = new float[ma.Size()];
for (int i = 0; i < ma.Size(); i++)
{
elements[i] = ma.elements[i];
}
numberOfElements = ma.numberOfElements;

c++ dynamic array Floating Point exception

For my homework I had to design an arraylist in c++ using only 1d arrays and pointers to make the array dynamic. I have done ample testing and my functions work correctly, but when I use the main that the teacher has provided me I get this floating point error. The point of this homework is to create a class that will work for the teachers main without changing any code in the main
here is the main:
#include "ArrayList.h"
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
ArrayList arr;
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
cout << "Should contain numbers 1..50, is ";
cout << arr.toString() << endl;
for (int i=arr.size()-1;i>=1;i--)
{
arr.erase(arr[i]);
}
cout << "Should contain only 1, is ";
cout << arr.toString() << endl;
arr.erase(arr[0]);
for (int i=1;i<=50;i++)
{
if (i<=2)
arr.push_back(i);
else
{
int j=1;
while ((j<arr.size()) && (i%arr[j]!=0))
j++;
if (j==arr.size())
{
arr.push_back(i);
}
}
}
cout << "Prime numbers between 1 and 50 are: " << arr.toString() << endl;
}
here is my cpp:
#include<iostream>
#include<string>
#include<sstream>
#include "ArrayList.h"
using namespace std;
void ArrayList:: intialArr(int arr[])
{
for(int i = 0; i < length; i++)
{
arr[i] = 0;
}
}
string ArrayList:: toString()
{
std::ostringstream ss;
for(int i = 0; i < capacity; i++)
{
if(arr[i]>0 || arr[i] <0)
{
ss << arr[i] << " ";
}
}
return ss.str();
}
ArrayList::ArrayList()
{
length = 1;
capacity=0;
arr = new int[length];
intialArr(arr);
}
int& ArrayList:: operator[] (unsigned int i)
{
return arr[i];
}
void ArrayList:: push_back(int m)
{
if(capacity>=length)
{
int oldlength = length;
length = length*2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i < oldlength; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
arr[capacity] = m;
capacity++;
}
void ArrayList:: erase(int m)
{
if(capacity == length/2)
{
length = length/2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i<capacity; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
for(int i = 0; i < capacity; i++)
{
if(arr[i]==m)
{
for(int j = i; j<length; j++)
{
arr[j] = arr[j+1];
}
capacity--;
break;
}
}
cout << "length = " << length << " capacity = " << capacity << " capacity/length = " << capacity*2 << endl;
}
from what I have read online floating point exceptions are normally thrown when you try to divide by zero or an infinate value arises but I dont understand how I am getting either of these issues to arise.
My code get through the main where number 1-50 are added and deleted but I get the error once I go into setting up the array to hold prime numbers (after the arr.erase(arr[0]) in the main)
I just set a couple of tags in the main to find what my number look like going into the while ((j<arr.size()) && (i%arr[j]!=0))and i find that my numbers before the crash are
j = 1 and arr[j] = 2
i = 5 and arr.size() = 4