Last element of JAVA char array is not replaced - java

In a JAVA 'char[] a' , I want to replace all the charachters by 'q', except 'x' and 'y'. I tried it by the JAVA code below. It works but fails to replace the last character. I need help to complete the replacement.
public static void main( String[] args )
{
char[] a ={'x','y','z','x','y','r','b'};
for(int i=0; i<a.length; i++){
if ( a[i]=='x') {
i=i+1;
if ( a[i]=='y') {
i=i+1;
a[i]='q';
}
System.out.println(a);
}
}
}

replace everything within your for by:
if ( a[i] != 'x' && a[i] != 'y' ){ a[i] = 'q'; }

I'm not going to inspect your code, but i will show you a way how u can accomplish your goal.
char[] a = {'x', 'y', 'z', 'x', 'y', 'r', 'b'};
for (int i = 0; i < a.length; i++) {
if (a[i] == 'x' || a[i] == 'y') {
continue;
} else {
a[i] = 'q';
}
}
System.out.println(a);
The keyword continue in java skips actual iteration and goes to the next one.

You need to check whether the current char (at index i) is not x or y. If it is one of there characters the for loop continues as usual and checks the next character.
for(int i = 0; i < a.length; i++){
char c = a[i]; //get current char
if(c != 'x' && c != 'y'){ //check if it is a x or y
a[i] = 'q' //replace current char
}
}

Your code inside the loop will only replace by q any char that follows sequence x, y. One way to replace all chars except x and y is can change your loop to:
for(int i=0; i<a.length; i++){
if ( a[i]!='x' && a[i] != 'y') {
a[i]='q';
}
}
System.out.println(a);
Also note that your System.out.println is seemingly in a wrong place and will not output anything useful.

As Jens points out, don't ever modify the loop counter.
Java doesn't care about this, but you may. Assuming we're in the first iteration, therefore:
int i = 0;
if ( a[i]=='x') { // i is still 0
i=i+1; // i becomes 1
if ( a[i]=='y') { // OOPS, i is 1 here. so this is a[1] and therefore 'y'
i=i+1;
a[i]='q';
}
System.out.println(a);
}
In a for loop, you can use continue; to skip the rest of the loop and jump to the next iteration.
Remember that the exit condition of a for gets only evaluated once: at the beginning of the for block.

surely instead of:
if (a[i] == 'x'){i=i+1;
if (a[i] == 'y'){i=i+1;
a[i] = 'q';
}
System.out.println(a);
}
you can do:
if (a[i] != 'x' || a[i] != 'y'){
a[i] = q;
System.out.println(a);
}

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]);
}

String-Word counter

I have to print the count of the words in a string which are repeated exactly N times?
example:
one two three four three two five
1
output:3
since one,four and five appears only once.
My code shows me the output as 1.
what is wrong with my code and logic?thank you.
import java.util.*;
public class Hello {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String s=scan.nextLine(),b;
int n=scan.nextInt();
int c=0,f=0,i;
String[] a=s.split(" ");
for(i=0;i<a.length;i++)
{
b=a[i];
for(int j=i+1;j<a.length;j++)
{
if(b.equalsIgnoreCase(a[j]))
{
c++;
}
}
if(n==c)
{
f++;
}
else
{
c=0;
}
}
System.out.print(f);
}
}
I see three reasons that makes your result incorrect.
First one is c
If a word is here once only, then the if statement if(b.equalsIgnoreCase(a[j])) will never be true. Which means that c will be always equal to 0.
So you you need to use 1 as default value for c or you should check the value of c using the following statement if (n == c + 1)
The second point is that you should reset the value of c even if it is equal to n.
Then with this double for loop:
for (i = 0; i < a.length; i++) {
b = a[i];
for (int j = i + 1; j < a.length; j++) {
When you searching for a value that is there once only, the last occurence of every words will be counted as well.
There is lot of ways to solve that. one of them is to use a Set<String> and only count for the words that has not been used before.
So at the end you will have something similar to that:
int c=1,f=0,i;
String[] a=s.split(" ");
Set<String> words = new HashSet<>();
for (i = 0; i < a.length; i++) {
b = a[i];
if (words.add(b)) {
for (int j = i + 1; j < a.length; j++) {
if (b.equalsIgnoreCase(a[j])) {
c++;
}
}
if (n == c) {
f++;
}
c = 1;
}
}
I think It's because you don't initialize C when n==c . Therefor it increases to 1 after one and one are matched. And it's not working well . It should be 0 for every loop
Also why j starts from i+1? After each loop it will lose comparison one by one Since a[j] is getting smaller. It should always containt list of full input numbers

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

"Removing" Duplicate spaces from a char array java

I'm attempting to create a method which will take a char array, cut out any duplicate spaces (2 or more) and then place '\u0000' characters at the end for however many spaces were cut out so that the array length is satisfied. I realize I have to shift the elements down but this is where I'm having trouble. My program works fine with 2 spaces but a sequence of three in a row will throw it off. I understand why this is happening but I don't know how to fix it. I know it stems from the code characters[j] = characters[j+1] but I don't know how to go about fixing it.
int duplicateCount = 0;
// Create a loop to read the element values
for(int i = 0; i + 1 < characters.length; i++){
// If the element is a space and the next one is a space
if(characters[i] == ' ' && characters[i+1] == ' '){
// Add to duplicate count and start shifting values down
duplicateCount++;
// *THIS IS WHERE I THINK BUG IS*
for(int j = i; j < characters.length - 1; j++){
characters[j] = characters[j+1];
}
}
}
// Replace characters at end with how many duplicates were found
for(int replace = characters.length - duplicateCount; replace < characters.length; replace++){
characters[replace] = '\u0000';
}
}
Thank you all.
From what I understood, you want all the spaces to be removed from between non-space characters and add \u0000 to the end.
If that's the issue, try this out:
I have used loops and if statements to achieve it.
for (int i = 0; i < characters.length; i++) {
int j =i+1;
if (characters[i] == ' ' || characters[i] == '\u0000' ) {
while (j<characters.length && (characters[j] == ' ' || characters[j] == '\u0000')) {
j++; //increment j till a non-space char is found
}
if(j<characters.length && (characters[j] != ' ' || characters[j] != '\u0000'))
// to ensure that the control entered while
{
characters[i] = characters[j]; //swapping the values
characters[j] = '\u0000'; //giving value \u0000 to position j
}
}
}
Very simple solution if you want to keep your current code.
Just add 1 line i--.
int duplicateCount = 0;
// Create a loop to read the element values
for(int i = 0; i + 1 < characters.length; i++){
// If the element is a space and the next one is a space
if(characters[i] == ' ' && characters[i+1] == ' '){
// Add to duplicate count and start shifting values down
duplicateCount++;
// *THIS IS WHERE I THINK BUG IS*
for(int j = i; j < characters.length - 1; j++){
characters[j] = characters[j+1];
}
i--; // so that multiple space case can be handled
}
}
// Replace characters at end with how many duplicates were found
for(int replace = characters.length - duplicateCount; replace < characters.length; replace++){
characters[replace] = '\u0000';
}
}
int count = 0; // Count of non-space elements
// Traverse the array. If element encountered is
// non-space, then replace the element at index 'count'
// with this element
for (int i = 0; i < n; i++)
if (arr[i] != '')
arr[count++] = arr[i]; // here count is
// incremented
// Now all non-space elements have been shifted to
// Make all elements '\u0000' from count to end.
while (count < n)
arr[count++] = 0;

