Explanation on Java Permutation program - java

this question might seem basic to some people but I've been analysing and dissecting this code without success as to how this permutation program by Robert Sedgewick prints the combination o f words or characters without using system.out.print in the methods perm1 and perm2. Any help or explanation for dummies is greatly appreciated. Thank you in advance.
This is the code under the link:
public class Permutations {
// print N! permutation of the characters of the string s (in order)
public static void perm1(String s) { perm1("", s); }
private static void perm1(String prefix, String s) {
int N = s.length();
if (N == 0) System.out.println(prefix);
else {
for (int i = 0; i < N; i++)
perm1(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, N));
}
}
// print N! permutation of the elements of array a (not in order)
public static void perm2(String s) {
int N = s.length();
char[] a = new char[N];
for (int i = 0; i < N; i++)
a[i] = s.charAt(i);
perm2(a, N);
}
private static void perm2(char[] a, int n) {
if (n == 1) {
System.out.println(a);
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
perm2(a, n-1);
swap(a, i, n-1);
}
}
// swap the characters at indices i and j
private static void swap(char[] a, int i, int j) {
char c;
c = a[i]; a[i] = a[j]; a[j] = c;
}
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String elements = alphabet.substring(0, N);
perm1(elements);
System.out.println();
perm2(elements);
}
}

It's right there:
if (N == 0) System.out.println(prefix);
System.out.print and System.out.println is basically the same, except the later prints a newline after the text.

Related

Rolling hash: my codes fails with modulo for long string

I'm trying to solve https://leetcode.com/problems/longest-repeating-substring/
I want to use rolling hash to match strings.
However, my codes don't seem to work when I deal with modulo.
For a string with all same characters, the maximum length of repeating substring should be string.length - 1.
public class Main {
public static void main(String[] args) {
String str = "bbbbbbbbbbbbbbbbbbb";
System.out.println(str.length() - 1);
Solution s = new Solution();
System.out.println(s.longestRepeatingSubstring(str));
}
}
class Solution {
public int longestRepeatingSubstring(String S) {
HashSet<Long> h = new HashSet();
long mod = (long)1e7 + 7;
for(int i = S.length() - 1; i >0; i--){
h = new HashSet();
long c = 0;
int j = 0;
for(; j < i; j ++){
c = (c*26 % mod + S.charAt(j) - 'a')% mod;
}
h.add(c);
for(; j < S.length(); j++){
c -= (S.charAt(j - i ) - 'a') * Math.pow(26,i-1)% mod;
c = (c*26 % mod + S.charAt(j) - 'a')% mod;
if(h.contains(c)){
return i;
}
h.add(c);
}
}
return 0;
}
}
Playground for my codes: https://leetcode.com/playground/F4HkxbFQ
We cannot see your original link, we need a password.
The usage of modulo seems to be really complex.
Why not try something like this
class Scratch {
// "static void main" must be defined in a public class.
public static void main(String[] args) {
String str = "bbaaabbbbccbbbbbbzzzbbbbb";
System.out.println(str.length() - 1);
Solution s = new Solution();
System.out.println(s.longestRepeatingSubstring(str));
}
static class Solution {
public int longestRepeatingSubstring(String s) {
int max = -1;
int currentLength = 1;
char[] array = s.toCharArray();
for (int index = 1; index < array.length; index++) {
if (array[index - 1] == array[index]) {
currentLength++;
max = Math.max(max, currentLength);
} else {
currentLength = 1;
}
}
return max;
}
}
}

What is wrong with my recursion to create permutations of a string?

It is printing out a few permutations but the rest are null and I'm not sure why. I need to but all the permutations into String[] and I can't import any other package except for util.Arrays. Please help!
import java.util.Arrays;
public class DIE
{
public static String[] printPermutations(String s)
{
int l = s.length();
int f = factorial(l);
int count = 0;
String[] array = new String[f];
permute("", s, array, 0);
Arrays.sort(array);
return array;
}
private static String[] permute(String x, String s, String [] array, int count)
{
int l = s.length();
if (l == 0)
{
array[count] = (x + s);
}
for (int i = 0; i < l; i++)
{
permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), array, count);
count++;
}
return array;
}
public static int factorial(int l)
{
if (l == 1)
{
return 1;
}
else
{
int result = l * factorial(l - 1);
return result;
}
}
/*
Do not edit anything below this comment.
*/
public static void main(String[] args)
{
String[] permutations = printPermutations(args[0]);
for(String p : permutations)
{
System.out.println(p);
}
}
}
Your count variable is wrong. Within the outermost call to permute("", "abc", ...) it is incremented only by one, even though the call to the next level permute("a", "bc", ...) creates two permutations!
There are two possible solutions:
Instead of a String[] to collect your result use a List<String>. Then you don't need to manually count the number of permutations.
let permute return the new count (instead of the result array, that one is never used anyway)
For permute to return the new count the method would look like this:
private static int permute(String x, String s, String [] array, int count)
{
int l = s.length();
if (l == 0)
{
array[count++] = x;
}
for (int i = 0; i < l; i++)
{
count = permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), array, count);
}
return count;
}
Using a List<String> would need some more changes, but the permute function would be smaller:
public static List<String> printPermutations(String s)
{
int l = s.length();
int f = factorial(l);
List<String> result = new ArrayList<>(f);
permute("", s, result);
Collections.sort(result);
return result;
}
private static void permute(String x, String s, List<String> result)
{
int l = s.length();
if (l == 0)
{
result.add(x);
}
for (int i = 0; i < l; i++)
{
permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), result);
}
}
And some small changes in the main method due to the changed result of printPermutations (IMHO a very bad named method: it prints out nothing, it creates the permutations together with a helper method)

