How to generate combinations obtained by permuting 2 positions in Java - java

I have this problem, I need to generate from a given permutation not all combinations, but just those obtained after permuting 2 positions and without repetition. It's called the region of the a given permutation, for example given 1234 I want to generate :
2134
3214
4231
1324
1432
1243
the size of the region of any given permutation is , n(n-1)/2 , in this case it's 6 combinations .
Now, I have this programme , he does a little too much then what I want, he generates all 24 possible combinations :
public class PossibleCombinations {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("Entrer a mumber");
int n=s.nextInt();
int[] currentab = new int[n];
// fill in the table 1 TO N
for (int i = 1; i <= n; i++) {
currentab[i - 1] = i;
}
int total = 0;
for (;;) {
total++;
boolean[] used = new boolean[n + 1];
Arrays.fill(used, true);
for (int i = 0; i < n; i++) {
System.out.print(currentab[i] + " ");
}
System.out.println();
used[currentab[n - 1]] = false;
int pos = -1;
for (int i = n - 2; i >= 0; i--) {
used[currentab[i]] = false;
if (currentab[i] < currentab[i + 1]) {
pos = i;
break;
}
}
if (pos == -1) {
break;
}
for (int i = currentab[pos] + 1; i <= n; i++) {
if (!used[i]) {
currentab[pos] = i;
used[i] = true;
break;
}
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
currentab[++pos] = i;
}
}
}
System.out.println(total);
}
}
the Question is how can I fix this programme to turn it into a programme that generates only the combinations wanted .

How about something simple like
public static void printSwapTwo(int n) {
int count = 0;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n - 1;i++)
for(int j = i + 1; j < n; j++) {
// gives all the pairs of i and j without repeats
sb.setLength(0);
for(int k = 1; k <= n; k++) sb.append(k);
char tmp = sb.charAt(i);
sb.setCharAt(i, sb.charAt(j));
sb.setCharAt(j, tmp);
System.out.println(sb);
count++;
}
System.out.println("total=" + count+" and should be " + n * (n - 1) / 2);
}

Related

String,which repeats ,but not starts from the beginning in Java (diamond pattern

This is the work that i done so far:I have to print diamond pattern which always starts with uppercase from string, which repeats,but not always starts from the beginning.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String userInput = keyboard.next();
userInput = Character.toUpperCase(userInput.charAt(0)) + userInput.substring(1);
int i;
int j;
if (userInput.length() % 2 != 0) {
for(i = 1; i < userInput.length(); i += 2) {
for(j = 0; j < userInput.length() - 1 - i / 2; ++j) {
System.out.print(" ");
}
for(j = 0; j < i; ++j) {
System.out.print(userInput.charAt(j));
}
System.out.println("");
}
for(i = userInput.length(); i > 0; i -= 2) {
for(j = 0; j < userInput.length() - 1 - i / 2; ++j) {
System.out.print(" ");
}
for(j = 0; j < i; ++j) {
System.out.print(userInput.charAt(j));
}
System.out.print("\n");
}
} else {
for(i = 2; i < userInput.length(); i += 2) {
for(j = 0; j < userInput.length() - 1 - i / 2; ++j) {
System.out.print(" ");
}
for(j = 0; j < i; ++j) {
System.out.print(userInput.charAt(j));
}
System.out.println("");
}
for(i = userInput.length(); i > 0; i -= 2) {
for(j = 0; j < userInput.length() - 1 - i / 2; ++j) {
System.out.print(" ");
}
for(j = 0; j < i; ++j) {
System.out.print(userInput.charAt(j));
}
System.out.print("\n");
}
}
}
For example my input is "Peter".
So my output is:
P
Pet
Peter
Pet
P
but it must be:
P
Ete
Rpete
Rpe
T
I dont know what to change to make this work
Here's a shorter version of your code:
public static void main(String[] args) {
String userInput = "Peter";
int length = userInput.length();
int m, j, i, n = 0;
for (m = length % 2 > 0 ? 1 : 2; m < length * 2; m += 2) {
i = m < length ? m : length * 2 - m;
for (j = 0; j < length - 1 - i / 2; ++j) {
System.out.print(" ");
}
for(j = 0; j < i; ++j) {
char c = userInput.charAt(n++ % length);
c = j == 0 ? Character.toUpperCase(c) : Character.toLowerCase(c);
System.out.print(c);
}
System.out.println("");
}
}
You need some few changes:
Declare int n=0; after int j;
Always print userInput.charAt(n++ % userInput.length()) instead of charAt(j)
In order to get only the first character in line in uppercase:
char c = userInput.charAt(n++ % userInput.length());
c = j == 0 ? Character.toUpperCase(c) : Character.toLowerCase(c);
System.out.print(c);
Check the modulo operator.
With these changes, you'll get this output:
P
Ete
Rpete
Rpe
T
Given the fact that the input itself gets printed in a cylic manner, we can make use out of it. My proposal would be to concatenate the input string and print out the substrings which are determined by the structure of the diamond pattern.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String userInput = keyboard.next();
String concatenated = userInput;
// build up the index array
int i, cumSum = 0;
ArrayList<Integer> helperIndex = new ArrayList<>();
for(i = 1; i < userInput.length(); i += 2) {
helperIndex.add(i);
cumSum += i;
}
for(i = userInput.length(); i > 0; i -= 2) {
helperIndex.add(i);
cumSum += i;
}
int numOfWordRepitition = cumSum / userInput.length() ;
for (i = 0; i < numOfWordRepitition; i++){
concatenated += userInput;
}
// print out diamond
String substr;
int prev = helperIndex.get(0);
int next = helperIndex.get(0);
substr = concatenated.substring(0 , helperIndex.get(0));
System.out.println(Character.toUpperCase(substr.charAt(0)) + substr.substring(1));
for(i = 1; i < userInput.length(); i++){
next += helperIndex.get(i);
substr = concatenated.substring(prev , next);
substr = Character.toUpperCase(substr.charAt(0)) + substr.substring(1);
System.out.println(substr);
prev = next;
}
}

