I want to create a method that returns 0 if array not sorted
returns 1 if it is sorted in ascending order and returns -1 if its sorted in descending order
This is what I have done so far:
public static int isSorted(int[] intArray) {
int end = intArray.length - 1;
int val = 0;
for (int i = 1; i < end; i++) {
if (intArray[0] < intArray[i]) {
val = 1;
}
else if (intArray[0] > intArray[i]) {
val = -1;
}
}
return v;
}
}
This returns 1 if its ascending and -1 if its descending.
But if I create a random array it does not return 0.
The question is how to check if both conditions fail, i.e.,
if its not sorted at all.
You can use two additional variables to count:
public static int isSorted(int[] intArray) {
int end = intArray.length-1;
int counterAsc = 0;
int counterDesc = 0;
for (int i = 0; i < end; i++) {
if(intArray[i] < intArray[i+1]){
counterAsc++;
}
else if(intArray[i] > intArray[i+1]){
counterDesc++;
}
}
if(counterDesc == 0){
return 1;
}
else if(counterAsc == 0){
return -1;
}
else return 0;
}
Your comparison is just between first element and other elements in the array.
val = 0;
for(int i=0;i<=end;i++){
for(int j=0;j<end;j++){
if(intArray[j]>intArray[j+1])
val = 1;
}
}
return val;
Here you go
public class stackoverflow {
public static int isSorted(int[] intArray) {
boolean sortedAsc = true;
boolean sortedDesc = true;
boolean sameValues=true;
int result = 0;
for (int i = 0; i < intArray.length-1; i++)
{
if (intArray[i] > intArray[i+1]) {
sortedAsc=false;
sameValues=false;
}
if (intArray[i] < intArray[i+1]) {
sortedDesc=false;
sameValues=false;
}
}
if(sortedAsc) result= 1;
if(sortedDesc) result = -1;
if(sameValues) result = 2;
return result;
}
public static void main(String[] args) {
// TODO code application logic here
int array[] = new int[4];
array[0]=1;
array[1]=2;
array[2]=3;
array[3]=4;
System.out.println(isSorted(array));
}
Related
You are given an array A of integers and an integer k. Implement an algorithm that determines, in linear time, the smallest integer that appears at least k times in A.
I have been struggling with this problem for awhile, coding in Java, I need to use a HashTable to find the smallest integer that appears at least k times, it also must be in linear time.
This is what I attempted but it does not pass any of the tests
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Here is the empty code with all of the test cases:
import java.io.*;
import java.util.*;
public class Lab5
{
/**
* Problem 1: Find the smallest integer that appears at least k times.
*/
private static int problem1(int[] arr, int k)
{
// Implement me!
return 0;
}
/**
* Problem 2: Find two distinct indices i and j such that A[i] = A[j] and |i - j| <= k.
*/
private static int[] problem2(int[] arr, int k)
{
// Implement me!
int i = -1;
int j = -1;
return new int[] { i, j };
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
private static final int LabNo = 5;
private static final String quarter = "Fall 2020";
private static final Random rng = new Random(123456);
private static boolean testProblem1(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int answer = problem1(arr.clone(), k);
Arrays.sort(arr);
for (int i = 0, j = 0; i < arr.length; i = j)
{
for (; j < arr.length && arr[i] == arr[j]; j++) { }
if (j - i >= k)
{
return answer == arr[i];
}
}
return false; // Will never happen.
}
private static boolean testProblem2(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int[] answer = problem2(arr.clone(), k);
if (answer == null || answer.length != 2)
{
return false;
}
Arrays.sort(answer);
// Check answer
int i = answer[0];
int j = answer[1];
return i != j
&& j - i <= k
&& i >= 0
&& j < arr.length
&& arr[i] == arr[j];
}
public static void main(String args[])
{
System.out.println("CS 302 -- " + quarter + " -- Lab " + LabNo);
testProblems(1);
testProblems(2);
}
private static void testProblems(int prob)
{
int noOfLines = prob == 1 ? 100000 : 500000;
System.out.println("-- -- -- -- --");
System.out.println(noOfLines + " test cases for problem " + prob + ".");
boolean passedAll = true;
for (int i = 1; i <= noOfLines; i++)
{
int[][] testCase = null;
boolean passed = false;
boolean exce = false;
try
{
switch (prob)
{
case 1:
testCase = createProblem1(i);
passed = testProblem1(testCase);
break;
case 2:
testCase = createProblem2(i);
passed = testProblem2(testCase);
break;
}
}
catch (Exception ex)
{
passed = false;
exce = true;
}
if (!passed)
{
System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
passedAll = false;
break;
}
}
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static int[][] createProblem1(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
Arrays.sort(numbers);
int maxK = 0;
for (int i = 0, j = 0; i < size; i = j)
{
for (; j < size && numbers[i] == numbers[j]; j++) { }
maxK = Math.max(maxK, j - i);
}
int k = rng.nextInt(maxK) + 1;
shuffle(numbers);
return new int[][] { numbers, new int[] { k } };
}
private static int[][] createProblem2(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
int i = rng.nextInt(size);
int j = rng.nextInt(size - 1);
if (i <= j) j++;
numbers[i] = numbers[j];
return new int[][] { numbers, new int[] { Math.abs(i - j) } };
}
private static void shuffle(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
{
int rndInd = rng.nextInt(arr.length - i) + i;
int tmp = arr[i];
arr[i] = arr[rndInd];
arr[rndInd] = tmp;
}
}
private static int[] getRandomNumbers(int range, int size)
{
int numbers[] = new int[size];
for (int i = 0; i < size; i++)
{
numbers[i] = rng.nextInt(2 * range) - range;
}
return numbers;
}
}
private static int problem1(int[] arr, int k) {
// Implement me!
Map<Integer, Integer> table = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
if (table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
} else {
table.put(arr[i], 1);
}
}
for (Map.Entry<Integer,Integer> entry : table.entrySet()) {
//As treemap is sorted, we return the first key with value >=k.
if(entry.getValue()>=k)
return entry.getKey();
}
//Not found
return -1;
}
As others have pointed out, there are a few mistakes. First, the line where you initialize ans,
int ans = 0;
You should initialize ans to Integer.MAX_VALUE so that when you find an integer that appears at least k times for the first time that ans gets set to that integer appropriately. Second, in your for loop, there's no reason to skip the first element while iterating the array so i should be initialized to 0 instead of 1. Also, in that same line, you want to iterate through the entire array, and in your loop's condition right now you have i < k when k is not the length of the array. The length of the array is denoted by arr.length so the condition should instead be i < arr.length. Third, in this line,
if (k < table.get(arr[i])){
where you are trying to check if an integer has occurred at least k times in the array so far while iterating through the array, the < operator should be changed to <= since the keyword here is at least k times, not "more than k times". Fourth, k should never change so you can get rid of this line of code,
k = table.get(arr[i]);
After applying all of those changes, your function should look like this:
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Pseudo code:
collect frequencies of each number in a Map<Integer, Integer> (number and its count)
set least to a large value
iterate over entries
ignore entry if its value is less than k
if entry key is less than current least, store it as least
return least
One line implementation:
private static int problem1(int[] arr, int k) {
return Arrays.stream(arr).boxed()
.collect(groupingBy(identity(), counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() >= k)
.map(Map.Entry::getKey)
.reduce(MAX_VALUE, Math::min);
}
This was able to pass all the cases! Thank you to everyone who helped!!
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
}else{
table.put(arr[i], 1);
}
}
Set<Integer> keys = table.keySet();
for(int i : keys){
if(table.get(i) >= k){
ans = Math.min(ans,i);
}
}
if(ans != Integer.MAX_VALUE){
return ans;
}else{
return 0;
}
}
randomEmpty() returns a random coordinate on the n x n grid that is empty (Method works). randomAdjacent() uses randomEmpty() to select an EMPTY coordinate on the map. Comparisons are then made to see if this coordinate has an VALID adjacent coordinate that is NON-EMPTY. The PROBLEM is that randomAdjacent does not always return the coordinates of space with an adjacent NON-EMPTY space. It will always return valid coordinates but not the latter. I can't spot the problem. Can someone help me identify the problem?
public int[] randomEmpty()
{
Random r = new Random();
int[] random = new int[2];
int row = r.nextInt(array.length);
int column = r.nextInt(array.length);
while(!(isEmpty(row,column)))
{
row = r.nextInt(array.length);
column = r.nextInt(array.length);
}
random[0] = row+1;
random[1] = column+1;
return random;
}
public int[] randomAdjacent()
{
int[] adjacentToX = new int[8];
int[] adjacentToY = new int[8];
int[] adjacentFrom = randomEmpty();
int count;
boolean isTrue = false;
boolean oneAdjacentNotEmpty = false;
while(!(oneAdjacentNotEmpty))
{
count = 0;
if(validIndex(adjacentFrom,1,-1))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,0,-1))
{
adjacentToX[count] = adjacentFrom[0];
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,-1,-1))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,-1,0))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1];
count++;
}
if(validIndex(adjacentFrom,-1,1))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,0,1))
{
adjacentToX[count] = adjacentFrom[0];
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,1,1))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,1,0))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1];
count++;
}
for(int i = 0; i < count; i++)
{
if(!(isEmpty(adjacentToX[i],adjacentToY[i])))
{
oneAdjacentNotEmpty = true;
isTrue = true;
}
}
if(isTrue)
break;
else
adjacentFrom = randomEmpty();
}
return adjacentFrom;
}
public boolean validIndex(int[] a,int i, int j)
{
try
{
Pebble aPebble = array[a[0]+i][a[1]+j];
return true;
}
catch(ArrayIndexOutOfBoundsException e)
{
return false;
}
}
public void setCell(int xPos, int yPos, Pebble aPebble)
{
array[xPos-1][yPos-1] = aPebble;
}
public Pebble getCell(int xPos, int yPos)
{
return array[xPos-1][yPos-1];
}
JUNIT Test Performed:
#Test
public void testRandomAdjacent() {
final int size = 5;
final Board board2 = new Board(size);
board2.setCell(1, 1, Pebble.O);
board2.setCell(5, 5, Pebble.O);
int[] idx = board2.randomAdjacent();
int x = idx[0];
int y = idx[1];
boolean empty = true;
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if ((i == x && j == y) || i < 1 || j < 1 || i > size || j > size) {
continue;
}
if (board2.getCell(i, j) != Pebble.EMPTY)
empty = false;
}
}
assertFalse(empty);// NEVER gets SET TO FALSE
assertEquals(Pebble.EMPTY, board2.getCell(x, y));
}
As for the answer: I got carried away optimizing your code for readability. I'd think it's most likely
if (board2.getCell(i, j) != Pebble.EMPTY)
empty = false;
causing the problem as getCell operates in 1-based coordinates, but i, j are in 0-based.
You should think about your logic overall. The way I see it, your code might never terminate as randomEmpty() could keep returning the same field over and over again for an undetermined period of time.
I took the liberty to recode your if-if-if cascade into utility method easier to read:
public boolean hasNonEmptyNeighbor(int[] adjacentFrom) {
for(int i = -1; i <= 1; ++i) {
for(int j = -1; j <= 1; ++j) {
if(validIndex(adjacentFrom, i, j) //Still inside the board
&& // AND
!isEmpty(adjacentFrom[0]+i //not empty
,adjacentFrom[1]+j)) {
return true;
}
}
}
return false;
}
Given my previous comment about random() being not the best of choices if you need to cover the full board, your main check (give me an empty cell with a non-empty neighbor) could be rewritten like this:
public void find() {
List<Point> foundPoints = new ArrayList<Point>();
for(int i = 0; i < Board.height; ++i) { //Assumes you have stored your height
for(int j = 0; j < Board.width; ++j) { //and your width
if(isEmpty(i, j) && hasNonEmptyNeighbor(new int[]{i,j})) {
//Found one.
foundPoints.add(new Point(i, j));
}
}
}
//If you need to return a RANDOM empty field with non-empty neighbor
//you could randomize over length of foundPoints here and select from that list.
}
I have made this program using array concept in java. I am getting Exception as ArrayIndexOutOfBound while trying to generate product.
I made the function generateFNos(int max) to generate factors of the given number. For example a number 6 will have factors 1,2,3,6. Now,i tried to combine the first and the last digit so that the product becomes equal to 6.
I have not used the logic of finding the smallest number in that array right now. I will do it later.
Question is Why i am getting Exception as ArrayIndexOutOfBound? [i couldn't figure out]
Below is my code
public class SmallestNoProduct {
public static void generateFNos(int max) {
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
}
}
smallestNoProduct(ar);
}
public static void smallestNoProduct(int x[]) {
int j[] = new int[x.length];
int p = x.length;
for (int d = 0; d < p / 2;) {
String t = x[d++] + "" + x[p--];
int i = Integer.parseInt(t);
j[d] = i;
}
for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}
}
public static void main(String s[]) {
generateFNos(6);
}
}
****OutputShown****
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at SmallestNoProduct.smallestNoProduct(SmallestNoProduct.java:36)
at SmallestNoProduct.generateFNos(SmallestNoProduct.java:27)
at SmallestNoProduct.main(SmallestNoProduct.java:52)
#Edit
The improved Code using array only.
public class SmallestNoProduct {
public static void generateFNos(int max) {
int s = 0;
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
s++;
}
}
for (int g = 0; g < s; g++) {
System.out.println(ar[g]);
}
smallestNoProduct(ar, s);
}
public static void smallestNoProduct(int x[], int s) {
int j[] = new int[x.length];
int p = s - 1;
for (int d = 0; d < p;) {
String t = x[d++] + "" + x[p--];
System.out.println(t);
int i = Integer.parseInt(t);
j[d] = i;
}
/*for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}*/
}
public static void main(String s[]) {
generateFNos(6);
}
}
Maybe it better:
public class SmallestNoProduct {
public static int smallest(int n) {
int small = n*n;
for(int i = 1; i < Math.sqrt(n); i++) {
if(n%i == 0) {
int temp = Integer.parseInt(""+i+""+n/i);
int temp2 = Integer.parseInt(""+n/i+""+i);
temp = temp2 < temp? temp2: temp;
if(temp < small) {
small = temp;
}
}
}
return small;
}
public static void main(String[] args) {
System.out.println(smallest(6)); //6
System.out.println(smallest(10)); //25
System.out.println(smallest(100)); //205
}
}
Problem lies in this line
String t=x[d++]+""+x[p--];
x[p--] will try to fetch 7th position value, as p is length of array x i.e. 6 which results in ArrayIndexOutOfBound exception. Array index starts from 0, so max position is 5 and not 6.
You can refer this question regarding postfix expression.
Note: I haven't checked your logic, this answer is only to point out the cause of exception.
We are unnecessarily using array here...
below method should work....
public int getSmallerMultiplier(int n)
{
if(n >0 && n <10) // if n is 6
return (1*10+n); // it will be always (1*10+6) - we cannot find smallest number than this
else
{
int number =10;
while(true)
{
//loop throuogh the digits of n and check for their multiplication
number++;
}
}
}
int num = n;
for(i=9;i>1;i--)
{
while(n%d==0)
{
n=n/d;
arr[i++] = d;
}
}
if(num<=9)
arr[i++] = 1;
//printing array in reverse order;
for(j=i-1;j>=0;j--)
system.out.println(arr[j]);
maxRec() is meant to calculate the maximum value within an array using a helper
method maximize(). When this code executes, it always seems to return zero, however
it will print out the correct value. When using a debugger, I noticed that
the maxRec() method will get the right return value but wont return it; instead it sets it back to zero and moves up to the else statement.I would be grateful for any suggestions that could help fix this.
public int maxRec(int[] v) {
int maxValue = 0;
int[] tempArray = maximize(v);
boolean executeCode = true;
if (tempArray.length == 1) {
maxValue = tempArray[0];
executeCode = false;
System.out.println(maxValue);
} else if (executeCode == true && tempArray.length != 1) {
maxRec(tempArray);
}
return maxValue;
}
public int[] maximize(int[] v) {
int count = 0;
int secondCount = 0;
for (int i = 0; i < v.length; i++) {
if (v[i] > v[0]) {
count++;
}
}
int[] newArray;
newArray = new int[count];
for (int i = 0; i < v.length; i++) {
if (v[i] > v[0]) {
newArray[secondCount] = v[i];
secondCount++;
}
}
return newArray;
}
Code should be changed like this.
public int maxRec(int[] v)
{
int maxValue=0;
int[] tempArray = maximize(v);
boolean executeCode = true;
if(tempArray.length==1)
{
maxValue=tempArray[0];
executeCode=false;
}
else if(executeCode==true && tempArray.length!=1 && tempArray.length > 0)
{
maxValue = maxRec(tempArray);
}
return maxValue;
}
public int[] maximize(int[] v)
{
int count=0;
int secondCount=0;
for(int i=0;i<v.length;i++)
{
if(v[i]>v[0])
{
count++;
}
}
int[] newArray;
newArray = new int[count];
if(count == 0)
{
newArray = new int[1];
newArray[0] = v[0];
return newArray;
}
for(int i=0;i<v.length;i++)
{
if(v[i]>v[0])
{
newArray[secondCount]=v[i];
secondCount++;
}
}
return newArray;
}
maximize returns an array of all values greater than the first item of the array.
To make a recursive function, one starts with the simplest case, the least work.
The rest one delegates to a clone of oneself, the recursive call.
public int maxRec(int[] v) {
if (v.length == 0) {
throw IllegalArgumentException();
}
int[] greaterThanFirst = maximize(v);
int maxValue = 0;
if (greaterThanFirst.length == 0) {
maxValue = v[0];
} else {
maxValue = maxRec(greaterThanFirst);
}
return maxValue;
}
First a sanity check, v not being empty.
If maximize did not yield a larger number, yield the first value, being the largest.
//-------------------------------------------------------------------
// 1. maxRec --> Computes the maximum item of MyList
//-------------------------------------------------------------------
/**
* The function computes the maximum item of m (-1 if m is empty).
* #param m: The MyList we want to compute its maximum item.
* #return: The maximum item of MyList
*/
public int maxRec(MyList<Integer> m){
int max = 0;
int res = 0;
int e0 = 0;
int e1 = 0;
// Scenarios Identification
int scenario = 0;
// Type 1. MyLyst is empty
if(m.length() == 0) {
scenario = 1;
}else {
scenario = 2;
}
// Scenario Implementation
switch(scenario) {
// If MyLyst is empty
case 1:
res = -1;
break;
// If there is 1 or more elements
case 2:
// Old School
for(int i = 0; i <= m.length()-1; i++)
if(m.getElement(i) > max) {
max = m.getElement(i);
}
// Recursively
//1. Get and store first element of array
e0 = m.getElement(0);
//2. We remove the first element from MyList we just checked
m.removeElement(0);
//3. We recursively solve the smaller problem
e1 = maxRec(m);
//4. Compare and store results
if(e0 > e1) {
res = e0;
}
else {
res = e1;
}
//5. Return removed element back to the array
m.addElement(0, e0);
break;
}
//6.Display the process to see what's going on
System.out.println("My Way: "+ max);
System.out.println("Recursive Way: " + res);
//7. Return result
return res;
}
This question already has answers here:
Algorithm to find next greater permutation of a given string
(14 answers)
Closed 8 years ago.
I am currently making a Permutation class for java. One of my methods for this class, is advance(), where the computer will take the array, and then display all permutations of the array.
So, for example, if I give the array {0,1,2,3,4,5}, or the number 6, it should give me from 012345.....543210.
Here is the code I have so far:
import java.util.*;
public class Permutation extends java.lang.Object {
public static int[] permutation;
public static int[] firstPerm;
public static int[] lastPerm;
public static int length;
public static int count;
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public Permutation(int n) {
length = n;
permutation = new int[length];
for (int i = 0; i < length; i++) {
permutation[i] = i;
}
}
public Permutation(int[] perm) {
length = perm.length;
permutation = new int[length];
boolean[] t = new boolean[length];
for (int i = 0; i < length; i++) {
if (perm[i] < 0 || perm[i] >= length) {
throw new IllegalArgumentException("INVALID ELEMENT");
}
if (t[perm[i]]) {
throw new IllegalArgumentException("DUPLICATE VALUES");
}
t[perm[i]] = true;
permutation[i] = perm[i];
}
}
public void advance() {
}
public int getElement(int i) {
return permutation[i];
}
public boolean isFirstPerm() {
firstPerm = new int[permutation.length];
for (int i = 0; i < permutation.length; i++) {
firstPerm[i] = permutation[i];
}
Arrays.sort(firstPerm);
if (Arrays.equals(firstPerm, permutation)) {
return true;
} else {
return false;
}
}
public boolean isLastPerm() {
lastPerm = new int[firstPerm.length];
for (int i = 0; i < firstPerm.length; i++) {
lastPerm[i] = firstPerm[firstPerm.length - 1 - i];
}
if (Arrays.equals(permutation, lastPerm)) {
return true;
} else {
return false;
}
}
public static Permutation randomPermutation(int n) {
if (n <= 0) {
throw new IllegalArgumentException("INVALID NUMBER");
} else {
length = n;
permutation = new int[length];
for (int i = 0; i < length; i++) {
permutation[i] = i;
}
Collections.shuffle(Arrays.asList(permutation));
return new Permutation(permutation);
}
}
public void reset() {
Arrays.sort(permutation);
}
public boolean isValid(int[] perm) {
boolean[] t = new boolean[length];
for (int i = 0; i < length; i++) {
if (perm[i] < 0 || perm[i] >= length) {
return false;
}
if (t[perm[i]]) {
return false;
}
}
return true;
}
public int[] toArray() {
return permutation;
}
public String toString() {
StringBuffer result = new StringBuffer();
for (int i = 0; i < permutation.length; i++) {
result.append(permutation[i]);
}
String perms = result.toString();
return perms;
}
public static long totalPermutations(int n) {
count = 1;
for (int i = 1; i <= n; i++) {
count = count * i;
}
return count;
}
}
As you can see, the advance() method is the last thing I need to do, but I can't figure it out. Any help will be grand.
One of methods you can employ is:
Fix the first element and recursively find all permutations of rest of the array.
Then change the first elements by trying each of the remaining elements.
Base case for recursion is when you travel the entire length to get 0 element array. Then, either print it or add it to a List which you can return at the end.
public void advance() {
int[] temp = Arrays.copyOf(arr, arr.length);
printAll(0,temp);
}
private void printAll(int index,int[] temp) {
if(index==n) { //base case..the end of array
//print array temp here
}
else {
for(int i=index;i<n;i++) {//change the first element stepwise
swap(temp,index,i);//swap to change
printAll(index+1, temp);//call recursively
swap(temp,index,i);//swap again to backtrack
}
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
The way your code looks right now, it sounds like you want to be able to control the permutation class externally, rather than only supporting the one operation of printing all the permutations in order.
Here's an example of how to calculate a permutation.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static int factorial(int x) {
int f = 1;
while (x > 1) {
f = f * x;
x--;
}
return f;
}
public static List<Integer> permute(List<Integer> list, int iteration) {
if (list.size() <= 1) return list;
int fact = factorial(list.size() - 1);
int first = iteration / fact;
List<Integer> copy = new ArrayList<Integer>(list);
Integer head = copy.remove(first);
int remainder = iteration % fact;
List<Integer> tail = permute(copy, remainder);
tail.add(0, head);
return tail;
}
public static void main(String[] args) throws IOException {
List<Integer> list = Arrays.asList(4, 5, 6, 7);
for (int i = 0; i < 24; i++) {
System.out.println(permute(list, i));
}
}
}
Just to elaborate, the idea behind the code is to map an integer (iteration) to a particular permutation (ordering of the list). We're treating it as a base-n representation of the permutation where each digit represents which element of the set goes in that position of the resulting permutation.
For example, if we're permuting (1, 2, 3, 4) then we know there are 4! permutations, and that "1" will be the first element in 3! of them, and it will be followed by all permutations of (2, 3, 4). Of those 3! permutations of the new set (2, 3, 4), "2" will be the first element in 2! of them, etc.
That's why we're using / and % to calculate which element goes into each position of the resulting permutation.
This should work, and it's pretty compact, only drawback is that it is recursive:
private static permutation(int x) {
if (x < 1) {
throw new IllegalArgumentException(x);
}
LinkedList<Integer> numbers = new LinkedList<>();
for (int i = 0; i < x; i++) {
numbers.add(i);
}
printPermutations(numbers, new LinkedList<>());
}
private static void printPermutations(
LinkedList<Integer> numbers, LinkedList<Integer> heads) {
int size = numbers.size();
for (int i = 0; i < size; i++) {
int n = numbers.getFirst();
numbers.removeFirst();
heads.add(n);
printPermutations(numbers, heads);
numbers.add(n);
heads.removeLast();
}
if (numbers.isEmpty()) {
String sep = "";
for (int n : heads) {
System.out.print(sep + n);
sep = " ";
}
System.out.println("");
}
}