C++ structure issue [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 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.

Related

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;
}
}

Program works fine only for one test case - Debugging [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 6 years ago.
Improve this question
I want to know whether my graph is bipartite or not, I have several test cases. If I run more than one test case it doesn't work properly, it always shows Bipartite. I am having a hard time figuring it out. For just one case, it works fine for any graph.
Here goes my code.
#include <iostream>
#include <cstdio>
#include <stack>
#include <list>
using namespace std;
class Graph
{
public:
int V;
list<int> *adj;
Graph(int V);
void addEdge(int v, int w);
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w);
adj[w].push_back(v);
}
class Bipartite
{
private:
bool isBipartite;
bool *color;
bool *marked;
int *edgeTo;
stack<int> cycle;
public:
Bipartite(Graph G)
{
isBipartite = true;
color = new bool [G.V];
marked = new bool [G.V];
edgeTo = new int [G.V];
for (int v = 0; v < G.V; v++)
{
if (!marked[v])
{
color[v] = false;
dfs(G, v);
}
}
delete color;
delete marked;
delete edgeTo;
}
void dfs(Graph G, int v)
{
marked[v] = true;
list<int>::iterator w;
for (w = G.adj[v].begin(); w != G.adj[v].end(); w++)
{
if (!cycle.empty())
return;
if (!marked[*w])
{
edgeTo[*w] = v;
color[*w] = !color[v];
dfs(G, *w);
}
else if (color[*w] == color[v])
{
isBipartite = false;
cycle.push(*w);
for (int x = v; x != *w; x = edgeTo[x])
{
cycle.push(x);
}
cycle.push(*w);
}
}
}
bool isBi()
{
return isBipartite;
}
};
void solve(int n,int **p){
long long int x,y;
Graph g(n);
for(x=0;x<n;x++)
for(y=0;y<n;y++)
{
if(p[x][y]==1)
g.addEdge(x,y);
}
Bipartite b(g);
if (b.isBi())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
int main()
{
long long int i,j,t,x,m,y,a,b;
int **p,n;
cin>>t;
for(i=0;i<t;i++)
{
cin>>n>>m;
p=new int*[n]();
for(x=0;x<n;x++)
{
p[x]=new int[n]();
}
for(j=0;j<m;j++)
{
cin>>a>>b;
a=a-1;
b=b-1;
p[a][b]=1;
p[b][a]=1;
}
for(x=0;x<n;x++)
{
for(y=0;y<n;y++)
{
if(x!=y)
{
p[x][y]=1-p[x][y];
}
}
}
/* for(x=0;x<n;x++)
{
for(y=0;y<n;y++)
cout<<p[x][y]<<" ";
cout<<"\n";
}
*/
solve(n,p);
}
return 0;
}
You never explicitly initialize the contents of marked, or, more accurately, the contents of the array that it points to.
The loop in your constructor reads elements of marked to decide how to assign to color, but you never initialized the elements of marked being read.
Similiar argument for color and edgeTo.
This means that, while they may have had the expected initializations for the first case, may well be using whatever value happened to be there in later cases.
Also Bipartite(Graph G) is calling the default copy constructor of Graph. Probably not what you want.
Try Bipartite(const Graph & G) instead (also in dfs).
And don't do new without delete.
Rather use vector<vector<int>> adj;, why even list? And reinit it in constructor with adj.resize(V);.
After your edit of code in question, as you use new to allocate array, you should delete it as array too, so use delete[] color;.
Or stop using new/delete completely. Again you can use std::vector<bool> color(G.V);, avoiding both new/delete hassle, and also having all values initialized to false by default.
In modern C++ there're very few (more like "none") reasons to ever use new or delete (unless you write some low level library, or you are optimizing for performance, and you know what you are doing).

C++ Class/Function interaction

I'm fairly new to c++ classes and exactly how they work, but I'm trying to figure what issues I have with this code. What I'm trying to do is that the class handle the dice object, how many faces the die has and the value of the roll. Then use those values later on in the code. I know I've done something fundamentally wrong here I'm just not sure what.
The class header is:
class Dice {
private :
int face ;
int value ;
public:
Dice()
{
face = 6;
}
Dice(int faceVal)
{
face = faceVal;
}
Dice(Dice &other)
{
face = other.face;
}
Dice& operator=(const Dice &rhs);
int roll() ;
int getValue() const { return value; }
int getFace() const { return face; }
} ;
Dice& Dice::operator=(const Dice &rhs)
{
face = rhs.face;
return *this;
}
#endif
The functions/methods that are being used:
int Dice::roll()
{
srand((unsigned)time(0));
int randomNumber = 1 + rand() % 5;
value = randomNumber;
return randomNumber;
}
int rollAll(Dice cup[], int n)
{
int faces = 0;
for(int i = 0; i < n; i++)
faces += cup[i].roll();
return sum ;
}
And the entrance into them from the main function is:
total = rollAll(cup,2) ;
for (int i = 0 ; i < 2 ; i++ )
(arr[i] = cup[i].getValue());
The glaring issue with your code is that your copy constructor and assignment operator are incorrect. You are failing to actually copy the object fully, as you are missing the value member in the copying operations.
Dice(Dice &other)
{
face = other.face;
// where is the `value` member?
}
So where is the copy of the value member being made? If you miss any members during the copy, your program will be using "half-copies" masquerading as real copies. These types of bugs, where you don't copy everything, are some of the toughest to find.
This is one reason why you should not get involved in writing copy/assignment functions unless it is absolutely required. In your case, the compiler generated copy constructor / assignment operator will do the job correctly without you having to write one.

How to write Console terminal with C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am studying for an exam and need your help.
I must write my own console terminal in C++, which must work in this way:
Example:
:>plus 5 7 "hit ENTER"
:>12
:>minus 10 12 "hit ENTER"
:>-2
:>combine Hello World "hit ENTER"
:>HelloWorld
:>run netstat "hit ENTER"
:>runs netstat
:>help
:>plus int1 int2
minus int1 int2
combine string1 string2
run ?????
:>exit
program exits
For main block I think it would be something like this
int main(void) {
string x;
while (true) {
getline(cin, x);
detect_command(x);
}
return 0;
}
The functions would be something like this
void my_plus(int a, int b) {
cout << a + b;
}
void my_minus(int a, int b) {
cout << a - b;
}
void my_combine(string a, string b) {
?????????????;
}
void my_run(?????????) {
???????????;
}
And the finally detect_command
void detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0) {
?????????????????????;
}
}
}
????? - means I don`t know what to write.
Help to make this program work.
Thanks.
I'm going to use the minus operation as an example...
Make a structure like so:
struct cmd_struct {
const char *name;
void (*func) (void *data);
};
Since your function parameters aren't the same, you gotta make a structure for each, e.g.:
struct minus_op {
int rhs;
int lhs;
};
And use the cmd_struct as an array, like so:
static cmd_struct commands[] = {
{ "minus", &my_minus },
...
};
my_minus would then be:
void my_minus(void *data) {
struct minus_op *mop = data;
... do the computation and return ...
}
And loop through it to detect the command used:
for (int i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) {
if (strcmp(commands[i].name, a) == 0) {
... prepare the data ...
commands[i].func(data);
}
}
Side Note: In order to get the function parameters from command line, have a splitter, e.g. a white space. Use a vector for this and pass that vector to detect_command
Do also note: Get rid of the void param used in this example and use a char **argv and int argc like in main(). argv would be the arguments, and argc would be the number of arguments passed to the function. e.g. if you say to the program:
>> minus 5 1
Then argc should be 2 (the 5 and the 1) and argv[0] = "5" and argv[1] = "1".
Now that you know the idea behind it, implementing a more flexible version is left to you.
Call a respective function to handle each word. For example:
enum commands {
PLUS,
MINUS,
HELP,
EXIT
//....
};
int detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0)
return i;
}
return -1; //unknow word
}
Give the string to detect_command() the function return the respective integer to enum commands (that's our i value) or -1 if word is unknow. Then you can write a function like this to use and process the value determined by detect_command():
void run_command(int cmd)
{
switch(cmd) {
case PLUS: run_plus(); break;
case MINUS: run_minus(); break;
// and so on to all comamnds available
default: error("unknow command");
}
}
each function run_*() should continues the command parsing according to own rules, i.e, the "plus" command should be follow by one integer, one white-space and then another integer, right? run_plus() must validate it and then compute the result. e.g.:
//pseudo code
void run_plus()
{
//input here is one after "plus" word
//here we must validate our valid input: two digits split by a white-spaces
int x = parse_digit();
check(white-space);
int y = parse_digit();
int r = x + y;
display_result(r);
}
NOTE: I'm not a C++ programmer; I did detect_command() code modification to you get my idea. I even don't know if it will compile in C++ for the mismatch types.

Sorting using vectors [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 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;