I get alot of errors
What errors exactly, at what line(s).
I get alot of errors
What errors exactly, at what line(s).
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.
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.
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, …
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!
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)
57, of which 39 are unique (sorry)
;-)
J
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
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.
ps I don't mean to be malicious, but how many ways can you roll three 12-sided dice for a total of 20?
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);
}
}
Where do you push into the stack?
Exactly what "error"s do you get?
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
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);
}
You can use the Runtime and Process classes in Java 6.
You will find tutorials and code on the web.
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.
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.
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.
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
}
}
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 …
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.
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
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.
Yo nick, norm is right. the O/P needs tough love; teach him, don't just fix this one problem.
Norm: I'm so sorry. I didn't read yourt post properly. My bad,
J
Mark this thread closed now?
Sorry Norm, it looks OK to me. There is a constructor that takes an Image, and ImageIcon is appropriate.
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.
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.
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.
Same as line 198 above. If you don't call pack() again the window won't be resized to fit the newly visible panel.
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.
If a variable is null, you can't test its length - it hasn't got a length!.
Use var == null
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.
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
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);
}
)
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
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
Sorry, major oprobs with internet connection - probablhy offline till next week. J
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.
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
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.
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.
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
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)
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.
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(); …
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.
unless, of course, it's a static method :-)
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.