dynamic programming dictionary exercise bottom-up approach in java

Here is the problem i want to solve:
You are given a dictionary, i.e. a set S of m strings, and a separate string t. You are required to output the minimum number of substrings that t can be broken up to, such that the union of these substrings is t and all the substrings belong to the dictionary.
Example:
Input:
5
0 1 11 1101 000
1111001000
Output:
6
I have solved it using the top-down with memoization approach (in java):
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
String[] s = new String[m];
for(int i = 0; i < m; ++i){
s[i] = sc.next();
}
String t = sc.next();
System.out.println(topDown(m, s, t));
}
public static int topDown(int m, String[] s, String t) {
int r[] = new int[m + 1];
for (int i = 0; i <= m; ++i) {
r[i] = Integer.MAX_VALUE - 3;
}
return memo(m, s, t, r);
}
public static int memo(int m, String[] s, String t, int[] r) {
int best = Integer.MAX_VALUE - 3;
for (int i = 0; i < m; ++i) {
if (t.equals(s[i])) {
r[m] = 1;
return 1;
}
}
if (m == 0) {
best = 0;
} else {
int a;
for (String str : s) {
if (t.endsWith(str)) {
a = 1 + memo(m, s, replaceLast(t, str, ""), r);
if (best > a)
best = a;
}
}
}
r[m] = best;
return best;
}
public static String replaceLast(String string, String substring,
String replacement) {
int index = string.lastIndexOf(substring);
if (index == -1)
return string;
return string.substring(0, index) + replacement
+ string.substring(index + substring.length());
}
}
I can't seem to find the way to solve this problem using the bottom-up approach... If someone could show me how to solve it with bottom-up it would be great

Combinations of integers

