I made this program that produces 6 random numbers between 1 and 41. In the UI i have 6 textfields and a button. If i press the button the 6 numbers are being displayed in the textfields. I have 1 function(theNumbers()) fired when the button is pressed, the first function makes an ObservableList with the numbers 1-41 and the second function picks 6 numbers randomly.
The problem that happens is that after pressing the button a few times there is an ArrayIndexOutofBound Exception: -1 thrown, usually after (or a few times after) the number 0 is produced (which isnt even in the list) also sometimes a IndexOutOfBoundsException: Index: 4, Size: 4 exception is thrown(the number is random btw). Also it seems to be able to produce the same number twice or numbers bigger then 41.(seen 151)
This is my code:
First function:
ObservableList<Integer> list1 = FXCollections.observableArrayList();
private void createList(ObservableList<Integer> list1) {
this.list1 = list1;
int numbers = 41;
for (int i = 1; i <= numbers; i++) {
list1.add(i);
}
}
Second function:
private void theNumbers() {
createList(list1);
ObservableList<Integer> finalNums = FXCollections.observableArrayList();
try {
for (int i = 0; i < 6; i++) {
FXCollections.shuffle(list1);
int lucky = new Random().nextInt(list1.size());
finalNums.add(lucky);
list1.remove(list1.indexOf(lucky));
}
} catch (Exception ex) {
throw ex;
}
FXCollections.sort(finalNums);
textField1.setText(finalNums.get(0).toString());
textField2.setText(finalNums.get(1).toString());
textField3.setText(finalNums.get(2).toString());
textField4.setText(finalNums.get(3).toString());
textField5.setText(finalNums.get(4).toString());
textField6.setText(finalNums.get(5).toString());
list1.clear();
finalNums.clear();
}
Any clues to why it does this? Could it be my Acer Aspire One Netbook messing up? To my knowledge these errors shouldn't be happening.
Your code tries to remove the exact same number twice ore more in one pass of the for construct. For example you cannot remove the number "2" more than once from the list. The indexOf(2) method will return with -1 because it cannot find the value 2 in the list anymore.
So you might check if a number still exists in list1 before you try to remove from there.
private void theNumbers() {
createList(list1);
ObservableList<Integer> finalNums = FXCollections.observableArrayList();
try {
for (int i = 0; i < 6; i++) {
FXCollections.shuffle(list1);
int lucky;
do
{
lucky= new Random().nextInt(list1.size());
}while(list1.indexOf(lucky) == -1);
finalNums.add(lucky);
list1.remove(list1.indexOf(lucky));
}
} catch (Exception ex) {
throw ex;
}
That should solve your problem.
try using
int lucky = new Random().nextInt(list1.size()-1);
Related
hi guys im having problome with my lockpairs functinog on pset3 tideman would love some feedback ty
bool checkcycle(int from, int to)
{
if(from == to)
{
return true;
}
int i;
for (i = 0; i < candidate_count; i++)
{
if(locked[from][i])
{
checkcycle(i,to);
}
}
return false;
}
void lock_pairs(void)
{
for (int i = 0; i < candidate_count; i++)
{
if(!checkcycle(pairs[i].winner , pairs[i].loser))
{
locked[pairs[i].winner][pairs[i].loser] = true;
}
return;
}
}
:( lock_pairs locks all pairs when no cycles
lock_pairs did not lock all pairs
:( lock_pairs skips final pair if it creates cycle
lock_pairs did not correctly lock all non-cyclical pairs
:( lock_pairs skips middle pair if it creates a cycle
lock_pairs did not correctly lock all non-cyclical pairs
Your checkcycle function just need a little adjustment. I would change from to winner and to to loser. I think it would be easier to understand. Given a pair, you will call checkcycle(winner, loser). After checking if winner == loser, you should iterate over all pairs checking if loser is the winner, and calling checkcycle(winner, loser), passing the same original winner, and the loser of the loser
I'm trying to make a multithreaded merge sort and I've encountered a stack overflow error and I'm not sure what is causing it.
public static void concurrentMergeSort(int[] arr, int threadCount) {
if(threadCount <= 1){
regularMergeSort(arr);
return;
}
int middle = arr.length/2;
int[] left = Arrays.copyOfRange(arr, 0, middle); //Says error here
int[] right = Arrays.copyOfRange(arr, middle, arr.length);
concurrentMergeSort(left);//Says error here
concurrentMergeSort(right);
Thread leftSort = new Thread(new Sorting(left, threadCount));
Thread rightSort = new Thread(new Sorting(right, threadCount));
try{
leftSort.join();
rightSort.join();
}
catch (Exception ex){
ex.printStackTrace();
}
merge(arr, left, right);
}
public static void regularMergeSort(int[] arr){
if(arr.length == 1){
return;
}
int middle = arr.length/2;
int[] left = Arrays.copyOfRange(arr, 0, middle);
int[] right = Arrays.copyOfRange(arr, middle, arr.length);
regularMergeSort(left);
regularMergeSort(right);
merge(arr, left, right);
}
}
I was thinking that maybe it was the thread count never decreasing, but when I modify the thread count I still get the same result. Also it was working until I added a regular merge sort and concurrent merge sort to separate it. I only added the regular merge sort as well because I was barely getting a speed increase from just having the concurrent merge sort method and the main purpose of this modification of merge sort is to increase the time it takes to sort with multithreading.
Your return condition from regularMergeSort is:
if(arr.length == 1)
When middle = 0, you will end up creating an empty array; and this terminating condition won't be hit, and there will be infinite loop. Change this condition to:
if(arr.length <= 1)
And assuming your merge function handles empty arrays, you should be good.
Im trying to call this method from SDK
public ThumborUrlBuilder crop(int top, int left, int bottom, int right) {
if (top < 0) {
throw new IllegalArgumentException("Top must be greater or equal to zero.");
}
if (left < 0) {
throw new IllegalArgumentException("Left must be greater or equal to zero.");
}
if (bottom < 1 || bottom <= top) {
throw new IllegalArgumentException("Bottom must be greater than zero and top.");
}
if (right < 1 || right <= left) {
throw new IllegalArgumentException("Right must be greater than zero and left.");
}
hasCrop = true;
cropTop = top;
cropLeft = left;
cropBottom = bottom;
cropRight = right;
return this;
}
How I can call the method if the parameters are from an Array or Map like this? Is that possible?
ArrayList arrayList = [299, 296, 301, 297]
crop(arraylist)
Java:
No you cant.
you will get this error:
Compilation Errors Detected
...
method crop in class Test cannot be applied to given types;
required: int,int,int,int
found: java.util.ArrayList<java.lang.Integer>
reason: actual and formal argument lists differ in length
Groovy:
Yes you can.
Check the sample code on groovyConsole.
def hello(int a, int b){
println "$a and $b"
}
hello(1, 2)
def param = [1,2]
hello(param)
public ThumborUrlBuilder crop(ArrayList params) {
if (params.size() != 4 ){
throw new IllegalArgumentException(...);
}
int top = params.get(0);
int left = params.get(1);
int bottom = params.get(2);
int right = params.get(3);
...
}
This is not directly possible in Java, because the function crop requires 4 parameters.
Passing the given ArrayList into the crop function would result in an error.
You could write your own function to handle the ArrayList for you like this:
public ThumboUrlBuilder special_crop(ArrayList arraylist){
crop(arraylist.get(0),arraylist.get(1),arraylist.get(2),arraylist.get(3));
}
I've got a processing program that is supposed to display 100 rings each one a bit bigger than the previous. when i run my program it shows 1 ring that is the biggest. i this case 100px from the middle.
here's my code:
Car[] myCar = new Car[100];
void setup(){
size(500,500);
noFill();
for (int i = 0; i != myCar.length; i=i+1) {
myCar[i] = new Car(i);
}
}
void draw(){
for (int i = 0; i != myCar.length; i=i+1) {
myCar[i].drive();
myCar[i].display();
}
}
class Car{
int c;
Car(int c_){
c = c_;
}
void drive(){
c = c + 2;
}
void display(){
background(255);
noFill();
stroke(10);
ellipseMode(CENTER);
ellipse(width/2,height/2,1+c,1+c);
}
}
my question is: why is only the biggest ring displayed?
it could be that
for (int i = 0; i != myCar.length; i=i+1) {
myCar[i] = new Car(i);
}
somehow doesn't give the variable "i" to my constructor.
or that I'm just dumb. I don't know.
Thanks in advance.
You don"t see them because when you call myCar[i].display(), that function clears everything that is already on the screen and sets background(255) and then goes on to draw a ring. This keeps happening and you only see one ring that is growing bigger and bigger every frame.
Just remove background(255) from the display() function and make it the first line of draw() and you will have your desired results.
Not always but for most cases, background() is called in either setup() or draw() because what it does is fill each pixel of the canvas with a color, think about that.
for (int i = 0; i < 100,000; i++)
{
threadEvent.Invoke(i, new EventArgs());// tell processbar value
}
threadEvent += new EventHandler(method_threadEvent);
void method_threadEvent(object sender, EventArgs e)
{
int nowValue = Convert.ToInt32(sender);
nowValueDelegate now = new nowValueDelegate(setNow);
this.Invoke(now, nowValue);
}
private void setNow(int nowValue)
{
this.progressBar1.Value = nowValue;
}
private delegate void nowValueDelegate(int nowValue);
in the loop i do nothing, but it also waste alot of time !
why threadEvent.Invoke spend so much time ?
Invoking is an expensive operation, because it has to cross thread boundaries.
It's best to reduce the amount of invokes, by for instance only updating the progress bar for each percentage of work you do, rather than for each iteration of the loop. That way, only 100 updates need to be processed, rather than one for each iteration.
First thing you need to do is to calculate or estimate the current progress.
For a typical loop
for (int i = 0; i < someValue; ++i)
{
... // Work here
}
A good estimate of progress is (i / someValue) * 100, which gives the percentage of the loop that has been completed. To update the progress to the UI thread only when the next percentage has been reached you could do something in the line of:
int percentCompleted = 0;
threadEvent.Invoke(percentCompleted, new EventArgs()); // Initial progressbar value
for (int i = 0; i < someValue; ++i)
{
int newlyCompleted = (i / someValue) * 100;
if (newlyCompleted > percentCompleted)
threadEvent.Invoke(percentCompleted, new EventArgs());
percentCompleted = newlyCompleted;
... // Work here
}
Now finally, you could use BeginInvoke instead of Invoke to make sure the worker thread doesn't wait for the threadEvent to complete (PostMessage behaviour). This works well here because there is no return value from threadEvent that you need.