"Removing" Duplicate spaces from a char array java - 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;

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

Skipping empty indexes in a 2d char[][] array when looping the array for a char value and appending it to a String

How do you skip all empty indexes in a 2D char[][] array when looping through it to build a string out of of all the indexes that do have a char value?
In the code below I used \0 to represent the empty indexes and wrote a condition to append all indexes that are not \0 to text. Is this a good way to do it or is there a more efficient method?
StringBuilder text = new StringBuilder();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col.length(); j++) {
if (charArray[i][j] != '\0') {
text.append(charArray[i][j]);
}
}
this.newText = text.toString();
You will need to travel the entire 2D array to find out the empty element.
For traveling a 2D A[m][n] array, the time complexity (best) is O(m*n), which you're using so there isn't any other method that will reduce the time complexity.
There is a difference between '\0' and ' '. `\0' is for null and ' ' is for empty char.
Your use case needs to omit empty char, so use ' '
for (int i = 0; i < row; i++) {
for (int j = 0; j < col.length(); j++) {
if (charArray[i][j] != '') {
text.append(charArray[i][j]);
}
}
this.newText = text.toString();
This would iterate all rows and columns of charArray test value and allows for arrays of different lengths:
char[][]charArray = new char[][] { new char[] {65, '\0', 66 }
, new char[] {68,69, 70, '\0', 71 }};
StringBuilder text = new StringBuilder();
for (int i = 0; i < charArray.length; i++) {
char[] theRow = charArray[i];
for (int j = 0; j < theRow.length; j++) {
if (theRow[j] != '\0') {
text.append(theRow[j]);
}
}
}
String s = text.toString();
System.out.println("s.length()="+s.length()+" s="+s);
Prints:
s.length()=6 s=ABDEFG
Note that '' is not a valid character, and '\0' is fine to use.

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

Last element of JAVA char array is not replaced

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

java character converting into number in 2D char array

I'm trying to convert all letters in a 2D char array into number. As results, I want a = 0, b=1, c=2, ... z=25.
Then, I tried this as part of my code:
char [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (char) ((letters[i][j] - 'a') + '0');
}
}
}
The result of my code is not what I expected before.
From 'a' to 'j', it worked well. But, from 'k' until 'z' it didn't print expected number.
What's wrong with my code?
First of all you can't store the number 10 as a single char. It is two chars, 1 and 0. So the result array has to be something else than a char array. If it is int your working with then you are probably best of storing them in an int array.
intarray[i][j] = (letters[i][j] - 'a'); where intarray is your array of int values that has the same size as the char array. Other option is to make a string array if you must store the result in the same array and convert it to a number and then into a string. Like this
String [][] letters = {{"i", "u"}, {"a", "g"}, {"e", "k"}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j].charAt(0) >= 'a' && letters[i][j].charAt(0) <= 'z') {
letters[i][j] = Integer.toString((letters[i][j].charAt(0) - 'a');
}
}
}
The reason is that the ascii table only has the numbers 0 to 9 as symbols. So in your case you get the first 10 letters to convert but after that you start getting various symbols in the ascii table. k for example would be :, l is ; m is < and so on. When you are working with converting chars to numbers you are better working with them as int as they are easier to do math on.
You could do the same without converting it into an int but that mean you need to find out char - 'a' is bigger than 10. If so you need get the number divided by 10 and then after that the modulo of the number and give each of them the associated ascii symbol to make them into a string. This is a lot more complex and hard to do, specially considering how easy this is by just doing it with ints.
There are 2 other options for you but I still feel the string option above is by far the easiest.
First would be to have the 2d array as an int. You could then initialize the ints to be letters. Then you can do arithmetic on them to find the number they fit. Like this:
int [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (letters[i][j] - 'a');
}
}
}
This would have the same effect. The issue with doing it this way is that printing the actual letter takes a bit more effort and in the end you would need to convert it to a char. So I would not recommend this way.
The second option would be to store everything as the char value in a char array. Like this:
char [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (char) (letters[i][j] - 'a');
}
}
}
To print this then you would need to cast the char to an int. So you could print them with:
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
System.out.printf("%d\n", (int) letters[i][j]);
}
}
This would then work as well but it is a bit hacky and you need to make sure you cast the char you have to an int all the time. So far I think the string array is the best option but it depends on what your goal is. But one thing that you can't do is store the char '10' in a char array as '10' isn't a single char but 2 chars and don't fit in a char.

Categories