Kevin Hernandez
Kevin Hernandez

Reputation: 1

C++ Data Structure: Can't display string corresponding to the largest number

My first C++ class coming from a basic Java class. This class is a more advanced C++ programming class about Data Structures. I don't know the basics of C++, only a little basics of Java.

Assignment is to :

-get 3 user inputs of states and their population (done).

-Get the most populated (biggest of three) and post it. (1/2)

I am able to get the highest number... but I'm not sure on the syntax on how to post it with the corresponding string (state).

I know this is some kind of array using struct, but I dont know how to post st.title

 #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <sstream>
    using namespace std;

    struct states_t {
        string statename;
        int population;
    } state[3];



    int main()
    {
        string mystr;
        int n;

        for (n = 0; n<3; n++)
        {
            cout << "Enter state name: ";
            getline(cin, state[n].statename);
            cout << "Enter population: ";
            getline(cin, mystr);
            stringstream(mystr) >> state[n].population;
        }

        cout << "\nYou have entered these movies:\n";
        for (n = 0; n < 3; n++)
            cout << state[n].statename << "\n" << state[n].population << "\n";
        return 0;


    }

==== UPDATED CODE WITH LARGEST POPULATION ====

#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct states_t {
    string statename;
    int population;
} state[3];



int main()
{
    string mystr;
    int n;

    for (n = 0; n<3; n++)
    {
        cout << "Enter state name: ";
        getline(cin, state[n].statename);
        cout << "Enter population: ";
        getline(cin, mystr);
        stringstream(mystr) >> state[n].population;
    }

    cout << "\nYou have entered these states:\n";
    for (n = 0; n < 3; n++)
        cout << state[n].statename << " " << state[n].population << "\n" << "\n";





    if ((state[0].population >= state[1].population) && (state[0].population >= state[2].population))
        cout << "The most populous state you entered is: " << state[0].statename << " with a population of " << state[0].population << "\n";
    else if ((state[1].population >= state[0].population) && (state[1].population >= state[2].population))
        cout << "The most populous state you entered is: " << state[1].statename << " with a population of " << state[1].population << "\n";
    else
        cout << "The most populous state you entered is: " << state[2].statename << " with a population of " << state[2].population << "\n";

    return 0;


}

Upvotes: 0

Views: 168

Answers (4)

David C. Rankin
David C. Rankin

Reputation: 84561

While there is nothing that prevents you from using a standard array-of-struct as you would in C, embracing the C++ std::vector can take a bulk of the tedium out of it. While using the array-of-struct, you get the benefit of protecting your array bounds manually indexing and manually handling storage, C++ has long sought to help alleviate or ease the manual aspects of handling collections of "things" (for lack of better words)

The std::vector container is tailor made to allow you to add to a collection of things using the simple push_back modifier. Basically you define your struct (say s_state_t) holding your name and pop, much as you have, and then declare and create an instance of a vector of type <s_state_t> (say state). Then to add a state (say s) to the vector you simply state.push_back(s) and let std::vector handle the storage and indexing. (vector also provides many other helpful member functions and modifiers to help get information about your collection)

Then the C++ way to approach managing a collection of states is to create either an additional struct or class to manipulate your collections of states, to add to, check and keep track of the max/min populations, etc. In a very simple form, you could create a class, that provides member functions that do just that, add a new state, check the max/min and then provide a way to output the contents of your collection. For example, you could do something like:

#include <vector>
#include <string>
#include <iomanip>
#include <limits>

typedef struct {        /* struct holding state name and population */
    std::string name;
    int pop;
} s_state_t;

