Erlangga
Erlangga

Reputation: 131

Java to C++ convert code

I have a Java code; this my Poin Java code:

import java.util.Scanner;

public class Poin {
    private int X;
    private int Y;

    public Poin() {
        X = 0;
        Y = 0;
    }

    public Poin(int X, int Y) {
        this.X = X;
        this.Y = Y;
    }

    public int getX() {
        return X;
    }
    public int getY() {
        return Y;
    }
    public boolean InRect(Poin TopLeft, Poin BottomRight) {
        if (this.X < BottomRight.getX() && this.X > TopLeft.getX()
                && this.Y < BottomRight.getY() && this.Y > TopLeft.getY()) {
            return true;
        } else {
            return false;
        }
    }

    public static void main(String [] args) {
        int N;
        int i;
        int x,y;
        int count = 0;
        Poin TopLeft, BottomRight;

        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();

        Poin[] a = new Poin[N];
        int x_top = sc.nextInt();
        int y_top = sc.nextInt();
        int x_bot = sc.nextInt();
        int y_bot = sc.nextInt();
        TopLeft = new Poin(x_top, y_top);
        BottomRight = new Poin(x_bot, y_bot);
        for (i = 0; i < N; i++) {
            x = sc.nextInt();
            y = sc.nextInt();
            Poin p = new Poin(x, y);
            a[i] = p;
            if (p.InRect(TopLeft, BottomRight)) {
                count += 1;
            }
        }
        System.out.println(count);
        for (i = 0; i < N; i++) {
            System.out.println(a[N-1-i].getX()+","+a[N-1-i].getY());
        }
    }
}

I want to convert this to c++. This is my c++ code:

#include <iostream>
#include <cstdlib>

using namespace std;
class Poin
{
    private :
    int x;
    int y;
    public :
    Poin() {
        x = 0;
        y = 0;
    }

    Poin(int x, int y) {
        this->x = x;
        this->y = y;
    }   

    int get_x() {
        return x;
    }

    int get_y() {
        return y;
    }

    bool InRect(Poin& TopLeft, Poin& BottomRight) {
        if (this->x < BottomRight.get_x() && this->x > TopLeft.get_x() && this->y < BottomRight.get_y() && this->y > TopLeft.get_y()) 
        {
            return true;
        } 
        else 
        {
            return false;
        }
    }
};

int main ()
{
    int N;
    int i;
    int x,y;
    int count = 0;
    int x_top;
    int y_top;
    int x_bot;
    int y_bot; 
    Poin TopLeft, BottomRight;


    Poin** a = new Poin*[N];
    cin>>x_top;
    cin>>y_top;
    cin>>x_bot;
    cin>>y_bot;
    TopLeft = new Poin(x_top, y_top);
    BottomRight = new Poin(x_bot, y_bot);
    for (i = 0; i < N; i++) {
        x = cin>>x;
        y = cin>>y;
        px = p.poin(x, y);
        a[i] = p;
        if (px.InRect(TopLeft, BottomRight)) {
            count += 1;
        }
    }
    cout<<count;
    for (i = 0; i < N; i++) {
        cout << a[N-1-i].getX() << "," << a[N-1-i].getY();
    }   
    return 0;
}

I have difficulty converting this code from Java to c++. Poin is class and using this as parameter in main program:

Poin TopLeft, BottomRight;
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);

Does anybody have a solution to solve my problem?

Upvotes: 0

Views: 2981

Answers (4)

Jerry Coffin
Jerry Coffin

Reputation: 490108

While you've gotten some advice about the superficial problems you've seen, the result of following that advice (by itself) is still going to be what I'd consider poor C++ code. So far, you're basically transliterating from Java to C++, making roughly the smallest changes in syntax necessary to get a C++ compiler to accept what's still basically Java code.

I'd advise, instead, writing C++ that's really C++. It'll be quite different from your Java code, because fundamentally the two are really quite different languages, and code written to use C++ (at all) well is markedly different from code to do the same job in Java.

Let's consider the fundamentals of what your code really does, and write some C++ that does that.

  1. read in points from a file (each point being a pair of ints)
  2. Count the points that are inside a rectangle
  3. print out the count
  4. print out the points in reverse order

We want to write the code to support that as cleanly as possible, so let's start with a poin class that's properly defined for the job. The necessary capabilities are:

  1. Construct from ints.
  2. Read from stream
  3. Write to stream
  4. Check if in rectangle

