I wanted to make some kind of sorting algorithms visualisation is java swing but I am stuck on quicksort since I need to stop the partition loop every iteration so the array can redraw. That's how I wanted to do it but without any success
public int partition(int lowIndex, int highIndex,int i)
{
int pivot = highIndex;
for(int j=lowIndex; j<highIndex; j++)
{
if(isBigger(j,pivot))
{
i++;
swap(i,j);
return i;
}
}
swap(i+1,pivot);
return i+1;
}
Didn't find any good solution to keep track on i as well. I'm just clueless
Google for "Java swing visualize sorting algorithms" and you'll find many hits.
For example:
Code Review: sorting algorithm visualization program
Key points:
You need to modify your "sort" code to trigger some kind of "event" at each step (e.g. every time you swap elements):
EXAMPLE:
public class BubbleSort implements SortingAlgorithm {
...
#Override
public void doSort(int[] nums) {
...
SortingAlgorithm.setCurrentBar(j+1);
SortingAlgorithm.sleepFor(delay);
The "event handler" will redraw the array (or, more accurately, request the Event Dispatcher thread (EDT) to repaint).
Consequently, the event handler needs to "know about" the array, and the current index
EXAMPLE:
public abstract interface SortingAlgorithm {
...
public abstract void doSort(int[] nums);
public abstract void changeDelay(int delay);
public static void setCurrentBar(int currentBarIndex) {
PaintSurface.currentBarIndex = currentBarIndex;
}
...
There also needs to be some kind of "delay" between each step
This example uses SwingUtilities.invokeLater(). The example camickr suggests SwingWorker.
I hope that gives you a few ideas, and points you in the right direction!
Instead of calling partition from other class I implemented partition() and sort() methods in an anonymous SwingWorker class and after every swap in partition() method I called publish(array). Uploading source code if anyone would like to see how I solved this problem or would need help himself. Any feedback is really appreciate since it's my first "bigger" project
private void startThread()
{
SwingWorker sw1 = new SwingWorker() {
public int partition(int lowIndex, int highIndex) {
int pivot = highIndex;
int i = lowIndex - 1;
for (int j = lowIndex; j < highIndex; j++) {
if (sorter.isBigger(pivot, j)) {
i++;
sorter.swap(i, j);
try {
Thread.sleep(100);
}
catch(Exception e)
{
// not implemented yet
}
publish(sorter.getArray());
}
}
sorter.swap(i+1,pivot);
publish(sorter.getArray());
return i+1;
}
public void sort(int lowIndex, int highIndex)
{
if(lowIndex < highIndex)
{
int i = partition(lowIndex,highIndex);
try{
sort(lowIndex,i-1) ;
}
finally {
sort(i+1, highIndex);
}
}
}
#Override
protected int[] doInBackground() throws Exception {
sorter.setArray(drafter.getArray());
while (!sorter.isArraySorted()) {
//Thread.sleep(10);
sort(0,sorter.getLength()-1);
}
return sorter.getArray();
}
protected void process(List chunks)
{
int[] val = (int[]) chunks.get(chunks.size()-1);
drafter.ChangeArray(val);
//drafter.repaint();
}
};
sw1.execute();
}
Related
I have a question for the more advanced OOP developers here.
I am currently a CS student. We learned a Procedural Programming in Java the first semester where ADT was introduced. I understand the theory and the idea of why ADT is good and what are the benefits of it but it seems quite difficult for me to implement it in code. I get confused and lost.
In addition to that our exit test was on paper (we had to write around 200 line of code on paper) and I found it difficult.
Are there any tips before starting to construct the program?
For instance, do you guys already know how many methods and what method what it will return and have as a formal argument before you start to write the code?
You can approach it programming-style.
First, you need to define an interface for the ADT. Just write down its name and what it does.
Example:
ADT: Integer Stack
void push(int element) - adds an element to the top of stack
int pop() - removes and returns an element from the top of stack
int peek() - returns the value of top. no removal of value
boolean isEmpty() - returns true if the stack is empty
int size() - returns the number of element in the stack.
void print() - print all values of stack
Next is you need to decide on its implementation. Since ADT is about storage, it will be good to decide on storage strategy first.
Example:
ADT: Integer Stack
Implementation: Array Integer Stack
Implements an int stack using Java's built-in array functionality.
Since array is a static collection, i need to use an integer variable to track "top"
When everything is set, you can now proceed to coding.
public interface IntegerStack {
void push(int e);
int pop();
int peek();
boolean isEmpty();
int size();
void print();
}
public class ArrayIntegerStack implements IntegerStack {
private static final int INITIAL_TOP_INDEX = -1;
private int topIndex = INITIAL_TOP_INDEX;
private int[] stackValue = new int[Integer.MAX_VALUE];
#Override
public void push(int element) {
stackValue[++topIndex] = element;
}
#Override
public int pop() {
return stackValue[topIndex--];
}
#Override
public int peek() {
return stackValue[topIndex];
}
#Override
public boolean isEmpty() {
return INITIAL_TOP_INDEX == topIndex;
}
#Override
public int size() {
return topIndex + 1;
}
#Override
public void print() {
for (int i = 0; i <= topIndex; i++) {
System.out.println(stackValue[i]);
}
}
}
Adding on to the answer of KaNa001, you could use a modified HashMap where the key is the index and the value is the integer in the stack. This wont cause an Exception, as the HashMap object can change its length.
public class OrderSet<T> {
private HashMap<Integer, T> array;
public OrderSet() {
array = new HashMap<Integer, T>();
}
public void addAt (T o, int pos) {
// uses Array indexing
HashMap<Integer, T> temp = new HashMap<Integer, T>();
if (!(array.size() == 0)) {
for (int i = 0; i < array.size(); i++) {
temp.put(i, array.get(i));
}
array.put(pos, o);
int size = array.size();
for (int i = pos + 1; i < size + 1; i++) {
array.put(i, temp.get(i - 1));
}
} else {
array.put(0, o);
}
}
public T getPos (int pos) {
if (array.size() == 0) {
return null;
} else {
return array.get(pos);
}
}
}
public class MyTest {
ArrayList<Integer> array = new ArrayList<>();
public void initialize() {
//....
}
private void editArray(int num) {
// modified the array
}
public void func(int n) {
for (int i = 0; i < n; i++) {
editArray(i);
}
}
}
I hope to execute "editArray" function in the forloop concurrently, which means n threads(call editArray function) can execute concurrently, how can I do that and add a lock for ArrayList array ? I google a lot, most of tutorials just teach how to spawn thread for different objects. What I want is that spawn thread in a single object.
I mainly want to know how to call a function concurrently in java.
Thanks.
It's silly problem. I have my own comparator interface, class Student - it's objects will be sorted, class BubbleSort with bubblesorting algorithm and main. I think every class except from main is written quite well, but I have problem with implementation of them in main to make my sorting to start :/ I've just created ArrayList of random Students I want to be sorted, but I have problem with BubbleSort class and have no idea, how to start.
In future (I hope it will be today :)) I will do exactly the same with another classes containing sorting algorithms like BubbleSort here. I think their implementation in main will be identical.
import java.util.Random;
import java.util.ArrayList;
public class Program {
public static void main(String[] args) {
int elements = 100000;
ArrayList<Student> list = new ArrayList<Student>();
Random rand = new Random();
for (int i=0; i<elements; i++) {
list.add(new Student(rand.nextInt(4)+2, rand.nextInt(900000)));
}
System.out.println(list);
}
}
.
import java.util.ArrayList;
public class BubbleSort {
private final Comparator comparator;
public BubbleSort(Comparator comparator) {
this.comparator = comparator;
}
public ArrayList<Student> sort(ArrayList<Student> list) {
int size = list.size();
for (int pass = 1; pass < size; ++pass) {
for (int left = 0; left < (size - pass); ++left) {
int right = left + 1;
if (comparator.compare(list.get(left), list.get(right)) > 0)
swap(list, left, right);
}
}
return list;
}
public int compare(Object left, Object right) throws ClassCastException
{ return comparator.compare(left, right); }
private void swap(ArrayList list, int left, int right) {
Object temp = list.get(left);
list.set(left, list.get(right));
list.set(right, temp);
}
}
.
public class Student implements Comparator<Student> {
int rate;
int indeks;
public Student(int ocena, int index) {
this.rate = ocena;
indeks = index;
}
public String toString() {
return "Numer indeksu: " + indeks + " ocena: " + rate + "\n";
}
public int getIndeks() {
return indeks;
}
public int getRate() {
return rate;
}
public int compare(Student left, Student right) {
if (left.getIndeks()<right.getIndeks()) {
return -1;
}
if (left.getIndeks() == right.getIndeks()) {
return 0;
}
else {
return 1;
}
}
}
.
public interface Comparator<T> {
public int compare(T left, T right) throws ClassCastException;
}
Your code looks little bit strange. You didnt mention if you have to use bubble sort so i write both my ideas
1.Without explicitly using bubble sort
You can use Collections.sort() combined with overridencompareTo() method
So your code will look like this
class Student implements Comparable<Student>{
//variables constructor methods go here
private index;
#Override
public int compareTo(Students s) {
int index = s.index;
if (this.index > index) {
return 1;
} else if (this.index == index) {
return 0;
} else {
return -1;
}
}
}
And in your main class Collections.sort(myStudents)
2.Explicitly using bubble sort
Student class
class Student{
//class variables methods constructor goes here
}
Comparator class
class StudentComparator implements Comparator<Student>{
#Override
public int compare(Student a, Student b) {
//bubble sort code goes here
}}
Main class
class MyMainClass{
public static void main(String[] args) {
public int elements = 100000;
ArrayList<Student> list = new ArrayList<Student>();
Random rand = new Random();
for (int i=0; i<elements; i++) {
list.add(new Student(rand.nextInt(4)+2, rand.nextInt(900000)));
}
Collections.sort(list, new StudentComparator());
}
Two points to make here:
a) You are not calling sort at all. You need to instantiate your BubbleSort class and actually call the method. list = new BubbleSort(new Comparator(){...}).sort(list); <-- This syntax also calls for the sort method to be static so that you don't need to make a new object for every sort. The example below sorts by index.
list = new BubbleSort(new Comparator<Student>() {
#Override
public compare(Student a, Student b) {
return a.getIndeks() - b.getIndeks();
}
}).sort(list);
Btw, this also assumes that BubbleSort is made generic, since it's easier (and kinda makes sense anyway)
b) I hope this is some kind of project where you have to show your ability to make a sorting algorithm, otherwise you should use library methods for these things
Also, while the code is not bad, you might want to show it to someone with professional Java experience (it does not conform to a lot of standards and many things can be improved and made consistent with each other), or post it to https://codereview.stackexchange.com/
I dont see you calling the bubblesort class anywhere. A list will not automatically sort its elements. Please go through this link. You ll find it handy.
http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/
I was experimenting with this question today, from Euler Problems:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I thought about it and it can of course be done with for-loops, however I want to use Java 8 as it opens up new options.
However first of all, I do not know how to generate an IntStream that produces such elements, so I still ended up using normal for-loops:
public class Problem4 extends Problem<Integer> {
private final int digitsCount;
private int min;
private int max;
public Problem4(final int digitsCount) {
this.digitsCount = digitsCount;
}
#Override
public void run() {
List<Integer> list = new ArrayList<>();
min = (int)Math.pow(10, digitsCount - 1);
max = min * 10;
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
int sum = i * j;
if (isPalindrome(sum)) {
list.add(sum);
}
}
}
result = list.stream().mapToInt(i -> i).max().getAsInt();
}
private boolean isPalindrome(final int number) {
String numberString = String.valueOf(number);
String reversed = new StringBuilder(numberString).reverse().toString();
return (numberString.equals(reversed));
}
#Override
public String getName() {
return "Problem 4";
}
}
As you can see I might be a bit lazy, bit really the IntStream::max is a very nice method and I think it is better to use that, as to write it yourself.
Here comes the issue though, I need to have a list now to be able to obtain the maximum in this manner, which means I need to store data, where I really should not do so.
So, the question now, would it be possible to implement this in Java 8?
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
yield i * j;
}
}
And then out of that method create an PrimitiveIterator.OfInt (unboxes version of Iterator<Integer>, or create an IntStream directly?
Then getting the answer with streamFromYield.filter(this::isPalindrome).max().getAsInt() would be really easy to implement.
Lastly, I know this question has been asked before, however the last time is already quite a bit ago and now Java 8 is going to happen very soon, where they have added as big concept Stream<T> and the new language construct, called lambdas.
So making such code may be very different now than when people were making it for Java 6 or 7.
Well, I think we've gotten carried away using the Streams API from the "outside," using flatMap, optimizing the palindrome-finding algorithm, etc. See answers from Boris the Spider and assylias. However, we've sidestepped the original question of how to write a generator function using something like Python's yield statement. (I think the OP's nested-for example with yield was using Python.)
One of the problems with using flatMap is that parallel splitting can only occur on the outermost stream. The inner streams (returned from flatMap) are processed sequentially. We could try to make the inner streams also parallel, but they'd possibly compete with the outer ones. I suppose nested splitting could work, but I'm not too confident.
One approach is to use the Stream.generate or (like assylias' answer) the Stream.iterate functions. These create infinite streams, though, so an external limit must be supplied to terminate the stream.
It would be nice if we could create a finite but "flattened" stream so that the entire stream of values is subject to splitting. Unfortunately creating a stream is not nearly as convenient as Python's generator functions. It can be done without too much trouble, though. Here's an example that uses the StreamSupport and AbstractSpliterator classes:
class Generator extends Spliterators.AbstractIntSpliterator {
final int min;
final int max;
int i;
int j;
public Generator(int min, int max) {
super((max - min) * (max - min), 0);
this.min = min;
this.max = max;
i = min;
j = min;
}
public boolean tryAdvance(IntConsumer ic) {
if (i == max) {
return false;
}
ic.accept(i * j);
j++;
if (j == max) {
i++;
j = min;
}
return true;
}
}
public static void main(String[] args) {
Generator gen = new Generator(100, 1000);
System.out.println(
StreamSupport.intStream(gen, false)
.filter(i -> isPalindrome(i))
.max()
.getAsInt());
}
Instead of having the iteration variables be on the stack (as in the nested-for with yield approach) we have to make them fields of an object and have the tryAdvance increment them until the iteration is complete. Now, this is the simplest form of a spliterator and it doesn't necessarily parallelize well. With additional work one could implement the trySplit method to do better splitting, which in turn would enable better parallelism.
The forEachRemaining method could be overridden, and it would look almost like the nested-for-loop-with-yield example, calling the IntConsumer instead of yield. Unfortunately tryAdvance is abstract and therefore must be implemented, so it's still necessary to have the iteration variables be fields of an object.
How about looking at it from another direction:
You want a Stream of [100,1000), and for each element of that Stream you want another Stream of that element multiplied by each of [100, 1000). This is what flatMap is for:
public static void main(final String[] args) throws Exception {
OptionalInt max = IntStream.range(100, 1000).
flatMap((i) -> IntStream.range(i, 1000).map((j) -> i * j)).
unordered().
parallel().
filter((i) -> {
String forward = Integer.toString(i);
String backward = new StringBuilder(forward).reverse().toString();
return forward.equals(backward);
}).
max();
System.out.println(max);
}
Not sure if getting a String and then the reverse is the most efficient way to detect palindromes, off the top of my head this would seem to be faster:
final String asString = Integer.toString(i);
for (int j = 0, k = asString.length() - 1; j < k; j++, k--) {
if (asString.charAt(j) != asString.charAt(k)) {
return false;
}
}
return true;
It gives the same answer but I haven't put it under an rigorous testing... Seems to be about 100ms faster on my machine.
Also not sure this problem is big enough for unordered().parallel() - removing that gives a little boost to speed too.
Was just trying to demonstrate the capabilities of the Stream API.
EDIT
As #Stuart points out in the comments, as multiplication is commutative, we only need to IntStream.range(i, 1000) in the sub-stream. This is because once we check a x b we don't need to check b x a. I have updated the answer.
There always have been ways to emulate that overrated yield feature, even without Java 8. Basically it is about storing the state of an execution, i.e. the stack frame(s), which can be done by a thread. A very simple implementation could look like this:
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class Yield<E> implements Iterable<E> {
protected interface Flow<T> { void yield(T item); }
private final class State implements Runnable, Iterator<E>, Flow<E> {
private E nextValue;
private boolean finished, value;
public synchronized boolean hasNext() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
return value;
}
public synchronized E next() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
if(!value) throw new NoSuchElementException();
final E next = nextValue;
value=false;
notify();
return next;
}
public void remove() { throw new UnsupportedOperationException(); }
public void run() {
try { produce(this); }
finally {
synchronized(this) {
finished=true;
notify();
}
}
}
public synchronized void yield(E next) {
while(value) try { wait(); } catch(InterruptedException ex){}
nextValue=next;
value=true;
notify();
}
}
protected abstract void produce(Flow<E> f);
public Iterator<E> iterator() {
final State state = new State();
new Thread(state).start();
return state;
}
}
Once you have such a helper class, the use case will look straight-forward:
// implement a logic the yield-style
Iterable<Integer> y=new Yield<Integer>() {
protected void produce(Flow<Integer> f) {
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
f.yield(i * j);
}
}
}
};
// use the Iterable, e.g. in a for-each loop
int maxPalindrome=0;
for(int i:y) if(isPalindrome(i) && i>maxPalindrome) maxPalindrome=i;
System.out.println(maxPalindrome);
The previous code didn’t use any Java 8 features. But it will allow using them without the need for any change:
// the Java 8 way
StreamSupport.stream(y.spliterator(), false).filter(i->isPalindrome(i))
.max(Integer::compare).ifPresent(System.out::println);
Note that the Yield support class above is not the most efficient implementation and it doesn’t handle the case if an iteration is not completed but the Iterator abandoned. But it shows that such a logic is indeed possible to implement in Java (while the other answers convincingly show that such a yield logic is not necessary to solve such a problem).
I'll give it a go. Version with a loop then with a stream. Although I start from the other end so it's easier because I can limit(1).
public class Problem0004 {
public static void main(String[] args) {
int maxNumber = 999 * 999;
//with a loop
for (int i = maxNumber; i > 0; i--) {
if (isPalindrome(i) && has3DigitsFactors(i)) {
System.out.println(i);
break;
}
}
//with a stream
IntStream.iterate(maxNumber, i -> i - 1)
.parallel()
.filter(i -> isPalindrome(i) && has3DigitsFactors(i))
.limit(1)
.forEach(System.out::println);
}
private static boolean isPalindrome(int n) {
StringBuilder numbers = new StringBuilder(String.valueOf(n));
return numbers.toString().equals(numbers.reverse().toString());
}
private static boolean has3DigitsFactors(int n) {
for (int i = 999; i > 0; i--) {
if (n % i == 0 && n / i < 1000) {
return true;
}
}
return false;
}
}
I have a batch of sprites (textured OpenGL ES 2.0 Quads) which I loop through to move. Here is a simplified version of my code:
//'sprite' & other values have been are assumed to exist for the purpose of the question
public void moveQuadBatch(){
//Loop for as many sprites as there are to draw
for (loop = 0; loop < sprite.number; loop++){
moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite
}
}
Now, for some batches, there is a countdown timer, or some other condition (and there isn't for others, like above). Therefore, I've created a similar method for these objects like so:
public void moveQuadBatchWithCheck(){
//Loop for as many sprites as there are to draw
for (loop = 0; loop < sprite.number; loop++){
//Only do this if the particular sprite's countdown/delay counter has reached 0 (counting down from another method not seen here)
if (sprite.delay[loop]<0){
moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite
}
}
}
However, I'm not entirely happy about this as there is a lot of code duplication. Instead of having these 2 methods is there any way I can use the first one and somehow 'slipstream' the additional check into the for loop? Or otherwise cut down on the duplication that I have here? This is a simple example, there are others and currently I have multiple methods which are all very similar.
Edit
As mentioned, the above is somewhat simplified. I could have some for loops which check another value (other than delay for example), and some could check 2 conditions.
public void moveQuadBatch(bool checkDelay) {
for (loop = 0; loop < sprite.number; loop++){
if (!checkDelay || sprite.delay[loop] < 0) {
moveQuadNumber(loop);
}
}
}
Now moveQuadBatch(false) is your first function and moveQuadBatch(true) is your second one.
As to "inserting extra code", you're basically talking about functions. In Python an elegant approach would be to pass a function in and offload all logic to the function, e.g:
def moveQuadBatch(predicate=None):
for loop, sprite in enumerate(self.sprites):
if not predicate or predicate(loop, sprite):
self.moveQuadNumber(loop)
Then you would use it as such:
inst.moveQuadBatch()
inst.moveQuadBatch(lambda loop, sprite: sprite.delay[loop] < 0)
inst.moveQuadBatch(lambda loop, sprite: sprite.doesItBlend(loop))
You can do this same thing in Java but not quite as neatly: you have to define a predicate class and instances of it. This is the approach B.J. Smegma was advocating.
public interface QuadBatchPredicate {
public boolean shouldMove(int loop, Sprite sprite);
}
Your function would look like this:
public void moveQuadBatch(QuadBatchPredicate pred) {
for (loop = 0; loop < sprite.number; loop++){
if (pred == null || pred(loop, sprite)) {
moveQuadNumber(loop);
}
}
}
public void moveQuadBatch() {
moveQuadBatch(null);
}
Then you can use anonymous classes to define the predicates:
moveQuadBatch();
moveQuadBatch(new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.delay[loop] < 0;
}
});
moveQuadBatch(new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.doesItBlend();
}
});
A bit cruftier than the Python solution, but it gets the point across. Now you can "insert code" into the function by defining the predicate, in-line, to be whatever you want it to be. Plus you can save often-used ones so you don't repeat them all over the place:
QuadBatchPredicate checkBlends = new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.doesItBlend();
}
};
Make an interface as so:
public interface MyInteface {
void do_something(int loop);
}
Make different implementations of that interface depending on your needs e.g.
public class MyInterfaceImpl {
public void do_something(int loop) {
if (!checkDelay || sprite.delay[loop] < 0) {
moveQuadNumber(loop);
}
}
Then your method could look simple as this:
public void moveQuadBatch(MyInterface interface) {
for (int loop = 0; loop < sprite.number; loop++){
interface.do_something(loop)
}
}
You could add "effects" to your sprites.
public class Sprite {
private boolean active = true;
private ArrayList<Effect> effects = new ArrayList<>();
public void update(int time) {
for(Effect e: effects) {
e.update(this, time);
}
}
public void addEffect(Effect effect) {
effects.add(effect);
}
public void setActive(boolean active) {
this.active = active;
}
}
public interface Effect {
void update(Sprite sprite, int time);
}
public class Delay implements Effect {
private int delay;
public Delay(int delay) {
this.delay = delay;
}
public void update(Sprite sprite, int time) {
delay -= time;
if(delay > 0) sprite.setActive(false);
else sprite.setActive(true);
}
}
I would create a seperate method for the delay check and change your method like this:
public void moveQuadBatchWithCheck(bool check){
for (loop = 0; loop < sprite.number; loop++){
if(check){
if (sprite.delay[loop]<0){
moveQuadNumber(loop);
}
}
else{
moveQuadNumber(loop);
}
}
Then when you want to check call the method with true
in the parameter.
Not sure if this is what you're looking for though, but I hope it helps.