Need help with Permutations

I'm writing a program that reads a city with x,y coordinates from a test file. It has to Permutate all the cities except the first and last city in the text file. It also needs to get an average of the x,y coordinates and then print the cities in the order in which they were permutated along with the average. My code seems to be leaving out the permutation all together but taking the average of all the coordinates, and only printing the first city. If any one can help me with this, I would greatly appreciate it. Not exactly sure what would be the best way to post my code on here, but here goes:

public static void rotate(int first, int last)

{

String temp = City[first];

for(int i = first; i < last - 1; i++)

{

City = City[i+1];

}

City[last - 1] = temp;

return;

}

//-

public static void perm(int first, int last)

{

if(last - first == 1)

{

for(int j=0; j < City.length; j++)

{

System.out.print(City[j] + " ");

}

System.out.println();

return;

}

else

{

for(int i =last-first; i>=1;i--)

{

perm(first+1, last);

rotate(first, last);

}

}

}

} //end CityList

//--

class CityListApp

{

public static void main (String[] args) throws FileNotFoundException, IOException

{

perm(1,4);

Reader fr = new FileReader ("c:/CityList.txt");

StreamTokenizer frstream = new StreamTokenizer(fr);

frstream.parseNumbers();

frstream.eolIsSignificant(true);

frstream.nextToken();

while(frstream.ttype != StreamTokenizer.TT_EOF)

{

double sum = 0;

int count = 0;

String City = frstream.sval;

frstream.nextToken();

while (frstream.ttype != StreamTokenizer.TT_EOF)

{

sum += frstream.nval;

count++;

frstream.nextToken();

}

double avg = sum / count;

DecimalFormat fmt = new DecimalFormat("0.00");

System.out.println(City + fmt.format(avg));

frstream.nextToken();

}

}

private static void perm(int i, int j) {

// TODO Auto-generated method stub

}

[2261 byte] By [Nic_C78a] at [2007-11-27 8:36:04]
# 1
The best way to post code is to wrap it in [code][/code] tags.When you create a post, there are several buttons above the text entry window. One says "code". Click that button and it creates the code tags for you automatically.
paulcwa at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 2
oh, ok, thank you! I'll know better for next time.
Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 3

At the very bottom of the code there is a part that says

private static void perm(int i, int j) {

// TODO Auto-generated method stub

}

Is this what's causing the problem (it may be overriding the other method named perm)?

Also, it's difficult to tell which classes the top two methods are in.

@modia at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 4

> At the very bottom of the code there is a part that

> says

>

> > private static void perm(int i, int j) {

> // TODO Auto-generated method stub

>

> }

>

>

> Is this what's causing the problem (it may be

> overriding the other method named perm)?

I don't believe that is the problem. I get the same result when I comment it out. I'm thinking that the perm and rotate method are not being called at all.

>

> Also, it's difficult to tell which classes the top

> two methods are in.

They are in my CityList class. Here's my full code:

public CityList(int max)

{

City = new String[max];

Elems = 0;

}

//--

public void insert (String cities)

{

City[Elems] = new String(cities);

Elems++;

}

public String getItem(int l)

{

return City[l];

}

//

public void display()

{

System.out.print("City + j");

}

//

public static void rotate(int first, int last)

{

String temp = City[first];

for(int i = first; i < last - 1; i++)

{

City[i] = City[i+1];

}

City[last - 1] = temp;

return;

}

//-

public static void perm(int first, int last)

{

if(last - first == 1)

{

for(int j=0; j < City.length; j++)

{

System.out.print(City[j] + " ");

}

System.out.println();

return;

}

else

{

for(int i =last-first; i>=1;i--)

{

perm(first+1, last);

rotate(first, last);

}

}

}

} //end CityList

//--

class CityListApp

