This question already has an answer here:
Finding two major peaks and the valleys between the peaks of a 2D array or histogram
(1 answer)
Closed 6 years ago.
I need to find the "Valleys" and "Peaks" of numbers in an array. "Valleys" and "Peaks" pretty much mean that I need to compare each index with the two indexes around it. So if the middle index is larger than the indexes around it, its a "Peak", but if the index in the middle is smaller than the two indexes around it, its a "Valley". I have to do this for every number on every array line shown below:
int[][] arrays = {
{ 2, 5, 3, 2, 1, 9, 7, 8, },
{ 4, 4, 7, 4, 2, },
{ 2, 5, 3, 3, 7, 2, },
{ 1, 9, 3, 5, 2, 7, 3, 5, 1 },
{ 2, 8, 8, 7, 9, 9, 9, 3 },
{ 4, 3, 2, 1, 0, },
{ 1, 2, 5, 9, 10, },
};
I tried to use if and else if but the smallest array goes to index 4 and if I try to use higher indexes the code will not run properly. Here is my attempt:
public class ValleyPeak {
public static void main(String[] args) {
int[][] arrays = {
{ 2, 5, 3, 2, 1, 9, 7, 8, },
{ 4, 4, 7, 4, 2, },
{ 2, 5, 3, 3, 7, 2, },
{ 1, 9, 3, 5, 2, 7, 3, 5, 1 },
{ 2, 8, 8, 7, 9, 9, 9, 3 },
{ 4, 3, 2, 1, 0, },
{ 1, 2, 5, 9, 10, },
};
for (int i = 0; i < arrays.length; i++)
valley_peak(arrays[i]);
}
static void valley_peak(int[] a) {
System.out.print("\narray: \n");
//1
if(a[0] > a[1]){
System.out.println("[0] is a peak, ");
}
else if(a[0] < a[1]){
System.out.println("[0] ia a valley, ");
}
//2
if(a[1] > a[0] && a[1] > a[2]){
System.out.println("[1] ia a peak, ");
}
else if(a[1] < a[0] && a[1] < a[2]){
System.out.println("[1] ia a valley, ");
}
//3
if(a[2] > a[1] && a[2] > a[3]){
System.out.println("[2] ia a peak, ");
}
else if(a[2] < a[1] && a[2] < a[3]){
System.out.println("[2] ia a valley, ");
}
//4
if(a[3] > a[2] && a[3] > a[4]){
System.out.println("[3] ia a peak, ");
}
else if(a[3] < a[2] && a[3] < a[4]){
System.out.println("[3] ia a valley, ");
}
//4
if(a[4] > a[3] && a[4] > a[5]){
System.out.println("[4] ia a peak, ");
}
else if(a[4] < a[3] && a[4] < a[5]){
System.out.println("[4] ia a valley, ");
}
//5
if(a[5] > a[4] && a[5] > a[6]){
System.out.println("[5] ia a peak, ");
}
else if(a[5] < a[4] && a[5] < a[6]){
System.out.println("[5] ia a valley, ");
}
//6
if(a[6] > a[5] && a[6] > a[7]){
System.out.println("[6] ia a peak, ");
}
else if(a[6] < a[5] && a[6] < a[7]){
System.out.println("[6] ia a valley, ");
}
//7
if(a[7] > a[6] && a[7] > a[8]){
System.out.println("[7] ia a peak, ");
}
else if(a[7] < a[6] && a[7] < a[8]){
System.out.println("[7] ia a valley, ");
}
//8
if(a[8] > a[7] && a[8] > a[9]){
System.out.println("[8] ia a peak, ");
}
else if(a[8] < a[7] && a[8] < a[9]){
System.out.println("[8] ia a valley, ");
}
//9
if(a[9] > a[8] && a[9] > a[10]){
System.out.println("[9] ia a peak, ");
}
else if(a[9] < a[8] && a[9] < a[10]){
System.out.println("[9] ia a valley, ");
}
}
}
I am stuck on what I should do next? I am fairly new to arrays, watched some videos but still can't figure out how to do it.
So this program should solve the problem
public class Array {
public static void main(String[] args) {
int[][] arrays = {
{ 2, 5, 3, 2, 1, 9, 7, 8, },
{ 4, 4, 7, 4, 2, },
{ 2, 5, 3, 3, 7, 2, },
{ 1, 9, 3, 5, 2, 7, 3, 5, 1 },
{ 2, 8, 8, 7, 9, 9, 9, 3 },
{ 4, 3, 2, 1, 0, },
{ 1, 2, 5, 9, 10, },
};
for(int i = 0; i < arrays.length; i++) {
int[] array = arrays[i];
System.out.println("array: " + i);
//Edge case first item of array
if(array[0] > array[1]) {
System.out.println("[0] is peak");
}
else if(array[0] < array[1]) {
System.out.println("[0] is valley");
}
// loop for all items in the middle of the array
for(int j = 1; j < array.length - 2; j++) {
if(array[j-1] < array[j] && array[j+1] < array[j]) {
System.out.println("[" + j + "] is peak");
}
else if(array[j-1] > array[j] && array[j+1] > array[j]) {
System.out.println("[" + j + "] is valley");
}
}
//Edge case last item of array
int indexLastItem = array.length - 1;
if(array[indexLastItem] > array[indexLastItem - 1]) {
System.out.println("[" + indexLastItem + "] is peak");
}
else if(array[indexLastItem] < array[indexLastItem - 1]) {
System.out.println("[" + indexLastItem + "] is valley");
}
}
}
}
So you use 2 loops. The first for the array in the arrays, the second for the item in the array. You have to make a special condition for the first and last item in the array, because they don't have 2 neighbors. For the rest you just compare each item to the one before and after it.
Related
I want to make a java program that asks for a number as input data and generates the following numerical series, the series must show the amount of numbers indicated by the user, but it will only be able to print the numbers from one to ten and then descending.
Input: 7
Output: 1, 2, 3, 4, 5, 6, 7
Input: 12
Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9
Input: 22
Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2
This is what I currently am working with:
System.out.print("Input number > ");
int number = sc.nextInt();
int j = 0;
boolean ascending = true;
for(int i = 1; i <= n4; i++){
if(ascending){
if(j >= 10){
j--;
ascending = false;
} else {
j++;
}
} else {
if (j <= 1){
j++;
ascending = true;
} else {
j--;
}
}
System.out.print(j + ", ");
}
The tricky bit in your sequence is that the limits (1 and 10) are printed twice. This means that there are not two, but three delta values in the sequence: +1, then 0, then -1. The following logic should be sufficient to produce the sequence:
int numLoops = sc.next();
int delta = +1;
int currentValue = 1;
StringBuilder result = new StringBuilder();
for (int i = 0; i < numLoops; i++) {
result.append(Integer.toString(currentValue) + ", ");
currentValue += delta;
if (currentValue >= 10) delta = (delta == 0) ? -1 : 0;
if (currentValue <= 1 ) delta = (delta == 0) ? +1 : 0;
}
System.out.println(result.toString());
Note that a StringBuilder instance is used to assemble the output rather than a series of calls to System.out. This is more stylish.
If today is Monday, its number is 2. And I needed to add next 5 working days which should not include Sunday(holiday) into the array list.
I'm new to coding, and I'm studying 9th Standard. Please help me in coding. Thanks in !
public class WeekView {
public static void main(String args[]) {
List<Integer> daysList = new ArrayList<>();
int m = 6, dayOfWeek = 6;
for (int i = 1; i <= m; i++) {
if (dayOfWeek == 1) {
daysList.add(dayOfWeek);
dayOfWeek++;
} else if (dayOfWeek == 2) {
daysList.add(dayOfWeek);
dayOfWeek++;
} else if (dayOfWeek == 3) {
daysList.add(dayOfWeek);
dayOfWeek++;
} else if (dayOfWeek == 4) {
daysList.add(dayOfWeek);
dayOfWeek++;
} else if (dayOfWeek == 5) {
daysList.add(dayOfWeek);
dayOfWeek++;
} else if (dayOfWeek == 6) {
daysList.add(dayOfWeek);
for (int j = 1; j < dayOfWeek; j++) {
daysList.add(j);
}
}
}
System.out.println("Day Num :" + daysList);
} }
and my current output is
Day Num :[6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]
But I need output like given below
6,1,2,3,4,5
List<Integer> daysList = new ArrayList<>();
int day = 6;
for (int i = 0; i < 6; i++) {
daysList.add(day);
day++;
if(day > 6) day = 1;
}
System.out.println("Day Num :" + daysList);
Where :
i iterates over the number of working days
daysList.add(day) to add the current day to the list
days++ to go to the next day at each loop iteration
if(day > 6) day = 1 to go back to monday if day reaches sunday
You don't have to add to day while you increment, you can use the modulus operator to remove the if check. Like,
int day = 6;
List<Integer> daysList = new ArrayList<>();
for (int i = 0; i < 6; i++) {
daysList.add(1 + ((day + i - 1) % 6));
}
System.out.println("Day Num :" + daysList);
or in Java 8+ using an IntStream to generate the values like
int day = 6;
List<Integer> daysList = IntStream.range(0, 6).map(i -> 1 + ((day + i - 1) % 6)).boxed()
.collect(Collectors.toList());
System.out.println("Day Num :" + daysList);
I want to single out only positive numbers in one line and only negative numbers in one line, but they only show one by one with the text.
Here's my code:
int[] array = {2, -5, 4, 12, 54, -2, -50, 150};
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
if (array[i] < 0) {
System.out.println("Less than 0: " + array[i]);
} else if (array[i] > 0) {
System.out.println("Greater than 0: " + array[i]);
}
}
You are currently printing a line for each element (and whether it is less than 0 or greater than 0), instead I would use an IntStream and filter() it for the desired elements (and collect those with Collectors.joining()). Like,
int[] array = { 2, -5, 4, 12, 54, -2, -50, 150 };
Arrays.sort(array);
System.out.println("Less than 0: " + IntStream.of(array) //
.filter(x -> x < 0).mapToObj(String::valueOf).collect(Collectors.joining(", ")));
System.out.println("Greater than 0: " + IntStream.of(array) //
.filter(x -> x > 0).mapToObj(String::valueOf).collect(Collectors.joining(", ")));
Outputs
Less than 0: -50, -5, -2
Greater than 0: 2, 4, 12, 54, 150
You could achieve the same result with a pair of StringJoiner(s) a for-each loop and (just because) formatted io. Like,
int[] array = { 2, -5, 4, 12, 54, -2, -50, 150 };
Arrays.sort(array);
StringJoiner sjLess = new StringJoiner(", ");
StringJoiner sjGreater = new StringJoiner(", ");
for (int x : array) {
if (x < 0) {
sjLess.add(String.valueOf(x));
} else if (x > 0) {
sjGreater.add(String.valueOf(x));
}
}
System.out.printf("Less than 0: %s%n", sjLess.toString());
System.out.printf("Greater than 0: %s%n", sjGreater.toString());
Since you sorted the values, you know all negative values come before the positive values, so you start printing values and then switch to new line when you encounter the first positive value.
E.g. like below, which can also handle an array of all negative values, an array of all positive values, and even an empty array.
This only uses Java constructs you've already shown you know.
int[] array = {2, -5, 4, 12, 54, -2, -50, 150};
Arrays.sort(array);
for (int i = 0, iFirstPositive = 0; i < array.length; i++) {
if (array[i] < 0)
iFirstPositive = i + 1; // Assume index of first positive value is next
if (i == iFirstPositive) {
if (i != 0)
System.out.println(); // End line of negative values
System.out.print("Greater than 0: "); // Start line of positive values
} else if (i == 0) {
System.out.print("Less than 0: "); // Start line of negative values
} else {
System.out.print(", ");
}
System.out.print(array[i]);
}
if (array.length != 0) {
System.out.println(); // End line if anything printed
}
Output
Less than 0: -50, -5, -2
Greater than 0: 2, 4, 12, 54, 150
Simpler, but slightly less optimal, you can also just do it with two loops:
int[] array = {2, -5, 4, 12, 54, -2, -50, 150};
Arrays.sort(array);
System.out.print("Less than 0:");
for (int i = 0; i < array.length; i++) {
if (array[i] < 0) {
System.out.print(" " + array[i]);
}
}
System.out.println();
System.out.print("Greater than 0:");
for (int i = 0; i < array.length; i++) {
if (array[i] > 0) {
System.out.print(" " + array[i]);
}
}
System.out.println();
Output
Less than 0: -50 -5 -2
Greater than 0: 2 4 12 54 150
Do something like this:
Arrays.sort(array);
String negative = "Less than 0: ";
String positive = "Greater than 0: ";
for (int i = 0; i < array.length; i++) {
if (array[i] < 0) {
negative.concat(array[i] + ",");
}
else (array[i] > 0) {
positive.concat(array[i] + ",");
}
}
System.out.println(positive);
System.out.println(negative);
Store the values in a string and then print them after the for loop.
This is a perfect use case for streams:
System.out.println(Arrays.stream(array).filter(n -> n < 0).collect(Collectors.toList()));
I tried to change your code as little as possible.
int[] array = { 2, -5, 4, 12, 54, -2, -50, 150 };
Arrays.sort(array);
boolean firstHalf = true;
System.out.print("Less than 0: ");
for (int i = 0; i < array.length; i++) {
if (array[i] < 0) {
System.out.print(array[i] + " ");
} else if (array[i] > 0) {
if (firstHalf){
System.out.print("\nGreater than 0: ");
firstHalf = false;
}
System.out.print(array[i] + " ");
}
}
I think using of partitioningBy (that introduced in java 8) is exactly for this situation. you don't need to sort array too.
Map<Boolean,List<Integer>> map = IntStream.range(0,array.length)
.mapToObj(i->array[i])
.collect(Collectors.partitioningBy(a->a>0));
print positive number
map.get(true).forEach(integer -> System.out.print(integer+","));
print negative number
map.get(false).forEach(integer -> System.out.print(integer+","));
if you want to sort it you can do it like bellow.
map.get(false).stream().sorted()....
Given a provided array, determine how many groups of a specified size exist.
For the array
[1,1,1,2,2,2,3,3,3,4,5,6,7]
there are 7 groups with at least one, 3 groups with at least 2, and 3 groups with at least 3. A group is a series of same values. 1 1 1 is a group of 3, but it also is a group of 1 and 2. To count as a group, all values must be the same. 1 1 1 is a group of 3 because there are 3 1s in a row.
I'm just curious, how would this be done?
Using java 8
long result = Stream.of(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7)
.collect(Collectors.groupingBy(i -> i))
.entrySet().stream()
.filter(entry -> entry.getValue().size() >= 1) // specify the size
.count();
System.out.println(result);
i used a set array where i looked at all the groups and did a loop to see each new number and if it was the same as the previous number. Which i have a group counter that is passed into a new array. Then the results are printed out.
public class Homework {
public static void main(String[] args) {
int[] array_list = {3, 3, 3, 3, 3, 9, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8};
int[] found_groups = new int[7];
int group_size = 1;
int num_changed = 0;
for (int i = 1; i < array_list.length; i++) {
if (array_list[i] == array_list[i-1]) {
group_size++;
if (group_size == 5) {
found_groups[0] = group_size;
}
if (group_size == 3) {
found_groups[2] = group_size;
found_groups[5] = group_size;
}
if (group_size == 4) {
found_groups[3] = group_size;
}
if (group_size == 2) {
found_groups[4] = group_size;
}
if (group_size ==8) {
found_groups[6] = group_size;
}
}
else if (array_list[i] != array_list[i-1]) {
num_changed++;
group_size = 1;
if (group_size == 1) {
found_groups[1] = group_size;
}
}
}
int group_one = 0;
int group_two = 0;
int group_three = 0;
int group_four = 0;
int group_five = 0;
int group_six = 0;
int group_one_final = 0;
for (int i = 0; i < found_groups.length; i++) {
if (found_groups[i] == 5) {
group_five++;
group_two++;
group_three++;
group_four++;
}
if (found_groups[i] == 1) {
group_one++;
group_one_final = group_one + num_changed;
}
if (found_groups[i] == 3) {
group_three++;
group_two++;
}
if (found_groups[i] == 4) {
group_four++;
group_two++;
group_three++;
}
if (found_groups[i] == 8) {
group_six++;
group_two++;
group_three++;
group_four++;
group_five++;
}
if (found_groups[i] == 2) {
group_two++;
}
}
System.out.println("number of ones groups: " + group_one_final);
System.out.println("number of two groups: " + group_two);
System.out.println("number of three groups: " + group_three );
System.out.println("number of fours groups: " + group_four);
System.out.println("number of fives groups: " + group_five);
System.out.println("number of sixes groups: " + group_six);
}
}
I am dealing with the following problem. I am not looking for anyone to provide me a solution i am looking for some guidance to solving this problem. Here is what i have come up with so far.
I have basically tried to first put a ( around values that repeat. However i am getting a out of bounds error. I would really appreciate it if someone can push me towards the right path for coding a small algorithm that would handle this problem.
My code (in progress)
import java.util.Random;
public class Test {
public static void main(String[] args) {
int[] values = { 1, 2, 5, 5, 3, 1, 2, 4, 3, 2, 2, 2, 2, 3, 6, 5, 5, 6,
3, 1 };
boolean inRun = false;
for (int i = 0; i < values.length; i++) {
if (values[i] == values[i + 1] && values[i + 1] < values.length) {
System.out.print("(");
}
System.out.print(values[i]);
}
}
}
You need to iterate to all the array and if it found a pair then you iterate it again in a while loop until it find the non pair.
sample:
int[] values = { 1, 2, 5, 5, 3, 1, 2, 4, 3, 2, 2, 2, 2, 3, 6, 5, 5, 6, 3, 1 };
boolean inRun = false;
for (int i = 0; i < values.length; i++) {
if (i + 1 < values.length && values[i] == values[i + 1] )
{
System.out.print("(");
while (i + 1 < values.length && values[i] == values[i + 1] )
{
System.out.print(values[i++]);
}
System.out.print(values[i++]);
System.out.print(")");
}
System.out.print(values[i]);
}
result:
12(55)31243(2222)36(55)631
Your error is here,
if (values[i] == values[i + 1] && values[i + 1] < values.length) {
Because i + 1 isn't being tested for less then, or in the correct order -
if (i + 1 < values.length && values[i] == values[i + 1]) {
Or you could use,
for (int i = 0; i < values.length - 1; i++) { // the length of values - 1 so we can
// get the next value.