I'd appreciate any help on the following problem. I have n integers from 0 to n-1, and I'm trying to generate a list of all possible combinations of length k (i.e. k concatenated integers) such that every pair of consecutive integers are not equal. So, for example, (1)(2)(3)(2) would be valid with k = 4, but (1)(2)(3)(3) would not be valid. Any ideas on how to approach this most efficiently? (I don't care much about length/degree of complexity of the code, just efficiency)
It is the code:
void Generate(int[] source, List<int[]> result, int[] build, int k, int num) {
if (num == k) {
int[] a = (int[])build.clone();
result.add(a);
return;
}
for (int i = 0; i < source.length; i++)
if (num == 0 || source[i] != build[num - 1])
{
build[num] = source[i];
Generate(source, result, build, k, num + 1);
}
}
How to call:
int k = 2;
List<int[]> a = new ArrayList<int[]>();
Generate(new int[]{1,2,3}, a, new int[k], k, 0);
public class Generator {
final int k = 2;
final char[] n = new char[]{'0','1','2','3','4','5','6','7','8','9'};
final char[] text = new char[k];
public void gen(int i, int not_n) {
if(i == k) {
System.out.println(text);
return;
}
for(int j = 0; j < n.length; j++) {
if(j == not_n) continue;
text[i] = n[j];
gen(i+1, j);
}
}
public static void main(String[] args) {
new Generator().gen(0, -1);
}
}
public static void recursiveOutput(Integer n, int k, int limit, String prints){
k++;
if(k>limit)
return;
String statePrints = prints;
//cycle through all available numbers
for(Integer i = 1; i<=n; i++)
{
statePrints = prints;
//First cycle
if(k==1){
statePrints+= "(" + i.toString() + ")";
recursiveOutput(n, k, limit, statePrints);
}
//check if predecessor is not the same
if(i != Integer.parseInt(statePrints.substring(statePrints.length()-2,statePrints.length()-1))){
statePrints += "(" + i.toString() + ")";
recursiveOutput(n, k, limit, statePrints);
}
}
//Check if the length matches the combination length
if(statePrints.length() == 3 * limit)
System.out.println(statePrints);
}
call :recursiveOutput(3,0,4,"");

Avoid printing the last comma

I'm trying to print this loop without the last comma. I've been Googling about this and from what i've seen everything seems overcomplex for such a small problem. Surely there is an easy solution to avoid printing the last comma. Much appreciated if somebody could help me out, this is driving me insane!!!
For example it loops from 1-10 // 1,2,3,4,5,6,7,8,9,10, < do not want this last comma
public static void atob(int a,int b)
{
for(int i = a; i <= + b; i++)
{
System.out.print(i + ",");
}
}
I might get stoned to death for this answer
public static void atob(int a,int b) {
if(a<=b) {
System.out.println(a);
for(int i = a+1;i<=b;i++) {
System.out.println(","+i);
}
}
}
}
Yet another way to do this.
String sep = "";
for(int i = a; i <= b; i++) {
System.out.print(sep + i);
sep = ",";
}
if you are using a StringBuilder
StringBuilder sb = new StringBuilder();
for(int i = a; i <= b; i++)
sb.append(i).append(',');
System.out.println(sb.subString(0, sb.length()-1));
Try this
public static void atob(int a,int b)
{
for(int i = a; i < b; i++)
{
System.out.print(i + ",");
}
System.out.print(b);
}
Java 8:
IntStream.rangeClosed(a, b)
.collect(Collectors.joining(","));
If you want to perform interleaving actions:
Java 8:
IntStream.rangeClosed(a, b)
.peek(System.out::print)
.limit(b - a) // [a:(b-1)]
.forEach(i -> System.out.print(","));
Java 9:
IntStream.rangeClosed(a, b)
.peek(System.out::print)
.takeWhile(i -> i < b) // [a:(b-1)]
.forEach(i -> System.out.print(","));
public static void atob(int a, int b) {
if (a < b) {
System.out.print(a);
while (a < b) {
a++;
System.out.print("," + a);
}
}
}
When called with
atob(0,10);
Will give the output
0,1,2,3,4,5,6,7,8,9,10
A general approach could be to make a distinction between the first item and all the others. The first run, no comma is printed BEFORE i. After that, a comma is printed before i, every time.
public static void atob(int a,int b) {
boolean first = true;
for(int i = a; i <= + b; i++) {
if ( first == false ) System.out.print(",");
System.out.print(i);
first = false;
}
}
In this specific case, using the ternary operator (http://en.wikipedia.org/wiki/Ternary_operation), you could write it as compact as:
public static void atob(int a,int b) {
for(int i = a; i <= + b; i++) {
System.out.print( i + ( i < b ? "," : "" ) );
}
}
Without ternary operation, this would look like this (and is more readable, which is often a good thing):
public static void atob(int a,int b) {
for(int i = a; i <= + b; i++) {
System.out.print( i );
if ( i < b ) System.out.print( "," );
}
}
(note that + b is the same as b, so you could replace that, as others have done in their answers)
With slight adjustments (method name, variables, and space after comma):
public static void printSequence(int start, int end) {
if (end < start) {
return; // or however you want to handle this case
}
if (end == start) {
System.out.print(start);
return;
}
StringBuilder sequence = new StringBuilder();
for (int i = start; i <= end; i++) {
sequence.append(i).append(", ");
}
// now simply print the sequence without the last ", "
System.out.print(sequence.substring(0, sequence.length() - 2));
}
Try:
public static void atob(int a, int b) {
if (b < a) {
final int temp = a;
a = b;
b = temp;
}
System.out.print(a++);
for (int i = a; i < b ; i ++ ) {
System.out.print("," + i);
}
}
Use StringBuilder for it. use substring based index.
public class arraySort {
public static void main(String[] args) {
int a[] = { 2, 7, 5, 6, 9, 8, 4, 3, 1 };
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] < a[j]) {
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
System.out.print("Descending order:{");
StringBuilder br = new StringBuilder();
for (int i = 0; i < a.length; i++) {
br.append(a[i] + ",");
}
System.out.print( br.substring(0, br.length()-1));
System.out.println("}");
}
}
public static void atob (int a,int b){
for(int i = a; i <= b; i++)
{
System.out.print(i );
if(i<b){
System.out.print(",");
}
}
}
Clunky solution, but hey - it works.
public static void atob(int a, int b){
int count = 1;
for(int i = a; i <= + b; i++) {
System.out.print(i);
if(count!=((b + 1) - a)) {
System.out.print(", ");
count++;
}
}
}
Alternatively, this works too.
public static void atob(int a, int b){
int count = 0;
for(int i = a; i <= + b; i++) {
if(count > 0){
System.out.print(", ");
}
System.out.print(i);
count++;
}
}
Found another simple way using regex:
String str = "abc, xyz, 123, ";
str = str.replaceAll(", $", "");
System.out.println(str); // "abc, xyz, 123"
You can simply use escape sequence for backspace(\b),outside the main loop,it will delete the last comma.
public static void atob(int a,int b)
{
for(int i = a; i <= + b; i++)
{
System.out.print(i + ",");
}
System.out.print("\b");
}

Categories