简体   繁体   中英

How do I write a function to calculate nearest point in C++?

I have a homework due on monday and I can't seem to figure it out. I don't know how to calculate nearest point. As you can see in my code I tried using arrays but it didn't work. The homework must be solved with linked lists. I was thinking of using a third variable, and comparing 2 elemtents of a list using a for loop and then storing the greatest in a variable, which is then also compared with the rest of the elements.

#include <iostream>
#include <cmath>
#include <string>
using namespace std;

struct obstacle {
    string carname;
    float x, y;
    float distance;
    obstacle *next;
};
obstacle *head = nullptr;

float DistanceToOrigin (float x, float y)
{
    float distance;
    distance = sqrt((x*x) + (y*y));
    return distance;
}
float CalcNearestPoint(obstacle points[], obstacle point, int n)
{
    obstacle temp;
    for (int i=0;i<n;i++){
        if(points[i].distance>points[i-1].distance)
        {
            temp.distance = points[i].distance;
            points[i].distance = points[i-1].distance ;
            points[i-1].distance = temp.distance;
        }
    }
    DistanceToOrigin(points[0].x,points[0].y);

}
void insertObstacle (string name, float a, float b)
{
    obstacle *newObstacle = new obstacle;
    newObstacle->carname = name;
    newObstacle->x = a;
    newObstacle->y = b;
    newObstacle->next = head;
    head = newObstacle;
}
int main()
{
    int x, y;
    string name;
    while (name != "0"){

        {
        cout << "string describing obstacle (""0"" for end of input):";
        cin >>name;
        cout << "\nx and y coordinate: ";
        cin >> x >> y;
        insertObstacle(name, x, y);
        }

    }
}

The required output looks something like this

string describing obstacle ("end" for end of input): A 
x and y coordinate: 0 1 
string describing obstacle ("end" for end of input): X 
x and y coordinate: 1 1 
string describing obstacle ("end" for end of input): E 
x and y coordinate: 0 3 
string describing obstacle ("end" for end of input): K 
x and y coordinate: -1 4 
string describing obstacle ("end" for end of input): W 
x and y coordinate: 0 10 
obstacle obstacle (end of end): end 
obstacle A: (0.00, 1.00), distance: 1.00m, nearest to this: X 
obstacle X: (1.00, 1.00), distance: 1.41m, nearest to this: A 
obstacle E: (0.00, 3.00), distance: 3.00m, nearest to this: K
obstacle K: (-1.00, 4.00), distance: 4.12m, nearest to this: E 
obstacle W: (0.00, 10.00), distance: 10.00m, nearest to this: K 
delete: AX

CalcNearestPoint is implementing a bubble sort. But you're missing the outer loop of the bubble sort, so you are only partially sorting your list. There are far more efficient solutions to this problem than sort-then-use-index-zero, but if you want to fix your code as written, go lookup how to write a canonical bubble sort and then add the outer loop.

So, I don't know if i understand it right, but i'll try my best.

So, as you are making a list, the insert function should look something like this

void insertObstacle(string name, float a, float b)
{
    //Create new obstacle
    obstacle* newObstacle = new obstacle;
    newObstacle->carname = name;
    newObstacle->x = a;
    newObstacle->y = b;
    newObstacle->next = head;

    //Update head
    head = newObstacle;
}

The function inserts the newly created element in the beginning of the list.

As far as I understand, you need the closest point to the center of the coordinate system, and you are returning the distance by return value, and the point via obstacle**

As you are supposed to work with lists and not arrays, your first argument has to be the head to the function. After that iterate over all the elements of the list, untill you come to the end of the list (the nullptr)

float CalcNearestPoint(obstacle* head, obstacle** point)
{
    //If the list is empty, return
    if(head == nullptr)
    {
        return 0.f;
    }

    //If you need the closest point
    obstacle* closest;
    //Distance between the first element and the given point
    float min_distance = DistanceToOrigin(head, point);


    for (obstacle* current = head->next; current != nullptr; current = current->next)
    {
        float dist = DistanceToOrigin(current, point);
        if(dist < min_distance)
        {
            min_distance = dist;
            closest = current;
        }
    }

    *point = closest;
    return min_distance;
}

Your question is incomplete so I'll do some assumptions:

  1. You have a list of 'obstacles' and you want to find one of them.
  2. After entering the list of 'obstacles', the user will enter a pair of coordinates and the program will answer with the nearest obstacle to that point.
  3. Considering the using namespace std clause, I'll assume you can use STD library.

My answer, in pseudocode, would be something like this:

  1. Get the list of obstacles (name, x, y) and store them in a forward_list container.
  2. Get the point to look for.
  3. Walk the list of obstacles looking for the shortest distance

In code:

#include <iostream>
#include <cmath>
#include <string>
#include <forward_list>

using namespace std;

struct obstacle {
    string carname;
    float x, y;

    obstacle(const string& n, float p1, float p2) : carname(n), x(p1), y(p2) {};

    float DistanceTo(const obstacle& p)
    {
        return sqrt(((x - p.x) * (x - p.x)) + ((y - p.y) * (y - p.y)));
    };
};

using ObstacleList = forward_list<obstacle*>;

const obstacle* CalcNearestPoint(ObstacleList& obstacles, obstacle point)
{
  float shortest_distance = HUGE_VAL;
  const obstacle* nearest_obstacle = nullptr;
  for (auto iter = obstacles.begin(); iter != obstacles.end(); ++iter)
  {
    float distance = (*iter)->DistanceTo(point);
    if (distance < shortest_distance)
    {
      shortest_distance = distance;
      nearest_obstacle = *iter;
    }
  }
  return nearest_obstacle;
}

int main()
{
    ObstacleList obstacles;

    int x, y;
    string name;
    while (true)
    {
        cout << "string describing obstacle (enter ""0"" for end of input):";
        cin >>name;
        if (name == "0")
          break;
        cout << "\nx and y coordinate: ";
        cin >> x >> y;
        obstacles.push_front(new obstacle(name, x, y));
    }

    cout << "x and y coordinate to look for:";
    cin >> x >> y;
    obstacle point("", x, y);

    auto result = CalcNearestPoint(obstacles, point);
    if (result == nullptr)
      cout << "Not found\n";
    else
      cout << "Found obstacle: " << result->carname << endl;
}

Cleanup (delete allocated objects) left for the reader.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM