How do you solve this problem with a nested for loop - java

My goal is to print out names with 2 letters that are the same with only one of the same letter in the name. For example brook would be printed out as brok and michelle would be printed out as michel. Whats wrong with my code?
for(int a = 0; a < word_1.length(); a++)
{
mychar = word_1.charAt(a);
for(int c = 1; c <word_1.length(); c++)
{
mychar_2 = word_1.charAt(c);
if(mychar == mychar_2)
{
word_3 = word_3 + "";
}
else
{
word_3 = word_3 + mychar;
}
}
}
System.out.println(word_3);

Better question is "what is right with the code". Basically the idea looks like going through all letters and then going through all matches. This is not too bad and we can slightly change your code to make it work (see comments):
for(int a = 0; a < word_1.length(); a++)
{
char mychar = word_1.charAt(a);
// flag for matching letters
Boolean found = false;
// you go through only previous characters!
for(int c = 0; !found && c < a; c++)
{
char mychar_2 = word_1.charAt(c);
if(mychar == mychar_2)
{
found = true;
}
}
// here you add character if no match found
if(!found) {
word_3 = word_3 + mychar;
}
}
This is a good way in academic coding, but in actual project if you deal with large numbers of words, you have to consider Map based solution to keep all existing letters and iterate only once through each word. Or you can search for some methods in numerous java libraries to do the job

This would solve the problem:
String testWord = "brook";
List<String> testSet = new ArrayList<String>();
for (int i = 0; i < testWord.length(); i++) {
if (!testSet.contains(String.valueOf(testWord.charAt(i)))) {
testSet.add(String.valueOf(testWord.charAt(i)));
}
}
StringBuilder builder = new StringBuilder();
for (Object s : testSet.toArray()) {
builder.append((String) s);
}
String str = builder.toString();
System.out.println(str);

Related

how to merge two strings into one by using chartAt() and arrays technique

as mentioned in the title, I got an error in each line inside for loop which says (variable expected) and this is my code
String s = "ABC";
String t = "DEFGH";
String merge = "";
// merge should looks like "ADBECFGH"
int i = 0;
for (; i < s.length(); i=i+2) {
merge.charAt(i) = s.charAt(i/2);
merge.charAt(i+1) = t.charAt(i/2);
}
for (; i < t.length()+s.length() ; i++) {
merge.charAt(i) = t.charAt(i-s.length());
}
am trying to use same technique with arrays which I think its very effective.
If you like take one letter from first string and then from other try this:
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge += String.valueOf(s.charAt(i));
}
if (i < t.length()) {
merge += String.valueOf(t.charAt(i));
}
}
This is condition that let you iterate till longer String finish
i < s.length() || i < t.length()
Another one, since you are manipulating Strings inside a loop, it is better to use StringBuilder instead of String.
String s = "ABC";
String t = "DEFGH";
StringBuilder merge = new StringBuilder();
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge.append(s.charAt(i));
}
if (i < t.length()) {
merge.append(t.charAt(i));
}
}
System.out.println(merge.toString());
The method charAt(int index) returns the character at the specified index(IT IS A GETTER NOT A SETTER). You cannot use it as
merge.charAt(i) = s.charAt(i/2)
one of the easiest ways to perform such operation is to use string operation such as concatination as shown in the below example
s="abc";
t="def";
System.out.print(s.concat(t));
You could simply use the .concact() method without using the for loop:
so your code would look like:
merge = s.concat(t);
try this : concatenate two string without inbuilt method and without + operator.
public static void main(String[] args) {
String s = "ABC";
String s1 = "DEF";
String merge = "";
char[]ch = new char[120];
for(int i=0;i<s.length();i++) {
ch[i] = s.charAt(i);
}
for(int i = 0;i<s1.length();i++) {
ch[s.length()+i] = s1.charAt(i);
}
System.out.println(ch);
}
CharacterIterator a = new StringCharacterIterator("haaaaallo");
CharacterIterator b = new StringCharacterIterator("12345");
StringBuilder output = new StringBuilder();
if(a.getEndIndex() < b.getEndIndex()) { //true -> swap a and b
CharacterIterator holder = a;
a = b;
b = holder;
}
while (a.current() != CharacterIterator.DONE) {
output.append(a.current());
while (b.current() != CharacterIterator.DONE) {
output.append(b.current());
break;
}
a.next();
b.next();
}
System.out.println(output.toString()); //h1a2a3a4a5allo
To show "the manual way". The used Strings can be any size.
I would go with #Bartek's answer its simple and easy to remember..
the complicated way to achieve this would be
String a = "abcdefgh";
String b = "ijklmnopqrst";
int i = 0;
StringBuilder merge = new StringBuilder();
for (; i < a.length() && i < b.length(); i++) {
merge.append(a.charAt(i)).append(b.charAt(i));
}
if (i < a.length())
merge.append(a.substring(i));
if (i < b.length())
merge.append(b.substring(i));
Only to avoid having if conditions inside the for loop.. (optimal only in case of large strings, strings of vastly different lengths)

How can I create all vowel combinations of a String and add each combination to an ArrayList

I'm having trouble printing off all vowel combinations of a given input. My input is "SOMETHING" and I would like to print off all vowel combinations such as sxmxthxng where x is aeiou vowels. I believe my problem is that I find a vowel, change it with all the others vowels and move on. I need to continue down the rest of the word and find additional vowels and change those before proceeding.
Other refs
vowelList is an ArrayList containing all lower case vowels.
Code
private static void createVowelCombos(String word) {
Set<String> rmRepeats = new HashSet<>();
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
for (int i = 0; i < word.length(); i++) {
// System.out.println("real word: " + splitWord[i]);
if (splitWord[i].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(i, vowelList.get(j).charAt(0));
System.out.println(sbAddWord.toString());
}
}
}
}
Sample Output with input "SOMETHING"
samething
semething
simething
something
sumething
sumathing
sumething
sumithing
sumothing
sumuthing
sumuthang
sumutheng
sumuthing
sumuthong
sumuthung
For some reason it is giving me all the combinations with 'u' but not the other vowels. I would like to get all the results for the other vowels as well.
as already suggested your problem can be best solved by using recursion (with backtracking). I've modified your code so as to print the required output. Have a look !!
private static void createVowelCombos(String word, int start) {
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
if(start==splitWord.length)
{
System.out.println(word);
return;
}
if (splitWord[start].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(start, vowelList.get(j).charAt(0));
createVowelCombos(sbAddWord.toString(),start+1);
//System.out.println(sbAddWord.toString());
}
}
else
createVowelCombos(sbAddWord.toString(),start+1);
}
Call createVowelCombos("something",0) from the calling method.

Get the meaning of a word/ String array

So this is the continuation of my question from this thread: here
String[] words = {"cowboy", "animal", "monster"};
String[] meanings = {"meaning1", "meaning2", "meaning3"};
boolean check = false;
for (int i = 0; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
} else {
}
}
if (check) {
System.out.println("Yes");
} else {
System.out.println("No");
}
But I can't seem to figure out how and where to put the specific meaning of each word that has been typed by the user in the edittext. Any help would be gladly appreciated. Thanks.
static String[] words = { "Cowboy", "animal", "monster" };
static String s = "My animal is a Cowboy";
static boolean check = false;
static String[] meanings = {"meaning1", "meaning2", "meaning3"};
static ArrayList<String> typed_words = new ArrayList<String>();
static ArrayList<String> typed_meanings = new ArrayList<String>();
for (int i = 0; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
typed_words.add(words[i]);
typed_meanings.add(meanings[i]);
check = true;
} else {
}
}
if (check) {
System.out.println("Yes");
for(int i=0;i<typed_words.size();i++){
System.out.println("Word: "+typed_words.get(i)+" Meaning: "+typed_meanings.get(i));
}
} else {
System.out.println("No");
}
what about something like that?
int index;
...
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
index = i;
} else {
....
if (check) {
System.out.println(meanings[index]);
} else {
...
If the words and their meanings have the same relative positions in the two arrays then re-use the index i to print the corresponding meaning as well. But, the i would now have to be defined outside the loop so that it has a bigger scope now and is available inside the if check.
int i = 0
for (; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
break;
}
}
if (check) {
System.out.println("Meaning found: " + meanings[i]);
}
Since words and meanings arrays have the relative indexing, you can-
boolean check = false;
for (int i = 0; i < words.length; i++) {
if (s.equalsIgnoreCase(words[i])) { // We don't need "toLowerCase"
System.out.println("Word: " + words[i] + "\tMeaning: " + meanings[i]);
check = true;
break; // Match found; so get out of the loop
}
}
if(check){
System.out.println("Found!");
} else {
System.out.println("Not Found!");
}
Why not use a java.util.HashMapin which every word maps to a meaning?
String s = "";
HashMap<String,String> meaningMap = new HashMap<String,String>();
//just for the example
meaningMap.put("cowboy", "meaning1");
...
if (s.toLowerCase().contains(words[i].toLowerCase())) {
ouput = meaningMap.get(s);
}
...
System.out.println(s);
Another idea would be to use HashMap to store your data.
HashMap hm = new HashMap();
hm.put("cowboy", "meaning1");
hm.put("animal", "meaning2");
And then use
String s = yourEdittext.getText();
String[] words = s.split("\s+");
for (int i = 0; i < words.length(); i++) {
words[i] = words[i].replaceAll("[^\w]", "");
}
for (int i=0; i < words.length(); i++) {
if (hm.containsKey(words[i])) {
System.out.println("Meaning found: " + hm.get(words[i]));
}
}
This basically gets the sentece form the edittext, splits it into words then checks if each word is in the HashMap. This is good if your list of words is going to be quite big in comparison to the length of the sentence.
i would suggest that you make a Hashmap<String ,ArrayList<String>>
as you have more than one meaning for oneword.
so now just passing the word you need to find the meaning for.
you can.also use treemap if you need to store them in a sorted fashion.
so here's how you can find the meaning for a word .
ArrayList<String> meaning =map.get("cowboy");
for(String string : meaning ) {
Log.v("meaning",string);
}

How to Search a string array for specific strings

I am trying to search an array for a couple of specific strings that I get from words in a sentence. Eventually this sentence will be in-putted by the user but I have hard coded it in at the moment to make testing easier.If the program finds the strings it should return with "Yes" and "No" if it doesn't. The problem is that I am getting yes all the Time.
public class main {
public static void main(String[]args)
{
String Sentence = "This is a sentence";
String[] CensorList =
{"big","head"};
String[] words = Sentence.split(" ");
System.out.println(words.length);
boolean match = false;
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals(CensorList[j]))
{
match = true;
}else{
match = false;
}
}
}
if (match = true){
System.out.println("Yes");}
else{
System.out.println("No");
}
}
}
I would really appreciate any help with this one, Thanks in advance.
the if in your second for() has wrong braces.
try this one:
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j])) {
match = true;
System.out.println("Yes");
} else {
System.out.println("No");
}
match = false;
}
for your second try:
the
if (match = true)
does not compare match with true, it sets the match flag to true, which results always in true.
compare the flag in your if:
if (match == true) // or simply if (match)
{ ....
Try it:
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j]))
match = true;
}
if (match) {
System.out.println("Yes"); }
else {
System.out.println("No"); }
match = false;
}
I think you have some typos in here.
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j]));
}
This will do essentially nothing, as the if has nothing to do if the expression is evaluated to true. Then after the loop you set match to true, so it will be true always, and it will always print "Yes"
You can use a simple RegEx based solution for this
private static boolean test(String value) {
String[] CensorList = { "This", "No" };
for (String string : CensorList) {
Pattern pattern = Pattern.compile("\\b" + string + "\\b", Pattern.CASE_INSENSITIVE);
if (pattern.matcher(value).find()) {
return true;
}
}
return false;
}
Then
String string = "This is a sentence";
if(test(string)){
System.out.println("Censored");
}
Any reason you are not using String.indexOf(String) ?
Another issue is if you are doing this repeatedly for the same (very large) stirng in which case, you might want to look into more sophisticated algorithms like suffix trees or even use specialized software like Apache Lucene
Try to use
public class main {
public static void main(String[]args)
{
String Sentence = "This is a sentence";
String[] CensorList =
{"This","No"};
String[] words = Sentence.split(" ");
System.out.println(words.length);
boolean match = false;
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].compareTo(CensorList[j])==0)
{
System.out.println("Yes");
}
else{System.out.println("No");}
}
}
}

