Given the array, i need to find how many monotonically increasing Sub-arrays there are in that array?
For example, with [0, 1, 3, 1 , 2] - has 2 monotonical sub-arrays : [0, 1,3] and [1,2].
public class SUB_ARRAY {
public static void main(String a[]){
int[] x = new int[6];
x[0]=1;
x[1]=2;
x[2]=3;
x[3]=6;
x[4]=9;
x[5]=10;
ArrayList<Object> arraylist = new ArrayList<Object>();
HashSet list = new HashSet();
for ( int i=0; i< (x.length -1); i++){
if (x[i+1]> x[i] ){
list.add(x[i]);
list.add(x[i+1]);
} else if (x[i+1] < x[i] || x[i+1]==x[i]) {
arraylist.add(list.clone());
list.clear();
}
}
System.out.println(arraylist.size());
}
}
The output is : 0 (instead of 1).
So, where I'm wrong?
Check out this solution. It now only displays the counter but print you the subarrays. If you need only the continues subarrays you can easily modify it.
As you see I use neither HashSet nor ArrayList for storing temporary data just a counter.
import java.util.ArrayList;
public class SUB_ARRAY{
public static int SUBARRAY_MINIMUM_LENGTH = 2;
public static void main(String a[]){
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(5);
x.add(0);
x.add(1);
x.add(3);
x.add(4);
x.add(2);
x.add(3);
x.add(6);
x.add(1);
x.add(0);
x.add(4);
int monoton = 0;
int changed = -1;
System.out.println("Initial array: " + x.toString());
for ( int i=0; i< x.size() -1; ++i){
if (x.get(i+1) > x.get(i)){
if (changed > -1){
for (int j = changed; j <i+2; ++j){
monoton += checkSubArray(x, j, i+2);;
}
}
else{
System.out.println("New monoton subarray start index: " + i + " value: " + x.get(i));
changed = i;
monoton += checkSubArray(x, changed, i+2);
}
}
else if (changed > -1){
changed = -1;
}
}
System.out.println("Monoton count: " + monoton);
}
private static int checkSubArray(ArrayList<Integer> x, int start, int end)
{
if (end-start < SUBARRAY_MINIMUM_LENGTH){
return 0;
}
for (int subi = start; subi < end; ++subi){
System.out.print(" " + x.get(subi));
}
System.out.println();
return 1;
}
}
The output will be the following
Initial array: [5, 0, 1, 3, 4, 2, 3, 6, 1, 0, 4]
New monoton subarray start index: 1 value: 0
0 1
0 1 3
1 3
0 1 3 4
1 3 4
3 4
New monoton subarray start index: 5 value: 2
2 3
2 3 6
3 6
New monoton subarray start index: 9 value: 0
0 4
Monoton count: 10
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 2 years ago.
I've been trying to merge two sorted arrays into one sorted array. However, the system gives me an error even when I tried to fix it by doing counter--; Anyways, here is the full code.
import java.util.Arrays;
public class Methods2 {
static int[] combine(int[] array1, int[] array2) {
int[] combinedArray = new int[array1.length + array2.length];
boolean ToF = false;
int temp = 0;
int counter = 0;
for (int value : array1) {
for (int i : array2) {
if (value < i) {
temp = value;
counter++;
combinedArray = append(combinedArray, counter, temp);
}
}
}
return combinedArray;
}
static int[] append(int[] combinedArray, int counter, int temp) {
counter--;
combinedArray[counter] = temp;
return combinedArray;
}
public static void main(String[] args) {
int[] array1 = {1, 3, 5, 7, 9};
int[] array2 = {2, 4, 6, 8, 10};
System.out.println(Arrays.toString(combine(array1, array2)));
}
}
Any help would be appreciated.
Pay attention here:
for (int value : array1) {
for (int i : array2) {
if (value < i) {
temp = value;
counter++;
combinedArray = append(combinedArray, counter, temp);
}
}
}
this loops 25 times (5 iterations over array2 for every of 5 elements in array1). This should already warn you.
Another issue: during 5 first iterations you put "1" (because it satisfies if clause) into out array 5 times. Try debugging or at least some troubleshooting system.out.println
like:
for (int value : array1) {
for (int i : array2) {
if (value < i) {
temp = value;
counter++;
System.out.println("value: " + value);
System.out.println("i: " + i);
System.out.println("counter: " + counter);
System.out.println("---------------");
combinedArray = append(combinedArray, counter, temp);
}
}
}
// output:
value: 1
i: 2
counter: 1
---------------
value: 1
i: 4
counter: 2
---------------
value: 1
i: 6
counter: 3
---------------
value: 1
i: 8
counter: 4
---------------
value: 1
i: 10
counter: 5
---------------
value: 3
i: 4
counter: 6
---------------
value: 3
i: 6
counter: 7
---------------
value: 3
i: 8
counter: 8
---------------
value: 3
i: 10
counter: 9
---------------
value: 5
i: 6
counter: 10
---------------
value: 5
i: 8
counter: 11
---------------
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
this shows all issues with implemented logic.
Something like below should work for you. Please pay attention on bounds checks for arays
import java.util.Arrays;
public class Methods2 {
static int[] combine(int[] array1, int[] array2) {
int[] combinedArray = new int[array1.length + array2.length];
int index1 = 0;
int index2 = 0;
for (int i = 0; i < combinedArray.length; i++) {
if (index1 < array1.length && index2 < array2.length) {
// element left in both arrays
if (array2[index2] < array1[index1]) {
combinedArray[i] = array2[index2];
index2++;
} else {
combinedArray[i] = array1[index1];
index1++;
}
} else if (index1 < array1.length) {
// element left in 1 array only
combinedArray[i] = array1[index1];
index1++;
} else {
// element left in 2 array only
combinedArray[i] = array2[index2];
index2++;
}
}
return combinedArray;
}
public static void main(String[] args) {
int[] array1 = {1, 3, 5, 7, 9};
int[] array2 = {2, 4, 6, 8, 10};
System.out.println(Arrays.toString(combine(array1, array2)));
}
}
It's a value passing and reference passing problem. The counter-- in append() will not affect the other counter in combine(). Btw, you can use two pointer method to solve merge two sorted array problem, not just one counter param. If you have no idea, you can check this solution github.
I have a requirement to write a function to divide an array in 2 parts {4,5,2,1,3}, such that sum in first array is greater than in second array but length of 1st array is smaller than that of second.The union of their sums is total sum and they dont have any intersection.So, an answer would be {4,5}.
import java.util.ArrayList;
import java.util.Stack;
public class DP2 {
public static void main(String args[]) {
int[] arr= {5,2,10,4,1,11};
ArrayList<Integer> list=new ArrayList<>();
//calculate sum
int finalSum=0;
/*
for(int i: arr)
finalSum+=arr[i];
*/
int len=arr.length;
int mid=(len)/2;
System.out.println(mid);
int sum=0;
//initialize 2 pointers
//will use a stack
Stack<Integer> stack = new Stack<Integer>();
int i=0,j=len-1;
int max=Integer.MIN_VALUE;
while(i < j ) {
//int max=Math.max(arr[i], arr[j]);
// System.out.println(max);
while(stack.size() < mid) {
max=Math.max(arr[i], arr[j]);
stack.push(max);
//System.out.println(stack.size());
// System.out.println(stack.peek());
i++;
j--;
}
// max=Math.max(arr[i], arr[j]);
i++;
j--;
if(stack.size() < mid && stack.peek() < max ) {
stack.pop();
stack.push(max);
}
}
while(!stack.isEmpty())
System.out.println(stack.pop());
}
}
It wont return the expected answer. It is not popping out from stack as I had coded to do. Can someone please help what I am doing wrong.
From what I can see there is nothing wrong, everything works as expected. The only problem was that the popping operation was giving you the result in reverse order. I have fixed that in the code below:
Integer[] result = new Integer[stack.size()];
for (int i1 = result.length - 1; i1 >= 0 && !stack.isEmpty(); i1--) {
result[i1] = stack.pop();
}
System.out.println(Arrays.toString(result));
Output
[4, 5]
EDIT: As requested here is a full solution to your problem:
/**
* Convert an array of primitive numbers to Integer objects.
*/
private static Integer[] intToInteger(int[] array) {
return Arrays.stream(array).boxed().toArray( Integer[]::new );
}
/**
* Converts a primitive integer array to an ArrayList.
*/
private static ArrayList<Integer> intArrayTolist(int[] array) {
return new ArrayList<>(Arrays.asList(intToInteger(array)));
}
public static void main(String[] args) {
int[] arr0 = { 5, 2, 10, 4, 1, 11 };
/* determine the size of the first array */
float quotient = (float)arr0.length / 2;
int mid = (int) Math.floor(quotient);
int size = quotient != mid ? mid : mid - 1;
/* Initialize arrays here */
Integer[] arr1 = new Integer[size];
Integer[] arr2 = new Integer[arr0.length - mid];
List<Integer> list = intArrayTolist(arr0);
/* Populate the first array with largest values
* found within the main array
*/
for (int i = 0; i < size; i++) {
/*
* Find out the largest value in the main array
* and add that value to the first array
*/
arr1[i] = java.util.Collections.max(list);
list.remove(arr1[i]);
}
arr2 = list.toArray(arr2);
int sum = Arrays.stream(arr0).sum();
System.out.println("First array: " + Arrays.toString(arr1));
System.out.println("Second array: " + Arrays.toString(arr2));
System.out.println("Sum of all numbers: " + sum);
}
Output
First array: [11, 10]
Second array: [5, 2, 4, 1]
Sum of all numbers: 33
Note that it might not be as elegant I would have hopped but it gets the job done. I will see if I can do some further cleaning and optimizing as I feel there is a lot of redundancies in there. It's just a quick mock up so you can have something that actually works.
I used recursion. This is the way I did it:
#Test
public void stackoverflow() {
int[] array = { 39, 2, 3, 40, 0, 0, 0 };
System.out.println("index is " + method(array, 0));
}
String method(int[] array, int i) {
if (i < array.length / 2 && sum(array, 0, i) > sum(array, i + 1, array.length - 1)) {
return "the sub array goes from 0 to " + i;
}
else if (i >= array.length / 2 && sum(array, array.length - 1 - i + array.length / 2, array.length - 1) > sum(array, 0, array.length - i - 2 + array.length / 2)) {
int index = array.length - 1 - i + array.length / 2;
return "the sub array goes from " + index + " to " + (array.length - 1);
}
return method(array, i + 1);
}
int sum(int[] array, int i, int j) {
int sum = 0;
for (int k = i; k <= j; k++) {
sum = sum + array[k];
}
return sum;
}
This is the explanation: you start from position 0 of the array. If the sum of the element at [0] is greater than the sum from position [1] to [n-1], you are done. If not, you call the same logic, comparing the sum from [0] to [1] versus [2] to [n-1]. Since you are looking for the smallest array, when you hit the half of the array (n/2), then you do the same starting from the end of the array.
My logic returns the index of the array. The index represents either the last element or the first element of the sub array which contains the greater sum. For example, in this case:
{ 0, 0, 0, 0, 40, 1, 2, 3 }
it will return "4". [4] is this element:
{ 0, 0, 0, 0, 40, 1, 2, 3 }
*
Is clear here that if the index > n/2, then the sub array goes from index to n-1. If not, then the sub array goes from 0 to n/2.
I have a 2D array which if filled like this .
1 2 0 0 0
1 2 0 0 0
0 0 3 4 5
0 0 3 4 5
0 0 3 4 5
another example
1 2 3 0
1 2 0 4
1 0 3 4
0 2 3 4
the code which I want to write is
searching about the maximum set of number repeated in the array .
in example 1 : the answer is 3 because the maximum is ( 3 4 5 ) repeted 3 times unlike ( 1 2 ) repeated just once .
Also in example 2, the maximum is 2 because you will not have the same set of numbers repeated more than two times .
I want to write a code for that .
any help ?!
Although this does not solve your issue directly, you can gather and count all sequences by assigning them as keys in a Map. After you do this, you can get the longest sequences and see which one has the highest frequency.
Output from Code Below
Sequence Frequency
-------- ---------
2 2
5 3
1,2 2
3,4,5 3 // <- Longest sequence, Highest frequency.
4,5 3
Sequence Frequency
-------- ---------
1 1
2 1
3 1
4 3 // <- Highest frequency, but not a sequence.
2,3,4 1
1,2 1
1,2,3 1
2,3 1
3,4 2 // <- Second highest frequency, is a sequence.
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class MatrixSequenceFrequency {
public static void main(String[] args) {
int[][] arr1 = new int[][] {
{ 1, 2, 0, 0, 0 },
{ 1, 2, 0, 0, 0 },
{ 0, 0, 3, 4, 5 },
{ 0, 0, 3, 4, 5 },
{ 0, 0, 3, 4, 5 }
};
printSequences(findSequences(arr1));
int[][] arr2 = new int[][] {
{ 1, 2, 3, 0 },
{ 1, 2, 0, 4 },
{ 1, 0, 3, 4 },
{ 0, 2, 3, 4 }
};
printSequences(findSequences(arr2));
}
private static Map<String, Integer> findSequences(int[][] arr) {
Map<String, Integer> sequences = new HashMap<String, Integer>();
for (int i = 0; i < arr.length; i++) {
indexSequences(arr[i], sequences);
}
return sequences;
}
private static void indexSequences(int[] arr, Map<String, Integer> sequences) {
StringBuffer buff = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != 0) {
buff.append(arr[j]).append(',');
} else {
break; // `0` breaks the sequence.
}
}
if (buff.length() > 0) {
if (buff.charAt(buff.length() - 1) == ',') {
buff.deleteCharAt(buff.length() - 1); // Remove extra comma.
}
Integer value = sequences.get(buff.toString());
sequences.put(buff.toString(), value == null ? 1 : value + 1);
buff.delete(0, buff.length()); // Clear Buffer
}
}
}
private static void printSequences(Map<String, Integer> sequences) {
String format = "%-10s %s%n";
System.out.printf(format, "Sequence", "Frequency");
System.out.printf(format, "--------", "---------");
for (Iterator<Entry<String, Integer>> it = sequences.entrySet().iterator(); it.hasNext();) {
Entry<String, Integer> entry = it.next();
System.out.printf(format, entry.getKey(), entry.getValue().toString());
}
System.out.println();
}
}
I would filter through the array and add each number that is the same to a variable and then display the variable with the most hits
int three = 0;
for (int i = 0; i < array.size(); i++){
if(array.get(i) == 3){
three++;
}else if(array.get(i) == "Some other number"){
number++;
}
then you would need to filter through the numbers you just added up so
Collections.sort(arrayList); // Sort the arraylist
arrayList.get(arrayList.size() - 1); //gets the last item, largest for an ascending sort
then i would sort through the Array as to see how many are the same
if(arrayList.size() - 1 == arrayList.size() - 2){
System.out.println(arrayList.size() - 1 " & " arrayList.size() - 2);
}
There would be a lot more tedious coding but this would be the foundation of your code you first add the values to the variable and sort through the array list to see what value appeared the most and you would need a 2D Array for adding the actual variables we made at the start then sort them highest to lowest.
Here use this program
public class Matrix {
public static void main(String[] args) {
int[][] a = new int[][] {
{ 1, 2, 3 },
{ 3, 3, 3 },
{ 1, 2, 3 }
};
int result = 0;
int largestNum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (result <= count(a[i][j], a)) {
result = count(a[i][j], a);
largestNum = a[i][j];
}
}
}
// Display the result
System.out.println("Largest Number: " + largestNum);
}
public static int count(int arrVal, int[][] a) {
int count = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (arrVal == a[i][j]) {
count++;
}
}
}
return count;
}
}
For simplicity I have declared a 2d array of length 3 for both rows and columns. You can use array of any length
I have an array, i'd like to calculate the length of the longest subsequence made by equals numbers:
Example: 5 1 1 9 9 9 4 4 6 6 4 4 4 --> the length of the longest subsequence is 3 (9 9 9).
This is what i got so far but it doesn't work.
int lung=0, lungmax=0;
int indice = 0;
int [] values = new int [30];
for(int k=0; k<30; k++)
{
if (values[k]==values[k+1])
{
lung++;
if (lung>lungmax)
{
lungmax=lung;
indice=values[k];
}
}
else lung=0;
}
lungmax = lungmax++;
System.out.println("the length of the longest subsequence is: "+lungmax);
Your code has two errors:
for(int k=0; k<30; k++) {
if (values[k]==values[k+1]) {
This loop will be executed until k reaches value 30. Therefore, the last used value for k is 29. If you use that value in the if statement, you'll exceed that array bounds by calling values[k+1] (== values[30]).
Change that loop to:
for(int k = 0; k < values.length - 1; k++) {
The second problem is this line:
lungmax = lungmax++;
This is the same as:
int temp = lungmax;
lungmax = lungmax + 1;
lungmax = temp;
As you can see, you're "ignoring" the increment. Change that line to:
lungmax++;
Try this. By applying my approach, the ArrayIndexOutOfBoundsException has been eliminated.
public static void main(String args[]) {
int lung = 1, lungmax = 0;
int indice = 0;
int[] values = {1, 2, 2, 3, 3, 3, 5, 5, 5, 5, 6};
for (int k = 1; k < values.length; k++) {
if (values[k - 1] == values[k]) {
lung++;
if (lung > lungmax) {
lungmax = lung;
indice = values[k];
}
} else {
lung = 1;
}
}
System.out.println("the length of the longest subsequence is: " + indice + "/" + lungmax);
}
Or simply
make following changes
int lungmax=1;
and replace
lungmax=lung
with
lungmax++;
and remove last lungmax=lungmax++
plus what Tom suggested : k<30-1
The complete code can be found at: https://skydrive.live.com/redir?resid=7B7D2F11B13EF9C9!54468&authkey=!AD4fD8sGgc7oJIE
This is part of the code:
g_sorted = 0;
for (int l_loop = 0; l_loop < l_length; l_loop++)
{
if (!l_IntegerArray[l_loop].equals(g_exclude))
{
g_tag[g_sorted] = l_loop;
g_tosort_Integer[g_sorted] = l_IntegerArray[l_loop];
g_sorted++;
}
} // for (int l_loop = 0; l_loop < p_toSort; l_loop++)
Arrays.sort
(g_tag, 0, g_sorted, new Comparator<Integer>()
{
public int compare(Integer i1, Integer i2)
{
return Integer.compare(g_tosort_Integer[i1], g_tosort_Integer[i2]);
}
}
);
g_tosort_Integer, g_tag, g_tosort_Integer are 'Integer'.
g_exclude is used to exclude items which must not be part of the sort.
When no items are excluded (no item has the value equal to g_exclude or the if-statement is commented), everything works fine.
When 1 or more items are excluded I get a NullPointerException:
Exception in thread "main" java.lang.NullPointerException
at TestSort$1.compare(TestSort.java:53)
at TestSort$1.compare(TestSort.java:50)
at java.util.TimSort.binarySort(TimSort.java:265)
at java.util.TimSort.sort(TimSort.java:190)
at java.util.Arrays.sort(Arrays.java:727)
at TestSort.<init>(TestSort.java:48)
at TestSort.main(TestSort.java:71)
Can someone explain this to me ? Thanks.
This is how to solve. I kept your class "structure", but I took the liberty of changing variable names to get clearer what I was doing. You asked how to order an array not changing the order of elements, but changing a index upon it.
Here's the code.
public class TestSort {
int c_maxSort = 10000;
Integer[] unsortedAndFiltered = new Integer[c_maxSort];
Integer[] index = new Integer[c_maxSort];
public TestSort() {
Integer exclude = 0;
int newPosition;
int lengthOfOriginalArray;
Integer[] originalArray = { 5, 3, 0, 2, 7, 1, 5, 6, 8, 4 };
lengthOfOriginalArray = originalArray.length;
System.out.print("Original: ");
for (int i = 0; i < lengthOfOriginalArray; i++)
System.out.print(originalArray[i] + " ");
System.out.println(" - Length: " + lengthOfOriginalArray);
newPosition = 0;
for (int i = 0; i < lengthOfOriginalArray; i++) {
if (!originalArray[i].equals(exclude)) {
index[newPosition] = newPosition;
unsortedAndFiltered[newPosition] = originalArray[i];
newPosition++;
}
}
System.out.println("Tags: ");
for (int i = 0; i < newPosition; i++)
System.out.print(index[i] + " ");
System.out.println("");
System.out.println("Unsorted numbers: ");
for (int l_loop = 0; l_loop < newPosition; l_loop++)
System.out.print(unsortedAndFiltered[l_loop] + " ");
System.out.println("");
int deleted = lengthOfOriginalArray - newPosition;
Arrays.sort(index, 0, newPosition, new IndirectedComparator(unsortedAndFiltered, index));
System.out.println("Sorted Tags: ");
for (int i = 0; i < newPosition; i++)
System.out.print(index[i] + " ");
System.out.println("");
System.out.println("Sorted Numbers: ");
for (int i = 0; i < newPosition; i++)
System.out.print(unsortedAndFiltered[index[i]] + " ");
System.out.println("");
}
public static void main(String[] args) {
new TestSort();
}
}
where the comparator is coded like this:
public class IndirectedComparator implements Comparator<Integer> {
private Integer[] array;
private Integer[] index;
public IndirectedComparator(Integer [] array, Integer[] index){
this.array = array;
this.index = new Integer[index.length];
System.arraycopy(index, 0, this.index, 0, index.length);
}
#Override
public int compare(Integer i1, Integer i2) {
return Integer.compare(array[index[i1]], array[index[i2]]);
}
}
This is my execution:
Original: 5 3 0 2 7 1 5 6 8 4 - Length: 10
Tags:
0 1 2 3 4 5 6 7 8
Unsorted numbers:
5 3 2 7 1 5 6 8 4
Sorted Tags:
4 2 1 8 0 5 6 3 7
Sorted Numbers:
1 2 3 4 5 5 6 7 8