Removing special character without using Java Matcher and Pattern API - java

I am trying to write one java program. This program take a string from the user as an input and display the output by removing the special characters in it. And display the each strings in new line
Let's say I have this string Abc#xyz,2016!horrible_just?kidding after reading this string my program should display the output by removing the special characters like
Abc
xyz
2016
horrible
just
kidding
Now I know there are already API available like Matcher and Patterns API in java to do this. But I don't want to use the API since I am a beginner to java so I am just trying to crack the code bit by bit.
This is what I have tried so far. What I have done here is I am taking the string from the user and stored the special characters in an array and doing the comparison till it get the special character. And also storing the new character in StringBuilder class.
Here is my code
import java.util.*;
class StringTokens{
public void display(String string){
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
char[] str = {' ','!',',','?','.','_','#'};
for(int i=0;i<string.length();i++){
for(int j =0;j<str.length;j++){
if((int)string.charAt(i)!=(int)str[j]){
stringToken.append(str[j]);
}
else {
System.out.println(stringToken.toString());
stringToken.setLength(0);
}
}
}
}
public static void main(String[] args){
if(args.length!=1)
System.out.println("Enter only one line string");
else{
StringTokens st = new StringTokens();
st.display(args[0]);
}
}
}
When I run this code I am only getting the special characters, I am not getting the each strings in new line.

One easy way - use a set to hold all invalid characters:
Set<Character> invalidChars = new HashSet<>(Arrays.asList('$', ...));
Then your check boils down to:
if(invaidChars.contains(string.charAt(i)) {
... invalid char
} else {
valid char
}
But of course, that still means: you are re-inventing the wheel. And one does only re-invent the wheel, if one has very good reasons to. One valid reason would be: your assignment is to implement your own solution.
But otherwise: just read about replaceAll. That method does exactly what your current code; and my solution would be doing. But in a straight forward way; that every good java programmer will be able to understand!
So, to match your question: yes, you can implement this yourself. But the next step is to figure the "canonical" solution to the problem. When you learn Java, then you also have to focus on learning how to do things "like everybody else", with least amount of code to solve the problem. That is one of the core beauties of Java: for 99% of all problems, there is already a straight-forward, high-performance, everybody-will-understand solution out there; most often directly in the Java standard libraries themselves! And knowing Java means to know and understand those solutions.
Every C coder can put down 150 lines of low-level array iterating code in Java, too. The true virtue is to know the ways of doing the same thing with 5 or 10 lines!

I can't comment because I don't have the reputation required. Currently you are appending str[j] which represents special character. Instead you should be appending string.charAt(i). Hope that helps.
stringToken.append(str[j]);
should be
stringToken.append(string.charAt(i));

Here is corrected version of your code, but there are better solutions for this problem.
public class StringTokens {
static String specialChars = new String(new char[]{' ', '!', ',', '?', '.', '_', '#'});
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Enter only one line string");
} else {
display(args[0]);
}
}
public static void display(String string) {
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
for(char c : string.toCharArray()) {
if(!specialChars.contains(String.valueOf(c))) {
stringToken.append(c);
} else {
stringToken.append('\n');
}
}
System.out.println(stringToken);
}
}

public static void main(String[] args) {
String a=",!?#_."; //Add other special characters too
String test="Abc#xyz,2016!horrible_just?kidding"; //Make this as user input
for(char c : test.toCharArray()){
if(a.contains(c+""))
{
System.out.println(); //to avoid printing the special character and to print newline
}
else{
System.out.print(c);
}
}
}

you can run a simple loop and check ascii value of each character. If its something other than A-Z and a-z print newline skip the character and move on. Time complexity will be O(n) + no extra classes used.
String str = "Abc#xyz,2016!horrible_just?kidding";
char charArray[] = str.toCharArray();
boolean flag=true;;
for (int i = 0; i < charArray.length; i++) {
int temp2 = (int) charArray[i];
if (temp2 >= (int) 'A' && temp2 <= (int) 'Z') {
System.out.print(charArray[i]);
flag=true;
} else if (temp2 >= (int) 'a' && temp2 <= (int) 'z') {
System.out.print(charArray[i]);
flag=true;
} else {
if(flag){
System.out.println("");
flag=false;
}
}
}

Related

How can I prevent the user from entering the same letter in Hangman JAVA?

I am writing a hangman program and one of the requirements to a hangman game is preventing the user from entering the same letter twice.
I have written the code for that, but the problem is every time I enter a letter it says it is already entered. I need to only say it when it is entered the second time. You guys have any suggestions? I've been trying to fix this for the past few hours, I figured I could ask on here to find some help. I already looked at another Stackoverflow question regarding something similar to this but all those solutions have the same result.
In Java, how can I determine if a char array contains a particular character?
I've tried something like this but it won't work either:
boolean contains = false;
for (char c : store) {
if (c == character) {
System.out.println("Already Entered");
contains = true;
break;
}
}
if (contains) {
// loop to top
continue;
}
SECOND CLASS-
public void hangman(String word, int life) {
KeyboardReader reader = new KeyboardReader();
char[] letter = new char[word.length()];
char[] store = new char[word.length()];
String guess;
int i = 0, tries = 0, incorrect = 0, count = 1, v = 0;
while (i < word.length()) {
letter[i] = '-';
I would just use the String.contains() method:
String aString = "abc";
char aChar = 'a';
return aString.contains(aChar + "");
To keep track of guessed letters you can use a StringBuffer, appending them using a StringBuffer.append() to append new letters (maintaining state) and use the StringBuffer.toString() method to get the String representation when you need to do the comparison above.
Since Java 1.5 the class String contains the method contains(). My idea is to collect all entered letters into a string variable and using above method:
// My code line
String letterAlreadyEntered = "";
// Your code line
char character = reader.readLine().charAt(0);
// My code line
if (letterAlreadyEntered.contains("" + character) == true) {
//Put code here what ever you want to do with existing letter
} else {
letterAlreadyEntered += character;
}
In my opinion, this is an easier way to check for occurrences than in arrays, where you have to write your own check method.

recursion moving char to the end of the string

i need to get a string and rearrange it with recursion by getting char and by that char i have to move that char everywhere on the string to the end
like "Hello world!" ,'l' => "Heo word!lll"
i have problems understading the recursion way of thinking
so i started with this:
public static String ChToLast (String str, char ch){
if(str.indexOf(ch)== -1){
return str;
}else{
if(str.indexOf(0) == ch){
return str;
}
}
thank you for your help :)
Recursion is the practise of reusing your method inside itself. In this case, I will provide a solution to explain what happens:
public static String chrToLast(String str, char ch) {
//This if statement details the end condition
if(str.length() < 1) {
return "";
}
String newString = str.substring(1); //Create new string without first character
if(str.indexOf(ch) == 0) { //This happens when your character is found
return chrToLast(newString, ch) + ch;
} else { //This happens with all other characters
return str.charAt(0) + chrToLast(newString, ch);
}
}
If you execute:
chrToLast("Hello, World!", 'l')
This will result in the desired result: Heo, Word!lll
Process
In general, this method works by checking which character is currently the first in the given string, and then deciding what to do. If the first character is the same as the one your looking for (l), it will then remove that character from the string and use chrToLast on that new string. But, it also adds the character it found to the end of the result by using + ch. It continues to do this until there are no more characters left, which is what the end condition is for.
The end condition
The end condition returns an empty string "" because that is what is called the base case of the algorithm. You can think of a recursive algorithm as something solving a problem by calling itself a number of times. By calling themselves, recursive algorithms move towards a base. In this particular case, it does that by subtracting one character off the string each time the method is executed. Once there are no characters left, it reaches the base case which is "", where the string is finally empty and no characters can be subtracted anymore. (Hence it returns nothing as it's final state)
I hope this answers your question. It's important to understand this concept, as it is very powerful. Try to study the code and comment if something's not clear.
Something that can also help is by executing this code in an IDE and using the debugger to walk through its execution. You can then see for yourself what the flow of the program is, and see the value of the variables in play.
If you use recursion, it will be pretty expensive call for the result you are expecting. Lot of movement of String or charArray elements, eitherway you do. I don't see its a wiser choice. I would do it this way, it will be of space complexity O(2n) & performance complexity O(n).
public class Solve {
public static void main(String[] args) {
System.out.println(ChToLast("Hello world!", 'l'));
}
public static String ChToLast(String str, char ch) {
char[] chars = str.toCharArray();
char[] modChars = new char[chars.length];
int i = 0;
for(char element : chars){
if(ch != element){
modChars[i++] = element;
}
}
Arrays.fill(modChars, i, chars.length , ch);
return new String(modChars);
}
}
If you use while loop and write a method to check if that string means perfect statement then that may work for you
Here you would need some help of NLP concept to check everytime if arranged chars are making any statement or are grammatically correct.
This will help

Substring a string based on presence of a character

I have a string: LOAN,NEFT,TRAN. I want to substring the string based on getting a , during traversing the string. So I tried to first get a count for how many , are there. but not sure what function to user to get what I want. Also this should be dynamic, meaning I should be able to create as many substrings as required based on number of ,s. I tried the following code:
package try1;
public class StringTest {
public static void main(String[] args) {
String str="LOAN,NEFT,TRAN";
int strlen=str.length();
int count=0;
for(int i=0;i<strlen;i++)
{
if(str.contains("'"))
count++;
}
System.out.println(""+count);
for (int j=0;j<count;j++)
{
//code to create multiple substrings out of str
}
}
}
But I do not think contains() is the function I am looking for because value of count here is coming 0. What should I use?
Your code doesn't actually count the , characters because 1) contains doesn't take into account your loop variable 2) it's searching for ', not ,
Assuming you want to work at a low level rather than using high level functions like .split(), then I'd recommend the following.
for(char c : str.toCharArray()) {
if (c == ',') {
count++;
}
}
You can use split to get substrings directly:
String[] substrings = str.split(",");
Is this what you want as an output: (shown below)?
["LOAN", "NEFT", "TRAN"] // Array as an output
Or to just get the count of the splitting char, you can use the same line as above with this:
int count = substrings.length - 1;

Finding Palindromes in a word list

I'm working on a program for Java on how to find a list of palindromes that are embedded in a word list file. I'm in an intro to Java class so any sort of help or guidance will be greatly appreciated!
Here is the code I have so far:
import java.util.Scanner;
import java.io.File;
class Palindromes {
public static void main(String[] args) throws Exception {
String pathname = "/users/abrick/resources/american-english-insane";
File dictionary = new File(pathname);
Scanner reader = new Scanner(dictionary);
while (reader.hasNext()) {
String word = reader.nextLine();
for (int i = 0; i > word.length(); i++) {
if (word.charAt(word.indexOf(i) == word.charAt(word.indexOf(i)) - 1) {
System.out.println(word);
}
}
}
}
}
There are 3 words that are 7 letters or longer in the list that I am importing.
You have a few ways to solve this problem.
A word is considered a palindrome if:
It can be read the same way backwards as forwards.
The first element is the same as the last element, up until we reach the middle.
Half of the word is the same as the other half, reversed.
A word of length 1 is trivially a palindrome.
Ultimately, your method isn't doing much of that. In fact, you're not doing any validation at all - you're only printing the word if the first and last character match.
Here's a proposal: Let's read each end of the String, and see if it's a palindrome. We have to take into account the case that it could potentially be empty, or be of length 1. We also want to get rid of any white space in the string, as that can cause errors on validation - we use replaceAll("\\s", "") to solve that.
public boolean isPalindrome(String theString) {
if(theString.length() == 0) {
throw new IllegalStateException("I wouldn't expect a word to be zero-length");
}
if(theString.length() == 1) {
return true;
} else {
char[] wordArr = theString.replaceAll("\\s", "").toLowerCase().toCharArray();
for(int i = 0, j = wordArr.length - 1; i < wordArr.length / 2; i++, j--) {
if(wordArr[i] != wordArr[j]) {
return false;
}
}
return true;
}
}
I'm assuming that you're reading in strings. Use string.toCharArray() to convert each string to a char[]. Iterate through the character array using a for loop as follows: on iteration 1, if the first character is equal to the last character, then proceed to the next iteration, else return false. On iteration 2, if the second character is equal to the second-to-last character then proceed to the next iteration, else return false. And so on, until you reach the middle of the string, at which point you return true. Be careful of off-by-one errors; some strings will have an even length, some will have an odd length.
If your palindrome checker is case insensitive, then use string.toLowerCase().toCharArray() to preprocess the character array.
You can use string.charAt(i) instead of string.toCharArray() in the for loop; in this case, if the palindrome checker is case insensitive then preprocess the string with string = string.toLowerCase()
Let's break the problem down: In the end, you are checking if the reverse of the word is equal to the word. I'm going to assume you have all of the words stored in an array called wordArray[].
I have some code for getting the reverse of the word (copied from here):
public String reverse(String str) {
if ((null == str) || (str.length() <= 1)) {
return str;
}
return new StringBuffer(str).reverse().toString();
}
So, now we just need to call that on every word. So:
for(int count = 0; count<wordArray.length;count++) {
String currentWord = wordArray[count];
if(currentWord.equals(reverse(currentWord)) {
//it's a palendrome, do something
}
}
Since this is homework, i'll not supply you with code.
When i code, the first thing i do is take a step back and ask myself,
"what am i trying to get the computer to do that i would do myself?"
Ok, so you've got this huuuuge string. Probably something like this: "lkasjdfkajsdf adda aksdjfkasdjf ghhg kajsdfkajsdf oopoo"
etc..
A string's length will either be odd or even. So, first, check that.
The odd/even will be used to figure out how many letters to read in.
If the word is odd, read in ((length-1)/2) characters.
if even (length/2) characters.
Then, compare those characters to the last characters. Notice that you'll need to skip the middle character for an odd-lengthed string.
Instead of what you have above, which checks the 1st and 2nd, then 2nd and 3rd, then 3rd and fourth characters, check from the front and back inwards, like so.
while (reader.hasNext()) {
String word = reader.nextLine();
boolean checker = true;
for (int i = 0; i < word.length(); i++) {
if(word.length()<2){return;}
if (word.charAt(i) != word.charAt(word.length()-i) {
checker = false;
}
}
if(checker == true)
{System.out.println(word);}
}

Space Replacement for Float/Int/Double

I am working on a class assignment this morning and I want to try and solve a problem I have noticed in all of my team mates programs so far; the fact that spaces in an int/float/double cause Java to freak out.
To solve this issue I had a very crazy idea but it does work under certain circumstances. However the problem is that is does not always work and I cannot figure out why. Here is my "main" method:
import java.util.Scanner; //needed for scanner class
public class Test2
{
public static void main(String[] args)
{
BugChecking bc = new BugChecking();
String i;
double i2 = 0;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (i2 <= 0.0)
{
i = in.nextLine();
i = bc.deleteSpaces(i);
//cast back to float
i2 = Double.parseDouble(i);
if (i2 <= 0.0)
{
System.out.println("Please enter a number greater than 0.");
}
}
in.close();
System.out.println(i2);
}
}
So here is the class, note that I am working with floats but I made it so that it can be used for any type so long as it can be cast to a string:
public class BugChecking
{
BugChecking()
{
}
public String deleteSpaces(String s)
{
//convert string into a char array
char[] cArray = s.toCharArray();
//now use for loop to find and remove spaces
for (i3 = 0; i3 < cArray.length; i3++)
{
if ((Character.isWhitespace(cArray[i3])) && (i3 != cArray.length)) //If current element contains a space remove it via overwrite
{
for (i4 = i3; i4 < cArray.length-1;i4++)
{
//move array elements over by one element
storage1 = cArray[i4+1];
cArray[i4] = storage1;
}
}
}
s = new String(cArray);
return s;
}
int i3; //for iteration
int i4; //for iteration
char storage1; //for storage
}
Now, the goal is to remove spaces from the array in order to fix the problem stated at the beginning of the post and from what I can tell this code should achieve that and it does, but only when the first character of an input is the space.
For example, if I input " 2.0332" the output is "2.0332".
However if I input "2.03 445 " the output is "2.03" and the rest gets lost somewhere.
This second example is what I am trying to figure out how to fix.
EDIT:
David's suggestion below was able to fix the problem. Bypassed sending an int. Send it directly as a string then convert (I always heard this described as casting) to desired variable type. Corrected code put in place above in the Main method.
A little side note, if you plan on using this even though replace is much easier, be sure to add an && check to the if statement in deleteSpaces to make sure that the if statement only executes if you are not on the final array element of cArray. If you pass the last element value via i3 to the next for loop which sets i4 to the value of i3 it will trigger an OutOfBounds error I think since it will only check up to the last element - 1.
If you'd like to get rid of all white spaces inbetween a String use replaceAll(String regex,String replacement) or replace(char oldChar, char newChar):
String sBefore = "2.03 445 ";
String sAfter = sBefore.replaceAll("\\s+", "");//replace white space and tabs
//String sAfter = sBefore.replace(' ', '');//replace white space only
double i = 0;
try {
i = Double.parseDouble(sAfter);//parse to integer
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
System.out.println(i);//2.03445
UPDATE:
Looking at your code snippet the problem might be that you read it directly as a float/int/double (thus entering a whitespace stops the nextFloat()) rather read the input as a String using nextLine(), delete the white spaces then attempt to convert it to the appropriate format.
This seems to work fine for me:
public static void main(String[] args) {
//bugChecking bc = new bugChecking();
float i = 0.0f;
String tmp = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (true) {
tmp = in.nextLine();//read line
tmp = tmp.replaceAll("\\s+", "");//get rid of spaces
if (tmp.isEmpty()) {//wrong input
System.err.println("Please enter a number greater than 0.");
} else {//correct input
try{//attempt to convert sring to float
i = new Float(tmp);
}catch(NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
System.out.println(i);
break;//got correct input halt loop
}
}
in.close();
}
EDIT:
as a side note please start all class names with a capital letter i.e bugChecking class should be BugChecking the same applies for test2 class it should be Test2
String objects have methods on them that allow you to do this kind of thing. The one you want in particular is String.replace. This pretty much does what you're trying to do for you.
String input = " 2.03 445 ";
input = input.replace(" ", ""); // "2.03445"
You could also use regular expressions to replace more than just spaces. For example, to get rid of everything that isn't a digit or a period:
String input = "123,232 . 03 445 ";
input = input.replaceAll("[^\\d.]", ""); // "123232.03445"
This will replace any non-digit, non-period character so that you're left with only those characters in the input. See the javadocs for Pattern to learn a bit about regular expressions, or search for one of the many tutorials available online.
Edit: One other remark, String.trim will remove all whitespace from the beginning and end of your string to turn " 2.0332" into "2.0332":
String input = " 2.0332 ";
input = input.trim(); // "2.0332"
Edit 2: With your update, I see the problem now. Scanner.nextFloat is what's breaking on the space. If you change your code to use Scanner.nextLine like so:
while (i <= 0) {
String input = in.nextLine();
input = input.replaceAll("[^\\d.]", "");
float i = Float.parseFloat(input);
if (i <= 0.0f) {
System.out.println("Please enter a number greater than 0.");
}
System.out.println(i);
}
That code will properly accept you entering things like "123,232 . 03 445". Use any of the solutions in place of my replaceAll and it will work.
Scanner.nextFloat will split your input automatically based on whitespace. Scanner can take a delimiter when you construct it (for example, new Scanner(System.in, ",./ ") will delimit on ,, ., /, and )" The default constructor, new Scanner(System.in), automatically delimits based on whitespace.
I guess you're using the first argument from you main method. If you main method looks somehow like this:
public static void main(String[] args){
System.out.println(deleteSpaces(args[0]);
}
Your problem is, that spaces separate the arguments that get handed to your main method. So running you class like this:
java MyNumberConverter 22.2 33
The first argument arg[0] is "22.2" and the second arg[1] "33"
But like other have suggested, String.replace is a better way of doing this anyway.

Categories

Resources