Im really stuck in a rut for this one.
I want generate all the combinations such that there is Ordered Sampling with Replacement (i think this is what its called, see my example) and the result is output in an array of arrays (2D array).
For example
public static int[][] combinations(int n, int k)
on input n=3, k=2 would give:
[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
I'm really unsure how to do this efficiently. Any pointers are appreciated!
Here we have a set with n elements and we want to draw k samples from the set such that ordering matters and repetition is allowed.
Here the code:
public static void main(String[] args) {
int n = 4;
int k = 2;
int[][] result = combinations(n, k);
System.out.println(Arrays.deepToString(result));
//this will print:
//[[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]]
}
public static int[][] combinations(int n, int k) {
int[] nArray = IntStream.range(0, n).toArray();
List<String> list = new ArrayList<String>();
combinationStrings(k, nArray, "", list);
return fromArrayListToArray(list, k);
}
private static void combinationStrings(int k, int[] nArray, String currentString, List<String> list) {
if (currentString.length() == k) {
list.add(currentString);
} else {
for (int i = 0; i < nArray.length; i++) {
String oldCurrent = currentString;
currentString += nArray[i];
combinationStrings(k, nArray, currentString, list);
currentString = oldCurrent;
}
}
}
private static int[][] fromArrayListToArray(List<String> list, int k) {
int[][] result = new int[list.size()][k];
for (int i=0;i<list.size();i++) {
String[] split = list.get(i).split("\\B");
for (int j = 0; j < split.length; j++) {
result[i][j] = Integer.parseInt(split[j]);
}
}
return result;
}
Related
I created a class that finds the number of n occurrences for numbers in an Int non sorted Java array. I need to improve it so i do not have to use for loop inside another for. The array can take maximum 99 items. The array can not be sorted. So no sorting allowed by the use cases. Also no imports allowed. You can run the code here. Any help appreciated.
import java.util.Arrays;
public class Solution {
public static void main(String args[])
{
Solution newInstance = new Solution();
int[] myIntArray = {1,2,6,2,3,3,3,4,5,5};
newInstance.solution( myIntArray ,1);
}
public static int[] solution(int[] data, int n) {
int newData[] = new int[data.length];
int indexOfNewData = 0;
int timesCurrentTempItemFound = 0;
System.out.println ("temp array: " + Arrays.toString(data) + "\n");
for (int k=0; k<data.length; k++) {
int currentTempItem = data[k];
timesCurrentTempItemFound = 0;
for (int i=0; i<data.length; i++) {
if (currentTempItem == data[i]) {
timesCurrentTempItemFound++;
}
}
if (timesCurrentTempItemFound == n) {
boolean itemAlreadyExists = false;
for (int index=0; index<data.length; index++) {
if (data[k] == newData[index]) {
itemAlreadyExists = true;
}
}
if (itemAlreadyExists == false) {
newData[indexOfNewData] = data[k];
indexOfNewData++;
}
}
}
indexOfNewData = 0;
for(int i = 0; i<newData.length; i++) {
if(newData[i] != 0) {
newData[indexOfNewData] = newData[i];
indexOfNewData++;
}
}
int totalItemsInDataArrayWithoutZeros = indexOfNewData;
int newDataArray[] = new int[totalItemsInDataArrayWithoutZeros];
for (int i=0; i<totalItemsInDataArrayWithoutZeros; i++) {
newDataArray[i] = newData[i];
}
System.out.println ("temp array remove zeros: " + Arrays.toString(newDataArray) + "\n");
return newDataArray;
}
}
You can use a hashmap to store the numbers as keys and frequencies as values.
Take a look at the 2nd method of this article that covers this in detail
The original requirement for problem has been provided by OP in this comment.
It turns out that imports are allowed contrary to what was specified in the question.
So instead of performing redundant brute-force iterations in the nested loop, you can generate a Map of occurrences of each element in the given array.
The next step is to find the number of values of the Map that are less than n, that would be the size of the resulting array.
Then, to preserve the order, iterate over the given array and filter out elements that have the number of occurrences greater than n. The elements having the number of occurrences less or equal to n can be stored into the array.
That's how the implementation might look like:
public int[] solution(int[] data, int n) {
Map<Integer, Integer> frequencies = new HashMap<>();
for (int next: data) {
frequencies.merge(next, 1, Integer::sum);
}
int[] result = new int[getArraySize(frequencies, n)];
int index = 0;
for (int next: data) {
if (frequencies.get(next) <= n) {
result[index++] = next;
}
}
return result;
}
public int getArraySize(Map<Integer, Integer> frequencies, int n) {
int size = 0;
for (int freq: frequencies.values()) {
if (freq <= n) size++;
}
return size;
}
The same logic can be implemented using Stream API:
public static int[] solution(int[] data, int n) {
Map<Integer, Integer> frequencies = getFrequencies(data);
return Arrays.stream(data)
.filter(i -> frequencies.get(i) <= n)
.toArray();
}
public static Map<Integer, Integer> getFrequencies(int[] data) {
return Arrays.stream(data)
.boxed()
.collect(Collectors.toMap(
Function.identity(),
i -> 1,
Integer::sum
));
}
I can find BFS and DFS values in a two-dimensional array array, but there is no increase in scoring. I could not figure out exactly which part I did wrong. When I print the values that should be, the sort is correct. but the grade is still 0. I am open to your ideas.
public class BFS_DFS {
public static int[] BFS (int [][] graph) {
int[] output = {0};
int start=0;
int v=graph.length;//a[][] is adj matrix declared globally
boolean visited[]=new boolean[v];//indexing done from 1 to n
LinkedList<Integer> queue=new LinkedList<Integer>();
visited[start]=true;
queue.add(start);
while(queue.size()!=0)
{
int x=queue.remove();
System.out.print(x+" ");
for(int j=graph.length;j<graph.length;j++){
output[j-1]=x;
}
for (int i=1; i < v; i++)
if((graph[x][i] == 1) && (!visited[i]))
{
queue.add(i);
visited[i]=true;
}
}
return output ;
}
public static void main(String[] args) {
//DO NOT WRITE ANY CODE IN MAIN METHOD
int [][] graph={{0,1,1,1,0,0},{1,0,0,0,1,1},{1,0,0,0,0,1},{1,0,0,0,0,0},{0,1,0,0,0,0},{0,1,1,0,0,0}};
int [] BFSresult={0,1,2,3,4,5};
int [] DFSresult={0,1,4,5,2,3};
int grade=0;
if (Arrays.equals(BFS(graph),BFSresult )) {
System.out.println("BFS is working correctl");
grade+=50;
}
else
System.out.println("BFS is not working correctly");
if (Arrays.equals(DFS(graph),DFSresult )) {
System.out.println("DFS is working correctl");
grade+=50;
}
else
System.out.println("DFS is not working correctly");
System.out.println("Your grade is->"+grade);
}
}
Array (int[] output) is not appropriate to store results of un-known length, because it has a fixed length.
Use a collection like List instead:
public static int[] BFS (int [][] graph) {
//you do not know what is the path length so use a List
List<Integer> output = new ArrayList<>();
int start=0;
int v=graph.length;
boolean visited[]=new boolean[v];//indexing done from 1 to n
LinkedList<Integer> queue=new LinkedList<>();
visited[start]=true;
queue.add(start);
while(queue.size()!=0)
{
int x=queue.remove();
System.out.print(x+" ");
output.add(x); //add to output
for (int i=1; i < v; i++) {
if((graph[x][i] == 1) && (!visited[i]))
{
queue.add(i);
visited[i]=true;
}
}
}
//convert back to array
return output.stream().mapToInt(Integer::intValue).toArray();
/*if you can't use java 8 stream, convert output to array using:
int[] ret = new int[output.size()];
int i = 0;
for (int e : output) { ret[i++] = e; }
return ret;
*/
}
So the purpose of this program is to selectively sort a random array of integers form largest to smallest. To do this, I needed to keep swapping the first element with the largest element. I think my methods are correct, but I am fairly new to Java and not sure what to call in main in order to execute my methods correctly. Thank you in advance!
package sortarray;
public class SortArray {
public static int randomInt(int low, int high) {
double e;
double x=Math.random();
e=low+x*(high-low);
return (int)e;
}
public static int[] randomIntArray(int n) {
int[] a = new int[n];
for(int i = 0; i < a.length; i++) {
a[i] = randomInt(-5, 15);
}
return a;
}
public static int indexOfMaxInRange(int[] a, int low, int high) {
int index = low;
for (int i = low + 1; i < a.length; i++) {
if (a[i] > a[index]) {
index = i;
}
}
return index;
}
public static void swapElement(int[] a, int index1, int index2) {
int temp = a[index1];
a[index1] = a[index2];
a[index2] = temp;
}
public static void sort(int[] a) {
int length = a.length;
//use length-1 because do not need to swap last element with itself
for (int i = 0; i < length-1; i++) {
int indexOfMax = indexOfMaxInRange(a, i, length-1);
swapElement(a, i, indexOfMax);
}
}
public static void printArray(int[] a) {
for(int i = 0; i < a.length; i++) {
System.out.print(" " + a[i]);
}
}
public static void main(String[] args) {
int[] array = randomIntArray(30);
printArray();
}
}
To sort the array, you simply need to call the following:
sort(array);
Then, you can print the array again to verify that it is sorted with:
printArray(array);
Also you can call the method sort() within of printArray() method, so when you call printArray() it will print sorted:
...
public static void printArray(int[] a) {
sort(a);
for (int i = 0; i < a.length; i++) {
System.out.print(" " + a[i]);
}
}
public static void main(String[] args) {
int[] array = randomIntArray(30);
printArray(array);
}
...
Here is my code that I posted on Code Review. This sort an array of String, But you can put integer instead.
https://codereview.stackexchange.com/questions/160243/sort-a-given-string-in-ascending-order
Given string
[H, B, D, G, F, E, A, C]
Output
[A, B, C, D, E, F, G, H]
public class sortArray {
public static void sort (String[] str)
{
int lastPos = str.length - 1;
int minPos = 0;
String s = "";
for (int i = 0; i < lastPos; i++)
{
minPos = i;
for (int j = i + 1; j <= lastPos; j++)
if (str[j].compareTo (str[minPos]) < 0)
minPos = j;
if (minPos != i)
{
s = str[i];
str[i] = str[minPos];
str[minPos] = s;
}
}
}
public static void main(String[] args){
String[] str = {"H", "B", "D", "G","F", "E", "A", "C"};
sort(str);
System.out.println(Arrays.toString(str));
}
}
There must have the arguments in the methods you use,
you should put the array in the ( )
you can use inbuilt function of Arrays. Simply call the inbuilt method and pass your array.
Arrays.sort(pass your array here).
If you dot want to use inbuilt method please refer this link.
Java : Sort integer array without using Arrays.sort()
I'm not very familiar with recursion in Java. I'm trying to write a method that calculates all the permutations of an array of integers. I need to modify the following perfectly working method so that, instead of printing to screen all the permutations of an array, it inserts them in a bidimensional array. So the input of the method is the array of n integers and the output is a bidimensional array with n! rows and n columns. The program I need to modify is this:
public static void permute(int[] array, int k)
{
for(int i=k; i<array.length; i++)
{
int temp;
temp = array[i];
array[i] = array[k];
array[k] = temp;
permute(array, k+1);
int temp2;
temp2 = array[i];
array[i] = array[k];
array[k] = temp2;
}
if (k == array.length-1)
{
Array.printValues(array);
}
}
So, what I need is something like this:
public static int[][] permute(int[] array, int k)
{
//code here
}
Thank you.
Stick them in a list and then get an array out of it. You could go directly with an int[][] but you do not know the first dimension value without an extra repetition.
public static int[][] permuteToArray(int[] array, int k){
ArrayList<int[]> arrL=new ArrayList<>();
for(int i=k; i<array.length; i++)
{
int temp;
temp = array[i];
array[i] = array[k];
array[k] = temp;
permute(array, k+1, arrL);
int temp2;
temp2 = array[i];
array[i] = array[k];
array[k] = temp2;
}
if (k == array.length-1)
{
arrL.add(array);
}
return arrL.toArray(new int[][]);
}
Change permute( to be:
public static void permute(int[] array, int k, ArrayList arrL) //raw type, I know
{
for(int i=k; i<array.length; i++)
{
int temp;
temp = array[i];
array[i] = array[k];
array[k] = temp;
permute(array, k+1);
int temp2;
temp2 = array[i];
array[i] = array[k];
array[k] = temp2;
}
if (k == array.length-1)
{
arrL.add(array);
}
}
public static void _permute(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> cur, int k, boolean[] status, int[] array)
{
if (cur.size() == k) {
res.add((ArrayList<Integer>)cur.clone());
return;
}
for (int i = 0; i < k; i++)
{
if (status[i]) continue;
cur.add(array[i]);
status[i] = true;
_permute(res, cur, k, status, array);
status[i] = false;
cur.remove(new Integer(array[i]));
}
}
public static ArrayList<ArrayList<Integer>> permute(int[] array, int k)
{
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> cur = new ArrayList<Integer>();
boolean[] status = new boolean[k];
for (int i = 0; i < k; i++)
{
status[i] = false;
}
_permute(res, cur, k, status, array);
return res;
//code here
}
You can get all permutation of array in array list. I think you can extract array from the list yourself. And be careful, this function can remove duplication if there're same numbers in original array.
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void permute(int[] array, List<int[]> cache, int k)
{
if (k == array.length-1)
{
cache.add(array.clone()); //use clone, or you will get the same int array
return;
}
for(int i=k; i<array.length; i++)
{
swap(array, i,k);
permute(array, cache, k+1);
swap(array, i, k);
}
}
I can give you an example recursive algorith of permutation.
It is based on the fact that permutation of n elements is based on permutation of n-1 elements.
import java.util.ArrayList;
import java.util.List;
class Permutation {
public static void main(String[] args) {
List<Object> input = new ArrayList<>();
input.add(1);
input.add(2);
input.add(3);
print(permutation(input));
}
public static void print(List<List<Object>> list) {
for (List<Object> objects : list) {
System.out.println(objects);
}
}
public static List<List<Object>> permutation(List<Object> input) {
if (input.isEmpty()) {
throw new IllegalStateException();
}
// This is end condition for recursion
if (input.size() == 1) {
List<List<Object>> result = new ArrayList<>();
result.add(input);
return result;
}
return merge(input.get(0), permutation(input.subList(1, input.size())));
}
private static List<List<Object>> merge(Object o, List<List<Object>> input) {
List<List<Object>> result = new ArrayList<>();
int inputSize = input.get(0).size();
for (int i = 0; i < inputSize + 1; i++) {
for (List<Object> oneRow : input) {
// copy the row and insert additional element
List<Object> oneRowExpanded = new ArrayList<>();
oneRowExpanded.addAll(oneRow);
oneRowExpanded.add(i, o);
result.add(oneRowExpanded);
}
}
return result;
}
}
This will print the following:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[3, 1, 2]
[2, 3, 1]
[3, 2, 1]
I've been tasked with turning this code into a reverse sort, but for the life of me cannot figure out how to do it. These are my sort, findlargest and swap methods. I have a feeling I am missing something glaringly obvious here, any help would be really appreciated.
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, arr.length - pass);
if (largestPos != arr.length - pass)
{
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = 0;
for (int i = 1; i <= num; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second)
{
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
}
Don't reinvent the wheel -
String[] strs = {"a", "b", "d", "c", "e"};
Arrays.sort(strs, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(strs));
[e, d, c, b, a]
Follow up from A. R. S.'s answer:
You could use a custom comparator if you are allowed to use the Arrays.Sort method...
Arrays.sort(stringArray, new Comparator<String>() {
#Override
public int compare(String t, String t1) {
return -t.compareToIgnoreCase(t1); //reverse the comparison, while ignoring case
}
});
Can you just turn findLargest to findSmallest, like this:
public static void sort(String[] arr) {
for (int pass = 1; pass < arr.length; pass++) {
int largestPos = findSmallest(arr, arr.length - pass);
if (largestPos != arr.length - pass) {
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findSmallest(String[] arr, int num) {
int largestPos = 0;
for (int i = 1; i <= num; i++) {
if (arr[i].compareToIgnoreCase(arr[largestPos]) < 0) {
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second) {
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
I think This is the one you need (if you don't think about collection framework).
public static void main(String args[]) {
String [] arr ={"abc","bac","cbc"};
String temp="";
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j].compareTo(arr[i]) > 0){
temp = arr[i] ;
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(String val:arr){
System.out.println(val);
}
}
Output is
cbc
bac
abc
you can use Arrays.sort(arr) to sort in alphabetical order.
and then reverse it.
public static void sort(String[] arr) {
Arrays.sort(arr);
for (int i=0; i<arr.length/2; i++) {
swap(arr,i,arr.length-1-i);
}
}
Try this one if you want. In your version you are moving the largest towards the end of the array, resulting in alphabetical order.
Just in case you insist on your original approach, I have made some minor changes to your code:
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, pass-1);
if (largestPos != pass - 1)
{
swap(arr, largestPos, pass - 1);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = num;
for (int i = num+1; i < arr.length; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
The most trivial one though, as suggested by Ian Roberts, is simply Arrays.sort(arr, Collections.reverseOrder());.
So, first we need to create String array, then use Arrays.sort(String[]);, then use for to reverse sort array to reverse order.
import java.util.Arrays;
public class SortClass {
public static void main(String[] args) {
String[] arrayString = new String[5];
arrayString[0] = "Cat";
arrayString[1] = "Apple";
arrayString[2] = "Dog";
arrayString[3] = "Mouse";
arrayString[4] = "kitchen";
Arrays.sort(arrayString);
String[] arrReverse = new String[arrayString.length];
for (int i = arrayString.length - 1; i >= 0; i--) {
arrReverse[arrayString.length - 1 - i] = arrayString[i];
}
}
}
String arr[]= new String[];
String s; //input string
int count=0;
for(int i=0;i<=s.length()-k;i++){
arr[i]=s.substring(i,i+k); //using substring method
count++;
}
int i=0;
int b=count;
while(count>0){
int j=0;
while(j<b){
if((arr[i].compareTo(arr[j])>0)){
String temp= arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
j++;
}
i++;
count--;
}
for(i=0;i<b;i++)
System.out.println(arr[i]);