A series of String Manipulation Operations with counter in Java - 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

Related

Replacing Duplicates in Character Array with placeholder character ' '?

For any string of characters I input to my charArray, this simply returns the first character and the rest as spaces. Why? I simply want to replace all of the non-original renditions of a character with a space.
for (int i = 0 ; i<charArray.length ; i++) {
for (int j = 1 ; j<charArray.length ; j++) {
if (charArray[i] == charArray[j])
charArray[j] = ' ';
}
}
Your inner loop needs to start at i + 1 instead of the hardcoded value 1:
char[] charArray = "abcdabce".toCharArray();
for (int i = 0; i < charArray.length; i++)
{
// check if a space was already inserted at this index
if (charArray[i] == ' ')
continue;
// check all remaining characters
for (int j = i + 1; j < charArray.length; j++)
{
if (charArray[i] == charArray[j])
{
charArray[j] = ' ';
}
}
}
System.out.println(charArray);
Output:
abcd e
To put it simply, this is what your code currently does:
For each character in the char array, if the same character appears somewhere in the array starting from the index 1, then change it to a space. This concretely means that all the characters starting from index 1 will be replaced (because the condition that they appear after index 0 will always be satisfied).
A simple example can illustrate why this won't actually work.
Suppose your input array is ['h','e','l','l','o'].
When i = 1 and j = 1, charArray[i] == charArray[j] will return true, thus your 'e' will be replaced by a space.
I would suggest looping through the array once, using a data structure that memorizes which characters previously appeared, which in this case corresponds to a Set.
Set<Character> charSet = new HashSet<>();
for (int i = 0; i < charArray.length; i ++) {
if (charSet.contains(charArray[i])) charArray[i] = ' ';
else charSet.add(charArray[i]);
}

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

Java Decode Run Length Assignment

Here's the basics of the assignment:
Your task is to write a program that decodes a sequence of characters which was encoded using a simple form of run-length encoding, as described by the rules below.
Any sequence of between 2 to 9 identical characters is encoded by two characters. The first character is the length of the sequence, represented by one of the characters 2 through 9. The second character is the value of the repeated character. A sequence of more than 9 identical characters is dealt with by first encoding 9 characters, then the remaining ones.
Any sequence of characters that does not contain consecutive repetitions of any characters is represented by a 1 character followed by the sequence of characters, terminated with another 1. If a 1 appears as part of the sequence, it is escaped with a 1, thus two 1 characters are output.
Example Input and Output:
Input:
9A1ABC131
1112 3124
111111
Output:
AAAAAAAAAABC111
12 344
11
My code that I have so far but doesn't quite work:
import java.util.Scanner;
public class RunLength {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
String test = kb.nextLine();
System.out.println(decode(test));
}
public static String encode(String s) {
if (s == "" || s == null) return "";
StringBuffer sb = new StringBuffer();
int count = 0;
char ch = 0;
for (int i = 0; i < s.length(); i++) {
if (i == 0) {
ch = s.charAt(i);
count++;
} else {
if (ch == s.charAt(i)) {
count++;
} else {
sb.append(ch).append(count);
count = 1; // count is set to 1 as 1 occurrence of ch has been appended to the output
ch = s.charAt(i);
}
}
}
sb.append(ch).append(count);
return sb.toString();
}
public static String decode(String st) {
if (st == "" || st == null) return "";
char[] stArr = st.toCharArray();
char lastseen = 0;
StringBuffer sb = new StringBuffer();
for (char s : stArr) {
if (!Character.isDigit(s)) {
lastseen = s;
sb.append(s);
} else {
int n = Integer.parseInt(String.valueOf(s));
for (int i = 0; i < n - 1; i++) {
sb.append(lastseen);
}
}
}
return sb.toString();
}
public static int[] decode2(String source) {
int arrLength = 0;
for (int i = 0; i < source.length(); i += 2) {
int count = Character.getNumericValue(source.charAt(i));
arrLength += count;
}
int array[] = new int[arrLength];
int k = 0;
for (int i = 0; i < source.length(); i += 2) {
int count = Character.getNumericValue(source.charAt(i));
for (int j = 0; j < count; j++) {
array[i + k] = Character.getNumericValue(source.charAt(i + 1));
}
}
return array;
}
}
I suggest you try to split your decode methods into two main logical parts:
One for the case that you are actually performing a RLE and the other for the case where you have a sequence of non-repeated characters, in which 1s have to be escaped.
The latter is easy to implement and your solution for that part seems to be correct.
The former needs you to loop over the next characters until the end of the sequence has been found.
If you read anything but a 1, just add it to the output.
In case there is a 1, you need to look ahead at the next character to see whether there is another 1, meaning there is an unrepeated 1 that had to be escaped, which is to be added to the output (consuming the lookahead, too). If the look ahead is not a 1 (including the special case where there is no next character) the unrepeated characters sequence ends here and nothing is to be added to the output.
Since this page is not supposed to solve your homework, I won't post a complete solution, though.

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