The problem I am having is that I need to print the resulting set from the union_set function using the copy function. (So I am not allowed to just put output as the last term of the set_union function). I cannot seem to get the copy function to work correctly for the lastAunionB pointer (i have to to a few more times as well). What I have currently is just my last attempt at an answer, although I tried many more things. What am I doing incorrectly with the copy function? Here is the code.
#include <iostream>
#include <iterator>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int setA[5] = {2, 4, 5, 7, 8};
int setB[7] = {1, 2, 3, 4, 5, 6, 7};
int setC[5] = {2, 5, 8, 8, 15};
int setD[6] = {1, 4, 4, 6, 7, 12};
set<int> set2A(setA,setA+5);
set<int> set2B(setB,setB+7);
set<int> set2C(setC,setC+5);
set<int> set2D(setD,setD+6);
int AunionB[12];
int AunionC[10];
int BunionD[13];
int AintersectB[12];
int AintersectC[10];
set<int> finalUnion;
set<int> finalIntersection;
set<int> final2Union;
set<int> final2Intersection;
set<int> final2Difference;
ostream_iterator< int > output( cout, " " );
int *lastAunionB;
int *lastAunionC;
int *lastBunionD;
int *lastAintersectB;
int *lastAintersectC;
cout << "setA = ";
copy(set2A.begin(), set2A.end(), output);
cout << endl;
cout << "setB = ";
copy(set2B.begin(), set2B.end(), output);
cout << endl;
cout << "setC = ";
copy(set2C.begin(), set2C.end(), output);
cout << endl;
cout << "setD = ";
copy(set2D.begin(), set2D.end(), output);
cout << endl;
//here is where the problem lies
cout << "AunionB = ";
lastAunionB = set_union(setA, setA+5, setB, setB+7, AunionB);
copy(lastAunionB, lastAunionB, output);
cout << endl;
/*
cout << "AunionC = ";
set_union(setA, setA+5, setC, setC+5, AunionC);
cout << endl;
cout << "BunionD = ";
set_union(setB, setB+7, setD, setD+6, BunionD);
cout << endl;
cout << "AintercectB = ";
set_intersection(setA, setA+5, setB, setB+7, AintersectB);
cout << endl;
cout << "AintercectC = ";
set_intersection(setA, setA+5, setC, setC+7, AintersectC);
cout << endl;
*/
return 0;
}
lastAunionB = set_union(setA, setA+5, setB, setB+7, AunionB);
copy(lastAunionB, lastAunionB, output);
The last argument you pass to set_union will correspond to the beginning of the range of the new set constructed. The return value of set_union will be the end of this range.
You'd want lastAunionB and the other raw pointers and pretty much everything you're passing as an iterator here to be defined with the type std::set<int>::iterator and you'd want to copy over the range like this:
std::copy(AunionB, lastAunionB, output);
You're trying to copy from an empty range.
copy(ptr,ptr,output);
will always not print anything.
Related
I'm trying to find duplicates even though they have been put in by user input. I've tried a few methods, for loop to do the checks but that doesnt work.
Anyone got any idea how I might be able to do this effectively?
#include <iostream>
#include <algorithm>
int main()
{
int size, * array;
std::cout << "Indtast arrayet's stoerrelse." << std::endl;
std::cin >> size; // optager input til størrelse af arrayet fra brugeren
array = new int[size]; // dynamisk allokeret array
while (size >= 100) { // while loop til at tjekke om arrayets størrelse er for stort
std::cout << "Forkert input af array." << std::endl;
break;
}
while (size <= 100) { // while loop til når arrayet er af rigtig størrelse
float sum = 0;
float gns = 0;
std::cout << "Tast op til " << size << " vaerdier ind." << std::endl;
for (int i = 0; i < size; i++) { // for loop til at optage input til hver element i arrayen
std::cout << "Indtast vaerdi for array-nr: " << i << std::endl;
std::cin >> array[i]; // optager input til hvert element
sum += array[i]; // finder summen af elementerne i arrayet
}
std::cout << "Min-vaerdi er: " << *std::min_element(array, array + size) << std::endl;
std::cout << "Max-vaerdi er: " << *std::max_element(array, array + size) << std::endl;
std::cout << "Summen er: " << sum << std::endl;
gns = sum / size; // udregner gennemsnittet
std::cout << "Gennemsnittet er: " << gns << std::endl;
return 0;
}
}
Here is a modern (C++20) approach using ranges. As suggested in the comments, you should sort your vector and then use adjacent_if. It is always recommended to use the algorithms from the standard library than to try to re-implement common stuff like this yourself using basic procedural tools like for and while loops.
This approach would work with an array as well, but I suggest using an std::vector.
#include <vector>
#include <algorithm>
#include <iostream>
void print(std::vector<int> const& v){
// print the vector
for (auto const& i: v){
std::cout << i << ", ";
}
std::cout<<"\n";
};
int main()
{
std::vector<int> v{1, 2, 1, 1, 3, 3, 3, 4, 5, 4};
std::cout << "Input vector = \t\t";
print(v);
// sort the vector
std::ranges::sort(v);
std::cout << "Sorted vector = \t";
print(v);
// find duplicates and print them
auto it = std::ranges::adjacent_find(v);
while (it != v.end()){
std::cout
<< "Duplicates start at v["
<< std::distance(v.begin(), it)
<< "] = "
<< *it
<< "\n";
it = std::ranges::adjacent_find(it, v.end(), std::ranges::not_equal_to());
it = std::ranges::adjacent_find(it, v.end());
}
for (; it != v.end(); ++it){
std::cout << *it << std::endl;
}
// remove duplicates
auto ret = std::ranges::unique(v);
v.erase(ret.begin(), ret.end());
std::cout << "No duplicates = \t";
print(v);
return 0;
}
Output:
Input vector = 1, 2, 1, 1, 3, 3, 3, 4, 5, 4,
Sorted vector = 1, 1, 1, 2, 3, 3, 3, 4, 4, 5,
Duplicates start at v[0] = 1
Duplicates start at v[4] = 3
Duplicates start at v[7] = 4
No duplicates = 1, 2, 3, 4, 5,
Try it on compiler explorer: https://godbolt.org/z/YP3zb7PYf
I created a struct named products that contains multiple data types:
struct products{
int ID;
string Name;
double Price;
int Quantity;
};
Then in the main function, I created an array named details which utilizes the struct products:
int main(){
struct products details[5];
Then I gave each array element data.
details[0] = {1, "Apple Juice", 12, 240};
details[1] = {2,"Bread", 10, 100};
details[2] = {3, "Chocolate", 5, 500};
details[3] = {4, "Dates", 50, 150};
details[4] = {5, "Eggs", 30, 360};
finally, I tried to print the values of the element at index 2:
cout<<details[2];
it gave me this error:
"Invalid operands to binary expression ('std::ostream' (aka 'basic_ostream') and 'struct products')"
Here is a picture of the whole code
There are several ways of doing what you need, here's 3 of them:
Overload << operator:
std::ostream& operator<< (std::ostream& os, const products& pr)
{
return os << pr.ID << " " << pr.Name << " " << pr.Price << " " << pr.Quantity;
}
std::cout << details[2]; should now work as expected.
Print the struct members directly:
std::cout << details[2].ID << " " << details[2].Name
<< " " << details[2].Price << " " << details[2].Quantity;
Add a to_string() member function:
struct products{
//...
std::string to_string() const
{
std::ostringstream os; // #include <sstream>
os << ID << " " << Name << " " << Price << " " << Quantity;
return os.str();
}
};
Usage:
std::cout << details[2].to_string();
i write you like code.
#include <iostream>
using namespace std;
struct H{
int n;
int b;
};
int main() {
H h[] = {10, 20};
cout << h[0] << endl; // you can not print it becouse it is array!
return 0;
}
in this code i try to print struct!
but i can not do it!
it like:
#include <iostream>
using namespace std;
struct H{
int n;
int b;
};
int main() {
H h = {10, 20};
cout << h << endl;
return 0;
}
just try:
#include <iostream>
using namespace std;
struct H{
int n;
int b;
};
int main() {
H h[] = {10, 20};
cout << h[0].n << endl;
cout << h[0].b << endl;
return
0;
}
I am trying to make it possible to assign to an array from an initializer list in C++, if this is possible how to do it? may be the new versions of C++ needs to achieve it or not?
Code:
#include <iostream>
#include <array>
using namespace std;
int main()
{
int arrayName_A[5];
arrayName_A = {1,2,3,4,5};
for (int i=0;i<5;i++)
{
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
}
}
No, it's not possible. You either have to intialize the array directly:
int arrayName_A[5] = {1,2,3,4,5};
or use std::array instead:
std::array<int, 5> arrayName_A;
arrayName_A = {1, 2, 3, 4, 5};
Arrays do not have the assignment operator. Arrays are non-modifiable lvalues.
That is you may not write for example
int a[3] = { 1, 2, 3 };
int b[3] = a;
or
int a[3] = { 1, 2, 3 };
int b[3];
b = a;
You may set each element of an array with a value from an initializer list using the range-based for loop as it is shown in the demonstrative program below.
#include <iostream>
int main()
{
int arrayName_A[5];
size_t i = 0;
for ( const auto &item : { 1, 2, 3, 4, 5 } ) arrayName_A[i++] = item;
for ( const auto &item : arrayName_A ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
The program output is
1 2 3 4 5
Otherwise use the standard class std::array that has the assignment operator. For example
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> arrayName_A;
arrayName_A = { 1, 2, 3, 4, 5 };
// or
arrayName_A = { { 1, 2, 3, 4, 5 } };
for ( const auto &item : arrayName_A ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
The program output is the same as shown above that is
1 2 3 4 5
You need to initialize the array as soon as you declare it, like this :
#include <iostream>
#include <array>
using namespace std;
int main()
{
int arrayName_A[5] = {1,2,3,4,5};
for (int i=0;i<5;i++)
{
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
}
}
I am using Eigen Solver. I am having trouble retrieving the values from Vectors/Matrix that I create. For example in the following code, I don't have an error but get a run time error.
#include <iostream>
#include <math.h>
#include <vector>
#include <Eigen\Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix3f A;
Vector3f b;
vector<float> c;
A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
b << 3, 3, 4;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the vector b:\n" << b << endl;
Vector3f x = A.colPivHouseholderQr().solve(b);
for (int i = 0; i < 3; i++)
{
c[i] = x[i];
cout << c[i] << " ";
}
//cout << "The solution is:\n" << x << endl;
return 0;
}
How do I retrieve the value in x to a variable of my choice (I need this as this will be a parameter in another function I wrote).
Use
vector<float> c(3);
Or
for (int i = 0; i < 3; i++)
{
c.push_back(x[i]);
cout << c[i] << " ";
}
As stated in the comment, the problem was that c was not resized before assigning values to it. Additionally, you actually don't need the Eigen::Vector3f x, but you can assign the result of the .solve() operation directly to a Map which points to the data of the vector:
#include <iostream>
#include <vector>
#include <Eigen/QR>
using namespace Eigen;
using namespace std;
int main()
{
Matrix3f A;
Vector3f b;
vector<float> c(A.cols());
A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
b << 3, 3, 4;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the vector b:\n" << b << endl;
Vector3f::Map(c.data()) = A.colPivHouseholderQr().solve(b);
for(int i=0; i<3; ++i) std::cout << "c[" << i << "]=" << c[i] << '\n';
}
I'm trying to insert data based on a given value - strBeg. I want the vectors to be sorted numerically based on this value. There are two different vectors. With my driver program shown below I would want the output to be:
linei[0][0] = 1 linei[0][1] = 8 refi[0][0] = 81 refi[0][1] = 88
linei[1][0] = 21 linei[1][1] = 31 refi[1][0] = 10 refi[1][1] = 20
linei[0][0] = 33 linei[0][1] = 44 refi[0][0] = 0 refi[0][1] = 11
linei[1][0] = 45 linei[1][1] = 47 refi[1][0] = 6 refi[1][1] = 8
As you can see the value of refBeg/refEnd does not affect the order, but must stay with it's strBeg/strEnd pair. I've posted my code below...it does not work. My current method is going to require a very large sorting function accounting for many different cases and I would like to avoid that if possible. I'm wondering if there is a more efficient way to implement this? I've though about combining the two vectors into one that will have 4 columns but would rather not as this will make it more confusing to understand (but am not completely opposed if it's the best/easiest option). Also there will be no overlap in linei, as in there will not be two sets of data with the same strBeg and strBeg/strEnd will not fall in between another strings start and stop points. I read through some other similar questions but couldn't quite figure out how to adapt them to my situation. Any help would be greatly appreciated!!!
NOTE: If I don't reply tonight I will in the morning. Thanks again!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void insertData(const int refBeg, const int refEnd, const int strBeg, const int strEnd, vector<vector<int> >& refi, vector<vector<int> >& linei);
int main(int argc, const char * argv[])
{
vector<vector<int> > refi;
vector<vector<int> > linei;
insertData(0, 11, 33, 44, refi, linei);
insertData(10, 20, 21, 31, refi, linei);
insertData(6, 8, 45, 47, refi, linei);
insertData(80, 88, 1, 8, refi, linei);
for (int i=0; i<linei.size(); i++) {
cout << "linei[" << i << "][0] = " << linei[i][0] << " ";
cout << "linei[" << i << "][1] = " << linei[i][1] << " ";
cout << "refi[" << i << "][0] = " << refi[i][0] << " ";
cout << "refi[" << i << "][1] = " << refi[i][1] << endl;
}
return 0;
}
void insertData(const int refBeg, const int refEnd, const int strBeg, const int strEnd, vector<vector<int> >& refi, vector<vector<int> >& linei) {
linei.push_back(vector<int>() );//creates a new row in linei
refi.push_back(vector<int>() );//creates a new row in refi
int size=(int)linei.size();
if ((size-1) == 0) {
linei[0].push_back(strBeg);
linei[0].push_back(strEnd);
refi[0].push_back(refBeg);
refi[0].push_back(refEnd);
} else {
for (int i=0; i<size; i++) {
if (strBeg > linei[i][0]) {
linei[i+1].push_back(strBeg);
linei[i+1].push_back(strEnd);
refi[i+1].push_back(refBeg);
refi[i+1].push_back(refEnd);
break;
}
}
}
}
Working code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct line_ref
{
vector<int> linei;
vector<int> refi;
bool operator<(const line_ref &rhs) const { return linei[0] < rhs.linei[0]; }
};
void insertData(const int refBeg, const int refEnd, const int strBeg, const int strEnd, vector<line_ref>& line_ref_i);
int main(int argc, const char * argv[])
{
vector<line_ref> line_ref_i;
insertData(0, 11, 33, 44, line_ref_i);
insertData(10, 20, 21, 31, line_ref_i);
insertData(6, 8, 45, 47, line_ref_i);
insertData(80, 88, 1, 8, line_ref_i);
cout << "UNSORTED\n";
for (int i=0; i<line_ref_i.size(); i++) {
cout << "LINEI[0] = " << line_ref_i[i].linei[0] << " ";
cout << "LINEI[1] = " << line_ref_i[i].linei[1] << " ";
cout << "REFI[0] = " << line_ref_i[i].refi[0] << " ";
cout << "REFI[1] = " << line_ref_i[i].refi[1] << endl;
}
sort(line_ref_i.begin(), line_ref_i.end() );//, /*??*/);
cout << "SORTED\n";
for (int i=0; i<line_ref_i.size(); i++) {
cout << "LINEI[0] = " << line_ref_i[i].linei[0] << " ";
cout << "LINEI[1] = " << line_ref_i[i].linei[1] << " ";
cout << "REFI[0] = " << line_ref_i[i].refi[0] << " ";
cout << "REFI[1] = " << line_ref_i[i].refi[1] << endl;
}
return 0;
}
void insertData(const int refBeg, const int refEnd, const int strBeg, const int strEnd, vector<line_ref>& line_ref_i) {
line_ref_i.push_back(line_ref() );
int size = (int)line_ref_i.size() - 1;
line_ref_i[size].linei.push_back(strBeg);
line_ref_i[size].linei.push_back(strEnd);
line_ref_i[size].refi.push_back(refBeg);
line_ref_i[size].refi.push_back(refEnd);
}
Instead of parallel vectors, why not put the related elements into a struct?
struct line_ref
{
vector<int> linei;
vector<int> refi;
};
vector <line_ref> line_ref_i;
Alternately, instead of declaring a struct, you could just use a std::pair<int,int>, if you don't mind generic names like first and second for the fields.