How to increment an array with a nested for loop? - java

There must be a more elegant way to do the following:
for(int i = 0; i < subsets.length-10; i++) {
sample = (int)subsets[i];
int y = (sample
+ ((int)(subsets[i+1]))
+ ((int)(subsets[i+2]))
+ ((int)(subsets[i+3]))
+ ((int)(subsets[i+4]))
+ ((int)(subsets[i+5]))) / 6;
}
Basically, it adds the next 5 values for 'subsets' incrementally. How to use a nested for loop to use a single formula that means I can increase how many times it adds the next value and then divide by that many also to get an average.
Something like?:
y = (sample + ((int)(subsets[i++n]))/n
where n is number of times it incrementally adds the next value
any ideas?

y = Arrays.stream(subsets, i, i+6).sum()/6;

This Stream should give you all the y values:
IntStream.range(0, subsets.length - 10)
.map(i -> Arrays.stream(subsets, 0, 6).sum() / 6);
You could also use IntStream.average() instead of calculating it yourself if a double is ok.

sample is not special, it's only i+0 so you don't have to isolate it. You can try:
for(int i = 0; i < subsets.length-10; i++) {
int y = 0;
for(int j=i;j<i+n-1;j++) {
y += (int)subsets[j];
}
y = y / n;
}

Your approach of an nested loop is correct. Try something like this:
for ( int i = 0; i < subsets.length - 10; i++ )
{
sample = subsets[ i ];
int y = sample;
for ( int k = i; k < i + 5; k++ )
{
y += subsets[ k ];
}
y /= 6;
}

int sample;
for (int i = 0; i < subsets.length - 10; i++) {
sample = (int) subsets[i];
for (int j = i; (j < i + 6) && (j < subsets.length -10); j++) {
sample += subsets[i];
}
int y = sample / 6;
}

Related

Find average of List<Point> in Java

I have a List variable 'l' which has values like this:
List<Point> l = new ArrayList<Point>();
Imgproc.convexHull(contours,hull);
for (int j = 0; j < intlist.length; j++) {
l.add(contours.toList().get(hull.toList().get(j)));
}
After this I am getting following values of l:
l = [{1,2}, {3,4}, {5,6}]
and so on. How to find the average of 1st and 2nd values in l.get(i) for all i, as an array. For example, for the above I want the following:
x = 3
y = 4
Finally I got the answer! Below code will do the job:
double sum_x = 0;
double sum_y = 0;
int j;
for (j = 0; j < hull.size().height; j++) {
l.add(contours.toList().get(hull.toList().get(j)));
sum_x += l.get(j).x;
sum_y += l.get(j).y;
}
x = sum_x / j;
y = sum_y / j;

Interpreting Big O Loops and arrays

So, I know I'm going wrong in my thinking but my answer for all three pieces of code is that they are O(n^2).
Can someone tell me if I'm wrong?
If yes, can you help me think through how to solve similar problems. Thank you in advance!
public static int firstLoop(int[] arr) {
int sum = 0; int n = arr.length;
int limit = n * n;
for ( int j = 0; j < limit; j += 2 ) {
sum = (sum + arr[j / n] ) % 100;
}
return sum; }
public static int withLoop(int[] arr) {
int sum = 0; int n = arr.length;
int j = 1;
int limit = n * n;
for ( j= limit - 1; j > 0; j /= 2 ) {
sum = (sum + arr[j / n] ) % 100; }
return sum; }
public static int fwLoop(int[] arr)
{ int sum = 0;
int n = arr.length;
int limit = n * n;
for ( int k = 0; k < limit; k += 2 ) {
int t = 1; for ( j = limit - 1; j > 0; j /= 2 ) {
t = (t + arr[j / n] ) % 100;
} sum = (sum + t + arr[k / n] ) % 200;
} return sum;
}
The first piece of code runs in O(n^2) as you rightly said because limit is of size n^2
The second however does j/=2 which divides the length of limit each time by 2, therefore the loop will run for k times where k=log(n^2) = 2log(n) therefore it is of O(log(n)) order
The third is a combination of first and the second, it runs in O((n^2)*log(n)) time

ArrayIndexOutOfBoundsException Java Issue

So I have been working on this problem for a while now. I keep getting an ArrayIndexOutOfBoundsException but I am unable to locate where the issue lies. If someone could point me in the right direction, I would really appreciate it! Thanks!
public class Answer {
public static void main(String[] args){
double[] y = {23, 11.1, 50.4};
double[] x = {22.2, 46, 100.0};
Answer answer = new Answer();
answer.answer(y, x);
}
public static int answer(double[] y, double[] x) {
int result = 0;
double percent_1, percent_2;
double[] compareList_1 = new double[x.length];
double[] compareList_2 = new double[y.length];
// Calculate percent of first 2 x value array items with y
// all y values. Store the results in a seperate list.
for(int i = 0; i < x.length; i++){
percent_1 = compare(y[i], x[0]);
percent_2 = compare(y[i], x[1]);
compareList_1[i] = percent_1;
compareList_2[i] = percent_2;
}
// Compare those lists to find common number
// There you have your answer.
result = (int)compareLists(compareList_1, compareList_2);
return result;
}
// Calculates percentage from x and y values
public static double compare(double y, double x){
double result = 1 - (y/x);
return result;
}
// Finds common value in lists
public static double compareLists(double[] list_1, double[] list_2){
for(int i = 0; i < list_1.length + 1; i++){
for(int j = 0; j < list_2.length + 1; j++){
if(list_1[i] == list_2[j]){
return list_1[i];
}
}
}
// Just cus this shouldn't ever return.
return 100;
}
}
In your iteration (compareLists), you should use 'length' (not length + 1)
for(int i = 0; i < list_1.length; i++)
for(int j = 0; j < list_2.length; i++)
I think the problerm is in
for(int i = 0; i < list_1.length + 1; i++){
for(int j = 0; j < list_2.length + 1; j++){
i < list_1.length + 1 or j < list_2.length + 1 change it to
for(int i = 0; i < list_1.length; i++){
for(int j = 0; j < list_2.length ; j++){
remove +1 from each condition.For j < list_2.length + 1 the list_2.length will give you length of array ie lastIndex +1 and you are adding another +1 in it causing loop condition to be j<lastIndex +1 giving you index error on the last iteration of loop in the line if(list_1[i] == list_2[j]){ for list_2[j]
Also in answer method you declare array by
double[] compareList_1 = new double[x.length];
double[] compareList_2 = new double[y.length];
and in the loop you are iterating upto x.length if x.length is greater than y.length the you can get the Index error in compareList_2[i] = percent_2;(inside the loop) because its length is y.length.

Infinite loop when printing an N x N table

Consider the following Java program:
public class RelativelyPrime {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // Dimensions of grid
int i, j;
int r; // Remainder when i is divided by j
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
do { // Using Euclidean algorithm
r = i % j;
i = j;
j = r;
} while (r > 0);
if (i == 1) System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
}
}
This program prints an N x N table (or matrix, if you like) where N is a command-line argument.
The (i, j)-entry is a * if i and j are relatively prime, or a single whitespace if they are not relatively prime. When I run the program by entering, for instance, java RelativelyPrime 3 it endlessly prints *. Why is this happening?
You changed i and j in the while loop.
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
int ii = i, jj = j;
do { // Using Euclidean algorithm
r = ii % jj;
ii = jj;
jj = r;
} while (r > 0);
if (ii == 1) System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
This is where using the debugger would have helped you solve the problem.
Inside your loops, you alter both i and j which means they never reach N and thus you have an infinite loop.
I suggest you not alter these variables but instead use two new variables, ideally with meaningful names.

Printing a triangle in Java

I'm practicing basic coding exercises and trying to print the following triangle in Java:
*
***
*****
***
*
The following code gives me the results but I feel like there must be a much more elegant solution
for (int i = 1; i <= 5; i++) {
if (i % 2 == 1) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println("");
}
}
for (int i = 3; i > 0; i--) {
if (i % 2 == 1) {
for (int j = 1; j < i + 1; j++) {
System.out.print("*");
}
System.out.println("");
}
}
Can anyone provide some insight into how to make this work in a better way?
Ok, here's some more code that produces the correct result that uses just the two for loops, but it looks even uglier:
for (int i = 1; i <= 10; i += 2) {
if (i <= 5) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println("");
}
else if(i > 5 && i < 8){
for(int j = i/2; j > 0; j--){
System.out.print("*");
}
System.out.println("");
}
else{
for(int j = 1; j > 0; j--){
System.out.print("*");
}
System.out.println("");
}
}
First, you are skipping each 2nd iteration of the loop because you want to increase two steps at once. You can do this by changing the "i++" in your loop to "i += 2" and "i--" to "i -= 2", that will have the same effect and allows you to remove the if inside both loops.
Another improvement would be using a single outer loop and figuring out whether the inner loop should be increasing or decreasing the amount of asterisks. Maybe you can come up with an equation that gives you the amount of asterisks based on the value of i? (I didn't want to solve it completely so you have some exercise left, just comment if you want a full solution)
Updated with a solution that might be considered elegant as you can change the height of the triangle and there is no repetition:
int height = 5;
for (int i = 1; i <= 2 * height; i += 2) {
int numAsterisks;
if (i <= height) {
numAsterisks = i;
} else {
numAsterisks = 2 * height - i;
}
for (int j = 0; j < numAsterisks; j++) {
System.out.print("*");
}
System.out.println();
}
What about the following?
public void printTriangle(int size) {
int half = size / 2;
for (int i = 0; i < size; i++) {
int stars = 1 + 2 * (i <= half ? i : size - 1 - i);
char[] a = new char[stars];
Arrays.fill(a, '*');
System.out.println(new String(a));
}
}
Or just a bit more optimized:
public void printTriangle(int size) {
int half = size / 2;
char[] a = new char[size];
Arrays.fill(a, '*');
for (int i = 0; i < size; i++) {
int stars = 1 + 2 * (i <= half ? i : size - 1 - i);
System.out.println(new String(a, 0, stars));
}
}
for(int i = 0; i < 7; i++) {
for(int j = 0; j < i; j++) {
print("*");
}
print("\n");
}
This can be another solution to print a regular right triangle...
Here's a different way of looking at the problem. By using an integer array, I can solve lots of shape drawing problems by changing the values in the array.
When solving more difficult problems, you would use model classes instead of simple integers. The idea, however, is the same.
Here's the output.
*
***
*****
***
*
And here's the code:
public class Triangle {
public static void main(String[] args) {
int[] heights = {1, 3, 5, 3, 1};
for (int i = 0; i < heights.length; i++) {
for (int j = 0; j < heights[i]; j++) {
System.out.print("*");
}
System.out.println("");
}
}
}
How about...
int width = 5;
for (int i = 1; i <= width; i+=2){
System.out.println(String.format("%"+i+"s", "").replaceAll(" ", "*"));
}
for (int i = width-2; i > 0; i-=2){
System.out.println(String.format("%"+i+"s", "").replaceAll(" ", "*"));
}
Or, even better yet...
int width = 7;
double half = width / 2
for (int i = 0; i < width; i++){
System.out.println(String.format("%"+((i < half ? i : (width-i-1))*2+1)+"s", "").replaceAll(" ", "*"));
}
Gives
*
***
*****
***
*

Categories