JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I get alot of errors

What errors exactly, at what line(s).

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Thank you for the compliment! And thanks for starting this thread; I've had a lot of fun playing with this problem.
Yes, recursion is one of those techniques that, when you have the right problem, is a fabulous solution.
If anyone is interested I've now made about an order of magnitude improvement in the performance of the de-duplication. I keep the known solutions in an array that's always sorted, so I can use a binary search to see if a new solution is already in the array (using the methods in the Arrays class, of course). The dreaded 10 dice totalling 44 case now runs in under 600mSec including de-duplication. I can post that code if anyone wants.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You could solve this in a generic sort of way by also having a "mask" image - same size as the card images, with each pixel either black or white depending on whether or not you want to compare the corresponding pixels in the two card images.
That way, if the shape or size of the images changes you just need 1 minute in a picture editor for the mask, as opposed to having to change the program or some obscure data file.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hello again. I'm embarrased to admit that some nonsense crept into the code I last posted, and the numbers I gave for the 12-sided dice were dodgy.
Here, by way of apology, is the full version with extraction of duplicate results (ps Norm, the duplicate code is a vastly simpler, better version than the String based thing we discussed offline).

import java.util.ArrayList;
import java.util.Arrays;

public class Dice {

   public static void main(String[] args) {

      final int n; // number of dice
      final int s; // no of sides per die
      final int t; // target total

      n = 3;  s = 12;  t = 20;
      // n = 10;  s = 6;  t = 44;  

      System.out.println("Rolling " + n + " " + s + "-sided dice with target " + t
            + "... ");

      long start = new java.util.Date().getTime();
      Dice d = new Dice(n, s, t);
      long end = new java.util.Date().getTime();

      System.out.println(d.getNumberOfSolutions() + " solutions, (" +
            d.getNumberOfUniqueSolutions() + " unique) found in " + 
            (end - start) + "mSec");
      d.displayUniqueSolutions();
   }

   private int nSides; // no of sides/faces on each dice
   private int[] rolls; // no of dice rolled for each side
   // eg if you roll 5,4,5  then  rolls = {0,0,0,1,2,0}
   private int nSolutions; // includes duplicates
   private ArrayList<int[]> uniqueSolutions; 
   // contains copies of all the unique rolls[] that are a solution

