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]);
}
Related
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
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.
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;
I'm writing a method to trim certain characters from a string. s1 is the actual string, and s2 is the char that you want to trim from the string. In my main method, I called:
String text = U.trim("what ?? the hell", '?');
And the rest of the code is the trim method I wrote. The problem is that whenever I put two ? marks together it only trims one of them, but if I put them apart it trims them fine. I don't know what I did wrong, and I even put print statements in the code itself to try to debug it, and if you run the code you'll see that the two question marks are at c[5] and c[6], and below the if statement if that char is a ? mark it'll replace it and print out "5;?", but I don't know why when it's comparing c[6], and the question mark it returns as false, since c[6] is a question mark. Please help.
static String trim(String s1, char s2) {
char c[] = new char[s1.length()];
String text = "";
for (int i = 0; i < s1.length(); i++) {
c[i] = s1.charAt(i);
}
for (int i = 0; i < s1.length(); i++) {
System.out.println("C" + i + ": " + c[i]);
}
for (int i = 0; i < s1.length(); i++) {
System.out.println("Start: " + i);
if (c[i] == s2) {
System.out.println(i + ";" + s2);
for (int j = i; j < s1.length(); j++) {
if (j != s1.length() - 1) {
c[j] = c[j + 1];
} else {
c[j] = '\0';
}
}
}
}
for (int i = 0; i < c.length; i++) {
text = text + c[i];
}
return text;
}
I try the pattern class, it didn't trim the question marks.
String text = "Hello ????";
text.replaceAll(Pattern.quote("?"), "");
System.out.println(text);
You can use s1.replace("?", "")
This is similar to replaceAll, but replaceAll uses a regex.
replace() replaces all occurances in the string.
Now, as to what you did wrong:
When you found a match in the character array, you shift the remaining characters towards the head.
Starting with "abc??def", your first match is at i=3.
You shift all the remaining characters to get "abc?def"
Then, you increment i to 4, and carry on.
c[4] is 'd' at this point.
So, the error is that when you shifted the characters to the left, you still increment i anyway, causing the first shifted character to be skipped.
I got another nooby question to Java gurus
Basically what I want is:
Take word;
Transform it to arrayOfChar;
Hide it to following manner: _ _ _ _;
I could get to to second step, however when I try to hide word in underscores it shows as ____ rather than _ _ _ _.
Code for it:
//Randomly picks word from Array which played
public String pickWord(){
String guessWord = (wordsList[new Random().nextInt(wordsList.length)]);
return guessWord;
}
//Hides picked word
public char[] setWord(){
word = pickWord().toCharArray();
for (int i = 0; i < Array.getLength (word); i++) {
word[i] = '_';
}
return word;
}
You will need to allow for the spaces in your new char array:
String testWord = "test";
char[] word = new char[testWord.length() * 2];
for (int i = 0; i < word.length; i+=2) {
word[i] = '_';
word[i + 1] = ' ';
}
When you store '' in word variable and print it it shows "__" because it shows consecutive '' . You can do it in various ways- like you can put a space every character of word or padding a space in word variable
for (int i = 0; i < Array.getLength (word); i++) {
word[2*i] = '_';
word[2*i+1] = ' ';
}
Add extra condition in for-loop
if(i%2 == 0)
word[i]='_';
else
word[i]=' ';
or simply override the word[i] only when i%2 =0. just one if block after you have
word[i]='_';
if(i%2 != 0)
word[i]=' ';
word = pickWord().toCharArray();
spacedWord = new char[word.length*2-1];
for (int i = 0; i < 2*word.length; i+=2) {
spacedWord[i] = '_';
spacedWord[i+1] = ' ';
}
return spacedWord;