Reputation: 13
I am trying to make a city distance calculator using the longitude and latitude of a city. The problem I am having is putting the cities into an array. My array attempt is commented out in the main method. Please let me know what I am doing wrong.
#include <iostream>
#include <math.h>
#define pi 3.14159265358979323846
using namespace std;
double distance(double lat1, double lon1, double lat2, double lon2, char unit);
double deg2rad(double deg);
double rad2deg(double rad);
class City
{
public:
//declare variables
string name;
double latitude;
double longitude;
City(string, double, double); //constructor
double distance(string, string);
};
double cityDistance(City a, City b);
int main() {
//construct cities
City Providence("Providence", 41.8239890, -71.4128340);
City Cranston("Cranston", 41.7798230, -71.4372800);
City NewYork("NewYork", 40.7143530, -74.0059730);
City Boston("Boston", 42.3584310, -71.0597730);
City Killington("Killington", 43.6775680, -72.7798250);
City Springfield("Springfield", 42.1014830, -72.5898110);
City Bridgeport("Bridgeport", 41.1865480, -73.1951770);
City Cambridge("Cambridge", 42.3736160, -71.1097340);
City Norwalk("Norwalk", 41.1175970, -73.4078970);
City Quincy("Quincy", 42.2528770, -71.0022710);
//put city into array
// City cityArray[] = { };
// cityArray[0] = {"Providence", 41.8239890, -71.4128340};
// cityArray[1] = {"Cranston", 41.7798230, -71.4372800};
// cityArray[2] = {"NewYork", 40.7143530, -74.0059730};
// cityArray[3] = {"Boston", 42.3584310, -71.0597730};
// cityArray[4] = {"Killington", 43.6775680, -72.7798250};
// cityArray[5] = {"Springfield", 42.1014830, -72.5898110};
// cityArray[6] = {"Bridgeport", 41.1865480, -73.1951770};
// cityArray[7] = {"Cambridge", 42.3736160, -71.1097340};
// cityArray[8] = {"Norwalk", 41.1175970, -73.4078970};
// cityArray[9] = {"Quincy", 42.2528770, -71.0022710};
//calculate distance
cout << "Distance between Providence and Cranston: " << distance(41.8239890, -71.4128340, 41.7798230, -71.4372800, 'M') << endl;
cout << "Distance between NewYork and Boston: " << distance(40.7143530, -74.0059730, 42.3584310, -71.0597730, 'M') << endl;
cout << "Distance between Killington and Norwalk: " << distance(43.6775680, -72.7798250, 41.1175970, -73.4078970, 'M') << endl;
//print distance using city name
cout << endl;
cout << "Distance between Providence and Cranston: " << cityDistance(Providence, Cranston) << endl;
cout << "Distance between NewYork and Boston: " << cityDistance(NewYork, Boston) << endl;
cout << "Distance between Killington and Norwalk: " << cityDistance(Killington, Norwalk) << endl;
//end
return 0;
}
City::City(string n, double lt, double lg)
{
name = n;
latitude = lt;
longitude = lg;
}
double deg2rad(double deg)
{
return (deg * pi / 180);
}
double rad2deg(double rad)
{
return (rad * 180 / pi);
}
double distance(double lat1, double lon1, double lat2, double lon2, char unit)
{
double theta, dist;
theta = lon1 - lon2;
dist = sin(deg2rad(lat1)) * sin(deg2rad(lat2)) + cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * cos(deg2rad(theta));
dist = acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
switch(unit) {
case 'M':
break;
case 'K':
dist = dist * 1.609344;
break;
case 'N':
dist = dist * 0.8684;
break;
}
return(dist);
}
double cityDistance(City a, City b)
{
return distance(a.latitude, a.longitude, b.latitude, b.longitude, 'M');
}
Upvotes: 1
Views: 5723
Reputation: 7068
The way you do it now is you create an array of size 0. Then you try to put your cities in non-existent cells 0 to 9.
One way to solve that issue is to declare an array of size 10 without specifying content at the declaration point.
City cityArray[10];
And then assign each cell individually as you do. This, however is not the best solution and it won't even work, because you haven't defined a default parameterless constructor.
You can instead create an array whith cities you exactly want your array to hold. See code below.
If you want to use struct-like initialization, like you do, the code would go like this:
//put city into array
City cityArray[] = {
{"Providence", 41.8239890, -71.4128340},
{"Cranston", 41.7798230, -71.4372800},
{"NewYork", 40.7143530, -74.0059730},
{"Boston", 42.3584310, -71.0597730},
{"Killington", 43.6775680, -72.7798250},
{"Springfield", 42.1014830, -72.5898110},
{"Bridgeport", 41.1865480, -73.1951770},
{"Cambridge", 42.3736160, -71.1097340},
{"Norwalk", 41.1175970, -73.4078970},
{"Quincy", 42.2528770, -71.0022710}
};
However, you have defined a constructor for the class City, therefore, this won't compile. You can do it like this instead:
City cityArray[] = {
City("Providence", 41.8239890, -71.4128340),
City("Cranston", 41.7798230, -71.4372800),
City("NewYork", 40.7143530, -74.0059730),
City("Boston", 42.3584310, -71.0597730),
City("Killington", 43.6775680, -72.7798250),
City("Springfield", 42.1014830, -72.5898110),
City("Bridgeport", 41.1865480, -73.1951770),
City("Cambridge", 42.3736160, -71.1097340),
City("Norwalk", 41.1175970, -73.4078970),
City("Quincy", 42.2528770, -71.0022710)
};
You could also reuse City objects you have just created above:
City cityArray[] = {
Providence,
Cranston,
NewYork,
Boston,
Killington,
Springfield,
Bridgeport,
Cambridge,
Norwalk,
Quincy
};
But in the code above, you have to be aware that the objects Providence
, Cranston
etc. will be copied to the array. Therefore you will have two independent copies of the same data, e.g. one in Providence
variable and one in cityArray[0]
. Changing one won't affect the other.
Whatever case you choose, this will create an array of fixed size (as all arrays in c++ have a fixed size). You cannot add any more cities.
If you want your array to be 'extendable' - you would like to add new cities to it in the future, then instead of an array you should use one of the STL collections. Such as vector<City>
or map<City>
. Map is especially useful if you intend to search the collection for a specific city, e.g. by its name.
Upvotes: 4
Reputation: 2049
Arrays are not dynamic in C++. You'd need to declare your array with the exact size you're going to need. You can't also populate a class with that notation, it's not a valid C++ construct since you didn't declare a default constructor. Try something like this:
//put city into array
City cityArray[9];
cityArray[0].name = "Providence";
cityArray[0].latitude = 41.8239890;
cityArray[0].longitude = -71.4128340;
cityArray[1] = ...
You could of course make it a little less verbose, and make it dynamic, using the constructor for your class and an STL container like vector.
explicit vector<City*> cityArray(9);
cityArray.push_back(new City("Providence", 41.8239890, -71.4128340));
...
The argument (size) in the vector's constructor is optional, but you'll get better performance if you explicitly tell it to reserve memory for the most likely number of cities you're going to store. The vector will grow automatically if that limit is surpassed.
Upvotes: 2
Reputation: 15870
This is a great example of when to use std::vector
or std::map
. In this particular case, I think std::map
would be the better choice (since you wouldn't have to iterate the entire list to find 2 cities you are looking for):
std::map<std::string, City> cities;
cities["Providence"] = City("Providence", 41.8239890, -71.4128340);
// ...
Upvotes: 3
Reputation: 1583
Use this
City cityArray[10] = {
City ("Providence", 41.8239890, -71.4128340),
City ("Cranston", 41.7798230, -71.4372800),
City ("NewYork", 40.7143530, -74.0059730),
City ("Boston", 42.3584310, -71.0597730),
City ("Killington", 43.6775680, -72.7798250),
City ("Springfield", 42.1014830, -72.5898110),
City ("Bridgeport", 41.1865480, -73.1951770),
City ("Cambridge", 42.3736160, -71.1097340),
City ("Norwalk", 41.1175970, -73.4078970),
City ("Quincy", 42.2528770, -71.0022710)
};
Upvotes: 0