Recursive with void method? - java

I have a problem with one of my program (my programming language is java) :
I have an object Douglas-Peucker which is an array of Points and I have an algorithm, the Douglas-Peucker algorithm. I want to work directly on this array of Points and here the problem begin. This is Douglas-Peucker algorithm :
protected Point[] coinImage;
// My constructor
public Peucker(Point [] tab) {
coinImage = new Point[tab.length];
for(int i = 0; i < coinImage.length; i++) {
coinImage[i] = new Point(tab[i].x, tab[i].y);
}
}
public Point[] algoDouglasPeucker() {
return douglasPeuckerAux(0,coinImage.length - 1);
}
public Point[] douglasPeuckerAux(int startIndex, int endIndex) {
double dmax = 0;
int index = 0;
for(int i = startIndex + 1; i < endIndex; i++) {
double distance = this.distancePointSegment(this.coinImage[i], this.coinImage[startIndex], this.coinImage[endIndex]);
if(distance > dmax) {
index = i;
dmax = distance;
}
} ***
if(dmax >= this.epsilon) {
Point[] recResult1 = douglasPeuckerAux(startIndex,index);
Point[] recResult2 = douglasPeuckerAux(index,endIndex);
Point [] result = this.unionTabPoint(recResult1, recResult2);
return result;
}
else {
return new Point[] { coinImage[0],coinImage[endIndex] };
}
}
*** my problem is here : both methods have a specific type of return : array of Point or I want to change this because I want to work directly on my attribut (coinImage).
How change this in void methods ?
Help me please !
Sorry I forget one method : I also want to change the type of this method :
public Point[] unionTabPoint(Point [] P1,Point [] P2) {
Point[] res = new Point[P1.length + P2.length];
for(int i = 0; i < P1.length;i++) {
res[i] = new Point(P1[i].x,P1[i].y);
}
int k = 0;
for(int j = P1.length; j < res.length; j++) {
res[j] = new Point(P2[k].x,P2[k].y);
k++;
}
return res;
}
She return the union of two array but without specific order.

Well the basic layout for a void recursive method is like this:
int i = 0;
public void recursive(){
if(i == 6){
return;
}
i++;
recursive();
}
You can keep looping the method, as it would return the the next line, of the method that called it. In this case, the return, would reach the '}' and terminate the method, as it is finished.
Hope I helped :D

Java is doing call by reference. It is possible to use an local instance of your result and/or use it in your parameterlist, for example method(x, y, Point[]) and force the method as a result, what is your method call. Like:
public void doSome(x,y) { x==0 ? return : doSome(x-1, y-1); }

I hope this is what you looking for ...(if not pls clarify more)
public void douglasPeuckerAux(int startIndex, int endIndex) {
...
Point[] newCoinImage = new Point[] { coinImage[0],coinImage[endIndex] };
coinImage = newCoinImage;
}
public void unionTabPoint(Point [] P1,Point [] P2) {
...
coinImage = res;
}

Related

Writing an equals method to compare two arrays

I have the following code, I believe something is off in my equals method but I can't figure out what's wrong.
public class Test {
private double[] info;
public Test(double[] a){
double[] constructor = new double[a.length];
for (int i = 0; i < a.length; i++){
constructor[i] = a[i];
}
info = constructor;
}
public double[] getInfo(){
double[] newInfo = new double[info.length];
for(int i = 0; i < info.length; i++){
newInfo[i] = info[i];
}
return newInfo;
}
public double[] setInfo(double[] a){
double[] setInfo = new double[a.length];
for(int i = 0; i < a.length; i++){
setInfo[i] = a[i];
}
return info;
}
public boolean equals(Test x){
return (this.info == x.info);
}
}
and in my tester class I have the following code:
public class Tester {
public static void main(String[] args) {
double[] info = {5.0, 16.3, 3.5 ,79.8}
Test test1 = new Test();
test 1 = new Test(info);
Test test2 = new Test(test1.getInfo());
System.out.print("Tests 1 and 2 are equal: " + test1.equals(test2));
}
}
the rest of my methods seem to function correctly, but when I use my equals method and print the boolean, the console prints out false when it should print true.
You are just comparing memory references to the arrays. You should compare the contents of the arrays instead.
Do this by first comparing the length of each array, then if they match, the entire contents of the array one item at a time.
Here's one way of doing it (written without using helper/utility functions, so you understand what's going on):
public boolean equals(Test x) {
// check if the parameter is null
if (x == null) {
return false;
}
// check if the lengths are the same
if (this.info.length != x.info.length) {
return false;
}
// check the elements in the arrays
for (int index = 0; index < this.info.length; index++) {
if (this.info[index] != x.info[index]) {
return false;
} Aominè
}
// if we get here, then the arrays are the same size and contain the same elements
return true;
}
As #Aominè commented above, you could use a helper/utility function such as (but still need the null check):
public boolean equals(Test x) {
if (x == null) {
return false;
}
return Arrays.equals(this.info, x.info);
}

