Sorting using vectors [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm writing a program of a stock market where I read from a file and sort with symbols and percent gain/loss. I have completed sorting with symbols but having trouble establishing the percent gain loss. Basically i am instructed to use vectors. We are required to produce the list ordered by percent gain/loss and i need to sort the stock list by this component. However i'm not to physically sort the list by component percent gain/loss; instead provide a logical ordering with respect to this component.
so basically i added a data member, a vector to hold the indices of the stock list ordered by the component percent gain/loss. i called it array indexByGain. so when i print the list ordered by the percent gain/loss, i use the array indexByGain to print the list. my problem is an i need help on how to start if someone could show me an example or explain on how to go about this i can continue or correct me on my rough draft that will be helpful. below is a rough draft of my code. stockType has to do with the where data is stored from the file.
#include <iostream>
#include "stockType.h"
class stockListType
{
public:
void sortBySymbols();//sort out symbols and it comiples correctly.
void sortByGain();
void printByGain();
void insert(const stockType& item);
private:
vector<int> indexByGain;//declared a vector array indexByGain..
vector<stockType> list;
};
void stockListType::insert(const stockType& item)
{
list.push_back(item)//inserts the data from file to vector array.
}
//function prints out the gain
void stockListType::printByGain()
{
//my code to print out the gain..
}
//function to sort the gain and this is where i am stuck.
void stockListType::sortGain()
{
int i, j, min, maxindex;
for(i=0;i<list.size();i++)
{
min = i;
for(j=i+1;j<list.size();j++)
list[maxindex].getPercentage()<list[j].getPercentage();
maxindex = j;
indexGain.push_back(maxindex);
}
I know I am wrong but am i starting on a good base or totally of. please you could assist me or correct me. Thanks. oh sorry before i forget getPercentage() calculates and returns the percentage gain/loss.

Initialize the index and use std::sort:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
struct Data {
int value;
int percent;
};
typedef std::vector<Data> DataVector;
typedef DataVector::size_type size_type;
typedef std::vector<size_type> IndexVector;
DataVector data { { 1, 1 }, { 2, -2 }, { 3, 3 }, { 4, -4 }, { 5, 5} };
IndexVector index;
index.resize(data.size());
for(size_type i = 0; i < data.size(); ++i) {
index[i] = i;
}
struct Less
{
const DataVector& data;
Less(const DataVector& data)
: data(data)
{}
bool operator () (size_type a, size_type b) {
return data[a].percent < data[b].percent;
}
};
std::sort(index.begin(), index.end(), Less(data));
for(size_type i = 0; i < index.size(); ++i) {
std::cout << data[index[i]].value << ": " << data[index[i]].percent << std::endl;
}
}
You may use C++11:
std::sort(index.begin(), index.end(),
[&](size_type a, size_type b) { return data[a].percent < data[b].percent; }
);
for(auto i: index)
std::cout << data[i].value << ": " << data[i].percent << std::endl;

Related

Delete an array of pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I'm struggling with removing the array from the memory.. it was allocated dynamically. I'd love some help, thanks!
void RemoveAllocationOfIntegerArray(int** arr, int size) {
for (int i = size - 1; i >= 0; i--) {
delete arr[i];
arr[i] = NULL;
}
delete[] arr;
arr = NULL;
}
First, you don't need these lines:
arr[i] = NULL;
// or
arr = NULL;
Next, you should delete arrays using delete[] operator. So, replace
delete arr[i];
with:
delete[] arr[i];
Another point is, you can free memory using delete or delete[] only if it is allocated with new or new[].
Lastly, You don't need to go backward when freeing. It is not necessary (except for some odd cases).
Example of using std::vector, or std::vectorstd::vector<int>
#include <format>
#include <vector>
#include <iostream>
void function_on_2d_data(std::vector<std::vector<int>>& values) // pass non const so you can modify values.
{
values[1][1] = 7;
}
void show_2d_data(const std::vector<std::vector<int>>& values) // pass const, show should not modify content
{
for (const auto& row : values)
{
for (const auto& value : row)
{
std::cout << value << " ";
}
std::cout << "\n";
}
}
// a function returning dynamically allocated 2d arrays (much more safe then int** with no size info);
std::vector<std::vector<int>> create_2d_data()
{
std::vector<std::vector<int>> values(4, std::vector<int>(3, 1)); // This does all the "new"-ing for you, and set values in each row to 1
return values;
}
int main()
{
// create a 2d datastructure containing 4 row and 3 columns;
std::vector<std::vector<int>> values = create_2d_data();
std::cout << std::format("values has {0} rows\n", values.size()); // see size information is returned too
function_on_2d_data(values);
show_2d_data(values);
return 0;
// values goes out of scope and it will do all the "delete"-ing for you
}

c++ how to use while properly [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
I am learning c++ around two weeks and therefore have a lot of questions. It feels like i learn a new sport. My body in my thinking already moving much better than any other olympic players, but the actual movement is so poor.
what i want to know is if i can use "while" in cout together.
int main() {
struct {
string engineType;
string brand;
int price;
int range;
} candidate1, candidate2;
// information of candidate 1
candidate1.name = "IONIQ5";
candidate1.range = 450;
candidate1.price = 35000;
// information of candidate 2
candidate2.brand = "Tesla_Model_3";
candidate2.range = 650;
candidate2.price = 55000;
// show each price with while function
int i = 1;
while (i<3) {
cout << "Price :" << candidate[i].range << endl ;
i++;
}
return 0;
I want to have as a result of print
450
650
what do i have to do to get it ?
Thanks for the help !
Use an array and initialize it.
First you need to name your structure:
struct candidate {
std::string engineType;
std::string brand;
int price;
int range;
};
Then create and initialize the array:
std::array<candidate, 2> candidates = {
{ "Electric", "IONIQ5", 35000, 450 },
{ "Electric", "Tesla_Model_3", 55000, 650 }
};
And finally iterate over it:
for (auto const& candidate : candidates) {
std::cout << "Price: " << candidate.price << '\n';
}
All this should be well-covered in a decent book.
You can use an array with elements of type Candidate and then loop through the array and print the values as shown below:
//class representing a Candidate info
struct Candidate{
string engineType;
string brand;
int price;
int range;
};
int main() {
//create an array witht element of type Candidate;
Candidate arr[] = {{"IONIQ5", "Honda", 450, 3500}, {"Tesla_Model_3", "Tesla", 650, 55000}};
//iterate through the array using range based for loop
for(const Candidate& candidate: arr)
{
std::cout<<candidate.range<<std::endl;
}
}
Working demo
You cannot use candidate1 like candidate[i] because it works as a variable name . You need to use maps or arrays for this type of tasks.
You are declaring 2 separate variables, called candidate1 and candidate2 as an array, so candidate[i] does not resolve to anything.
You need to initialize the array as follows:
main ()
{
struct
{
string engineType;
string brand;
int price;
int range;
} candidate[3];
// information of candidate 1
candidate[1].brand = "IONIQ5";
candidate[1].range = 450;
candidate[1].price = 35000;
// information of candidate 2
candidate[2].brand = "Tesla_Model_3";
candidate[2].range = 650;
candidate[2].price = 55000;
// show each price with while function
int i = 1;
while (i < 3)
{
cout << "Price :" << candidate[i].range << endl;
i++;
}
return 0;
}
Please note that arrays start with 0, so an array of 3 will have values for postitions 0, 1, 2, hence the candidate[3], but I would recommend going with candidate[2] and setting values for positions 0 and 1.

How can I print any given target element in a vector? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to make a function that has access to a specific element found in a vector. The goal is that the function would dynamically work with any element it is passed. I am not sure how else to implement this, but I am trying to use pointers and offsets, but I cant figure out how to properly calculate the offset since (afaik) pointer subtraction requires the same object type. Any help would be appreciated!!
This picture shows what I am trying to do on the right side (to get the target element in each item).
https://imgur.com/a/MvwRFaJ
#include <iostream>
#include <vector>
struct item
{
int numItems = 0;
float price = 0;
double foo = 0;
item(int num, float pr, double f)
{
numItems = num;
price = pr;
foo = f;
}
};
// GOAL: I can pass any target element of the vector as an argument,
// and have some sort of loop to print that element found in the entire vector
/// <summary>
/// This function prints any given target element through the entirety of a vector
/// </summary>
/// <param name="vecItemPtr"> Starts as the pointer to the first item found in the vector,
/// vecItemPtr is iterated after each targetElement is printed </param>
/// <param name="targetElemPtr"> Indicates the position of the element we are trying to
/// find in each item</param>
/// <param name="endIndex"> Indicates the number of items in the array that we will have to
/// iterate through</param>
template <class T>
void printValues(item* vecItemPtr, T* targetElemPtr, int numItems)
{
// I think It would be possible to do this by finding the
// 'offset' (in bytes) of the targetElement found in each item
// BUT these items are of different type (*int/*float/*double vs item*)
ptrdiff_t targetElementOffset = targetElemPtr - vecItemPtr;
// ^ Error C2440 '-': cannot convert from 'item *' to 'T*' IterateVectorPtr
for (int i = 0; i < numItems; i++)
{
// Print the value found at the address of the vecItemPtr PLUS the offset
printf("%f", *(vecItemPtr + targetElementOffset));
}
vecItemPtr++;
}
int main()
{
std::vector<item> test;
item item1(10, 3.0f, 8);
item item2(20, 1.0f, 4);
test.reserve(2);
test.push_back(item1);
test.push_back(item2);
// Say I want to print all numItems in the vector
printValues(&test[0], &test[0].numItems, test.size());
// Say I want to print all prices in the vector
printValues(&test[0], &test[0].price, test.size());
// Say I want to print all foo's in the vector
printValues(&test[0], &test[0].foo, test.size());
}
The reason your code doesn't work is because you are trying to perform pointer arithmetic using incompatible pointer types. Since you need to deal with byte offsets, you need to operate with byte pointers, eg:
template <class T>
void printValues(item* vecItemPtr, T* targetElemPtr, int numItems)
{
ptrdiff_t targetElementOffset = reinterpret_cast<char*>(targetElemPtr) - reinterpret_cast<char*>(vecItemPtr);
for (int i = 0; i < numItems; i++)
{
std::cout << *reinterpret_cast<T*>(reinterpret_cast<char*>(vecItemPtr + i) + targetElementOffset) << std::endl;
}
}
...
printValues(&test[0], &test[0].numItems, test.size());
printValues(&test[0], &test[0].price, test.size());
printValues(&test[0], &test[0].foo, test.size());
Demo
However, a safer and cleaner solution is to use a pointer-to-member instead, then you don't need to deal with byte offsets manually at all, eg:
template <class T>
void printValues(item* vecItemPtr, T item::* targetElemPtr, int numItems)
{
for (int i = 0; i < numItems; i++)
{
std::cout << (vecItemPtr[i].*targetElemPtr) << std::endl;
}
}
...
printValues(test.data(), &item::numItems, test.size());
printValues(test.data(), &item::price, test.size());
printValues(test.data(), &item::foo, test.size());
Demo
For more flexibility you can let the function take a functor. Don't use pointers, also don't pass the size seperate from the container. One benefit of using std::vector is that you need not do that. If you pass iterators, the same function will also work for other containers with ForwardIterators.
For example you might want to to let the function print the product of numItems and price:
#include <iostream>
#include <vector>
struct item {
int numItems = 0;
float price = 0;
double foo = 0;
item(int num, float pr, double f) : numItems(num), price(pr), foo(f)
{
// prefer the member initialization list over assignment in the constructors body
}
};
template <class IT,class F>
void printValues(IT begin, IT end, F f) {
for (; begin != end; ++begin) {
std::cout << f(*begin) << "\n";
}
}
int main() {
std::vector<item> test;
item item1(10, 3.0f, 8);
item item2(20, 1.0f, 4);
test.reserve(2);
test.push_back(item1);
test.push_back(item2);
printValues(test.begin(),test.end(),[](auto i){ return i.numItems;});
printValues(test.begin(),test.end(),[](auto i){ return i.numItems * i.price;});
}
Output:
10
20
30
20

How to access the object array in c++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am new to programming. My goal is to realize the pancake sort in C++ without using STL. I have 3 classes, they are pancake, pancakepile and MpancakePiles. I have a question about the access to the object array. My code is as following:
My pancake pile is a 3D pile and Z is it's height.
So for a single pancake pile, it has Z pancakes.
I need to find the max size's index of these Z pancakes.
However, I don't know how to access the object array, like what should I fill in the ??? area if I want to process the object array size inside the pancake P. Max is a defined function.
There is no particular reason for not using STL. N is a static size, N=512. burnt=0 means burnt side face down.
int Max(int size[], int n)
{
int mi,i;
for(mi=0,i=0;i<n;i++)
if(size[i]> size[mi])
mi=i;
return mi;
}
class pancake
{
public:
int size;
bool burnt;
void flip_pancake()
{
burnt=~burnt;
}
};
class pancakepile
{
public:
pancake P[N];
int Z;
void pan_sort_ascending()
{
int mi=Max(???,Z);
......
}
}
You throw away your current implementation of pan_sort_ascending, and replace it with a call to std::sort, passing a function that describes which of two pancakes should go below the other.
#include <algorithm>
// A pancake is smaller than another if it's size is less
bool pancake_less(const pancake & lhs, const pancake & rhs)
{
return lhs.size < rhs.size;
}
// sorts smallest first
void pancakepile::pan_sort_ascending()
{
std::sort(P, P + Z, pancake_less);
}
Now if you want a pan_sort_descending, you can just flip the logic of the comparison
// A pancake is larger than another if it's size is greater
bool pancake_greater(const pancake & lhs, const pancake & rhs)
{
return lhs.size > rhs.size;
}
// sorts largest first
void pancakepile::pan_sort_descending()
{
std::sort(P, P + Z, pancake_greater);
}
I am not sure what you want but If you only want to return the bigest pancake of the pancake list I would implement a memberfunction in the pancakepile class:
class pancakepile
{
public:
pancake P[N];
int Z;
void pan_sort_ascending()
{
int mi=max();
......
}
pancake max()
{
pancake bigestPancake;
foreach(pancake pan, P)
{
if(bigestPancake.Z < pan.Z)
bigestPancake = pan;
}
return bigestPancake;
}
}
Edit:
If you want to get the Index of the bigestPancake you can do this instead:
class pancakepile
{
public:
pancake P[N];
int Z;
void pan_sort_ascending()
{
int mi=max();
......
}
int max()
{
int bigestPancakeIndex;
for(int i = 0; i < P.size(); i++)
{
if(P[bigestPancakeIndex].Z < P[i].Z)
bigestPancakeIndex= i
}
return bigestPancakeIndex;
}
}

C++ structure issue [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
What is the functionality of this part below?
bool operator < ( const edge& p ) const
{
return w < p.w;
}
I'm giving the Full code here(I don't know if it's necessary or not to paste the whole code). I just don't understand the structure part.
I've searched several resources but don't get any simplicity.
struct edge
{
int u,v,w;
bool operator < ( const edge& p ) const
{
return w < p.w;
}
};
int pr[MAXN];
vector<edge>e;
int find(int r)
{
return (pr[r]==r) ? r: find(pr[r]);
}
int mst(int n)
{
sort(e.begin(),e.end());
for(int i=1;i<=n;i++)pr[i]=i;
int count=0,s=0;
for(int i=0;i<(int)e.size();i++)
{
int u=find(e[i].u);
int v=find(e[i].v);
if(u!=v)
{
pr[u]=v;
count++;
s+=e[i].w;
if(count==n-1) break;
}
}
return s;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edge get;
get.u=u; get.v=v; get.w=w;
e.push_back(get);
}
cout<<mst(n)<<endl;
return 0;
}
Think about when you do 1 < 3. 1 is obviously smaller than 3. Alright, but suppose you have this struct/class/union (note the 3 are almost the same thing in C++) called Toy:
struct Toy
{
float _volume;
float _weight;
std::string _brand;
};
Now you instantiate 2 Toy objects:
Toy car, kite;
car._volume = 27000.0; //27000 cm^3
car._weight = 150.0; //150 grams
kite._volume = 10000; //10000 cm^3
kite._weight = 200.0; // 200 grams
if (kite < car){
std::cout << "car!"; // is toy car bigger!?
}else{
std::cout << "kite!"; // or is it the kite?
}
Now, there, the C++ language doesn't know what you mean when you check if the kite is smaller than the toy car. It could be either that you want to see which has less weight, or it could be that you're checking which takes less space; smaller in volume. To solve the ambiguity, C++ asks you the programmer to implement operators for your custom objects.
If we strip the syntactic sugar part of the design of many operators, let it be smaller than (<) for the sake of the example, a < b becomes a.operator<(b). So operator< can be said to be a class/struct/union method like any other!
To clear the ambiguity in the toy example, we re-implement/overload our struct's operator<() method to let it compare volumes as follows:
struct Toy
{
float _volume;
float _weight;
std::string _brand;
bool operator<(const Toy & otherToy)
{
return _volume < otherToy._volume; // or ._weight for each if we want to compare by weight
}
};
if (kite < car){
std::cout << "car!"; // the car has more volume!
}else{
std::cout << "kite!";
}
With your code snippet, you can see that an edge object comparison criterion was defined in operator< definition as the member w. So whichever has the smaller w is the smaller object when compared with that operator.