ok here's the block of code i wrote :
public ArrayList<Location> possibleMoves() {
ArrayList<Location> a1 = new ArrayList<Location>(); // an array to contain all possible locations
Board testB = new Board(); // a test board to test if locations are valid or not
// locations have x & y coordinates
a1.add(new Location(getCurrentLocation().getx() - 1, getCurrentLocation().gety() + 1));
a1.add(new Location(getCurrentLocation().getx() + 1, getCurrentLocation().gety() - 1));
a1.add(new Location(getCurrentLocation().getx() - 1, getCurrentLocation().gety() - 1));
a1.add(new Location(getCurrentLocation().getx() + 1, getCurrentLocation().gety() + 1));
for (int i = 0; i < a1.size(); i++) {
try {
Tower testTower = testB.getGrid()[a1.get(i).getx()][a1.get(i).gety()];
}catch(ArrayIndexOutOfBoundsException e) {
a1.remove(a1.get(i));
}
}
return a1;
}
When you remove the element, the position of the following ones is decreased. Do this also to i. And, you can just use remove(int).
for (int i = 0; i < a1.size(); i++) {
try {
Tower testTower = testB.getGrid()[a1.get(i).getx()][a1.get(i).gety()];
} catch(ArrayIndexOutOfBoundsException e) {
a1.remove(i--);
}
}
If you want to remove elements from a List while visiting its elements I suggest to used the following pattern:
Iterator<Location> locationsIt = a1.iterator();
while (locationsIt.hasNext()) {
Location location = locationsIt.next();
try {
Tower testTower = testB.getGrid()[location.getx()][location.gety()];
} catch(ArrayIndexOutOfBoundsException e) {
locationsIt.remove();
}
}
It's easy to use and it's not error prone.
Related
I have an unsorted list with float values. I'm able to create graph from that.
But now, I want to create batches based on up and downs in that graph.
For example, I've an list like below
[6.17, 6.13, 6.12, 6.19, 6.2, 6.21, 6.28, 6.17, 6.2, 6.28]
First batch will be decreasing from 6.17 to 6.12 (index 0 to index 2).
Then second batch will be increasing from 6.12 to 6.28(index 3 to index 6)
All I can think of is to create two methods
increasing(List values) - to get all incremental values
decreasing(List values) - to get all decremental values
Call decreasing() method in increasing() method whenever I find sudden drop in values with sublist from last accessed element and vice-versa
But I don't think this is good idea.
Please find the graph image for reference
I've an object TimeAnalysis which contains start and end values.
In first case start=6.17 and end=6.12.
In second case start=6.12 and end=6.28
I want to get list of TimeAnalysis objects.
To actually split them up you can use Math.signum.
private List<List<Double>> splitAtInflectionPoints(List<Double> data) {
List<List<Double>> split = new LinkedList<>();
int start = 0;
for (int i = 1; i < data.size() - 1; i++) {
double leftSlope = Math.signum(data.get(i) - data.get(i - 1));
double rightSlope = Math.signum(data.get(i + 1) - data.get(i));
if (leftSlope != rightSlope) {
split.add(data.subList(start, i + 1));
start = i;
}
}
if (start < data.size()) {
split.add(data.subList(start, data.size()));
}
return split;
}
private void test() {
List<Double> data = Arrays.asList(6.17, 6.13, 6.12, 6.19, 6.2, 6.21, 6.28, 6.17, 6.2, 6.28);
for (List<Double> run : splitAtInflectionPoints(data)) {
System.out.println(run);
}
}
Prints:
[6.17, 6.13, 6.12]
[6.12, 6.19, 6.2, 6.21, 6.28]
[6.28, 6.17]
[6.17, 6.2, 6.28]
You can create a class that stores the list of values and type of Batch.
class Batch {
enum BatchType {
INCREASING,
DECREASING
};
BatchType batchType;
List<Float> values;
}
Now you can have a method called splitIntoBatches which returns a list of Batch.
public List<Batch> splitIntoBatches(List<Float> values) {
// Traverse through the list once and create list of batches.
}
You can loop through elements in your array and track if it's increasing or decreasing or possibly the same.
I used TimeAnalysis class you mentioned and wrote a static method splitList().
It is to split the list of time floats into list of TimeAnalysis.
public static List<TimeAnalysis> splitList(List<Float> timeList) {
if(timeList.size() == 0) return new ArrayList<>();
else if(timeList.size() == 1) {
List<TimeAnalysis> batches = new ArrayList<>();
batches.add(new TimeAnalysis(timeList.get(0), timeList.get(0)));
return batches;
}
ArrayList<TimeAnalysis> batches = new ArrayList<>();
// 0: same, 1: inc, 2: dec
int type = -1;
TimeAnalysis lastBatch = new TimeAnalysis(timeList.get(0), timeList.get
batches.add(lastBatch);
timeList.remove(0);
for(float t : timeList) {
switch(type) {
case 0: // same
if(t > lastBatch.end) { // inc
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 1;
} else if(t < lastBatch.end) { // dec
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 2;
}
break;
case 1: // inc
if(t > lastBatch.end) { // inc
lastBatch.end = t;
} else if(t < lastBatch.end) { // dec
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 2;
} else { // same
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 0;
}
break;
case 2: // dec
if(t > lastBatch.end) { // inc
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 1;
} else if(t < lastBatch.end) {
lastBatch.end = t;
} else {
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 0;
}
break;
default:
if(t > lastBatch.end) type = 1;
else if(t < lastBatch.end) type = 2;
else type = 0;
lastBatch.end = t;
break;
}
}
return batches;
}
When I run:
Scanner in = new Scanner(System.in);
ArrayList<Float> input = new ArrayList<>();
for(int i=0; i<10; i++) input.add(in.nextFloat());
List<TimeAnalysis> output = TimeAnalysis.splitList(input);
for(TimeAnalysis batch : output) System.out.println("start: " + batch.start + ", end: " + batch.end);
and give your data as input, I get:
start: 6.17, end: 6.12
start: 6.12, end: 6.28
start: 6.28, end: 6.17
start: 6.17, end: 6.28
Right now i'm struggeling with a basic algorithm, that shall sort a linked list. I have two additional linked lists (in the beginning empty), in which i can copy the Integer Objects of the first linkedlist.
My problem is, that all of my tries simply doesn't work. In the copied example at the bottom, it goes through both of the while loops, but i don't know how to loop everything, until everything is sorted in the third linked list (zug3.zug3). Also i shall compare the actual smallest value of zug1 to the smallest of zug2 and then continue sorting in the list where the value is smaller. That is not possible at the start of sorting, because if i wanna getSmallest() of an empty List, it will get a null pointer exception.
I'm tryin this now since three days with different, for-loops, while-loops, if-else sentences but i don't find out, how to make it work accurate.
Please help!
Example of the Programm:
public class Abstellgleis {
LinkedList<Integer> zug1 = new LinkedList<Integer>();
void initialize() {
for (int i = 0; i <15;i++) {
Random zahl = new Random();
int integer = zahl.nextInt(15);
zug1.add(integer);
}
}
public void wagenAnkoppeln(int i) {
zug1.addFirst(i);
}
int wagenAbkoppeln() {
int waggonNummer = zug1.getFirst();
zug1.removeFirst();
return waggonNummer;
}
int getSmallest() {
int smallest = zug1.size();
for( int i =1; i <zug1.size()-1; i++)
{
if(zug1.get(i) < smallest )
{
//int smallest = integers.get(Oedipus);
smallest = zug1.get(i);
}
}
return smallest;
}
}
public class Rangiergleis {
LinkedList<Integer> zug2 = new LinkedList<Integer>();
void waggonAnkoppeln(int i) {
zug2.addFirst(i);
}
int waggonAbkoppeln() {
int waggonNummer = zug2.getFirst();
zug2.removeFirst();
return waggonNummer;
}
int getSmallest() {
int smallest = 100;
for (int i = 0; i < zug2.size() - 1; i++) {
if (zug2.get(i) < smallest) {
smallest=zug2.get(i);
}
}
return smallest;
}
}
public class Zuggleis {
LinkedList<Integer> zug3 = new LinkedList<Integer>();
void waggonAnkoppeln(int i) {
zug3.addLast(i);
}
}
public class Steuerung {
public static void main(String[] args) {
Abstellgleis zug1 = new Abstellgleis();
zug1.initialize();
Rangiergleis zug2 = new Rangiergleis();
Zuggleis zug3 = new Zuggleis();
System.out.println("Abstellgleis:" + zug1.zug1);
System.out.println("Rangiergleis: " + zug2.zug2);
System.out.println("Abstellgleis: " + zug3.zug3);
while (!zug1.zug1.isEmpty()) {
if (zug1.zug1.getFirst() != zug1.getSmallest()) {
zug2.waggonAnkoppeln(zug1.zug1.getFirst());
System.out.println("Vom Abstellgleis wurde Wagen " +
zug1.zug1.getFirst() + " aufs Rangiergleis bewegt");
zug1.zug1.removeFirst();
}
else if (zug1.zug1.getFirst() == zug1.getSmallest()) {
zug3.waggonAnkoppeln(zug1.zug1.getFirst());
System.out.println(zug1.zug1.getFirst() + "wurde aufs Zuggleis bewegt");
zug1.zug1.removeFirst();
}
System.out.println("Abstellgleis:" + zug1.zug1);
System.out.println("Rangiergleis: " + zug2.zug2);
System.out.println("Zuggleis: " + zug3.zug3);
}
while (!zug2.zug2.isEmpty()) {
if (zug2.zug2.getFirst() != zug2.getSmallest()) {
zug1.wagenAnkoppeln(zug2.zug2.getFirst());
System.out.println("Vom Rangiergleis wurde Wagen " +
zug2.zug2.getFirst() + " aufs Abstellgleis bewegt");
zug2.zug2.removeFirst();
}
else if (zug2.zug2.getFirst() == zug2.getSmallest()) {
zug3.waggonAnkoppeln(zug2.zug2.getFirst());
System.out.println(zug2.zug2.getFirst() + " wurde vom Rangiergleis aufs Zuggleis bewegt");
zug2.zug2.removeFirst();
}
System.out.println("Abstellgleis:" + zug1.zug1);
System.out.println("Rangiergleis: " + zug2.zug2);
System.out.println("Zuggleis: " + zug3.zug3);
}
if (zug1.zug1.isEmpty()) {
while (!zug2.zug2.isEmpty())
if (zug2.zug2.getFirst() != zug2.getSmallest()) {
zug1.wagenAnkoppeln(zug2.zug2.getFirst());
System.out.println("Vom Abstellgleis wurde Wagen " +
zug2.zug2.getFirst() + " aufs Rangiergleis bewegt");
zug2.zug2.removeFirst();
}
else if (zug2.zug2.getFirst() == zug2.getSmallest()) {
zug3.waggonAnkoppeln(zug2.zug2.getFirst());
System.out.println(zug2.zug2.getFirst() + "wurde aufs Zuggleis bewegt");
zug2.zug2.removeFirst();
}
System.out.println("Abstellgleis:" + zug1.zug1);
System.out.println("Rangiergleis: " + zug2.zug2);
System.out.println("Zuggleis: " + zug3.zug3);
}
}
}
Your getSmallest methods in Abstellgleis and Rangiergleis don’t look right. In the first you start by setting smallest to zug1.size(). First time when the size is 15 this is probably fine, but as the Zug grows shorter, there may come a point when the size is smaller than the smallest element, and then your method will give the wrong result. In Rangiergleis you are initializing to 100, that’s sounder. In both methods you are missing the last element. For example in Abstellgleis.getSmallest():
for( int i =1; i <zug1.size()-1; i++)
This is in fact missing both the first and the last element. Elements are indexed 0 through zug1.size() - 1, so it should be one of the two following:
for (int i = 0; i < zug1.size(); i++) {
for (int i = 0; i <= zug1.size() - 1; i++) {
The former would be conventional. If you are sure there is at least one wagon in the train, you may of course initialize smallest to zug1.get(0) and the have the loop run from 1 (this could have been what you intended).
In Rangiergleis.getSmallest() your loop runs from 0 as it should, but is missing the last element in the same way as in Abstellgleis.
Can someone please let me know what's the problem with the below code?
Am trying to sort an array stored in "Options" variable. But it throws 'Null' exception.
public static void CheckOptionsPresent(String s1) throws Exception
{
try
{
List optionsList=null;
webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance button")).click();
int listcount = webDriver.findElements(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li")).size();
System.out.println(listcount);
String[] options=new String[listcount];
for (int i=2; i<=listcount; i++ )
{
options[i-1] = webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li:nth-child("+i+") a span")).getText();
System.out.println(options[i-1]);
}
System.out.println(options.length);
for(int j=0; j<options.length;j++)
{
for (int i=j+1 ; i<options.length; i++)
{
if(options[i].compareToIgnoreCase(options[j])<0)
{
String temp= options[j];
options[j]= options[i];
options[i]=temp;
}
}
System.out.println(options[j]);
}
}
catch (RuntimeException e)
{
System.out.println(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
Output:
14
AB - Alberta
BC - British Columbia
MB - Manitoba
NB - New Brunswick
NL - Newfoundland and Labrador
NS - Nova Scotia
NT - Northwest Territories
NU - Nunavut
ON - Ontario
PE - Prince Edward Island
QC - Québec
SK - Saskatchewan
YT - Yukon Territory
14
Below is the error:
org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.
for (int i=j+1 ; i<options.length; i++) {
if(options[i].compareToIgnoreCase(options[j])<0) {
String temp= options[j]; options[j]= options[i];
options[i]=temp;
}
}
String.compareToIgnoreCase() does not like null as its argument.
After your first loop, options[0] = null;
A NullPointerException happens when this gets hit on the first pass of if(options[i].compareToIgnoreCase(options[j])<0)then the indexes are (i = 1, j = 0).
Working Code :
public static void CheckOptionsPresent(String s1) throws Exception {
try {
List < String > optionsList = null;
webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance button")).click();
int listcount = webDriver.findElements(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li")).size();
System.out.println(listcount);
String[] options = new String[listcount];
for (int i = listcount; i >= 2; i--) {
options[i - 1] = webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li:nth-child(" + i + ") a span")).getText();
System.out.println(options[i - 1]);
optionsList = Arrays.asList(options);
}
System.out.println(optionsList);
System.out.println(isSorted(optionsList));
} catch (RuntimeException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
public static boolean isSorted(List < String > list) {
boolean sorted = true;
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i) == null) continue;
if (list.get(i).compareTo(list.get(i + 1)) > 0) sorted = false;
}
return sorted;
}
I had to make a Temp array to keep resizing the array list if the user decides to keep adding items to the cart, but my Temp array works until I try to add 3 different items to the cart.
I was instructed to do it this way instead of an array list to show the difficulty of arrays.
orderProduct [productCount] = aProduct;
orderQuantity [productCount] = aQuantity;
}
}
You forgot to increase productCount when there is already a product in the cart.
Moreover, you can just set the product and quantity array to the temp arrays instead of copying back.
orderProduct = tempOrderedProducts;
orderQuantity = tempOrderedQuantity;
Because you forgot productCount++ after resizing the array.
The following code will work:
public void setOrderProduct(Product aProduct, int aQuantity) {
if (productCount == 0) {
orderProduct[0] = aProduct;
orderQuantity[0] = aQuantity;
} else {
Product[] tempOrderedProducts = new Product[orderProduct.length + 1];
int[] tempOrderedQuantity = new int[orderQuantity.length + 1];
for (int i = 0; i < orderProduct.length; i++) {
tempOrderedProducts[i] = orderProduct[i];
tempOrderedQuantity[i] = orderQuantity[i];
}
orderProduct = new Product[tempOrderedProducts.length];
orderQuantity = new int[tempOrderedQuantity.length];
for (int i = 0; i < orderQuantity.length; i++) {
orderProduct[i] = tempOrderedProducts[i];
orderQuantity[i] = tempOrderedQuantity[i];
}
orderProduct[productCount] = aProduct;
orderQuantity[productCount] = aQuantity;
productCount++; //you forgot this
}
}
What's more, there is a simple way to deal with array copy:
public void setOrderProduct(Product aProduct, int aQuantity) {
if (productCount == 0) {
orderProduct[0] = aProduct;
orderQuantity[0] = aQuantity;
} else {
Product[] tempOrderedProducts = new Product[orderProduct.length + 1];
int[] tempOrderedQuantity = new int[orderQuantity.length + 1];
//System.arraycopy is more convenient and efficient
System.arraycopy(orderProduct, 0, tempOrderedProducts, 0, orderProduct.length);
System.arraycopy(orderQuantity, 0, tempOrderedQuantity, 0, orderQuantity.length);
//you don't need to copy back, just re-assign the reference
orderProduct = tempOrderedProducts;
orderQuantity = tempOrderedQuantity;
orderProduct[productCount] = aProduct;
orderQuantity[productCount] = aQuantity;
productCount++;
}
}
I have read a little about ConcurrentModificationException in stackflow and my actual update appears not to be the issue, it could be a problem in my design or I need a technique I haven't learnt yet.
Example Situation:
My iterator is running along position markers.
Then an action can be performed to shift the markers over (e.g. Inserting into string).
All Markers greater than the current position must also be shifted to preserve correctness.
Task:
How do I update the remaining markers without the iterator exploding?
Can I refresh the iterator, or break and start the loop again?
The following code is abstracted from my work.
public void innerLoop(Boolean b) {
//An Example of what I'm working with
HashMap<String, HashSet<Integer>> map = new HashMap<String, HashSet<Integer>>() {
{
put("Nonce",
new HashSet<Integer>() {
{
add(1);
add(2);
add(3);
add(4);
add(5);
}
});
}
};
//for each key
for (String key: map.keySet()) {
HashSet<Integer> positions = map.get(key);
//for each integer
for (Iterator<Integer> it = positions.iterator(); it.hasNext();) {
Integer position = it.next();
System.out.println("position =" + position);
//(out of scope) decision requiring elements from the outter loops
if (new Random().nextBoolean()&&b) {
//shift position by +4 (or whatever)
//and every other (int >= position)
System.out.println("Shift " + position + " by 4");
Integer shift = 4;
update(position,
shift,
positions);
it.remove();
}
}
}
}
public void update(Integer current,
Integer diff,
Set<Integer> set) {
if (set != null) {
HashSet<Integer> temp = new HashSet<Integer>();
for (Integer old: set) {
if (old >= current) {
temp.add(old);
System.out.println(old + "Added to temp");
}
}
for (Integer old: temp) {
set.remove(old);
System.out.println(old + "removed");
set.add(old + diff);
System.out.println((old + diff) + "Added");
}
}
}
Edited with Garrett Hall Solution
public void nestedloops() {
HashMap<String, HashSet<Integer>> map = new HashMap<String, HashSet<Integer>>() {
{
put("Hello",
new HashSet<Integer>() {
{
add(5);
add(2);
add(3);
add(4);
add(1);
add(6);
}
});
}
};
//for each key
for (String key: map.keySet()) {
ArrayList<Integer> positions = new ArrayList<Integer>(map.get(key));
//for each integer
for (int i = 0; i < positions.size(); i++) {
Integer position = positions.get(i);
System.out.println("[" + i + "] =" + position);
//out of scope decision
if (new Random().nextBoolean()) {
//shift position by +4
//and every other (int >= position)
System.out.println("Shift after " + position + " by 4");
Integer shift = 4;
//Update the array
for (int j = 0; j < positions.size(); j++) {
Integer checkPosition = positions.get(j);
if (checkPosition > position) {
System.out.println(checkPosition + "increased by 4");
positions.set(j,
checkPosition + shift);
}
}
}
}
//Add updated Array
map.put(key,
new HashSet<Integer>(positions));
}
}
You best bet is indexing the HashSet by putting it into a list. Then you can use indices to refer to elements rather than an Iterator. So long as you are not removing or adding (only updating) elements, then your indices will be correct. Otherwise you will have to account for that. Example:
ArrayList<Integer> positions = new ArrayList<Integer>(map.get(key));
for (int i = 0; i < positions.size(); i ++) {
// updating list
for (int j = i; i < positions.size(); j ++) {
positions.set(j, positions.get(i) + diff);
}
}
I would copy the original set to a list so that you don't need to worry about the current iteration code. Then update a secondary list (not being iterated).
Reasons:
You can't iterate and modify your original collection at once (there is no way around the ConcurrentModificationExceptions)
Nice one liner to shift items in a list.
Collections.rotate(list.subList(j, k+1), -1);
Guava will be able to handle the "find first index that satisfies that predicate and transform the list" which a bunch of utility methods.