Using Arrays.sort, empty array returned

I'm using the Arrays.sort method to sort an array of my own Comparable objects. Before I use sort the array is full, but after I sort the array and print it to System nothing is printing out. EDIT. the array prints nothing at all. not empty line(s), just nothing.
here is the code for my method which uses sort :
public LinkedQueue<Print> arraySort(LinkedQueue<Print> queue1)
{
Print[] thing = new Print[queue1.size()];
LinkedQueue<Print> newQueue = new LinkedQueue<Print>();
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
Arrays.sort(thing);
for(int j = 0;j<thing.length-1;j++)
{
System.out.println(thing[j]); //printing does not work here
newQueue.enqueue(thing[j]);
}
return newQueue;
}
and here is the class for the Comparable object called Print.
public class Print implements Comparable<Print>
{
private String name;
private int numPages,arrivalTime,startTime,endTime;
public Print(String n, int p, int time, int sTime, int eTime)
{
name = n;
numPages = p;
arrivalTime = time;
startTime = sTime;
endTime = eTime;
}
public int getPages()
{
return numPages;
}
public int compareTo(Print other)
{
if(this.getPages()<other.getPages())
return -1;
else if(this.getPages()>other.getPages())
return 1;
else
return 0;
}
public String toString()
{
return name+"("+numPages+" pages) - printed "+startTime+"-"+endTime+" minutes";
}
}
Your last for loop doesn't print the last element in the array. If the array has only one element, it won't print anything at all. Change to:
for (int j = 0; j < thing.length; j++) //clean code uses spaces liberally :)
{
System.out.println(thing[j]);
newQueue.enqueue(thing[j]);
}
or (if supported by the JDK/JRE version used):
for (Print p : thing)
{
System.out.println(p);
newQueue.enqueue(p);
}
I hope the problem is this part of code
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
replace the above with
for(int i = 0; !queue1.isEmpty() ; i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}

Method not working?

Updated code:
import java.util.*;
public class Main {
/**
* #param args
*/
static int[] C;
static int[] D;
static String P;
public static void main(String[] args) {
C = new int[10];
D = new int[10];
getNumber();
}
private static void getNumber() {
System.out
.println("Enter your first number with spaces in between digits.");
Scanner S = new Scanner(System.in);
String O = S.nextLine();
String[] A = new String[10];
A = O.split(" ");
for (int X = 0; A.length > X; X++) {
C[X] = toNumber(A[X]);
}
String P = S.nextLine();
String[] B = new String[10];
B = P.split(" ");
for (int Y = 0; B.length > Y; Y++) {
C[Y] = toNumber(A[Y]);
}
System.out.print(C[0]);
remainders();
}
private static void remainders() {
for (int A = 0; C.length > A; A++) {
if (D[1] * C[A] >= 10) {
Integer B = new Integer(D[1] * C[A]);
Character E = B.toString().charAt(0);
P.concat(E.toString());
}
}
for (int A = 0; C.length > A; A++) {
if (D[0] * C[A] >= 10) {
Integer B = new Integer(D[1] * C[A]);
Character E = B.toString().charAt(0);
P.concat(E.toString());
}
}
System.out.print(P);
}
private static int toNumber(String string) {
if (string.equals("0")) {
return 0;
} else if (string.equals("1")) {
return 1;
} else if (string.equals("2")) {
return 2;
} else if (string.equals("3")) {
return 3;
} else if (string.equals("4")) {
return 4;
} else if (string.equals("5")) {
return 5;
} else if (string.equals("6")) {
return 6;
} else if (string.equals("7")) {
return 7;
} else if (string.equals("8")) {
return 8;
} else if (string.equals("9")) {
return 9;
} else {
return 0;
}
}
}
For some reason, the last thing it prints is null. I am pretty sure the problem is the toNumber method, but I can't figure out what's wrong. If there are other problems with the code other than this, please let me know. Please help.
Edit: Problem seems to be with remainder method, please help
Use the string.equals(n) method to test if string is n
String constants are compared this way: "0".equals(string). String literals are actual String objects and You can call any String method on them. And you should prefer to call methods on constants, because it's guaranteed they exists, whereas variables can be null.
You don't need to reinvent the wheel. Java has rich SDK.
Simply use
int x = Integer.valueOf(a[X]);
If you want only numbers 0-9, then simply test
if (0 <= x && x <= 9) {
//valid continue
} else {
//invalid state handling
}

Making an immutable class