{

public static void main (String[] args) throws FileNotFoundException, IOException

{

//perm(1,4);

Reader fr = new FileReader ("c:/CityList.txt");

StreamTokenizer frstream = new StreamTokenizer(fr);

frstream.parseNumbers();

frstream.eolIsSignificant(true);

frstream.nextToken();

while(frstream.ttype != StreamTokenizer.TT_EOF)

{

double sum = 0;

int count = 0;

String City = frstream.sval;

frstream.nextToken();

while (frstream.ttype != StreamTokenizer.TT_EOF)

{

sum += frstream.nval;

count++;

frstream.nextToken();

}

double avg = sum / count;

DecimalFormat fmt = new DecimalFormat("0.00");

System.out.println(City + fmt.format(avg));

frstream.nextToken();

}

}

//private static void perm(int i, int j)

//{

// TODO Auto-generated method stub

//}

}

Any help I can get will be greatly appreciated.

Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 5
In this posting, you are missing part of the CityList class code, probably the part where fields are definied.
petes1234a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 6

when you say permutate, you mean go through all the combinations of two cities? all cities? Is order important -- are we dealing with permutations or combinations? What is the goal of the program? To find the average x and y of cities?

Please redefine the problem and be as precise as possible.

Good luck!

petes1234a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 7

> when you say permutate, you mean go through all the

> combinations of two cities? all cities? Is order

> important -- are we dealing with permutations or

> combinations? What is the goal of the program? To

> find the average x and y of cities?

The program needs to go through all the combinations of let's say 4 cities, but it has to leave the first(source) and the last(destination) in the text file in the same place. example is: Jax, Tampa, Miami, Orlando and the program would permutate Tampa and Miami while leaving Jax and Orlando as the source and desitnation.

>

> Please redefine the problem and be as precise as

> possible.

I have it working right now, without the permutaion. It's almost like the program is not calling my perm and rotate method. I'm not sure I have those methods right either.

>

> Good luck!

Thanks! I need all the luck I can get right now =)

Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 8

1) Are you trying to compare the differences in distances between different routes, when flying from one city to another?

2) Are you sure that you are going to be manipulating an array of Strings? It seems more logical to me to have an array of City objects where City has name and location (x and y coordinates).

3) Would it be better to use ArrayList<City> rather than array of City if you don't know in advance how big the array will be?

petes1234a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 9

> 1) Are you trying to compare the differences in

> distances between different routes, when flying from

> one city to another?

***Yes, I think I have that part done. It just doesn't change the order that the cities are pulled from the text file.

>

> 2) Are you sure that you are going to be

> manipulating an array of Strings? It seems more

> logical to me to have an array of City objects where

> City has name and location (x and y coordinates).

***The String array seems to be working other than the permutation.

>

> 3) Would it be better to use ArrayList<City> rather

> than array of City if you don't know in advance how

> big the array will be?

***Not sure, I know the size of the array, because I created the text file. I may try that if I can't get it right the way I have it.

Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 10

> > 1) Are you trying to compare the differences in

> > distances between different routes, when flying

> from

> > one city to another?

>

> ***Yes, I think I have that part done. It just

> doesn't change the order that the cities are pulled

> from the text file.

So if distance, do you have to use the equation:

distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

?

> > 2) Are you sure that you are going to be

> > manipulating an array of Strings? It seems more

> > logical to me to have an array of City objects

> where

> > City has name and location (x and y coordinates).

>

> ***The String array seems to be working other than

> the permutation.

But each City is defined by its name and x and y location. The information is tied together, correct? If so, a Class of City that encapsulates this information seems the correct way to go in the long run. It would seem that you need more than just a listing of cities in different orders, but a listing of order and how it affects the relative distances. All this info is tied together and again, should be encapsulated.

Or am I missing something?

petes1234a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 11

> > > 2) Are you sure that you are going to be

> > > manipulating an array of Strings? It seems more

> > > logical to me to have an array of City objects

> > where

> > > City has name and location (x and y

> coordinates).

> >

> > ***The String array seems to be working other than

> > the permutation.

>

> But each City is defined by its name and x and

> y location. The information is tied together,

> correct? If so, a Class of City that

> encapsulates this information seems the

> correct way to go in the long run. It would seem