finding length of union array

I am trying to find length of an array formed by union of two arrays. I can print out the union elements like this, but have no idea how to get length of my union array. Any ideas?
Can it be count variable length of my union array?
int[] array1={1,3,2,5};
int[] array2={4,5,1,3,2};
int m = array1.length, n = array2.length, k = array1.length, i = 0, flag = 0;
int c[] = new int[m + n];
int d[] = new int[m];
for (i = 0; i < m; i++) {
c[i] = array1[i];
}
for (i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (array2[i] != array1[j]) {
flag = 1;
} else {
flag = 0;
break;
}
}
if (flag == 1) {
c[k] = array2[i];
k++;
}
}
int count = 1;
for (i = 0; i < k - 1; i++) {
count++;
}
int p = 0;
for (i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (array2[i] == array1[j]) {
flag = 1;
break;
} else {
flag = 0;
}
}
if (flag == 1) {
d[p] = array2[i];
p++;
}
}
System.out.println("The length of the union array is: " + count);
The count should be k + m and not k. So just replace:
for (i = 0; i < k - 1; i++)
with
for (i = 0; i < k + m - 1; i++)
Better solution would be to assign k + m to count and print it. Something like this:
count = k + m;
System.out.println("count is " + count);
If you want a unique count then use Set:
Set<Integer> set = new HashSet<>();
set.addAll(Arrays.asList(array1));
set.addAll(Arrays.asList(array2));
count = set.size();

I am trying this simple sudoku

I am trying a simple sudoku program. i started by taking the values in a 3D
array and then copied them into a 1D array by using mr.serpardum's method.
i know that there is an error at the point where i am trying to find
duplicate elements,because even if i give same numbers as input the output
says "its a sudoku" but i can't to find it...apparently i can't add any
image coz i dont have enough credits
public class SecondAssignment {
#SuppressWarnings("unused")
public static void main(String[] args) throws IOException {
int i = 0, j = 0, k = 0;
boolean result = false;
int arr1[][];
arr1 = new int[3][3];
int arr2[];
arr2 = new int[9];
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the elements in the sudoku block");
//getting elements into array
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
arr1[i][j] = Integer.parseInt(br.readLine());
}
}
//printing it in matrix form
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
System.out.print(arr1[i][j] + "\t");
}
System.out.println(" ");
}
//copying array1 elements into array 2
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
arr2[i * 3 + j] = arr1[i][j];
}
}
//finding duplicate elements
for (i = 0; i < arr2.length; i++) {
for (int m = i + 1; m < arr2.length; m++) {
if (arr2[i] == (arr2[m])) {
System.out.println("Not a sudoku");
//result = true;
} else {
System.out.println("Its a sudoku");
//result = false;
}
}
}
}
}
You can update your code to following
//finding duplicate elements
for( i = 0; i < arr2.length; i++){
for(int m = i+1; m < arr2.length; m++){
if(arr2[i] == (arr2[m])){
result = true;
break;
}
}
}
if(result){
System.out.println("\nNot a sudoku");
}
else{
System.out.println("\nIts a sudoku");
}
You should have used break as soon as the match was found.
This code just checks if duplicate element is present in the array (of size 9) or not.

Bellman Ford detecting negative cycle of shortest length