I'm in the process of trying to make an immutable class in which represents natural numbers. I'm using recursion in order to handle the Increment and Decrement methods. Since the fields are final, I made a private constructor to assign new values to the necessary fields when decrementing/incrementing. After testing this implementation, I can't seem to pin point the problem. If I decrement 100, it will be 10. If I increment 99, it will be 9. If I increment/decrement a number not on the bound, I will get a long string of gibberish. I guess I need a nudge in the right direction. I'm able to get it to work fine if it's mutable because i don't have to worry about the final fields.
public final class SlowBigNatural implements BigNatural{
final private int natural[];
final private int nSize;
final private int HIGHEST = 9;
public SlowBigNatural() {
this.nSize = 1;
this.natural = new int[1];
this.natural[0] = 0;
}
public SlowBigNatural(int p) {
this(Integer.toString(p));
}
public SlowBigNatural(String s) {
this.nSize = s.length();
this.natural = new int[nSize];
for (int i = 0; i < nSize; i++) {
this.natural[i] = Character.digit(s.charAt(i), 10);
}
}
public SlowBigNatural(BigNatural c) {
this(c.toString());
}
private SlowBigNatural(int[] natural, int nSize){
this.nSize = nSize - 1;
this.natural = new int[this.nSize];
for (int i = 0; i < this.nSize; i++) {
this.natural[i] = natural[i];
}
}
public BigNatural increment() {
int[] nClone = new int[nSize];
System.arraycopy(natural, 0, nClone, 0, nSize);
if (nSize == 1 || nClone[nSize - 1] != HIGHEST) {
nClone[nSize - 1]++;
BigNatural nInc = new SlowBigNatural(nClone.toString());
return nInc;
}
else {
nClone[nSize - 1] = 0;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.increment();
return temp;
}
}
public BigNatural decrement() {
int[] nClone = natural.clone();
if (nClone[nSize - 1] != 0) {
nClone[nSize - 1]--;
BigNatural nDec = new SlowBigNatural(nClone.toString());
return nDec;
}
else {
if (nSize != 1) {
nClone[nSize - 1] = HIGHEST;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.decrement();
return temp;
}
else{
BigNatural nDec = new SlowBigNatural(0);
return nDec;
}
}
}
public String toString() {
String nString = "";
for (int i = 0; i < nSize; i++) {
nString += String.valueOf(natural[i]);
}
return nString.replaceFirst("^0+(?!$)", "");
}
}
I stepped through my code, and the error seems to occur when I convert the array to a string and pass it through the constructor. It turns the array into a bunch of craziness. Continuing to investigate.
Haven't fully looked into it but if SlowBigNatural is really correctly immutable, then the following:
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.increment();
return temp;
is unlikely to be useful as far as I can see. The above call to temp.increment() creates a new object that you ignore, seen that you return temp itself and not the result of temp.increment().
Could you try changing the above to this:
BigNatural temp = new SlowBigNatural(nClone, nSize);
return temp.increment();
And if works, do the same for decrement().

Beginner: Assigning values to arrays in Java

I am attempting to write a simple Genetic Algorithm in Java after reading a book on Machine Learning and have stumbled on the basics. I'm out of practice with Java so I'm probably missing something extremely simple.
Individual
public class Individual {
int n;
int[] genes = new int[500];
int fitnessValue;
public int getFitnessValue() {
return fitnessValue;
}
public void setFitnessValue(int fitnessValue) {
this.fitnessValue = fitnessValue;
}
public int[] getGenes() {
return genes;
}
public void setGenes(int index, int gene) {
this.genes[index] = gene;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
// Constructor
public Individual() {
}
}
Population
import java.util.Random;
public class Population {
public Population() {
}
public static void main(String[] args) {
Random rand = new Random();
int p = rand.nextInt(10);
int n = rand.nextInt(10);
Individual pop[] = new Individual[p];
System.out.println("P is: " + p + "\nN is: " + n);
for(int j = 0; j <= p; j++) {
for(int i = 0; i <= n; i++) {
pop[j].genes[i] = rand.nextInt(2);
}
}
}
public void addPopulation() {
}
}
The aim of this code is to populate the Population and the Genes with a random number. Could someone please take a look at my code to see where I'm going wrong?
before
pop[j].genes[i] = rand.nextInt(2);
add
pop[j] = new Individual();
the elements of the array are null.
I believe you need to initialize pop[j] before doing pop[j].genes[i] = rand.nextInt();
Individual pop[] = new Individual[p];
This just initializes the array, not the individual elements. Try to put pop[j] = new Individual() between your two loops.
What they said...
Also, do you mean to call your setGenes method, or do you just want to directly access the gene array.
From what I understand of your code I think you need to do this:
for(int j = 0; j <= p; j++) {
pop[j] = new Individual();
for(int i = 0; i <= n; i++) {
pop[j].setGenes(i, rand.nextInt(2));
}
}

Categories