> that you need more than just a listing of cities in

> different orders, but a listing of order and how

> it affects the relative distances. All this info

> is tied together and again, should be encapsulated.

>

> Or am I missing something?

*** oh, ok. I think I know what you're saying now. I need to create another class for City Instead of just trying to define the varibles within the class CityList. Do I understand you correctly? Sorry, I don't have the vocabulary down good yet, so I get a little lost. =)

Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 12
Anoher question, How would I call the perm method in the App. I can't figure out how and where to put it?
Nic_C78a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 13

I'm still trying to grok your specifications. What does the text file look like? Can you print out a sample here?

And where are you creating your array of City as you input data? Without the array, you can't do permutations.

And, have you tested your permutation function in a small test app (without the file input and all that fancy stuff)? Are you sure that it doesn't have an infinite loop in it?

Message was edited by:

petes1234

petes1234a at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 14

> Anoher question, How would I call the perm method in

> the App. I can't figure out how and where to put it?

You need to instantiate a new CityList object and then call the perm(...) method on that variable in your main method.

Like this:

CityList list = new CityList(10);

list.perm(0,9);

prometheuzza at 2007-7-12 20:32:50 > top of Java-index,Java Essentials,New To Java...
# 15

> I'm still trying to grok your specifications. What

> does the text file look like? Can you print out a

> sample here?

>

Here's what it looks like in NotePad:

Jacksonville,15,30

Tampa,35,20

Orlando,55,30

Miami,40,45

> And where are you creating your array of City as you

> input data? Without the array, you can't do

> permutations.

I tried this:

> int Size = 50;

Object [] City;

City = new Object (Size);

But it didn't seem to want to work with what I have, so I took it out. I guess I should try it with the Object class?

And, have you tested your permutation function in a

> small test app (without the file input and all that

> fancy stuff)? Are you sure that it doesn't have an

> infinite loop in it?

No I haven't.

>

> Message was edited by:

> petes1234

Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 16

> You need to instantiate a new CityList object and

> then call the perm(...) method on that variable in

> your main method.

> Like this:

> CityList list = new CityList(10);

> list.perm(0,9);

But before permuting he has to fill the list. for that he needs to first create a City class, make the list a list of this Object, then enter objects into the list from the text file, then permute it.

petes1234a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 17

> Here's what it looks like in NotePad:

> Jacksonville,15,30

> Tampa,35,20

> Orlando,55,30

> Miami,40,45

Ok, may I suggest reading the file line by line and then splitting on the comma.

A file can be read very easily by the java.util.Scanner class:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html (code samples there as well!)

I find the Scanner class to be far easier than how you are parsing the file now.

> int Size = 50;

> bject [] City;

> City = new Object (Size);

>

> But it didn't seem to want to work with what I have,

> so I took it out. I guess I should try it with the

> Object class?

No, petes meant that you need to create a custom object (not an Object!) that represents a city. Here's what that class would look like:

public class City {

private String name;

private int x;

private int y;

public City(String name, int x, int y) {

this.name = name;

this.x = x;

this.y = y;

}

// the rest of City's methods

}

Now you can create an array of these City objects like this:

City[] cities = new City[10];

cities[0] = new City("Rotterdam", 50, 60);

Oh, and use Java's code conventions! Class names start with a capital but variable names and methods start with a small letter. Please follow these "rules".

> No I haven't.

You should do that then.

prometheuzza at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 18

> ...

> But before permuting he has to fill the list. for

> that he needs to first create a City class, make the

> list a list of this Object, then enter objects into

> the list from the text file, then permute it.

Yes, the OP has quite some work to do!

; )

prometheuzza at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 19

don't work with Object. There are better ways. Create a class City and make a list of this. Here is a for instance that doesn't use your model, but is close enough for you to learn from:

First class, my Foo class:

public class Foo

{

private String name;

private double a, b;

public Foo(String name, double a, double b)

{

this.name = name;

this.a = a;

this.b = b;

}

public String getName()

{

return name;

}

public double getA()

{

return a;

}

public double getB()

{

return b;

}

@Override

public String toString()

{

return "Foo: " + this.name + " (" + a + ", " + b + ")";

}

}