Fibonacci Words from ACM Contest

I'm trying to figure out how to solve one of the problems from one of the ACM ICPC finals (from 2012, so I guess the most recent). It's called Fibonacci Words and is described here under Problem D.
I think I'm very close, as all the test cases except the last are giving the correct answer. But for the last, I'm getting 6440026026380244497, which is on the right order of magnitude but still way off--since the order of magnitude is huge. :)
Here's my Java code, with a lot of comments (too many, you think? could it be refactored?):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class FibonacciWords {
public static StringBuilder[] updateChars(StringBuilder lastOneBack, StringBuilder firstTwoBack, StringBuilder lastTwoBack, StringBuilder firstThreeBack) {
int pattLen = lastOneBack.length();
StringBuilder[] newChars = new StringBuilder[2];
newChars[0] = new StringBuilder(pattLen); // will become the new lastOneBack!
newChars[1] = new StringBuilder(pattLen); // will become the new firstTwoBack!
if(lastOneBack.charAt(0) == 'E') { // lastOneBack not full yet
int shiftCharsBy = 0; // holds amount to shift lastOneBack by
for(int i = 0; i < pattLen; i++) {
if(firstTwoBack.charAt(i) != 'E') {
shiftCharsBy++; // need to move whatever is at beginning of firstTwoBack to end of lastOneBack
} else {
break; // when first 'E' is reached in firstTwoBack, the rest are 'E' also
}
}
for(int i = 0; i < pattLen-shiftCharsBy; i++) {
newChars[0].append(lastOneBack.charAt(i+shiftCharsBy)); // shift lastOneBack by shiftCharsBy characters
}
for(int i = 0; i < shiftCharsBy; i++) {
newChars[0].append(firstTwoBack.charAt(i)); // fill remainder of new lastOneBack with what's in firstTwoBack
}
} else { // lastOneBack already full
newChars[0] = lastTwoBack; // make lastOneBack lastTwoBack (following pattern)
}
if(firstTwoBack.charAt(pattLen-1) == 'E') { // firstTwoBack not full yet
if(lastOneBack.charAt(0) == 'E') {
for(int i = 1; i < pattLen; i++) {
if(lastOneBack.charAt(i) != 'E') {
newChars[1].append(lastOneBack.substring(i)); // move last characters of lastOneBack to front of new firstTwoBack
break;
}
}
int charsAdded = newChars[1].length();
for(int i = 0; i < pattLen-charsAdded; i++) {
newChars[1].append('E'); // fill whatever might remain with 'E'
}
} else {
//newChars[1] = lastOneBack;
for(int i = 0; i < pattLen; i++) {
if(firstTwoBack.charAt(i) != 'E') {
newChars[1].append(firstTwoBack.charAt(i));
} else {
break;
}
}
int charsAdded = newChars[1].length();
// now take from firstThreeBack--which also isn't full if firstTwoBack isn't--until pattLen is reached
for(int i = 0; i < pattLen-charsAdded; i++) {
newChars[1].append(firstThreeBack.charAt(i));
}
}
} else {
newChars[1] = firstTwoBack; // firstTwoBack doesn't change when already full
}
return newChars;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String pattern = br.readLine();
long numPattTwoPrior = 0; // number of times pattern occurred in F(n-2)
if(pattern.equals("0")) {
numPattTwoPrior++; // since n starts at 2 below, increment this if pattern is F(0), or "0"
}
long numPattOnePrior = 0; // number of times pattern occurred in F(n-1)
if(pattern.equals("1")) {
numPattOnePrior++; // since n starts at 2 below, increment this if pattern is F(1), or "1"
}
int pattLen = pattern.length();
StringBuilder lastCharsInOnePrior = new StringBuilder(pattLen); // keeps track of last pattLen characters in F(n-1)
for(int i = 0; i < pattLen; i++) {
lastCharsInOnePrior.append('E'); // 'E' stands for empty
}
lastCharsInOnePrior.setCharAt(pattLen-1, '1'); // since F(1) = "1"
StringBuilder firstCharsInTwoPrior = new StringBuilder(pattLen);
for(int i = 0; i < pattLen; i++) {
firstCharsInTwoPrior.append('E');
}
firstCharsInTwoPrior.setCharAt(0, '0'); // since F(0) = "0"
StringBuilder lastCharsInTwoPrior = null; // last characters always the same as 2 back, so keep track of this
StringBuilder firstCharsInThreePrior = null; // used for special case in updateChars
// number of times pattern occurs in F(n)
long numPattCurr = (n == 0) ? numPattTwoPrior : (n == 1) ? numPattOnePrior : 0;
for(int i = 2; i <= n; i++) { // finding F(n) up to the n given by the input
numPattCurr = numPattTwoPrior + numPattOnePrior; // at least this many times in F(n)
// adding to above all patterns found as part of concatenating F(n-1) and F(n-2), but not either on its own
middle:
for(int j = 1; j < pattLen; j++) { // starting at pos. 1 b/c [0, pattLen) is all F(n-1)
if(lastCharsInOnePrior.charAt(j) == 'E') {
continue;
}
StringBuilder compareWith = new StringBuilder(pattLen); // to compare with pattern
for(int k = 0; k < pattLen; k++) {
if(j + k >= pattLen) { // reached end of characters in F(n-1), start checking F(n-2)
int posInFirstChars = (j + k) % pattLen;
if(firstCharsInTwoPrior.charAt(posInFirstChars) == 'E') {
break middle; // none of the remaining overlap between F(n-1) and F(n-2) is as long as pattern, so can stop here
} else {
compareWith.append(firstCharsInTwoPrior.charAt(posInFirstChars));
}
} else {
compareWith.append(lastCharsInOnePrior.charAt(j + k));
}
}
if(pattern.equals(compareWith.toString())) {
numPattCurr++; // this overlap matched pattern
}
}
// changing characters of F(n-1) and F(n-2), as needed, for next iteration
StringBuilder[] updatedChars = updateChars(lastCharsInOnePrior, firstCharsInTwoPrior, lastCharsInTwoPrior, firstCharsInThreePrior);
lastCharsInTwoPrior = lastCharsInOnePrior;
firstCharsInThreePrior = firstCharsInTwoPrior;
lastCharsInOnePrior = updatedChars[0];
firstCharsInTwoPrior = updatedChars[1];
// changing number of times pattern found for F(n-1) and F(n-2) for next iteration
numPattTwoPrior = numPattOnePrior;
numPattOnePrior = numPattCurr;
}
System.out.println(numPattCurr);
System.exit(0);
}
}
I think I only left in one line of commented code, which gave the exact same answers in all the test cases when that was the only line within its else block--though what I replaced it with is more correct.
Any suggestions on what I'm missing or how I might go about debugging the last test case? Or interested in talking it through with someone because you're preparing for the contest or just working on learning algorithms? Please let me know.
C++ solution with verification (online judge)

Categories

Resources