That should be all it needs, so let's just implement that:

class Poin {
    int x;
    int y;
public:
    // construct a point from two ints. Note that we prefer to use the member 
    // initialization list over assigning inside the body of the ctor
    Poin(int x=0, int y=0) : x(x), y(y) {}

    bool operator<(Poin const &other) const {
        return x < other.x && y < other.y;
    }

    bool in_rect(Poin const &TL, Poin const &BR) const {
        return (*this < BR) && (TL < *this);
    }

    // read a Poin from a stream:    
    friend std::istream &operator>>(std::istream &is, Poin &p) {
        return is >> p.x >> p.y;
    }

    // display a Poin on a stream. Note: operator>> won't read what this writes
    friend std::ostream &operator<<(std::ostream &os, Poin const &p) {
        return os << p.x << "," << p.y;
    }
};

Note a few points (pardon the pun): we don't have/need/want a getX or getY or anything similar. A poin knows how to handle its own I/O, so outside code just reads or writes a poin -- it doesn't have to deal with the details of the x and y coordinates that make up a poin. Likewise, a poin "knows" how to compare itself to another poin (in a way that fits our needs--certainly not the only possible way it could be defined though). We then use that to get a fairly simple definition of in_rect.

Using that, along with the algorithms, iterators, and containers in the standard library, our main becomes drastically simpler and cleaner:

int main() {
    // read points defining the rectangle from standard input:
    Poin TL, BR;
    std::cin >> TL >> BR;

    // read points from standard input to initialize collection:    
    std::vector<Poin> points{ 
        std::istream_iterator<Poin>(std::cin),
        std::istream_iterator<Poin>() };

    // display count of points inside rectangle:
    std::cout << "Count: "
              << std::count_if(points.begin(), points.end(), 
                               [&](Poin const &p) { return p.in_rect(TL, BR); })
              << "\n";

    // display all points in reverse order:
    std::copy(points.rbegin(), points.rend(),
        std::ostream_iterator<Poin>(std::cout, "\n"));
}

I've had to work hard to resist the temptation to expound on the superiority and simplicity of this code, and the advantages over a lower level language like Java, but I guess I'll let the code speak for itself on that subject.

I will add one final note though: this code is written in C++11. If you're using an older compiler, you may have trouble with a couple of points. Two obvious ones are the initialization of points -- with an older compiler, you might need to change the syntax slightly, to:

std::vector<Poin> points( 
    (std::istream_iterator<Poin>(std::cin)),
    std::istream_iterator<Poin>());

The other obvious problem you'd run into would be the use of the lambda expression:

[&](Poin const &p) { return p.in_rect(TL, BR); }

This can be worked around as well, but if you have trouble with either, I'd advise updating your compiler rather than munging the code. These were introduced in C++11, and (many) compilers supported them even before the standard was finalized. To reverse the old advertising slogan, this is a place it's better to switch than fight.

Upvotes: 8

Zac Howland
Zac Howland

Reputation: 15872

When coming from Java, you must break yourself of the bad habit of declaring all variables with the new keyword. In C++, most of the time you will not use that keyword.

Poin TopLeft, BottomRight;
...
TopLeft = new Poin(x_top, y_top); // TopLeft of is type Poin, new returns a type Poin*
BottomRight = new Poin(x_bot, y_bot); // same here

What you want is really:

cin>>x_top;
cin>>y_top;
cin>>x_bot;
cin>>y_bot;
Poin TopLeft(x_top, y_top);
Poin BottomRight(x_bot, y_bot);

Upvotes: 1

benjymous
benjymous

Reputation: 2122

If you have a particular reason to use new

Poin* TopLeft;
Poin* BottomRight;
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);

otherwise

Poin TopLeft(x_top, y_top);
Poin BottomRight(x_bot, y_bot);

If you're coming from a java background, and don't understand how c++ pointers work, then the second option would be far better for you!

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409166

In C++ you don't need to use new to create new objects, just declaring the variable is enough:

Poin TopLeft, BottomRight;

There you go, two objects declared, defined and created.

If you want to specify constructor arguments, you can do that in the declaration:

Poin TopLeft(x_top, y_top), BottomRight(x_bot, y_bot);

You don't need new until you start to learn about pointers, which you probably should do quite soon if you want to write any serious program. Also remember that in C++ dynamically allocated objects (that you allocate with new) are not automatically released, you have to do that manually release them with delete when done with the objects.

Upvotes: 4

Related Questions