Next, a FooList class:

import java.util.ArrayList;

import java.util.List;

public class FooList

{

private List<Foo> foos;

public FooList()

{

foos = new ArrayList<Foo>();

}

public void addFoo(Foo f)

{

foos.add(f);

}

public int size()

{

return foos.size();

}

public Foo getFoo(int i)

{

if (i < 0 || i >= foos.size())

{

return null;

}

else

{

return foos.get(i);

}

}

public double getAverageA() //throws ArithmeticException

{

if (foos.size() == 0)

throw new ArithmeticException("can't divide by zero");

else

{

double temp = 0.0;

for (int i = 0; i < foos.size(); i++)

{

temp += foos.get(i).getA();

}

return temp / foos.size();

}

}

public double getAverageB() //throws ArithmeticException

{

if (foos.size() == 0)

throw new ArithmeticException("can't divide by zero");

else

{

double temp = 0.0;

for (int i = 0; i < foos.size(); i++)

{

temp += foos.get(i).getB();

}

return temp / foos.size();

}

}

And finally, TestFooList class:

public class TestFooList

{

public static void main(String[] args)

{

FooList myFooList = new FooList();

myFooList.addFoo(new Foo("A", 0.0, 1.0));

myFooList.addFoo(new Foo("B", 2.0, 4.0));

myFooList.addFoo(new Foo("C", 5.0, 2.0));

myFooList.addFoo(new Foo("D", 9.0, 5.0));

System.out.println("myFooList:");

for (int i = 0; i < myFooList.size(); i++)

{

System.out.println(myFooList.getFoo(i));

}

System.out.println();

System.out.println("Average 'a' = " + myFooList.getAverageA());

System.out.println("Average 'b' = " + myFooList.getAverageB());

}

}

Message was edited by:

petes1234

petes1234a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 20
Thank you so much for all your help, both of you!! I should be ok now. I appreciate it!=)
Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 21

ok, so I'm not quite as ok as I thought I would be. I changed from an Array to List and I'm getting the error:

The type of the expression must be an array type but it resolved to List

Here's the part of the code that I'm getting the error on:

public static void rotate(int first, int last)

{

List temp = cityname[first];

for(int i = first; i < last - 1; i++)

{

cityname[i] = cityname[i+1];

}

cityname[last - 1] = temp;

return;

}

Any ideas on how to fix it? Thanks!

Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 22

This rotate looks all wrong. I have to see the rest of your code.

I'm assuming that you now have a generic list of city like so:

List<City> cityList;

and that if so, a better rotate may be simply:

public void rotate(int first, int last)

{

City temp = cityList.remove(first); // removes the first from the arraylist

cityList.add(last - 1, temp); // replaces the first at the last -1 position

// though may need to make it cityList.add(last - 2, temp);

// since the List has been shortened by the prior removal

}

Message was edited by:

petes1234

petes1234a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 23

Here's a copy of my code:

class City

{

public static int length;

private String name;

private int x;

private int y;

public City(String name, int x, int y)

{

this.name = name;

this.x = x;

this.y = y;

}

public String getName()

{

return name;

}

public double getX()

{

return x;

}

public double getY()

{

return y;

}

}

//CityList.java

//demonstrates use of Recursion using text file

//to run this program c>java CityListApp

//////////////////////////////////////////////////////////////////////////

class CityList

