I'm trying to find all permutations of a word and add that to an Arraylist and return the array list. But, I believe my recursion is right but, there is a problem with adding the results to the ArrayList.This is what I have so far. The parameters I passed were "eat" and "" and what is returned is "tea" three times
public static ArrayList<String> permutations(String word, String beginning)
{
int l = word.length();
ArrayList<String> temp = new ArrayList<String>();
if(l == 0)
temp.add(beginning + word);
else
{
char c = word.charAt(l-1);
String blah = (beginning + c);
word = word.substring(0, l-1);
for(int i = 0; i < l; i++)
{
permutations(word, blah);
temp.add(blah + word);
}
}
return temp;
}
Probably I didn't have the right idea of your approach to find an easy fix and by the time I got things working I ended up with this. I hope it isn't too much of a departure and that it's still helpful. The output is:
[tea, tae, eta, eat, ate, aet]
import java.util.ArrayList;
public class Perm {
public static void main(String[] args) {
ArrayList<String> perms = new ArrayList<String>();
permutations("tea", perms);
System.out.println(perms);
}
public static ArrayList<String> permutations(String word, ArrayList<String> perms)
{
int l = word.length();
// If the word has only a single character, there is only
// one permutation -- itself. So we add it to the list and return
if (l == 1) {
perms.add(word);
return perms;
}
// The word has more than one character.
// For each character in the word, make it the "beginning"
// and prepend it to all the permutations of the remaining
// characters found by calling this method recursively
for (int i=0; i<word.length(); ++i) {
char beginning = word.charAt(i);
// Create the remaining characters from everything before
// and everything after (but not including) the beginning char
String blah = word.substring(0,i)+word.substring(i+1);
// Get all the permutations of the remaining characters
// by calling recursively
ArrayList<String> tempArray = new ArrayList<String>();
permutations(blah, tempArray);
// Prepend the beginning character to each permutation and
// add to the list
for (String s : tempArray) {
perms.add(beginning + s);
}
}
return perms;
}
}
Related
I want to write a method which finds the longest String (word). The output should be the longest word in case of two words with the same lenght the output should be: "More than one longest word".
I used ArrayList and almost had a solution, but something goes wrong. The case is that I have a problem when two words have the same lenght.
The output is :
More than one longest word
More than one longest word
14 incrementation is the longest word
Please check out piece of my code and help me to find the answer :)
public class LongestWord {
public static void main(String[] args) {
ArrayList<String> wordsList = new ArrayList<String>();
wordsList.add("december");
wordsList.add("california");
wordsList.add("cat");
wordsList.add("implementation");
wordsList.add("incrementation");
int largestString = wordsList.get(0).length();
int index = 0;
for (int i = 0; i < wordsList.size(); i++) {
if (wordsList.get(i).length() > largestString) {
largestString = wordsList.get(i).length();
index = i;
}else if(wordsList.get(i).length() == largestString){
largestString = wordsList.get(i).length();
index = i;
System.out.println("More than one longest word");
}
}
System.out.println(largestString +" " + wordsList.get(index) +" is the longest word ");
}
}
The fact is that you can't tell what the biggest word until you have iterated the whole list.
So iterate on the list
if word is bigger than previous largest size : clear list and save word
if word has same size as largest size : save word
if word is smaller : nothing
List<String> wordsList = Arrays.asList(
"december", "california", "cat",
"implementation", "incremntation");
int maxLength = Integer.MIN_VALUE;
List<String> largestStrings = new ArrayList<>();
for (String s : wordsList) {
if (s.length() > maxLength) {
maxLength = s.length();
largestStrings.clear();
largestStrings.add(s);
} else if (s.length() == maxLength) {
largestStrings.add(s);
}
}
if (largestStrings.size() > 1) {
System.out.println("More than one longest word");
System.out.println(largestStrings);
} else {
System.out.println(largestStrings.get(0) + " is the longest word");
}
Gives
More than one longest word
[implementation, incrementation]
azro is right. You can figure out the problem using two iteration. I m not sure but the code below works
for (int i = 0; i < wordsList.size(); i++) {
if (wordsList.get(i).length() > largestString) {
largestString = wordsList.get(i).length();
index = i;
}
}
for (int i = 0; i < wordsList.size(); i++) {
if (wordsList.get(index).length() == wordsList.get(i).length()) {
System.out.println("More than one longest word");
break;
}
}
You can do this with one loop iteration. Storing the longest word(s) as you go.
import java.util.*;
public class Test {
public static void main(String[] args) {
final Collection<String> words = Arrays.asList(
"december", "california", "cat",
"implementation", "incrementation");
final Collection<String> longestWords = findLongestWords(words);
if (longestWords.size() == 1) {
System.out.printf("The longest word is: %s\n", longestWords.iterator().next());
} else if (longestWords.size() > 1) {
System.out.printf("More than one longest word. The longest words are: %s\n", longestWords);
}
}
private static final Collection<String> findLongestWords(final Collection<String> words) {
// using a Set, so that duplicate words are stored only once.
final Set<String> longestWords = new HashSet<>();
// remember the current length of the longest word
int lengthOfLongestWord = Integer.MIN_VALUE;
// iterate over all the words
for (final String word : words) {
// the length of this word is longer than the previously though longest word. clear the list and update the longest length.
if (word.length() > lengthOfLongestWord) {
lengthOfLongestWord = word.length();
longestWords.clear();
}
// the length of this word is currently though to be the longest word, add it to the Set.
if (word.length() == lengthOfLongestWord) {
longestWords.add(word);
}
}
// return an unmodifiable Set containing the longest word(s)
return Collections.unmodifiableSet(longestWords);
}
}
My two cents to make it done in the single loop. Can be improved further.
ArrayList<String> wordsList = new ArrayList<String>();
wordsList.add("december");
wordsList.add("california");
wordsList.add("cat");
wordsList.add("implementation");
wordsList.add("incrementation");
String result;
int length = Integer.MIN_VALUE;
Map<String,String> map = new HashMap<>();
for(String word: wordsList){
if(word.length() >= length) {
length = word.length();
if (map.containsKey(String.valueOf(word.length())) || map.containsKey( "X" + word.length())) {
map.remove(String.valueOf(word.length()));
map.put("X" + word.length(), word);
} else {
map.put(String.valueOf(word.length()), word);
}
}
}
result = map.get(String.valueOf(length)) == null ? "More than one longest word" :
map.get(String.valueOf(length)) + " is the longest word";
System.out.println(result);
Here is one approach. I am using a set to hold the results as there is no reason to include duplicate words if they exist.
iterate over the words
if the current word length is > maxLength, clear the set and add the word, and update maxLength
if equal to the maxLength, just add the word.
List<String> wordsList = List.of("december", "implementation",
"california", "cat", "incrementation");
int maxLength = Integer.MIN_VALUE;
Set<String> results = new HashSet<>();
for (String word : wordsList) {
int len = word.length();
if (len >= maxLength) {
if (len > maxLength) {
results.clear();
maxLength = len;
}
results.add(word);
}
}
System.out.printf("The longest word%s -> %s%n", results.size() > 1 ? "s" : "", results);
prints
The longest words -> [implementation, incrementation]
I changed your code to suggest a different approach to the problem. Honestly, I hope you'll find it fascinating and helpful.
There are two different fashion of it, one that doesn't care about finding more than one longest word (it stamps just the first one - but you can change it as you prefer), and the other one that does.
First solution:
`
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class LongestWord {
public static void main(String[] args) {
List<String> wordsList = new ArrayList<>();
wordsList.add("december");
wordsList.add("california");
wordsList.add("cat");
wordsList.add("implementation");
wordsList.add("incrementation");
wordsList.stream()
.max(LongestWord::compare)
.ifPresent(a -> System.out.println(a.toUpperCase() + " is the longest word with length of: " + a.length()));
}
private static int compare(String a1, String b1) {
return a1.length() - b1.length();
}
}
`
Second solution:
`
public class LongestWord {
public static void main(String[] args) {
List<String> wordsList = new ArrayList<>();
wordsList.add("december");
wordsList.add("california");
wordsList.add("cat");
wordsList.add("implementation");
wordsList.add("incrementation");
int max_length = wordsList.stream()
.max(LongestWord::compare)
.map(String::length).orElse(0);
List<String> finalWordsList = wordsList.stream()
.filter(word -> word.length() == max_length)
.collect(Collectors.toList());
if (finalWordsList.size() > 1) {
System.out.println("More than one longest word");
} else {
System.out.println(finalWordsList.get(0) + " is the longest word");
}
}
private static int compare(String a1, String b1) {
return a1.length() - b1.length();
}
}
`
This assignment ask to implement printWordRun so that it prints whatever word run it can find starting from the beginning of the input list words. The word run should be printed in reverse order, with each word on a separate line. PrintWordRun is a method which takes a parameter called words which is an ArrayList<String>. The word run is a series of words in the input list, where each word is longer in length than the previous. The word run ends once we either encounter the end of the list, or we encounter a word whose length is equal to or shorter than the previous word.
The array is:
I
am
cat
with
happy
dog
sitting
the result should be:
happy
with
cat
am
I
To get full credit for this assignment, I have to use a stack to print it as I have done, but I cannot get the word "happy" into the stack. My output is:
I
am
cat
with
public class Program {
private void printWordRun(ArrayList<String> words) {
// Here is the code I Wrote.
Stack<String> wordRun = new Stack<>();
for(int i = 1; i < words.size(); i++) {
String str1 = words.get(i-1);
String str2 = words.get(i);
if(str2.length() < str1.length()) {
break;
}
if(str1.length() < str2.length()){
wordRun.push(str1);
}
System.out.println(wordRun);
}
}
public static void main(String[] args) {
Program program = new Program();
program.testPrintWordRun();
}
private void testPrintWordRun() {
ArrayList<String> words = new ArrayList<>();
words.add("I");
words.add("am");
words.add("cat");
words.add("with");
words.add("happy");
words.add("dog");
words.add("sitting");
System.out.println("Testing printWordRun...");
printWordRun(words);
System.out.println();
}
}
Here is one way to construct the printWordRun function:
Stack<String> wordRun = new Stack<>();
int maxLength = 0;
for(String s : words) {
if(s.length() > maxLength ) {
maxLength = s.length();
wordRun.add(s);
} else
break;
}
while(!wordRun.isEmpty())
System.out.println(wordRun.pop());
Just store a value of the current, maximum length and use this to compare your current string.
Output:
Testing printWordRun...
happy
with
cat
am
I
Start by adding the word to the stack with add(int index, E element) to insert the last item as first, and break the loop if the condition doesn't match afterwards.
private void printWordRun(ArrayList<String> words) {
// Here is the code I Wrote.
Stack<String> wordRun = new Stack<>();
for (int i = 1; i < words.size(); i++) {
String str1 = words.get(i);
String str2 = words.get(i - 1);
wordRun.add(0, str2);
if(str2.length() >= str1.length()) {
break;
}
}
System.out.println(wordRun); // [happy, with, cat, am, I]
}
I have a string that has no spaces and I wanted to create an array that consists of the substrings of the word. For instance, let the string is stackoverflow The array should be like:
[sta, cko, ver, flo, w]
The code that I use is below and that does give me only the first item. Any help will be appreciated.
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i=i+3){
words.add(s.substring(i, 3));
}
return words;
}
There are two issues with your code. First, the "3" in
s.substring(i, 3)
means the 3rd index from the beginning of the string, not the 3rd index from i, so you'd want
s.substring(i, i + 3)
Second, if the string is shorter than i + 3, you'll get an exception. To solve this, you can use Math.min. It would look something like this:
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i=i+3){
words.add(s.substring(i, Math.min(i + 3, i.length())));
}
return words;
}
You need to pass i + 3 as the second parameter of the substring call (it takes begin and end indexes). Also, I would prefer to program to the List interface. You might use += instead of i = i + 3. And you need an else clause for when there aren't three letters in the String. Like,
public static List<String> getWords(String s) {
List<String> words = new ArrayList<>();
for (int i = 0; i < s.length(); i += 3) {
if (i + 3 < s.length()) {
words.add(s.substring(i, i + 3));
} else {
words.add(s.substring(i));
}
}
return words;
}
Then, for completeness, I tested it with a basic main method like
public static void main(String[] args) {
System.out.println(getWords("stackoverflow"));
}
Which outputs (as requested)
[sta, cko, ver, flo, w]
You are on the right track, but your substring should be (i, i+3) as the following:
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i+=3){
if (i+3 >= s.length())
words.add(s.substring(i));
else
words.add(s.substring(i, i+3));
}
return words;
You can ease it significantly by using guava's Splitter:
String f = "stackoverflow";
List<String> p = Splitter.fixedLength(3).splitToList(f);
System.out.println(p); // [sta, cko, ver, flo, w]
I have a String ArrayList consisting alphabets followed by a digit as a suffix to each of the alphabet.
ArrayList <String> baseOctave = new ArrayList();
baseOctave.add("S1");
baseOctave.add("R2");
baseOctave.add("G4");
baseOctave.add("M2");
baseOctave.add("P3");
baseOctave.add("D1");
baseOctave.add("N1");
I pass the strings from this baseOctave and few other characters as input pattern for creating an object.
MyClass obj1 = new MyClass ("S1,,R2.,M2''-");
Since I frequently make use of these kind of input patterns during object instantiation, I would like to use simple characters S, R, G, M etc.
Ex:
MyClass obj1 = new MyClass ("S,,R.,M''-");
MyClass obj2 = new MyClass ("S1,G.,M,D1");
So the alphabets used during object creation may contain digits as suffix or it may not have digit as suffix.
But inside the constructor (or in separate method), I would like to replace these simple alphabets with alphabets having suffix. The suffix is taken from the baseOctave.
Ex: above two strings in obj1 and obj2 should be "S1,,R2.,M2''-" and "S1,G4.,M2,D1"
I tied to do this, but could not continue the code below. Need some help for replacing please..
static void addSwaraSuffix(ArrayList<String> pattern) {
for (int index = 0; index < pattern.size(); index++) {
// Get the patterns one by one from the arrayList and verify and manipulate if necessary.
String str = pattern.get(index);
// First see if the second character in Array List element is digit or not.
// If digit, nothing should be done.
//If not, replace/insert the corresponding index from master list
if (Character.isDigit(str.charAt(1)) != true) {
// Replace from baseOctave.
str = str.replace(str.charAt(0), ?); // replace with appropriate alphabet having suffix from baseOctave.
// Finally put the str back to arrayList.
pattern.set(index, str);
}
}
}
Edited information is below:
Thanks for the answer. I found another solution and works fine. below is the complete code that I found working. Let me know if there is any issue.
static void addSwaraSuffix(ArrayList<String> inputPattern, ArrayList<String> baseOctave) {
String temp = "";
String str;
for (int index = 0; index < inputPattern.size(); index++) {
str = inputPattern.get(index);
// First see if the second character in Array List is digit or not.
// If digit, nothing should be done. If not, replace/insert the corresponding index from master list
// Sometimes only one swara might be there. Ex: S,R,G,M,P,D,N
if (((str.length() == 1)) || (Character.isDigit(str.charAt(1)) != true)) {
// Append with index.
// first find the corresponsing element to be replaced from baseOctave.
for (int index2 = 0; index2 < baseOctave.size(); index2++) {
if (baseOctave.get(index2).startsWith(Character.toString(str.charAt(0)))) {
temp = baseOctave.get(index2);
break;
}
}
str = str.replace(Character.toString(str.charAt(0)), temp);
}
inputPattern.set(index, str);
}
}
I assume that abbreviation is only one character and that in full pattern second character is always digit. Code below relies on this assumptions, so please inform me if they are wrong.
static String replace(String string, Collection<String> patterns) {
Map<Character, String> replacements = new HashMap<Character, String>(patterns.size());
for (String pattern : patterns) {
replacements.put(pattern.charAt(0), pattern);
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
Character c = string.charAt(i);
char next = i < string.length() - 1 ? string.charAt(i + 1) : ' ';
String replacement = replacements.get(c);
if (replacement != null && (next <= '0' || next >= '9')) {
result.append(replacement);
} else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
ArrayList<String> baseOctave = new ArrayList<String>();
baseOctave.add("S1");
baseOctave.add("R2");
baseOctave.add("G4");
baseOctave.add("M2");
baseOctave.add("P3");
baseOctave.add("D1");
baseOctave.add("N1");
System.out.println(replace("S,,R.,M''-", baseOctave));
System.out.println(replace("S1,G.,M,D1", baseOctave));
System.out.println(replace("", baseOctave));
System.out.println(replace("S", baseOctave));
}
Results:
S1,,R2.,M2''-
S1,G4.,M2,D1
S1
I was trying out this question :
Write a function using Recursion to display all anagrams of a string entered by the user, in such a way that all its vowels are located at the end of every anagram. (E.g.: Recursion => Rcrsneuio, cRsnroieu, etc.) Optimize it.
From this site :
http://erwnerve.tripod.com/prog/recursion/magic.htm
This is what i have done :
public static void permute(char[] pre,char[] suff) {
if (isEmpty(suff)) {
//result is a set of string. toString() method will return String representation of the array.
result.add(toString(moveVowelstoEnd(pre)));
return;
}
int sufflen = getLength(suff); //gets the length of the array
for(int i =0;i<sufflen;i++) {
char[] tempPre = pre.clone();
char[] tempSuf = suff.clone();
int nextindex = getNextIndex(pre); //find the next empty spot in the prefix array
tempPre[nextindex] = tempSuf[i];
tempSuf = removeElement(i,tempSuf); //removes the element at i and shifts array to the left
permute(tempPre,tempSuf);
}
}
public static char[] moveVowelstoEnd(char[] input) {
int c = 0;
for(int i =0;i<input.length;i++) {
if(c>=input.length)
break;
char ch = input[i];
if (vowels.contains(ch+"")) {
c++;
int j = i;
for(;j<input.length-1;j++)
input[j] = input[j+1];
input[j]=ch;
i--;
}
}
return input;
}
Last part of the question is 'Optimize it'. I am not sure how to optimize this. can any one help?
Group all the vowels into v
Group all consonants into w
For every pair of anagrams, concat the results