I'm trying to find the rank of given strings using recursion - java

I'm trying to find the rank of given strings using recursion, but can't seem to to come out of the recursion the way I want to. Where am I going wrong?
class Solution {
public static int flag=0;
public static int ans=0;
public static int findRank(String A) {
/* write your solution here */
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
int rank=0;
rank=generate(rank,"",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
return rank;
}
public static int generate(int rank,String prefix,String suffix, ArrayList<String> list,String A){
if(suffix.length()==0){
list.add(prefix);
rank++;
if(prefix.equals(A)){
return rank;
}
}
for(int i=0;i<suffix.length();i++) {
// System.out.println(rank);
return generate(rank,prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A);
}
return rank;
}
}
This is the question:
Given a string, find the rank of the string amongst its permutations sorted lexicographically.
Assume that no characters are repeated.
Example :
Input : 'acb'
Output : 2
The order permutations with letters ‘a’, ‘c’, and ‘b’ :
abc
acb
bac
bca
cab
cba
I tried putting it in a visualizer, here's the code for that:
import java.util.*;
public class Solution {
public static int flag=0;
public static int ans=0;
public static void main(String args[]) {
/* write your solution here */
String A="dbca";
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
int rank=0;
rank=generate(rank,"",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
System.out.println(rank);
}
public static int generate(int rank,String prefix,String suffix, ArrayList<String> list,String A){
if(suffix.length()==0){
list.add(prefix);
rank++;
if(prefix.equals(A)){
return rank;
}
}
for(int i=0;i<suffix.length();i++){
// System.out.println(rank);
return generate(rank,prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A);
}
return rank;
}
}
https://cscircles.cemc.uwaterloo.ca/java_visualize/#mode=edit

Your for loop causes you to end the recursion after you find the first permutation, which is why you always return 1.
What you should be doing is to end the recursion once you find the permutation you are looking for. You can do that, for example, if your recursive method would return a boolean flag instead of an int.
Once the recursive method returns, the length of your list will be the rank you are looking for:
public static int findRank(String A)
{
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
generate("",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
return list.size();
}
public static boolean generate(String prefix,String suffix, ArrayList<String> list,String A)
{
if(suffix.length()==0){
list.add(prefix);
return (prefix.equals(A));
}
for(int i=0;i<suffix.length();i++) {
if (generate(prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A)) {
return true;
}
}
return false;
}

Related

finding all possible permutations of a given ArrayList<String>, and Storing them in global variable

In the code given below I am adding the a particular permutation of ArrayList in the function permute but while printing in the main function all possible permutations are not printed. Instead, the same ArrayList<String> is printed n! times where n is length of given ArrayList<String>.
I am adding the permutations in set(my global variable) in permute function as set.add(names) but while printing it in main function it gives output as the same unarranged Arraylist.
import java.util.*;
public class Q1 {
static Set<ArrayList<String>> set = new HashSet<>(); ;
public static void main(String args[]) {
int n;
Scanner in = new Scanner(System.in);
n = in.nextInt();
ArrayList<String> names = new ArrayList<String>();
for(int i=0;i<n;i++) {
String temp;
temp = in.next();
names.add(temp);
}
System.out.println(set.size());
permute(names,0,names.size()-1);
System.out.println(set.size());
for(ArrayList<String> i : set) {
System.out.println(i);
}
}
public static void permute(ArrayList<String> names , int l, int r) {
if(l==r) {
if(set.contains(names)) {
return;
}
set.add((ArrayList<String>)names);
//System.out.println(names);
return;
}
for(int i=l;i<=r;i++) {
Collections.swap(names,l ,i);
permute(names , l+1, r);
Collections.swap(names,l,i);
}
}
}
You are repeatedly adding the same object names to set. But you need to add a copy of names.
set.add((ArrayList<String>)names);
→
set.add(new ArrayList<>(names));

Getting an error while implementing memoization in the java code

Memoization is giving me wrong answers. Please can some one help me out here. Without memorization, I am getting the right answers as in function targetBestR, but in the memoized function targetBestM, I am getting the wrong values being stored in the array list for the respective keys.
import java.util.ArrayList;
import java.util.HashMap;
public class TargetSumBest {
public static ArrayList<Integer> targetBestR(int n, int arr[]){
if(n==0) return new ArrayList<Integer>();
if(n<0) return null;
ArrayList<Integer> shortestCombo=null;
for(int i=0;i<arr.length;i++) {
//System.out.println(i);
//System.out.println(arr[i]);
int rem=n-arr[i];
//System.out.println(n+"-"+i+"="+rem);
ArrayList<Integer> tar=targetBestR(rem, arr);
if(tar!=null) {
tar.add(arr[i]);
if(shortestCombo==null||tar.size()<shortestCombo.size()) {
shortestCombo=tar;
}
}
}
//System.out.println(n+"value"+shortestCombo);
return shortestCombo;
}
public static ArrayList<Integer> targetBestM(int n, int arr[], HashMap<Integer, ArrayList<Integer>> memo){
if(n==0) return new ArrayList<Integer>();
if(n<0) return null;
if(memo.containsKey(n)) return memo.get(n);
ArrayList<Integer> shortestCombo=null;
for(int i=0;i<arr.length;i++) {
//System.out.println(i);
//System.out.println(arr[i]);
int rem=n-arr[i];
//System.out.println(n+"-"+i+"="+rem);
ArrayList<Integer> tar=targetBestM(rem, arr,memo);
if(tar!=null) {
tar.add(arr[i]);
if(shortestCombo==null||tar.size()<shortestCombo.size()) {
shortestCombo=tar;
}
}
}
//System.out.println(n+"value"+shortestCombo);
memo.put(n, shortestCombo);
return shortestCombo;
}
public static void main(String[] args) {
int n=8; int arr[]= {1,4,2};
System.out.println(targetBestM(n, arr, new HashMap<Integer, ArrayList<Integer>>()));
System.out.println(targetBestR(n, arr));
}
}//error
Was able to find the problem. The array passed into the HashMap keeps getting used and added to. Was able to fix it by creating new ArrayLists when reading and writing from the HashMap.
when reading...
if (memo.containsKey(n)) {
System.out.println(indent + n + " memo.get(n) = " + memo.get(n));
return new ArrayList<>(memo.get(n));
}
when writing...
memo.put(n, new ArrayList<>(shortestCombo));

Card Game issue in Java

In my code I cannot find a way to assign my human and dealer variables in my method PlayGame() to their respective strings that are made from DealCards().
Whenever I run javac I get an error String[] cannot be converted to String. I don't understand this however because they are separate strings in the dealerOther array in the method DealCards(). Could someone please give me some help on this issue.
import java.util.Random;
public class GAME_8315085 {
static Random rand = new Random();
public static String[] MakeDeck() {
String[] deck=new String[51];
int k=0;
String[] suits={"\u2660", "\u2661", "\u2662", "\u2663"};
String[] ranks={"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
for (int i=0;i<suits.length;i++) {
for (int j=0;j<ranks.length;j++) {
if (suits[i].equals("\u2663") && ranks[j].equals("Q")) {
;
}
else {
deck[k]=ranks[j]+suits[i];
k++;
}
}
}
return deck;
}
public static void ShuffleDeck(String[] deck) {
for (int i=0;i<deck.length;i++) {
int random = rand.nextInt(deck.length);
String tmp=deck[i];
deck[i] = deck[random];
deck[random]=tmp;
}
}
public static String[][] DealCards(String[] deck) {
String[][] dealerOther = new String[2][26];
int j=0;
for (int i=0; i<=deck.length;i+=2) {
dealerOther[0][j]=deck[i];
j++;
}
j=0;
for (int i=1; i<deck.length;i+=2) {
dealerOther[1][j]=deck[i];
j++;
}
return dealerOther;
}
public static void PlayGame() {
String[] deck = MakeDeck();
ShuffleDeck(deck);
String[][] tmp=DealCards(deck);
String human=tmp[0];
String dealer=tmp[1];
}
public static void main(String[] args) {
PlayGame();
}
}
Problem is here
String[][] tmp=DealCards(deck);
String human=tmp[0];
String dealer=tmp[1];
Since tmp is array of arrays of string(kind of 2-D array), the human and dealer has to be array of strings.
Change it to
String[][] tmp=DealCards(deck);
String[] human=tmp[0];
String[] dealer=tmp[1];

How to search word in word list?

today I learn to write code puzzle word in java. I stress with search word in a list and I want to search it only (Vertical,horizontal) but not diagonal. My code is not gave me error and result. and can you help me to refresh it.
public class WordPuzzle {
private final String puzzleString[][];
private final int rowNumber;
public WordPuzzle(String[][] puzzleString,int rowNumber){
this.puzzleString=puzzleString;
this.rowNumber=rowNumber;
}
public void showPuzzle(){
for(int i=0;i<rowNumber;i++){
for(int j=0;j<rowNumber;j++){
System.out.print(" "+puzzleString[i][j]);
}
System.out.println();
}
}
public Set<String> searchWord(Set<String> word){
Set<String> foundWord=new HashSet<String>();
int minimumWordLength=findMinimumWordLenght(word);
Set<String>compWord=CompatitableWord(minimumWordLength);
for(String w:word){
for(String posibleWord:compWord){
if(posibleWord.contains(w) || posibleWord.contains(new StringBuffer(w).reverse())){
foundWord.add(w);
break;
}
}
}
return foundWord;
}
private int findMinimumWordLenght(Set<String> wordLength){
int minimumLenght=Integer.MAX_VALUE;
for(String w:wordLength){
if(w.length()<minimumLenght){
minimumLenght=w.length();
}
}
return minimumLenght;
}
private Set<String> CompatitableWord(int minimumWordLength){
Set<String>compWord=new LinkedHashSet<String>();
int puzzleLength=puzzleString.length;
if(puzzleLength>=minimumWordLength){
for(int i=0;i<puzzleLength;i++){
if(puzzleString[i].length>=minimumWordLength){
compWord.add(new String(puzzleString[i].toString()));
}
}
for(int i=0;i<puzzleLength;i++){
StringBuffer tmp=new StringBuffer();
for(int j=0;j<puzzleLength;j++){
tmp=tmp.append(puzzleString[j][i]);
}
compWord.add(new String(tmp));
}
}
return compWord;
}
public static void main(String[] args){
String[][] a={{"g","y","r","a","r","b","i","l","e"},
{"u","a","a","n","c","h","o","r","i"},
{"i","b","y","d","v","e","x","t","r"},
{"t","z","c","h","y","n","e","q","u"},
{"a","m","a","n","g","o","d","v","q"},
{"r","n","i","h","p","l","o","d","l"},
{"f","o","r","e","s","t","u","d","y"},
{"j","d","l","w","a","r","c","h","u"},
{"h","a","v","g","h","y","e","t","y"}
};
WordPuzzle pn=new WordPuzzle(a,9);
pn.showPuzzle();
Set<String> str=new HashSet<String>();
str.add("library");
Set<String>wordFound=pn.searchWord(str);
for(String w:wordFound){
System.out.println("Found"+pn.searchWord(str));
}
}
}
You can rewrite your program, because it is so complex and hardly. First, replace strings to chars: you should have matrix of char, char[][] mat. Second, save all rows and columns to String:
String[] rows = ... // use new String(mat[i])
String[] columns = ... // transform matrix and see solution for rows
After this, use rows[i].indexOf or columns[i].indexOf.
Also, you can use rows[i].reverse().indexOf or columns[i].reverse().indexOf.
Sorry for my bad English

Overrided add isn't working

Add is supposed to be an overrided method in which the string is put in the arraylist in alphabetical order, but whenever I execute the program, the Arraylist is always in the order that I added it in.
Here's Test:
import java.util.*;
public class Test
{
private static ArrayList x=new ArrayList();
private static ArrayList<String> li=new ArrayList<String>();
private static SortedList s=new SortedList();
// private static Person p[]=new Person[4];
// private static Fraction f[]=new Fraction[5];
public static void main(String args[])
{
//number 1
x.add(5);
x.add(6);
x.add(1.5);
x.add(7);
x.add(2.5);
System.out.println(average(x,2)); //5.5
System.out.println(average(x,7)); //4.4
//number 2
li.add("Hi");
li.add("del");
li.add("there");
li.add("del");
li.add("you");
li.add("del");
System.out.println(li);
takeOut(li,"del");
System.out.println(li);
//number 3
s.add("dog");
s.add("anteater");
s.add("kewl");
s.add("kitty");
s.add("a");
System.out.println(s);
//number 4
// p[0]=new Person("Kremer","Jim");
//p[1]=new Person("Shi","Kevin");
// p[2]=new Person("Shi","Rebecca"); //I know I spelled your name wrong, Rebecca. (I needed two last names to be the same)
// p[3]=new Person("Herman", "Jimmy");
// Arrays.sort(p); //static method in java.util.Arrays
// for(int i=0; i<p.length; i++)
System.out.println(p[i].getFirstName()+" "+p[i].getLastName());
//number 5
f[0]=new Fraction(4,5);
f[1]=new Fraction(5,4);
f[2]=new Fraction(-8,3);
f[3]=new Fraction(6,5);
f[4]=new Fraction(-1,2);
Arrays.sort(f);
for(int i=0; i<f.length; i++)
System.out.println(f[i].getNum()+"/"+f[i].getDenom());
}
//number 1
public static Double average(ArrayList samples, int num)
{
double sum=0.0;
if(num>samples.size())
{
for(int i=0; i<samples.size(); i++)
{
if(samples.get(i) instanceof Integer)
sum+=(Integer)samples.get(i);
else
sum+=(Double)samples.get(i);
}
return sum/samples.size();
}
else
{
for(int i=0; i<num; i++)
{
if(samples.get(i) instanceof Integer)
sum+=(Integer)samples.get(i);
else
sum+=(Double)samples.get(i);
}
return sum/num;
}
}
//number 2
public static void takeOut(List<String> words, String del)
{
for(int i=0; i<words.size(); i++)
{
if(words.get(i).equals(del))
{
words.remove(i);
i--;
}
}
}
}
And here's SortedList:
import java.util.ArrayList;
import java.util.List;
import java.lang.String;
public class SortedList extends ArrayList<String>
{
private ArrayList<String> a;
public SortedList()
{
a = new ArrayList<String>(10);
}
public SortedList(int cap)
{
super(cap);
}
public boolean add(String x)
{
if(a.size()!=0)
{
for(int i=0; i<a.size(); i++)
{
if(i==a.size()-1)
if(x.compareTo(a.get(i))>=0)
super.add(x);
else
{
if(i==0)
if(x.compareTo(a.get(i))<=0)
super.add(0,x);
if(x.compareTo(a.get(i))>=0 && x.compareTo(a.get(i+1))<=0)
super.add(i+1,x);
}
}
}
else
super.add(x);
return true;
}
}
Thanks in advance!
a.size() != 0 is always false as your SortedList implementation doesn't add any elements in the list a. This results that super.add(x) is always used and the overridden add-method doesn't actually modify the behavior of an ArrayList
User,
Look up Java Collections interface. Java can sort these elements alphabetically for you:
ArrayList<String> a = new ArrayList<String>
a.add("world");
a.add("hello");
Collections.sort(a);
//sorted alphabetically now
If the default sort is the wrong direction, just implement your own Comparator and call:
Collections.sort(a, myComparator);
This should do what you are seeking, unless of course this is a homework assignment...

Categories