{

private static List cityname;

//--

public CityList()

{

cityname = new ArrayList();

}

//--

public void addCity (City c)

{

cityname.add(c);

}

public int size()

{

return cityname.size();

}

public City getCity (int i)

{

if(i < 0 || i >= cityname.size())

{

return null;

}

else

{

return (City) cityname.get(i);

}

}

//

public void display()

{

System.out.print("City + j");

}

//

public static void rotate(int first, int last)

{

List temp = cityname[first];

for(int i = first; i < last - 1; i++)

{

cityname[i] = cityname[i+1];

}

cityname[last - 1] = temp;

return;

}

//-

public void perm(int first, int last)

{

if(last - first == 1)

{

for(int j=0; j < City.length; j++)

{

System.out.print(cityname + " ");

}

System.out.println();

return;

}

else

{

for(int i =last-first; i>=1;i--)

{

perm(first+1, last);

rotate(first, last);

}

}

}

I'll try your suggestion. Thanks!

Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 24
I tried your suggestion and that error went away, but now I'm getting an IndexOutOf BoundsException error. Do you see what it is in my code that's causing this? I can't find the issue, but I'm about to debug it.
Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 25

A couple of suggestions:

I'm not sure that you need this static variable. What purpose does it serve that CityList.size() can't handle?

class City

{

public static int length; // I'm not sure that you need this variable

private String name;

.....

make your list generic and non-static (make it an instance variable). Maybe I'm wrong, but I feel that you are loosing oop-ness by making this static.

class CityList

{

//private static List cityname;

//make this generic (add the <City>) and get rid of the static modifier

private List<City> cityname;

public CityList()

{

//cityname = new ArrayList();

//make this generic

cityname = new ArrayList<City>();

}

get rid of rotate's static modifier if possible. change the method.

//get rid of static modifier

public void rotate(int first, int last)

{

//scrap what you had

//my suggested method:

City temp = cityname.remove(first);

cityname.add(last - 1, temp);

}

Again, City.length seems redundant when cityname.size should do.

public void perm(int first, int last)

{

if(last - first == 1)

{

//for(int j=0; j < City.length; j++)

//change to

for(int j=0; j < cityname.size(); j++)

{

//System.out.print(cityname + " "); // check out the "get" method from arraylist

System.out.print(cityname.get(j).getName() + " ");

}

System.out.println();

return;

}

else

{

for(int i =last-first; i>=1;i--)

{

perm(first+1, last);

rotate(first, last);

}

}

}

Test the code to see what happens

public static void main(String[] args)

{

CityList cl = new CityList();

cl.addCity(new City("A", 1, 2));

cl.addCity(new City("B", 1, 2));

cl.addCity(new City("C", 1, 2));

cl.addCity(new City("D", 1, 2));

cl.perm(0, cl.size());

}

}

petes1234a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 26

GOT IT!!! Your test works perfect!

My code of course does not:

It's still not giving me the different combinations. The output is still just the list of ciites in the same order as they are in the text file.

class CityListApp

{

public static void main (String[] args) throws FileNotFoundException, IOException

{

CityList list = new CityList();

list.perm(0, list.size());

Reader fr = new FileReader ("c:/CityList.txt");

fr = new BufferedReader(fr);

StreamTokenizer frstream = new StreamTokenizer(fr);

frstream.parseNumbers();

frstream.eolIsSignificant(true);

frstream.nextToken();

while(frstream.ttype != StreamTokenizer.TT_EOF)

{

double sum = 0;

int count = 0;

String City = frstream.sval;

frstream.nextToken();

while (frstream.ttype != StreamTokenizer.TT_EOL)

{

sum += frstream.nval;

count++;

frstream.nextToken();

}

double avg = sum / count;

DecimalFormat fmt = new DecimalFormat("0.00");

System.out.println(City + fmt.format(avg));

frstream.nextToken();

}

}

} //end of CityListApp

Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 27

There are easier ways of getting text input. I suggest the following:

1) Read about the Scanner class here:

http://java.sun.com/docs/books/tutorial/essential/io/scanning.html

2) Read about the String split function. This can easily parse each line using the comma as delimiter.

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#split(java.lang.String)

3) Use a while block to read in each line. Split the line, then create a new City object using the splitted string result

4) Add the newly created City object to your list.

5) Permute to your hearts content.

petes1234a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...
# 28
Thank you so much for ALL of your help!!!
Nic_C78a at 2007-7-21 22:43:46 > top of Java-index,Java Essentials,New To Java...