I am trying to find the subsets of an array. In example if the array is [1,2] I am trying to print the following:
[1][2]
[1]
[2]
null
The code that I have written is as follows:
import java.util.*;
class PrintArray {
public static void printme(int a[], int pos, int size) {
if (pos >= size)
return;
else
System.out.println(a[pos]);
pos++;
printme(a, pos, size);
}
public static void generate(int a[], ArrayList<Integer> list, int pos, int size) {
if (pos > size) {
for (int i = 0; i < list.size() - 1; i++) {
System.out.print("[" + list.get(i) + "]");
}
System.out.println();
return;
}
list.add(a[pos]);
generate(a, list, pos + 1, size);
list.remove(list.size() - 1);
generate(a, list, pos + 1, size);
}
public static void main(String args[]) {
int ar[] = { 1, 2, 3, 4, 5 };
// printme(ar, 0, ar.length);
ArrayList<Integer> list = new ArrayList<Integer>();
generate(ar, list, 0, ar.length);
}
}
However I am running into the following OOBE error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds
That can be resolved by checking for pos>=size instead of pos>size but such a change does not generate all the sub-arrays.
A follow-up problem is that I am getting duplicate outputs as shown below:
[2][3][4]
[2][3]
[2][3]
[2]
[2][4]
[2]
[2]
Could someone please help me in overcoming these 2 issues?
You can look at your subsets array as a matrix. For {x, y} array:
the matrix will have 2^n elements, where n is the number of elements in the array;
it can be visualized in binary, 1 means print the element and 0 doesn't print anything:
public static void main (String[] args) throws Exception
{
int ar[] = {1, 2};
int nrOfSubsets = (int) Math.pow (2, ar.length);
// prints the subset matrix
for (int i = nrOfSubsets - 1; i >= 0; i--)
{
String output = "";
int temp = i;
// prints one matrix line
for (int j = ar.length - 1; j >= 0; --j)
{
// convert to binary, 1 means print the number
int rem = temp % 2;
temp = temp / 2;
if (rem == 1)
{
output = "[" + ar[j] + "]" + output;
}
}
if(output.isEmpty()) output = "null";
System.out.println (output);
}
}
Related
How can I make it so if the value appears more than once in an array the code can then say the value appears in index: 0, 1, etc?
I'm working on a homework assignment that asks to write a method called linearSearch that performs a linear search on an integer array: searches starting at index 0, then 1, 2, 3…. It should return the index of the array that contains the target or a -1 if it is not found in the array. I have done that, but an issue that I am seeing is if the target appears more than once in the array the print statement will only print where it's located first. For Example, if my array is [6, 3, 9, 2, 7, 6]. The print statement says "6 is found at index: 0". Is there a way to change it when the value appears more than once so the print statement will then say "6 is found at index: 0 and 5"?
import java.util.Arrays;
import java.util.Random;
public class Q6 {
public static void main(String[] args) {
Random random = new Random();
int x = random.nextInt(10);
int[] y = createRandomIntArray(x);
int z = x;
System.out.println(Arrays.toString(y));
System.out.println(z + " is found at index: " + linearSearch(y, z));
}
public static int[] createRandomIntArray(int n) {
Random random = new Random();
int[] result = new int[n];
for (int i = 0; i < result.length; i++)
result[i] = random.nextInt(10);
return result;
}
public static int linearSearch(int[] array, int target) {
for (int i = 0; i < array.length; i++) {
if (array[i] == target) {
return i;
}
}
return -1;
}
}
Output:
[6, 3, 9, 2, 7, 6]
6 is found at index: 0
I would use a list to store each index where the target number is found, then add them all together into one string before returning them:
public static String linearSearch(int[] array, int target) {
List<Integer> indices = new ArrayList<Integer>();
for (int i = 0; i < array.length; i++) {
if (array[i] == target) {
indices.add(i);
}
}
return indices.stream().map(String::valueOf).collect(Collectors.joining(" and "));
}
But I imagine that your professor does not want you using lists yet, let alone streams. So, here is another method which creates a new array to store the indices in, making it the same size as the source array, and uses a variable matches to keep track of how many indices are stored in that array:
public static String linearSearch(int[] array, int target) {
int[] indices = new int[array.length];
int matches = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == target) {
indices[matches++] = i;
}
}
if (matches == 1) {
return String.valueOf(indices[0]);
} else {
String builder = String.valueOf(indices[0]);
for (int i = 1; i < matches; i++) {
builder += " and " + indices[i];
}
return builder;
}
}
Rather than modify the return value of your linearSearch method to handle multiple matches you could instead add a start position for the search.
public static int linearSearch(int[] array, int target, int off) {
for (int i = off; i < array.length; i++) {
if (array[i] == target) {
return i;
}
}
return -1;
}
You would then make (potentially) multiple calls, using the position of the previously identified match as the starting point of the next search. You quit when you fail to find a match.
public static void main(String[] args)
{
int x = 6;
int[] y = {6, 3, 9, 2, 7, 6};
int off = 0;
while(true)
{
off = linearSearch(y, x, off);
if(off < 0) break;
System.out.println("Found at index: " + off);
off += 1;
}
}
Output:
Found at index: 0
Found at index: 5
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}
For example if input is:
2 0 6 3 1 6 3 1 6 3 1
then output should be 6 3 1.Need to find the first repetition cycle.
class FindDuplicate
{
void printRepeating(int arr[], int size)
{
int i;
System.out.println("The repeating elements are : ");
for (i = 0; i < size; i++)
{
if (arr[Math.abs(arr[i])] >= 0)
arr[Math.abs(arr[i])] = -arr[Math.abs(arr[i])];
else
System.out.print(Math.abs(arr[i]) + " ");
}
}
public static void main(String[] args)
{
FindDuplicate duplicate = new FindDuplicate();
int arr[] = {1, 2, 3, 1, 2, 3, 1, 2, 3 };
int arr_size = arr.length;
duplicate.printRepeating(arr, arr_size);
}
}
https://pastebin.com/12bnjzfw
Have used java 8 streams for collection creation.
for (int seqSize = ints.size() / 2; seqSize > 0; seqSize--) { //It should be first cycle. Main priority is biggest sequence
for (int i = 0; i < ints.size() / seqSize; i++) { //Start position of the first block
for (int j = i + seqSize; j < ints.size() - seqSize + 1; j++) {
if (ints.subList(i, i + seqSize).equals(ints.subList(j, j + seqSize))) {
System.out.println("Answer is: " + ints.subList(i, i + seqSize));
return;
}
}
}
}
class FindDuplicate {
static int STRING_LENGTH = 3;
void printRepeating(int arr[], int size) {
int i;
System.out.println("The repeating elements are : ");
String strVal = "";
for (int ii = 0; ii < size; ii++) {
strVal += arr[ii];
}
// strVal now has something we can search with.
for (i = 0; i < size; i++) {
int end = Math.min(size,i+STRING_LENGTH );
String searchString = strVal.substring(i, end);
if (searchString.length() != STRING_LENGTH)
break; // at end of arr, doesn't have length to search
int matchIndex = strVal.indexOf(searchString, i+1);
if (matchIndex != -1) {
String match = strVal.substring(matchIndex, matchIndex + STRING_LENGTH);
System.out.print(match + " ");
break; // done with loop
}
}
}
public static void main(String[] args) {
FindDuplicate duplicate = new FindDuplicate();
int arr[] = {1, 2, 3, 1, 2, 3, 1, 2, 3 };
int arr_size = arr.length;
duplicate.printRepeating(arr, arr_size);
}
}
Loop through those array elements and cache your elements until you have the same value for example
List list = Arrays.asList(1,2,3);
if(list.contains(element))
//code to check here
you will need get size of your list and based on that check exactly this amount of items if they match if yes then output if not clear cache and start cache from the begging.
I think I confused the methods and can't get the actual methods correct. Please help, the array needs to rotate to the right where the first digit will become the last digit. I generate a random array based on size that the user input. Then I print that array, then do the rotation, then print the new array with the first digit last and the last digit first.
import java.util.Scanner;
import java.util.Random;
public class modOne {
public static final int MIN = 1;
public static final int MAX = 15;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int arraySize = 0;
System.out.println("How many arrays to rotate right?");
int howMany = input.nextInt();
while(howMany <= 0) {
System.out.println("ERROR! Should be positive. REENTER: ");
howMany = input.nextInt();
}
while(howMany > 0) {
System.out.println("Enter array size: ");
arraySize = input.nextInt();
}
int[] a = new int[arraySize];
int[] b = new int[arraySize];
getRand(a, MIN, MAX);
System.out.println("The array before rotation: ");
printArray(a);
System.out.println("THe array after rotation: ");
transArray(a);
printArray(b);
System.out.println("Enter array size: ");
arraySize = input.nextInt();
}
public static void getRand (int[] list, int size, int low, int up) {
Random rand = new Random();
for(int r = 0; r < size; r++) {
list[r] = rand.nextInt(up - low + 1) + low;
}
}
public static void printArray(int[] list, int size) {
for (int r = 0; r < size; r++) {
System.out.printf("%5d", list[r]);
if(r % 6 == 5)
System.out.println();
}
System.out.println();
}
public static void transArray(int[] list, int size) {
for(int r = 0; r < size - 1; r++) {
list[r] = list[r-1];
}
}
}
You can make use of System.arrayCopy to copy sourceArray from start index to destination array from start index. You can also specify how many elements should e copied as last argument to System.arrayCopy method. See below:
int[] arr = new int[]{8, 15, 2,10, 11,15,1,3};
System.out.println("array before rotation: " + Arrays.toString(arr));
int lastElement = arr[arr.length -1 ];
System.arraycopy(arr, 0, arr, 1, arr.length-1);
arr[0] = lastElement;
System.out.println("array after rotation: " + Arrays.toString(arr));
I backup the last element and then copy the array entirely in a new array skipping the first element of the array and then I assign the first element of the array with the value that I backup early.
The output you get is as follow:
array before rotation: [8, 15, 2, 10, 11, 15, 1, 3]
array after rotation: [3, 8, 15, 2, 10, 11, 15, 1]
For more details on how System.arrayCopy works, you can see the following tutorial or read my answer in this question.
You just have to invert the order and save the value you are going to overwrite to recover it later. I also took the liberty to make some other changes to your code. Now it should work as intended.
while (howMany <= 0) {
System.out.println("ERROR! Should be positive. REENTER: ");
howMany = input.nextInt();
}
System.out.println("Enter array size: ");
arraySize = input.nextInt();
int[] a = new int[arraySize];
int[] b = new int[arraySize];
getRand(a, MIN, MAX);
System.out.println("The array before rotation: ");
printArray(a);
System.out.println("THe array after rotation: ");
printArray(transArray(a));
}
public static void getRand(int[] list, int low, int up) {
Random rand = new Random();
for (int r = 0; r < list.length; r++) {
list[r] = rand.nextInt(up - low + 1) + low;
}
}
public static void printArray(int[] list) {
for (int r = 0; r < list.length; r++) {
System.out.printf("%5d", list[r]);
if (r % 6 == 5) {
System.out.println();
}
}
System.out.println();
}
public static int[] transArray(int[] list) {
int temp1 = list[list.length - 1];
for (int r = list.length - 1; r > 0; r--) {
list[r] = list[r-1];
}
list[0] = temp1;
return list;
}
What you can do is use Arrays.copyOfRange(T[] original, int from, int to) in order to shift most of the array. Some numbers are cut off, though, and need to be placed back in afterwards.
public static void main( String[] args ) {
int[] arr = { 1, 2, 3, 4, 5, 6 };
arr = rot(arr, -1);
System.out.println(Arrays.asList(arr));
}
public static int[] rot( int[] arr, int amt ) {
while ( amt < 0 )
amt += arr.length;
amt = amt % arr.length;
int[] k = Arrays.copyOfRange(arr, amt, arr.length + amt);
for ( int i = 0; i < amt; i++ )
k[k.length - amt + i] = arr[i];
return k;
}
rot() rotates left by amt, so using the parameter amt = -1 achieves what you set out to do.
The rot() method first forces 0 ≤ amt < arr.length. This is because once you rotate by the full length of the array, you're back where you started. Next it shifts the array by amt, adding the integer's default value (0) to the end as padding to preserve length. Finally, it adds the lost elements back into the array where the 0's were placed.
for(int i = 0; i < validData.length / 2; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
The logic behind this is that you are swapping the values until you get to the center:
I made this image for you to better understand
Here, there is no center, but if there was a 3.5, then it would ignore the three point five because validData[validData.length - i - 1] = temp;
I need to split this array after it is sorted so that it prints something like
A: [8, 7, 6, 5]
B: [4, 3, 2, 1]
I know it might be simple but I cant figure it out. Do I need to do something like x.length / 2 ?
import java.util.Arrays;
public class RecursiveMerge
{
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] x= {8,7,5,6,2,4,3,1};
System.out.println(Arrays.toString(x));
System.out.println(Arrays.toString(mergeSort(x)));
}
public static int [] mergeSort (int []a)
{
if(a.length ==1)
return a;
else
{
int mid = a.length/2;
int [] left =mergeSort(Arrays.copyOfRange(a, 0 , mid ));
int [] right =mergeSort(Arrays.copyOfRange(a, mid, a.length ));
mergeSort(left);
mergeSort(right);
return merge (left, right);
}
}
public static int[] merge (int[] left, int[] right)
{
int [] result = new int [left.length + right.length];
int leftPtr=0, rightPtr=0, resultPtr=0;
while(leftPtr < left.length && rightPtr < right.length)
if (left[leftPtr] < right [rightPtr])
result[resultPtr++] = left[leftPtr++];
else
result[resultPtr++] = right[rightPtr++];
while (leftPtr < left.length)
result[resultPtr++] = left[leftPtr++];
while (rightPtr <right.length)
result[resultPtr++] = right[rightPtr++];
return result;
}
}
To make it dynamically, do it based on array length and split it in two:
int [] x= {8,7,5,6,2,4,3,1};
int len = x.length;
int a[] = Arrays.copyOfRange(mergeSort(x), 0, len/2);
int b[] = Arrays.copyOfRange(mergeSort(x), (len/2), len);
System.out.println("A: " + Arrays.toString(a));
System.out.println("B: " + Arrays.toString(b));
Hope it helps.
An edit to the accepted answer could take into account that half an odd numbered int is actually the nearest, smaller, whole number, to the half. So, something like this is more appropriate:
int size = array.size();
int half = size % 2 == 0 ? size / 2 : (size / 2) + 1;