class country {         /* class country - a collection of states */ 
    std::vector<s_state_t> state;   /* declare vector for states */
    s_state_t mx = { "", 0 },       /* declare structs for max min */
            mn = { "", std::numeric_limits<int>::max() };
    void chkmxmn (s_state_t s) {    /* function to set max/min */
        if (s.pop < mn.pop)
            mn = s;
        if (s.pop > mx.pop)
            mx = s;    
    }
  public:
    void addstate (std::string name, int pop) { /* add a state */
        s_state_t s = { name, pop };    /* struct for new state */
        chkmxmn (s);                    /* update max and min */
        state.push_back (s);            /* push_back to vector */
    }
    void prnstates() {                  /* output saved states, max/min */
        for (auto& i : state)           /* loop over vector */
            std::cout << std::setw(16) << std::left << i.name << 
                        std::setw(10) << std::right << i.pop << "\n";
        std::cout << "\nminimum and maximum populations:\n" <<
                    std::setw(16) << std::left << mn.name <<
                    std::setw(10) << std::right << mn.pop << "\n" <<
                    std::setw(16) << std::left << mx.name <<
                    std::setw(10) << std::right << mx.pop << "\n";
    }
};

int main (void) {

    country us; /* instance of country */

    us.addstate ("Texas", 25000000);        /* add names/pops */
    us.addstate ("Louisiana", 12000000);
    us.addstate ("California", 50000000);
    us.prnstates(); /* output results */

    return 0;
}

(note: you should add additional validations to check the name is not NULL or empty and pop is a reasonable number -- that is left to you)

Example Use/Output

$ ./bin/vector_states
Texas             25000000
Louisiana         12000000
California        50000000

minimum and maximum populations:
Louisiana         12000000
California        50000000

note: you can also create a typedef to your new vector type to cut down on the typing associated with specifying instances and parameters of the type with something similar to:

typedef std::vector<s_state_t> state_t; /* typedef to cut down typing */

which then allows you to declare new instances or parameters as simply, e.g.:

state_t state;                  /* declare vector for states */

Look things over. Neither method is more "right or wrong", but if you are going to learn C++ instead of C, you might as well go ahead and use the nice parts of it.

Upvotes: 0

user3109891
user3109891

Reputation: 50

Here's how I would do it:

I would first make two int arrays, one corresponding to the index values of the array of struct states_t, and then one corresponding to the population values, like such:

int index[3];
int pop[3];

for (int i = 0; i < 3; i++)
{
    index[i] = i;
    pop[i] = st[i].population;
}

Next, perform a bubble sort algorithm on the population, and move the indices of the objects around according to the actions of the sort algorithm like such:

int n = 3;

for (int i = 0 ; i < ( n - 1 ); i++)
{
    for (int j = 0 ; j < n - i - 1; j++)
    {
        //if the population of the next element
        //is higher than the current element, swap it
        //perform the same operation for state indices
        if (array[j] > array[j+1]) 
        {
            int swap = pop[j];
            int swap2 = index[j];
            pop[j] = pop[j+1];
            index[j] = index[j+1];
            pop[j+1] = swap;
            index[j+1] = swap2;
        }
    }
}

All that's left to do now is to call the first object in the list with the index array like such:

st[index[0]].title; //state with highest population

Coolest part about this method is that you can make this work for any number of States by changing the value of int n.

Upvotes: 0

Code-Apprentice
Code-Apprentice

Reputation: 83527

The first step is to store the name of each state with its population. It will help if you change title to name to make it more clear what the variable is for. If you do this correctly, you will quickly see that you no longer need mystr. (Note that you should always use meaningful variable names. A generic name like mystr often means that you do not know the purpose of the variable. Keep thinking about what the variable is for in order to make a more useful name.)

Now once you have the state data input into the array correclty, you should keep track of the data for the least and most populous state, rather than just its population. Instead of

int mn, mx;

declare

state_t mn, mx;

Then in your if statement do

mn = st[n];

and similarly for mx.

You will have to change your if condition to access the value in the struct. Then you can print the values directly from mn and mx.

Upvotes: 1

Maarten Hilferink
Maarten Hilferink

Reputation: 723

Your code is designed to find the highest (and lowest) population of all states. You could also have tried to find out what the index-number is of the state with the highest population and use that number to index the state array to get what you need from there.

Upvotes: 0

Related Questions