Counting the number of common chars in a string and a vector of strings

My problem is how to count but not count the same character twice. Like comparing 'aba' to 'are' should give 1 as result since it has only one char in common.
This is where I got so far:
public int sameChars (Vector<String> otherStrs){
int result = 0;
String original = "aba";
for (int h= 0; h< otherStrs.size(); h++) {
String targetStr = otherStrs.get(h);
for (int i=0; i< original.length(); i++) {
char aux = original.charAt(i);
for (int j=0; j< Math.min(original.length(), targetStr.length()); j++) {
char targetAux = targetStr.charAt(j);
if (aux == targetAux) {
result++;
break;
}
}
}
}
return result;
}
Ideas are welcome, thanks.
You can create a hash of character count from the original string. Then for each target string, check if it has a char that has a non-zero value in your hash. This will prevent scanning your original string more than once.
Pseudocode:
For each char c in original string {
hash[c]++
}
For each target string str {
For each char c_ in str {
if hash[c_] > 0 {
result++;
}
}
}
This smells like homework, so here's the just the basic idea: You need to keep track of the distinct characters you've already counted as being in both places. A Set might be a good way to do this. Before incrementing your counter, check to see if the character you're looking at is already in that Set.
I am not sure to understand your requirement: do you want to count the number of times the distinct characters found in the reference string original, here "aba" thus 'a' and 'b', are found in a set of strings stored in the Vector otherStrs?
If that's the case, I would advise first to reduce the original string to distinct characters (looking for and removing duplicates, or using a Map). Then loop over the strings in the Vector and do the same for each string (removing duplicates or using a Map) before incrementing your counter each time a character is found in common.
Just out of curiosity, what is the end goal of this computation?
Here's my implementation:
public static int commonChars(String s1, String s2) {
if (s1 == null || s1.isEmpty())
throw new IllegalArgumentException("Empty s1");
if (s2 == null || s2.isEmpty())
throw new IllegalArgumentException("Empty s2");
char[] a1 = s1.toCharArray();
char[] a2 = s2.toCharArray();
Arrays.sort(a1);
a1 = removeDups(a1);
Arrays.sort(a2);
a2 = removeDups(a2);
int count = 0;
for (int i = 0, j = 0; i < a1.length && j < a2.length;) {
if (a1[i] == a2[j]) {
i++;
j++;
count++;
}
else if (a1[i] > a2[j])
j++;
else
i++;
}
return count;
}
public static char[] removeDups(char[] array) {
char[] aux = new char[array.length];
int c = 1;
aux[0] = array[0];
for (int i = 1 ; i < array.length; i++) {
if (array[i] != array[i-1])
aux[c++] = array[i];
}
return Arrays.copyOf(aux, c);
}

Categories