   public Dice(int nDice, int nSides, int target) {
      this.nSides = nSides;
      rolls = new int[nSides];
      nSolutions = 0;
      uniqueSolutions = new ArrayList<int[]>();
      roll(nDice, …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Here's a complete runnable version with variable number of sides. Only change from previous simplest code is an extra test to prune impossible combinations - ie if target is < no of dice or > no of dice * no of sides - this saves checking a load of combinations that can never work anyway.

public class Dice {

   public static void main(String[] args) {

      int n = 3;   // number of dice
      int s = 12;  // number of sides on each dice
      int t = 20;  // target total

      System.out.println("Rolling " + n + " " + s + "-sided dice with target " + t + "... ");

      long start = new java.util.Date().getTime();
      roll(n, s, t);
      long end = new java.util.Date().getTime();

      System.out.println(nSolutions + " solutions found in "
            + (end - start) + "mSec");
   }

   int nSolutions = 0; // includes duplicates

   public static void roll(int nDice, int nSides; int target) {
      if (nDice == 1) {
         if (target >= 1 || target <= nSides) {
            // this is the last die and target can be rolled in one
            nSolutions++;
         }
         return;
      }
      int nDiceRemaining = nDice - 1;
      for (int roll = 1; roll <= nSides; roll++) {
         int targetRemaining = target - roll;
         if (targetRemaining < nDiceRemaining
               || targetRemaining > nSides * nDiceRemaining) return; // no solution possible
         roll(nDiceRemaining, nSides, targetRemaining);
      }
   }
}

(ps extracted from duplicate-finding version, please forgive any typos)
Have fun!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes. Recursion is the "only" proper way to do this! (See code in previous post- how neat is that? - it's complete, just call it & print the result)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

57, of which 39 are unique (sorry)
;-)
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I guess you missed this on the main forum page:

don't expect quick solutions to your homework. We'll help you get started and exchange algorithm ideas, but only if you show that you're willing to put in effort as well

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Absolutely yes. Read the values from the file (depends on how the file is formatted, but you know that already) and put them into the text fields. After that it's exactly the same as the program you've already got - ie user changes the values in the text fields and you save the document.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

ps I don't mean to be malicious, but how many ways can you roll three 12-sided dice for a total of 20?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi. Glad you came up with a solution to this problem. Well done!
Just for your amusement, and maybe for future reference, here's the simplest version of the recursive method:

int nSolutions = 0
public void roll(int nDice, int target) {
  if (nDice == 1) {
     if (target >= 1 || target <= 6) nSolutions++; // solution found
     return;
   }
   for (int roll = 1; roll <= 6; roll++) {
     roll(nDice - 1, target - roll);
   }
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Where do you push into the stack?
Exactly what "error"s do you get?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I agree about the spacing; I really believe that these things are very imnportant for code clarity, and, having suffered other people's code on a deadline, I'm an absolute believer in clarity.
I didn't look up the zero case, but as the only use of the value was to write that number of bytes to the outout stream, I guessed it didn't matter.
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I want to suggest a different answer - I really don't like the repeated logical expression, and overall I don't think its any easier to understand.
IMHO a major reason why it's hard to understand is the silly choice of variable name, and the use of the EOF code value -1. What about:

while((bytesRead=cis.read(cipherTextBytes)) > 0) {
   fos.write(cipherTextBytes,0,bytesRead);
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You can use the Runtime and Process classes in Java 6.
You will find tutorials and code on the web.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

is it the same as if i wrote at the main.

Car car=new Car();

and the method in the car class
void init(String model, String type){
this.model=model;
this.type=type;
}

and then if i called the method like this .. Car.init(mazda, auto)

is it the same?

Almost - you have a mistake in Car.init(mazda, auto). Car is the class. This should read car.init(mazda, auto) car (lower=case c) is the individual Car object that you are trying to initialise.

As for "public" - this controls who is allowed to access this method, inj this case, anybody. Without public, only methods defined in the same package can call it (that was oversimplified to make a point). You can google for the details.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You use the syntax
Car(String name, String model)
to define the method, and you use syntax like
Car("Mazda", "something")
or even
String a = "Mazda", b = "etc"; new Car(a,b);
to call the method
the new keyword is used when calling a constructor, so it's the second version.
It's just how Java syntax works.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

A constructor is a special method that you define inside the class.
It's called when hyou create a new instance of that class.
So

public Car(String name, String model) {...}

defines the constructor method and

Car mazda=new Car("MAzda", "something");

calls that method to create a new Car.

Car mazda=new Car(String name, String model);

is wrong.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

ps: here's a good example of how the right architecture can help you...
combining the word/number thing into the code I just posted is easy because of the way it's structured...
Inthe Phrase class you implement the abstract method like this

class Phrase {
  Superclass newLowerClassInstance(String params) {
    Word w = new Word(params);
    if (w.isAllNumeric()) return new NumericWord(w);
    // Word class needs a method to say it consists of all numerics
    return w;
  }
}

class NumericWord extends Word{
   NumericWord(Word w) {
     // copy the instance variables from w
   }
}
ankilosado commented: JamesCherrill, thanks for your effort in getting into my shoes, and for putting your knowledge at my fingertips. You took your time to carefully understand my problema and got it seriously to help. +1
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I like the idea of number as a subclass of word. I don't think there's much point in a new thread, there is no way to "convert" an instance to an instance of a subclass (it's all about initialisation & constructors). You could handle the conversion in the number constructor, passing the word as a parameter and copying its values.

Don't give up on generics! They are important, and just need a little time.
Here's a demo prog that shows how easy the code can be for you...

import java.util.ArrayList;

public abstract class Superclass {

   // Supoerclass has 3 subclasses Sub1, Sub2, Sub3, which form a hierarchy.
   // Each contains a List of instances of the next lower class in the hierarchy
   // Eg: Superclass is a document element, subclasses are Page, Sentence, Word.
   // and Page has a List of Sentences, Sentence has a List of Words
   // Subclass constructors take a single String as parameter,
   // (which isn't used, it's just there to illustrate how params are handled).

   public static void main(String[] args) { // run this - it works
      new Sub1("some parameters");
   }

   // this generic method adds a couple of instances of the next
   // lower class to an appropriate array.
   // NB: The class of the object returned by newLowerClassInstance()
   // must correspond to the type of element in the list.
   @SuppressWarnings("unchecked")
   <T extends Superclass> void load(ArrayList<T> list, String params) {
      for (int i = 0; i < 2; i++) {
         T …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The method is declared as having a return type of int. This means
1. There must be a return ...; statement in the method where ... is an int
2. When you call the method it is executed and the returned int value is then used for whatever the calling statement does next, so
int chosenOption = askUserForChoice();
says call the method, and use the value it returns to set my variable chosenOption.
There's nothing else you need to do (or can do) to "link" the two.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

do you mean something like:

public int askUserForChoice() {
  // do all the stuff with the dialog box as above
  return choice;
}
...
int chosenOption = askUserForChoice();
switch (chosenOption);
// etc
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You can find the answers to many of these questions if you use Google and a bit of intelligent work. But here's the answer to two that are not so easy to find...
System.out is the Java console, which is the window where you ran the program if you're using a command prompt.. Its println(...) method prints things to that destination. When it prints things, it calls their toString() method to get a printable version of them. That's why the Car class has a toString method.
So line 11 implicitly calls line 34 to get a printable String version of the car, and prints that to the java console.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yo nick, norm is right. the O/P needs tough love; teach him, don't just fix this one problem.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Norm: I'm so sorry. I didn't read yourt post properly. My bad,
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Mark this thread closed now?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Sorry Norm, it looks OK to me. There is a constructor that takes an Image, and ImageIcon is appropriate.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

This should help
http://oopweb.com/Java/Documents/IntroToProgrammingUsingJava/Volume/c4/s4.html
(I found it via Google).
But basically, a "function" in Java is just a method that takes one or more parameters and returns a value derived from the parameters. There's no special syntax, it's just a method.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi
You will have a problem with line 24 of the superclass - new <U>
1 I guess you mean new <T> or new T, but neither will work
You can do something like I suggested in my last post (I have some sample code if you get stuck), or there are other ways round it if you don't like that one.
Is ComponentesArrayList used anywhere - I think maybe its not needed becuase you craete arraylists of the exact correct type in each subclass.
Overall it's looking like a pretty good design to me.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I assume your Google and Wikipedia are both broken at the moment? If you tell me what search you would like done I can Google it for you and post the results back here.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Same as line 198 above. If you don't call pack() again the window won't be resized to fit the newly visible panel.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

When the user clicks the button you call init() (with a flag set), which always creates a new window from scratch. Rather than keep on adding & removing buttons, why not add panop2, but set its visibility to false. Then in the button handler you just have to make panop2 visible, and re-pack the window - without calling init() again. Similarly if the user de-selects scientific - just make it invisible & re-pack.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If a variable is null, you can't test its length - it hasn't got a length!.
Use var == null

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If you ensure that you have no remaining references to the "old" data, then it will definitely be garbage collected before the JVM runs out of memory and throws an "out of memory". (In a complex program it's all too easy to leave an object in a List somewhere which prevents it being GCed.)
Yu may also increase the jvm's memory allocation; the default isn't very big.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

ps: There's a small snag in that you need to parametise the kind of object that will be created & added to the arraylist, and you can't say new T();
This is a nasty limitation in the way Java does generics.
You may need to create a small factory class to create new objects of the right kind - there's lots of code via Google ("instantiate java generic type"), or have an abstract method in the superclass to return a new instance of the approropriate subclass and override that in each subclass with the correct type, eg

class Superclass {
  abstract Superclass newMember();
...
class Phrase {
  Superclass newMember() { 
    return new Word();
  }

Then in the superclass load method you can call newMwember() to get a new instance of the right type to add to the ArrayList

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

First thing is to move as much code as possible out of the constructor, because you cannot inherit constructors. Put it in a method that the constructor calls, that way the method can be inherited. I think you should be able to use generics to make that method apply to each level in the document hierarchy. Here's a very quick sketch of what I mean (not compiled or tested - just pseudo-code)

class Superclass {
  ArrayList<Superclass> myList;
  <T> void load(String source, String delimiter, ArrayList<T> destination ) {
      // parse source by delimiters into arraylist
  }
}
class Subclass1 {
  Subclass1(String source) {
    myList = new ArrayList<Subclass2>();
    load(source, "\n", myList);
  }
)
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Declaring an interface makes you lose inheritance. It forces you to implement a consistent set of methods in each class (which is good), but each has to be implemented in each class (bad). If Java allowed a class to inherit from multiple superclasses (you can't, it's not part of ther language for good reasons) you would probably never see an interface.
I can't spend hours studying this, but at first sight it looks to me like elementoCompuesto is a perfect superclass, You can say Phrase, Paragraph etc "is a kind of elementoCompuesto" - that says "superclass" to me.
Similarly , when you say "code some extra methods ... that I would have to write time after time, adapting the almost identical code to each." that also says to me: put those methods (and the ArrayList they need) in the superclass and inherit them, just code the differences in each class.
If you are lucky you can identify the places where you need the different parts - which is where you use abstract - eg in the superclass

public void doSomething() {
   // loads of common code
   doTheSpecialBits();
   // loads more common code
}
abstract void doTheSpecialBits(); // implement this in each subclass
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi, me again. People say bad things about the French nationalised industries, but France Telecom just replaced 1/2 mile of cable through trees to my house within 24 hours of localising a fault to that area. For free. Vive la France!
Anyway -

Norm and James, I still need your help in some questions

I'm back online, so start asking!
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Sorry, major oprobs with internet connection - probablhy offline till next week. J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

There are some easy extreme cases to check - eg 6 dice total 6 or 36 (only one solution for each of those!). It's always a good idea to test the extreme cases.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I'll leave Norm to help you with the base 6 stuff. If/when you're ready for recursion, I'll be watching this thread.
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK, but you are missing a very important learning opportunity. Recursion is an essential tool in the program designer's toolkit, and although it seems hard at first, it's easy when you get the hang of it. For this problem, with a variable number of dice, it's a very good approach.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, norm and I have been playing with this offline, and I hope he will agree with this:
The base 6 numbers idea is interesting, and works, but the recursive solution is less code and executes faster. Eliminating duplicate solutions (is saying that a throw of 6-6-2 is the same as a throw of 6-2-6 or 2-6-6) is challenging, especially if you want it to run quickly.
I recommend you go with the recursive approach, and ignore the duplicates problem for now. I outlined this in my earlier post - have a look and come back with your questions.
The basic recursive algorithm comes down to 10 lines of simple code - so its really easy once you've grasped the recursive concept.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

It looks OK, tho I haven't tried to complile or run it. Have you?
I'm a bit baffled by the if test:
if (true) dosomething
else doexactlythesamething

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

1. You need to create a new Timer before you try to schedule something with it.
2. Can't read you sample code - please stick to the Java convention of starting all class names with a capital letter - it really helps.
3. In general you pass the relevant instance of 2nd class to the 3rd class that needs it (eg in 3rd class' constructor)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

tong1: Hi.
Your code is valid, but it's not what the O/P needs, except in the trivial case where then method can (and should) be static. You will execute display() in the context of a new Sub2 that you have created. That is not the same as executing it in the context of an existing object whose instance variables you do not have access to.
Eg: suppose the Superclass defines Date whenInstantiated; and initialises this to new Date() in its default constructor. Add this info into what is displayed in each version of display(). Your code will display the whenInstatiated of the new Sub2 you create, not the whenInstantiated of the Sub1 created on line 30, which is what the O/P wants.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

So you have a reference variable "ref" declared to hold a reference to an object of type Superclass. That means it can also hold a ref to an object of type Sub1 or Sub2, OK so far. However, if that's how it is declared then the compiler will error any attempt to call methods only defined in Sub1 or Sub2 because all the compiler knows is that the referred object is a Superclass object.
At run time, the JRE knows the exact kind of every instatiated object, so if ref refers to a Sub2, the JRE knows that. If your code calls a Superclass method that's overidden in Sub2 the JRE will call the Sub2 version, regardless of how the reference variable was declared.
You can use run-time casting to inform the compiler that ref now contains a reference to an object of type (say) Sub2. In general the compiler cannot tell whether that will be true or not when the program is run, in which case it will allow the code to compile and trust that you know what you are doing. If you are wrong then the JRE will detect that at run time and throw a class cast exception.
So, this example works

Superclass ref=new Sub2();
((Sub1)ref).display()

because at run time ref contains a reference to a Sub2 and, by definition, all objects of type Sub2 are also objects of type Sub1 and of Superclass.

This example fails

Superclass ref=new Sub1(); …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK, java,util.timer it is then. Just remember that as well as creating the timer you have to schedule actions to make anythiung happen.

As for 3-tier. To me this means user interface, business logic/object model, persistence/database layer. I don't see how this applies to your project, which seems to have just the top 2 layers. Maybe he means MVC (model/view/controller) - in which case I have to bow out here because I've never found it to make any sense to separate the GUI elements from the GUI logic. I guess you'll have to check what your prof means by 3 tier.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

unless, of course, it's a static method :-)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The reason for this is that when you instantiate a subclass its constructor automatically calls the constructor(s) of it superclasses, so all the variables etc associated with the superclasses are initialised properly. However, when you instantiate the superclass none of the subclass contructors are called, so none of the subclasses are initialised, and their methods are unavailable.