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.
Related
int[] numbers = {3, 2, 5, 11, 7, 10, 11, 3, 15, 11, 17, 10, 5};
int count = 0;
boolean dup = false;
System.out.println("arrays value");
for (int n : numbers ) {
System.out.print(n +" ");
}
System.out.println("\n\nDuplicated value on arrays: ");
for (int a = 0 ; a < numbers.length ; a++ ) {
for (int b = a + 1 ; b < numbers.length ; b++ ) {
if (numbers[a] == numbers[b]) {
count = numbers[a];
dup = true;
}
}
if (dup) {
System.out.print(count +" ");
dup = false;
count = 0;
}
}
I want to print duplicated value only once each using only for loop and if
this output will print 3 5 11 10 11, how do I make only 3 5 11 10.
For this it is smart to use the data structure set which is a collecion that do not allow duplicates. This means that whatever the number of same values you add to the set only one will be stored. Now you can simply write
Set<Integer> mySet = new HashSet<>(Arrays.asList(numbers));
for(int number : mySet) {
System.out.println(number);
}
If you only want to print the values that are duplicates and not the values that only exist once (your question is not entirely clear) you may do something like this instead
Set<Integer> mySet = new HashSet<>();
for(int number : numbers) {
if(!mySet.add(number)) { //the set method add(e) returns false if e is a duplicate i.e. can not be added to the set
System.out.print(duplicate + " ");
}
}
If you want with for loop
import java.util.ArrayList;
public class stackov {
public static void main(String[] args) {
int[] numbers = {3, 2, 5, 11, 7, 10, 11, 3, 15, 11, 17, 10, 5};
int count = 0;
boolean dup = false;
System.out.println("arrays value");
for (int n : numbers) {
System.out.print(n + " ");
}
ArrayList<Integer> integers = new ArrayList<>();
System.out.println("\n\nDuplicated value on arrays: ");
for (int i : numbers) {
if (!integers.contains(i)) {
integers.add(i);
}
}
for (int x : integers) {
System.out.print(x + " ");
}
}
}
I assume that you are allowed multiple for-loops and the use of data structures.
Iterate over the values and accumulate the count the occurrences of each value in a Map. Then iterate over the Map and output the values with a count > 1.
public static void main(String[]args) {
int[] values = {...the values...};
Map<Integer,Integer> map = new HashMap<>();
for (int value : values) {
if (map.containsKey(value)) {
map.put(value, 1 + map.get(value));
} else {
map.put(value, 1);
}
}
for (Map.Entry<Integer,Integer> entry : map.entrySet()) {
if (entry.getValue() > 1) {
System.out.printf("Value %d was duplicated", value);
}
}
}
You need to mark all values that have been printed out, using a boolean array (instead of just a single boolean). Try something like:
System.out.println("\n\nDuplicated value on arrays: ");
boolean[] dup = new boolean[1000];
for (int a = 0 ; a < numbers.length ; a++ ) {
if (dup[numbers[a]] == false) {
System.out.print(numbers[a]);
dup[numbers[a]] = true;
}
}
If you want to use 2 for loops (which is slower), then you need to only check for the duplicate value before this current index (the for with b should be for (int b = 0; b < a; b++) )
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
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