Solving this Arbitage problem of UVA http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=40 but I am stuck with finding the negative cycle of shortest length(length here is number of vertices).Here is my code that successfully detects the negative cycle
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class _104 {
public static void main(String[] args) throws NumberFormatException,
IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
String input;
while ((input = reader.readLine()) != null) {
int n = Integer.parseInt(input);
double[][] cost = new double[n + 1][n + 1];
double[] spEstimate = new double[n + 1];
int parent[] = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
spEstimate[i] = Double.MAX_VALUE;
cost[0][i] = 0;
cost[i][0] = Double.MAX_VALUE;
parent[i] = Integer.MAX_VALUE;
}
spEstimate[0] = 0.0;
parent[0] = 0;
for (int i = 1; i < n + 1; i++) {
String[] line = reader.readLine().split("\\s+");
for (int j = 1; j < n + 1; j++) {
if (i == j) {
cost[i][j] = 0;
} else if (i < j) {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 2])) / Math
.log(2));
} else {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 1])) / Math
.log(2));
}
}
}
int save = 1, s = 1;
boolean flag = BellmanFord(n, cost, spEstimate, parent);
display(cost);
// Relax all edges once more
boolean brk = true;
for (int i = 0; i < cost.length && brk; i++) {
for (int j = 0; j < cost.length && brk; j++) {
//relax(i, j, spEstimate, cost[i][j], parent);
}
}
ArrayList<Integer> path = new ArrayList<Integer>();
while (parent[save] != s) {
path.add(save);
save = parent[save];
}
if (flag) {
System.out.println("no arbitrage sequence exists");
} else {
path.add(0, path.get(path.size() - 1));
for (int i = path.size() - 1; i >= 0; --i) {
System.out.println(path.get(i));
}
}
}
reader.close();
}
public static boolean BellmanFord(int n, double[][] cost, double[] sp,
int[] parent) {
for (int k = 0; k < n - 1; k++) {
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
relax(i, j, sp, cost[i][j], parent);
}
}
}
// Relax all edges once more to detect cycle
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
if (sp[j] > (sp[i] + cost[i][j])) {
return false;
}
}
}
return true;
}
static void relax(int i, int j, double[] sp, double cij, int[] parent) {
if (sp[j] > (sp[i] + cij)) {
sp[j] = sp[i] + cij;
System.out.println("relaxed " + i + " " + j + " " + cij + " "
+ sp[i] + " " + sp[j]);
parent[j] = i;
}
}
static void display(double[][] cost) {
System.out.println("Display Cost");
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
System.out.print(cost[i][j] + "\t");
}
System.out.println();
}
}
static void display(double[] sp) {
for (int i = 0; i < sp.length; i++) {
System.out.println(sp[i]);
}
}
}
You can do it like that:
Fix the start vertex of the cycle(let's call it v).
Run Ford-Bellman algorithm assuming that dist[i] = 0 if i = v and INF otherwise.
If there is a negative cycle that contains v, after k iterations of the outer loop in Ford-Bellman algorithm dist[v] will become negative. So you can easily find such smallest k by simply checking if dist[v] is still non-negative or not after each iteration.
The smallest k among all v is the answer.
It is possible to solve this problem by considering cycles of increasing length as opposed to finding negative cycles as described by kraskevich. The worst case complexity for both approaches is O(n^4). This approach resembles Floyd-Warshall where you consider increasing lengths instead of intermediate vertices.
You can find a detailed explanation that includes diagrams and code here.

Java permutations 2

I asked a question on helping me with this question about a week ago
Java permutations
, with a problem in the print permutation method. I have tidied up my code and have a working example that now works although if 5 is in the 5th position in the array it doesn't print it. Any help would be really appreciated.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPermutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPermutation(int[] p)
{
int n = p.length-1;
int j = 0;
int m;
int f = 0;
System.out.print("(");
while (f < n) {
m = p[j];
if (m == 0) {
do
f++;
while (p[f] == 0 && f < n);
j = f;
if (f != n)
System.out.print(")(");
}
else {
System.out.print(" " + m);
p[j] = 0;
j = m - 1;
}
}
System.out.print(" )");
}
}
I'm not too crazy about
int n = p.length-1;
followed by
while (f < n) {
So if p is 5 units long, and f starts at 0, then the loop will be from 0 to 3. That would seem to exclude the last element in the array.
You can use the shuffle method of the Collections class
Integer[] arr = new Integer[] { 1, 2, 3, 4, 5 };
List<Integer> arrList = Arrays.asList(arr);
Collections.shuffle(arrList);
System.out.println(arrList);
I don't think swapping each element with a random other element will give a uniform distribution of permutations. Better to select uniformly from the remaining values:
Random rand = new Random();
ArrayList<Integer> remainingValues = new ArrayList<Integer>(n);
for(int i = 0; i < n; i++)
remainingValues.add(i);
for(int i = 0; i < n; i++) {
int next = rand.nextInt(remainingValues.size());
result[i] = remainingValues.remove(next);
}
Note that if order of running-time is a concern, using an ArrayList in this capacity is n-squared time. There are data-structures which could handle this task in n log n time but they are very non-trivial.
This does not answer the problem you have identified.
Rather i think it identifies a mistake with your generateRandomPermutation(int n) proc.
If you add a print out of the random numbers generated (as i did below) and run the proc a few times it allows us to check if all the elements in the ARRAY TO BE permed are being randomly selected.
static int[] generateRandomPermutation(int n)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
System.out.println("random nums generated are: ");
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
System.out.print(r + " ");
Run the proc several times.
Do you see what i see?
Jerry.

Categories

Resources