Nested for loop, not picking up first instance in Array - java

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

Related

Java - add N distance to string

I am quite new in Java world and I am struggeling with the following problem:
I am currently trying to edit a coding in which, given a string, following changes are made:
if is uppercase, change it to lowercase and vice versa
to the corresponding string corresponds another string which is in a distance of N positions
I wrote the following:
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
public String code(String text, int distance) {
// cambio mayus <-> minus
StringBuilder sb = new StringBuilder(text);
for (int index = 0; index < sb.length(); index++) {
char c = sb.charAt(index);
if (Character.isLowerCase(c)) {
sb.setCharAt(index, Character.toUpperCase(c));
} else {
sb.setCharAt(index, Character.toLowerCase(c));
}
}
// comparison string to ALPHABET
for (int i = 0; i < sb.length(); i++) {
for (int j = 0, j < ALPHABET.length(); j++) {
//tiene en cuenta mayusculas y minusculas
if (sb[i] == ALPHABET[j] && sb[i] == ALPHABET[j].toUpperCase()) {
// adds the distance
sb[i] = ALPHABET[j+distance];
}
}
}
return sb;
}
Until now I doubt if is well done and I don't know how to deal with the problem that ALPHABET has a circular behaviour, I mean, if the distance N is greater than 26, from 'z', will go again to 'a' This is what I don't know how to express.
How would you do it?
Thank you in advance!

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

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

Delete letter from string in a for loop

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/

Replacing characters of a string in a particular sequence

The String word contains a character ] at more than one place. I want to replace any character before the ] by l, and any character after by r.
For example, the String defined below:
String word="S]RG-M]P";
Should be converted to:
String word="l]rG-l]r";
When I tried by the following code:
String word="S]RG-M]P";
char[] a = word.toCharArray();
for(int i=0; i<a.length; i++){
if (a[i]==']'){
a[i+1]='r';
a[i-1]='l';
}
}
It changes the right side of ] by r, but fails left to it by l. I need help to get the required results.
public static void main(String[] args) {
String word = "S]RG-M]P";
char[] a = word.toCharArray();
for (int i = 1; i < a.length-1; i++) {//#Jon Skeet again is right X2 :)
//no need now, for loop bound changed
//if(i+1>a.length){
// continue;
// }
if (a[i] == ']') {
//no need now, for loop bound changed
//#Jon Skeet you are right, this handles the case :)
//if(i==0 || i == a.length-1){
//continue;
//}
a[i + 1] = 'r';
a[i - 1] = 'l';
}
}
String outt = new String(a);
System.out.print(outt);
}// main
StringBuilder word = new StringBuilder("S]RG-M]P");
int index = word.indexOf("]");
while(index > 0){
word.setCharAt(index-1, 'l');
word.setCharAt(index+1, 'r');
index = word.indexOf("]", index+1);
}
System.out.println(word);
String word="S]RG-M]P";
word.replaceAll(".]." , "l]r");
using regex and string methods is useful in this situation
for(int i=0 ; i<word.length();i++){
char a = word.charAt(i);
String after =null;
if( Character.toString(a).equals("]")){
int j = i-1;
int k = i+1;
char b = word.charAt(j);
char c = word.charAt(k);
modifyword= word.replace( Character.valueOf(b).toString(), "l");
after= modifyword.replace( Character.valueOf(c).toString(), "r");
word = after;
}
}

Categories