Delete letter from string in a for loop - java

How can i get the letter from guess out of alphabet? So if the first guess is AABB i need to get the A and the B out of the String alphabet to make a new random guess without the letters A and B.
randomCode.clear();//Clears the random code ArrayList to put a new one in it
Random r = new Random();
String alphabet = "ABCDEF";
StringBuilder result = new StringBuilder(randomCode.size());
if(turn == 0){
guess = "AABB";
}else{
if(blackPin == 0 && whitePin ==0){
for (int c = 0; c < 4; c++) {
if(alphabet.charAt(c) == guess.charAt(c)){
}
randomCode.add(alphabet.charAt(r.nextInt(alphabet.length())));//generate 4 random letters with the letters ABCDEF and put in arrayList
}
for (Character c : randomCode){//Converts Char[] randomCode to a String
result.append(c);
}
guess = result.toString();//Gives the String guess 4 random letters.

If you have an ArrayList, for example:
ArrayList<Character> alphabet = new ArrayList<>(Arrays.asList('A', 'B', 'C', 'D'));
And a String:
String guess = "AABB";
You can remove from the alphabet each letter which occurs in the guess as shown:
for (int i = 0; i < guess.length(); i++)
alphabet.remove(new Character(guess.charAt(i)));
Now, if print out the alphabet:
for (int i = 0; i < alphabet.size(); i++)
System.out.print(alphabet.get(i));
the output will be: "CD".
You can use this all together:
ArrayList<Character> alphabet = new ArrayList<>(Arrays.asList('A', 'B', 'C', 'D'));
Random random = new Random();
String guess = "";
while (true) {
/* init a guess */
guess = "";
for (int j = 0; j < 4; j++)
guess += alphabet.get(random.nextInt(alphabet.size()));
System.out.println("The guess is: " + guess);
/* remove letters */
for (int j = 0; j < guess.length(); j++)
alphabet.remove(new Character(guess.charAt(j)));
/* the alphabet is empty */
if (alphabet.isEmpty()) {
System.out.println("The alphabet is empty");
break;
}
}

Why loop when you can avoid it:
String abd = "ABCDEF";
String guess = "AABB";
System.out.println(abd.replaceAll(String.join("|", guess.split("")), ""));
This prints:
CDEF

The most efficient way of doing this is to exploit the fact that the ASCII codes of the letters are 26 consecutive integers, and cast from char to int. Codes 65-68 are ABCD.
http://www.ascii-code.com/

Related

A series of String Manipulation Operations with counter in Java

Question:
The below string contains multiple words each separated by hash(#).
After splitting each word by #,
Reverse each character in words.
Start the counter form 1 for each word.
Find the character a,e,i,o,u and if you find the character then replace it with counter value and increment to 1.
Reset the counter for each word.
Print the final string.
Print the string at the end.
Example:
Input: my#name#is#manan
Output: ym 1m2n s1 n1n2m
My Code is :
import java.lang.*;
import java.io.*;
import java.util.*;
class StrSplit {
public static void main(String[] args) {
String sentence = "my#name#is#manan";
String[] word = sentence.split("#");
String[] reverseword = new String[word.length];
for (int i = 0; i < word.length; i++) {
StringBuilder revword = new StringBuilder(word[i]); // METHOD FOR USING .reverse()
revword.reverse(); // REVERSING
reverseword[i] = revword.toString(); // SAVING REVERSED WORDS INTO AN ARRAY.
}
for (int i = 0; i < reverseword.length; i++) {
int counter = 1;
String current = reverseword[i]; //SELECTING A WORD
for (int j = 0; j < current.length(); j++) {
char ch = current.charAt(j); //SELECTING A CHARACTER
char count=(char)(counter+ '0'); //VOWEL COUNTER
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
current = current.replace(current.charAt(j),count); //REPLACE VOWEL WITH NUMBER
counter++;
}
}
counter=1;
StringBuilder output= new StringBuilder(current);
output.append(' ');
System.out.print(output);
}
}
}
But there is one error in my output. My output is :
ym 1m2n s1 n1n1m
While it should have been :
ym 1m2n s1 n1n2m
The problem is, the counter is only incrementing if the vowels are not the same.
current.replace(current.charAt(j),count) replaces all the occurrences of current.charAt(j), so if the same vowel appears multiple times, you replace all of its occurrences in a single call, and increment the counter just once.
You can replace just the first occurrence if you change
current = current.replace(current.charAt(j),count);
to
current = current.replaceFirst(current.substring(j,j+1),Integer.toString(counter));
This way the counter will be incremented once for each replaced character.
Now the output is:
ym 1m2n s1 n1n2m
Note that replaceFirst() expects String arguments, instead of char.
Make reverseword an array of StringBuilder and use method replace of class java.lang.StringBuilder. You also use less variables and fewer manipulations.
String sentence = "my#name#is#manan";
String[] word = sentence.split("#");
StringBuilder[] reverseword = new StringBuilder[word.length];
for (int i = 0; i < word.length; i++) {
reverseword[i] = new StringBuilder(word[i]); // METHOD FOR USING .reverse()
reverseword[i].reverse(); // REVERSING
}
for (int i = 0; i < reverseword.length; i++) {
int counter = 1;
for (int j = 0; j < reverseword[i].length(); j++) {
char ch = reverseword[i].charAt(j); // SELECTING A CHARACTER
String count = String.valueOf(counter); // VOWEL COUNTER
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
reverseword[i].replace(j, j + 1, count); // REPLACE VOWEL WITH NUMBER
counter++;
}
}
// counter = 1; <- not required
StringBuilder output = new StringBuilder(reverseword[i]);
output.append(' ');
System.out.print(output);
}
Running above code produces following output:
ym 1m2n s1 n1n2m

Nested for loop, not picking up first instance in Array

I am trying to encode a word, and I am not sure why my for loops aren't picking up the first instance, 0. The input for this method is "This" and 3. The output from this method is klv. So my loop must not be working properly as the letter T is getting skipped. What is wrong with my loops?
String encodeWord(String word, int Shift) {
//word = "This"
//Shift = 3, is how far the letter is shifted to the right of the original
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
char[] temp = word.toCharArray();
char[] FA = new char[temp.length];
String tempWord = "";
StringBuilder sb = new StringBuilder(64);
for (int x = 0; x < word.length(); x++) {
for (int y = 0; y < alphabet.length; y++) {
if (word.charAt(0) == alphabet[y]) {
FA[0] = alphabet[y + shift];
System.out.println(FA[0]);
}
}
}
for (int i = 0; i < word.length(); i++) {
for (int j = 0; j < alphabet.length; j++) {
if (word.charAt(i) == alphabet[j]) {
FA[i] = alphabet[j + shift];
sb.append(FA[i]);
System.out.println(FA[i]);
}
}
}
System.out.println(sb);
return sb.toString();
}
The letter 'T' is different from the letter 't', so since only the letter 't' is found in your array, the program won't find a match for the letter 'T'.
Another problem with your code is that you will get an Index out of bounds exception if the input contains the letters 'x', 'y' or 'z' because there aren't 3 letters after them in the array.
public static String encoder(String word, int shift)
{
static const int max_char = 122; //letter 'z'
static const int min_char = 97; //letter 'a'
char[] c_array = word.toCharArray();
char[] encoded_string = new char[c_arary.length()];
for(for i = 0; i < c_array.length(); i++)
{
if( ((int)c + shift) > max_char) //makes sure that the ascii isnt a non number
{
encoded_string[i] = (min_char + (int)c + shift - max_char ); // this will correct the overflow
}
c = c + shfit;
}
return encoded_string;
}
This is an easier way to do this... also your loops have a few logical errors.. the first one i caught was in the first loop... if there is a z in your word your going to overflow your alphabet array.
This is using the Ascii table way

Java program to find the letter that appears in the most words?

I have a sentence, and I want to find the char that appears in the most words, and how many words it appears in.
For example: "I like visiting my friend Will, who lives in Orlando, Florida."
Which should output I 8.
This is my code:
char maxChar2 = '\0';
int maxCount2 = 1;
for (int j=0; j<strs2.length; j++) {
int charCount = 1;
char localChar = '\0';
for (int k=0; k<strs2[j].length(); k++) {
if (strs2[j].charAt(k) != ' ' && strs2[j].charAt(k) != maxChar2) {
for (int l=k+1; l<strs2[j].length(); l++) {
if (strs2[j].charAt(k)==strs2[j].charAt(l)) {
localChar = strs2[j].charAt(k);
charCount++;
}
}
}
}
if (charCount > maxCount2) {
maxCount2 = charCount;
maxChar2 = localChar;
}
}
, where strs2 is a String array.
My program is giving me O 79. Also, uppercase and lowercase do not matter and avoid all punctuation.
As a tip, try using more meaningful variable names and proper indentation. This will help a lot especially when your program is not doing what you thought it should do. Also starting smaller and writing some tests for it will help a bunch. Instead of a full sentence, get it working for 2 words, then 3 words, then a more elaborate sentence.
Rewriting your code to be a bit more readable:
// Where sentence is: "I like".split(" ");
private static void getMostFrequentLetter(String[] sentence) {
char mostFrequentLetter = '\0';
int mostFrequentLetterCount = 1;
for (String word : sentence) {
int charCount = 1;
char localChar = '\0';
for (int wordIndex = 0; wordIndex < word.length(); wordIndex++) {
char currentLetter = word.charAt(wordIndex);
if (currentLetter != ' ' && currentLetter != mostFrequentLetter) {
for (int l = wordIndex + 1; l < word.length(); l++) {
char nextLetter = word.charAt(l);
if (currentLetter == nextLetter) {
localChar = currentLetter;
charCount++;
}
}
}
}
if (charCount > mostFrequentLetterCount) {
mostFrequentLetterCount = charCount;
mostFrequentLetter = localChar;
}
}
}
Now all I did was rename your variables and change your for loop to a for-each loop. By doing this you can see more clearly your algorithm and what you're trying to do. Basically you're going through each word and comparing the current letter with the next letter to check for duplicates. If I run this with "I like" i should get i 2 but instead I get null char 1. You aren't properly comparing and saving common letters. This isn't giving you the answer, but I hope this makes it more clear what your code is doing so you can fix it.
Here is a somewhat more elegant solution
public static void FindMostPopularCharacter(String input)
{
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
input = input.toUpperCase();
HashMap<Character, Integer> charData = new HashMap<>();
char occursTheMost = 'A'; //start with default most popular char
int maxCount = 0;
//create the map to store counts of all the chars seen
for(int i = 0; i < alphabet.length(); i++)
charData.put(alphabet.charAt(i), 0);
//first find the character to look for
for(int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
//if contained in our map increment its count
if(charData.containsKey(c))
charData.put(c, charData.get(c) + 1);
//check for a max count and set the values accordingly
if(charData.containsKey(c) && charData.get(c) > maxCount)
{
occursTheMost = c;
maxCount = charData.get(c);
}
}
//final step
//now split it up into words and search which contain our most popular character
String[] words = input.split(" ");
int wordCount = 0;
CharSequence charSequence;
for(Character character : charData.keySet())
{
int tempCount = 0;
charSequence = "" + character;
for(int i = 0; i < words.length; i++)
{
if(words[i].contains(charSequence))
tempCount++;
}
if(tempCount > wordCount)
{
occursTheMost = character;
wordCount = tempCount;
}
}
System.out.println(occursTheMost + " " + wordCount);
}
Output of
String input = "I like visiting my friend Will, who lives in Orlando, Florida.";
FindMostPopularCharacter(input);
is
I 8
Note: If there are ties this will only output the character that first reaches the maximum number of occurrences.
FindMostPopularCharacter("aabb aabb aabb bbaa");
Outputs
B 4
because B reaches the max first before A due to the last word in the input.
FindMostPopularCharacter("aab aab b")
B 3

Checking characters in a string array aren't duplicates

So the idea is for a given set of strings in an array, I want to combine them to create one string.
for example:
array[0] = "abcde";
array[1] = "bcfgp";
array[2] = "fbcns";
array[3] = "fbdrq";
I want to join them thus getting the first of each letter from the array.
Which I done fine with this code:
String[] array = new String[4];
array[0] = "abcde";
array[1] = "bcfgp";
array[2] = "fbcns";
array[3] = "fbdrq";
int wordLength = array[0].length();
StringBuilder b = new StringBuilder();
// check through letter in each word
for (int i = 0; i < wordLength; i++) {
char[] charArray = new char[wordLength];
// checks each word in the array
for (int j = 0; j < 4; j++) {
char ch = array[j].charAt(i);
b.append(ch);
}
}
So this code creates the string "abffbcbbcfcddgnrepsq" which is fine.
What I would like is to remove duplicates at a position of i. so for the example used:
i=01234
array[0] = "abcde";
array[1] = "bcfgp";
array[2] = "fbcns";
array[3] = "fbdrq";
so you can see that when i=0, there is a duplicate of f so rather than adding two f's to the string, how would I add just one?
i=1 There are 3 b's so i'd only add one to the string and the c
i=2 Only add 1 c to the string and the d and d..
you get the picture, the end output would be:
"abfbccfddgnrepsq"
Set can be used to identify the duplicate as follow:
StringBuilder b = new StringBuilder();
// check through letter in each word
Set<Character>st = new HashSet<>();
for (int i = 0; i < wordLength; i++) {
st.clear();
char[] charArray = new char[wordLength];
// checks each word in the array
for (int j = 0; j < 4; j++) {
char ch = array[j].charAt(i);
if(st.add(ch))
b.append(ch);
}
}

Printing letters in 2D arrays? First letter not showing

I'm hoping someone can answer this so I'll try to explain this well.
My goal is to generate a MAXIMUM of 3 unique vowels (AEIOU) on a line of 5 squares. I have made 25 squares using a 2D array (board[][]), but I want to do the first line first. Picture it like this:
Now, my problem is, whenever I try to generate random letters in my squares, the first letter doesn't show. For example I have E and O, O would only show in my squares, and not E. It's printing in my console, but not in my GUI.
Also, sometimes DUPLICATES of letters are showing. I don't know how to fix this :|
Here are the codes I've done so far:
String board[][] = new String[5][5];
String alphabet = "AEIOU";
int numArray[] = new int[5]; //where I can store random indices of alphabet
int finalIndex = 0;
int random = (int) (Math.random()*3) + 1; //random number of vowels to be generated
//this loop covers everything
for(int ctr = 0; ctr < random; ctr++) {
while(ctr != finalIndex) { //checks if there are any duplicates
int rand = (int) (Math.random()*4); //random position for the letter
numArray[ctr] = rand;
while(numArray[ctr] != numArray[finalIndex]) {
finalIndex++;
}
}
//finds the position of the letter in alphabet and converts it to String
char character = alphabet.charAt(numArray[ctr]);
String s = String.valueOf(character);
System.out.println(s);
//loop for putting the letters to the 2D array
for(int i = 0; i < board.length; i++) {
int gen = (int) (Math.random()*4); //random square for letter
for(int j = 0; j <= gen; j++) {
if(i == 0 && j < 5) { //row 1
board[i][gen] = s;
}
}
}
}
I decided not to put my GUI code anymore just to make things simpler.
Sorry I couldn't read what you had, so i tried this myself...
int rows = 5;
Character [] vowels = {'A','E','I','O','U'};
Character [][] board = new Character [vowels.length][rows];
for(int row = 0;row<rows;row++){
ArrayList<Character> tempVowels = new ArrayList<Character>(Arrays.asList(vowels));
int numVowPerLine = (int)Math.floor(Math.random()*4);
for(int j = 0;j<numVowPerLine;j++){
do{
int pos = (int)Math.floor(Math.random()*5);
if(board[row][pos] == null){
int temp = (int)Math.floor(Math.random()*tempVowels.size());
board[row][pos] = tempVowels.get(temp);
tempVowels.remove(temp);
break;
}
}while(true);
}
}

Categories