Is it more efficient to use arrays or character? - java

is this the most efficient method to determine that there is a minimum of two unique characters in a String? Should I have used arrays to hold the characters? Thank you
public static Boolean checkPW(String pw) {
Boolean validLower = false, validUpper = false, validNumber = false;
char lowerCompare = '0', upperCompare = '0', numberCompare = 'a';
for(int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(character >= 'a' && character <= 'z') {
if(lowerCompare == '0')
lowerCompare = character;
else if(lowerCompare != character)
validLower = true;
} // lower-case if END
} // for-loop END
if(validLower)
return true;
else
return false;
} // checkPW END

If I had to do this in Java, in production, I might just use a set here:
String input = "abcdefgzz";
char[] letters = input.toCharArray();
Set<Character> set = new HashSet<>();
boolean valid = false;
for (char letter : letters) {
set.add(letter);
if (set.size() > 1) {
valid = true;
break;
}
}
if (valid) {
System.out.println("Minimum of two unique letters");
}
else {
System.out.println("Only one unique letter");
}

is this the most efficient method to determine that there is a minimum of two unique characters in a String?
No. The loop continues to run after 2 unique valid characters are found, which is unnecessary. It could stop immediately, and then it will be more efficient. Consider for example the string "ab" followed by a million characters. There's no need to go further than the first two.
Should I have used arrays to hold the characters?
The question is not clear. To make it meaningful, you would need to include reasoning for the benefits of both methods. And it's not clear what technique you're referring to.
It would be good to remove all the unnecessary variables from the program.
After fixing the inefficiency, and a bit of cleanup:
public static boolean checkPW(String pw) {
char first = '0';
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if ('a' <= character && character <= 'z') {
if (first == '0') {
first = character;
} else if (first != character)
return true;
}
}
}
return false;
}

I'd do this:
public static boolean checkPW(String pw) {
Character lowerCompare = null;
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(Character.isLowerCase(c)) { // this handles non-ASCII lower case characters
if(lowerCompare == null) {
lowerCompare = character;
} else if(lowerCompare != character) {
return true;
}
}
}
return false;
}

Related

Check if a String has vowels, and create a new String that doubles the consonants

So here's what I'm trying to do. I take a given string, and make a new string. The new string will be the same as the original string, but will have the consonants doubled.
For example, rabbit becomes rrabbitt and so forth. It only doubles the consonants that aren't already doubled.
Here's what I have so far:
// Returns a new string in which all consonants in the given string are doubled.
// Consonants that are already doubled are not doubled again.
// For example, doubleConsonants("rabbit") returns "rrabbitt".
// It is assumed that in the given string is alphabetic and that no character
// appears more than twice in a row.
// Parameters:
// s - given string
// Returns new string with all consonants doubled
----------------------------------------------------------------------------
public static String doubleConsonants(String s) {
String newString = "";
String vowels = "aeiouAEIOU";
for (int i = 0; i < s.length(); i++) {
boolean hasVowel = false;
for (int n = 0; n == 10; n++){
if ( vowels.charAt(n) == s.charAt(i)) {
newString += s.charAt(i);
i++;
hasVowel = true;
break;
}
}
if (hasVowel = false && s.charAt(i) != s.charAt(i+1) && s.charAt(i) != s.charAt(i-1)) {
newString += s.charAt(i);
i++;
}
else if (hasVowel = false) {
newString += s.charAt(i);
i++;
}
}
return newString;
}
Apparently there are some issues with "dead code" and the boolean hasVowels is "not used". What am I screwing up?
You can do one thing. Using a contains() method will greatly reduce all your work.
for (int i = 0; i < s.length(); i++) { // traverse through the string
if (i < s.length() - 1 && s.charAt(i) == s.charAt(i + 1)) {
newString += s.charAt(i); // handles the double constant special condition like bb in rabbit
i++;
} else if (vowels.contains("" + s.charAt(i))) { //check if the letter is a vowel
newString += s.charAt(i); // if yes, add it once
} else {
newString += "" + s.charAt(i) +s.charAt(i); // else add it twice
}
}
At the end of this code block, you will have the required string stored in newString. you can read more about contains()
Try this.
public static String doubleConsonants(String s) {
return s.replaceAll("(?i)(([^aeiou])\\2+)|([^aeiou])", "$1$3$3");
}
First thing I notice is that the if-statements towards the bottom are using the assignment operator. You want to use the double-equals to test the value. I'll have to look more closely at the logic for more.

how can I check if a string is a floating point number?

In my program I'm going to store user input in an array then going to check each character to see if it's a digit or dot or E or negative sign after that I'll store it in to an array called temps.
Now I have problem in my fleating method () that don't how should I make my condition for the pattern of floating number digit-digit-dot-digit-digit (e.g 12.22)
I have my work here:
public void sorting(String data) {
String[] temps = new String[200];
int cpos = 0;
int tpos = 0;
Arrays.fill(temps, null);
if (str.isEmpty() == false) {
char char1 = str.charAt(cpos);
int i = 0;
while (i < str.length()) {
char1 = str.charAt(cpos);
char1 = str.charAt(tpos);
System.out.println("the current value is " + char1 + " ");
tpos++;
if (Character.isDigit(char1)) {
temps[cpos] = "Digit";
// System.out.println(" this number is digit");
cpos++;
} else if (char1 == 'e' || char1 == 'E') {
temps[cpos] = "s_notaion";
cpos++;
} else if (char1 == '-') {
temps[cpos] = "negative";
cpos++;
} else if (char1 == '.') {
temps[cpos] = ".";
cpos++;
}
i++;
}
}
}
here is the method for floating number
private static boolean floating(String [] data) {
int count =0;
boolean correct = false;
for (int i = 0; i < data.length; i++) {
if (data[i]== "Digit" )
&& data[i]=="." && data[i]"Digit"){
// here is the problem for the condition
}
}
return false;
}
If I understood correctly, the Data array has stuff like ["Digit","Digit",".","Digit"]
So you want the
private static boolean floating(String [] data) {
method to return true if the array only has "Digit" entries and exactly one "." entry? is that it?
If so:
boolean foundLeDigit = false;
for (int i = 0; i < data.length; i++) {
if (data[i].equals("Digit") == false && data[i].equals(".") == false {
//we found something other than a Digit or . it's not a float
return false;
}
if(data[i].equals(".")) {
if(foundLeDigit) { return false; //as we found 2 "." }
foundLeDigit = true
}
}
return foundLeDigit;
The easiest way to test if a String can represent a float is to try to parse it:
String testString = "1.2345";
double result;
try {
result = Double.parseDouble(testString);
System.out.println("Success!")
}
catch (NumberFormatException nfe) {
// wasn't a double, deal with the failure in whatever way you like
}
The questions lacks a bit of context, so for my answer I'm going to presume that this is homework requiring a manual solution, and that all floating point numbers are supposed to be accepted.
Your approach (while over-engineered) is half-right: you are reducing the input string into classes of characters - digit, sign, exponent marker. What is missing is that now you have to make sure that these character classes come in the right order.
Identify the various parts of float numbers (just look at 0, -1.0, 400E30, 42.1E-30) and you'll see that they come in a specific order, even if some are optional, and that each part imposes restrictions on what characters are allowed there. For example, if there is an 'E' in the number, it has to be followed by a number (with optional sign).
So as you step through the characters of the string, think about how you could keep track of where you are in the number, and base your character validation on that (this is the state machine #JonKiparsky was mentioning).
A few small things:
Don't compare strings with '==' - use equalsTo().
Think about what it means if sorting() finds a character which is neither a digit, a sign, or the exponent 'E'?
You allocate the temps array for 200 entries, but the input string could be larger.
using the regular expression is the best way to Handel this problem
private static boolean floating(String [] data) {
int count =0;
boolean correct = false;
for (int i = 0; i < data.length; i++) {
if (str.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")){
System.out.println(" it's a floating number ");
correct= true;
break;
}else
correct = false;
}if (correct ==true){
return true;
}else
return false;
}

method that will return true if there is no digit in code

package code;
public class WriteUp{
public boolean containsNoDigits(String s){
s = s.toLowerCase();
char[] n = {'0', '1', '2', ....., '9'} //i wrote out 0-9
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if (c == n[i]);
return false; //if string contain digit
}
return true; //if string contain NO digit
}
}
I want to write a method (using Array) to check if my string contain a digit or not. digit => false; no digit => true;
my code fail to pass both the JUnit test
JUnit Test:
#Test
public void test(){
code.WriteUp wu = new code.WriteUp();
boolean expected = true;
boolean actual = wu.containsNoDigits("there is no digit")
assertTrue("", expected ==actual);
}
#Test
public void test01(){
code.WriteUp wu = new code.WriteUp();
boolean expected = false;
boolean actual = wu.containsNoDigits("there are digit, 0342432")
assertTrue("", expected ==actual);
}
How can I fix the code so that it will work correctly
The semicolon terminates the block, remove it
if (c == n[i]); // <-- here
return false;
is actually
if (c == n[i]); // <-- here
return false;
You need something like (with braces preferably)
if (c == n[i]) {
return false;
}
or
if (c == n[i])
return false;
Also, a regular expression would be more efficient. Like
public boolean containsNoDigits(String s){
return !s.matches("\\d"); // <-- digit pattern
}
This should work:
public boolean hasDigit(String x){
for (char c : x.toCharArray())
if (Character.isDigit(c))
return false;
return true;
}
You can use a character array to effortlessly loop through all characters in the string and use the function Character.isDigit(c) to easily check each character. This is likely the most simple and easiest to read.
Hope this helps.
Java's Character class contains a static method that will check weather a character is a digit. Character.isDigit(char ch) will do this for you.
You code using this method could be
public boolean hasNoDigits(String s){
for(int i=0;i<s.length();i++){
if(Character.isDigit(s.charAt(i))){
return false;
}
}
return true;
}
If you only want the method to return false if the string contains standard latin digits , 0 through 9 (\u0030 through \u0039), your code could be modified to be this:
public boolean hasNoDigits(String s){
for(int i=0;i<s.length();i++){
char atIndex=s.charAt(i);
if(atIndex >= '0' && atIndex <= '9'){
return false;
}
}
return true;
}
The reason for this change is that Character.isDigit(char ch) returns true on all characters that are classified by Unicode to be digits.
Some Unicode character ranges that contain digits:
'\u0030' through '\u0039', ISO-LATIN-1 digits ('0' through '9')
'\u0660' through '\u0669', Arabic-Indic digits
'\u06F0' through '\u06F9', Extended Arabic-Indic digits
'\u0966' through '\u096F', Devanagari digits
'\uFF10' through '\uFF19', Fullwidth digits
What this means is that a string containing this 昍 or this ० would return true.
after reading my code again carefully i was able to know why i messed up and figure out a solution.
public boolean containsNoDigits(String s) {
s = s.toLowerCase();
char[] n = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == n[0] || c == n[1] || c == n[2] || c == n[3] || c == n[4] ||
c == n[5] || c == n[6] || c == n[7] || c == n[8] || c == n[9]) {
return false; // if s has no digit
}
}
return true; // if s has digit
}
thank you for providing shorter and more efficient solution. I am a beginner therefore i was writing my code as basic as possible, this solution was so that i can have a better understanding for using array.

Making a Given String a Palindrome

Can someone please discuss and explain a way I can modify my code to function with these test cases... I am trying to make my program take a word and make it a palindrome by replacing one letter in a word that prevents the word from being a palindrome
Desired test cases:
Palindromes.isPalindrome2("cat", 'c') => true
Palindromes.isPalindrome2("axaa", 'x') => true
Palindromes.isPalindrome2("12bb", 'b') => true
Palindromes.isPalindrome2("ca", 'c') => true
This is what I have thus far...
public class Palindromes {
public static boolean isPalindrome(String word) {
//Strip out non-alphanumeric characters from string
String cleanWord = word.replaceAll("[^a-zA-Z0-9]","");
//Check for palindrome quality recursively
return checkPalindrome(cleanWord);
}
public static boolean isPalindrome2(String word) {
//Strip out non-alphanumeric characters from string
String cleanWord = word.replaceAll("[^a-zA-Z0-9]","");
//Check for palindrome quality recursively
return checkPalindrome2(cleanWord);
}
public static boolean checkPalindrome(String word) {
if(word.length() < 2) {
return true;
}
char first = word.charAt(0);
char last = word.charAt(word.length()-1);
if(first != last) {
return false;
}
else {
return checkPalindrome(word.substring(1,word.length()-1));
}
}
public void replace(int first, int last) {
if(first != last)
{ first = last;}
else if(last != first)
{ last = first;}
}
public static boolean checkPalindrome2(String word) {
char special = 0;
if(word.length() < 2) {
return true;
}
char first = word.charAt(0);
char last = word.charAt(word.length()-1);
if(first != last) {
return false;
}
if(first != last)
return false;
else {
return checkPalindrome2(word.substring(1,word.length()-1));
}
}
}
replace() was my attempt at handling the wildcard letter, but I cant seem to find the appropriate solution... All help will be greatly appreciated. thanks...
Here's my steps I would do:
Split the received string into 2 substrings. The first string front being the front half of the string, the second string back being the half end of the string.
Example:
char replacement = 'c';
String input = "aabbcc";
StringBuilder front = new StringBuilder(input.substring(0, input.length()/2));
// Do modulus to not include the odd middle (it mirrors itself)
StringBuilder back = new StringBuilder(input.substring((input.length()/2)+(input.length()%2));
Compare the two strings, replacing if one matches but the other doesn't. If neither match each other and is not the given 'replacement' character, return false. If you do more than one replacement, return false (since that is what you said the requirement is)
Example:
int replacements = 0;
for (int i=0; i < front.length(); ++i)
{
int backIndex = back.length() - i;
if (front.charAt(i) != back.charAt(backIndex))
{
// Characters do not match at all to given replacement
if ((front.charAt(i) != replacement) &&
(back.charAt(backIndex) != replacement)
{
// Cannot make it
// (Or if you want to force it, set both to replacement
// by deleting this one if statement)
return false;
}
// Front matches replacement
else if (front.charAt(i) == replacement)
{
// Replace back character with replacement
back.setCharAt(backIndex, replacement);
replacements++;
}
// Back matches replacement
else if (back.charAt(backIndex) == replacement)
{
// Replace front character with replacement
front.setCharAt(i, replacement);
replacements++;
}
if (replacements > 1)
{
// Can only replace one
return false;
}
}
}
String output = front.toString() + back.toString();
Here's my code, it splits the input into two halves, and compares the first half to the reversed second half. If they are equal, the input is already a palindrome. If they are not equal, it iterates through the first half, exchanging letters with the input char to replace with, and comparing with the reversed second half at every step. Then it does the same thing, but using the second half instead of the first half:
public class CanMakePalindrome {
public static void main(String[] args) {
System.out.println("cat using c: " + canMakePalindrome("cat", 'c'));
System.out.println("axaa using x: " + canMakePalindrome("axaa", 'x'));
System.out.println("12bb using b: " + canMakePalindrome("12bb", 'b'));
System.out.println("ca using c: " + canMakePalindrome("ca", 'c'));
}
private static boolean canMakePalindrome(String input, char c) {
int length = input.length();
String start = input.substring(0, length/2);
String end = input.substring(length/2+length%2, length); // need modulus in the case of odd length input
return (replaceLoop(start,end, c) || replaceLoop(end,start, c));
}
private static boolean replaceLoop(String start, String end, char c) {
if (start.equals(reverse(end))) {
System.out.println("Input is already a palindrome.");
return true;
}
for (int i=0; i<start.length(); i++) {
char[] startchars = start.toCharArray();
char[] endchars = end.toCharArray();
endchars = reverse(endchars);
startchars[i] = c;
if ((new String(startchars).equals(new String(endchars)))) return true;
}
return false;
}
private static char[] reverse(char[] input) {
int length = input.length;
char[] reversed = new char[length];
for (int i=0;i<length;i++) {
reversed[length-i-1]=input[i];
}
return reversed;
}
private static String reverse(String input){
String reversed = new String(reverse(input.toCharArray()));
return reversed;
}
}
Output:
cat using c: true
axaa using x: true
12bb using b: false
ca using c: true
Note that 12bb cannot be made into a palindrome using only one character change, so your test case appears to not match your specifications of replacing only one letter. Also my code will return true if given an empty string as input.

Check if String contains only letters

The idea is to have a String read and to verify that it does not contain any numeric characters. So something like "smith23" would not be acceptable.
What do you want? Speed or simplicity? For speed, go for a loop based approach. For simplicity, go for a one liner RegEx based approach.
Speed
public boolean isAlpha(String name) {
char[] chars = name.toCharArray();
for (char c : chars) {
if(!Character.isLetter(c)) {
return false;
}
}
return true;
}
Simplicity
public boolean isAlpha(String name) {
return name.matches("[a-zA-Z]+");
}
Java 8 lambda expressions. Both fast and simple.
boolean allLetters = someString.chars().allMatch(Character::isLetter);
Or if you are using Apache Commons, [StringUtils.isAlpha()].
First import Pattern :
import java.util.regex.Pattern;
Then use this simple code:
String s = "smith23";
if (Pattern.matches("[a-zA-Z]+",s)) {
// Do something
System.out.println("Yes, string contains letters only");
}else{
System.out.println("Nope, Other characters detected");
}
This will output:
Nope, Other characters detected
I used this regex expression (".*[a-zA-Z]+.*"). With if not statement it will avoid all expressions that have a letter before, at the end or between any type of other character.
String strWithLetters = "123AZ456";
if(! Pattern.matches(".*[a-zA-Z]+.*", str1))
return true;
else return false
A quick way to do it is by:
public boolean isStringAlpha(String aString) {
int charCount = 0;
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (aString.length() == 0) {
return false; //zero length string ain't alpha
}
for (int i = 0; i < aString.length(); i++) {
for (int j = 0; j < alphabet.length(); j++) {
if (aString.substring(i, i + 1).equals(alphabet.substring(j, j + 1))
|| aString.substring(i, i + 1).equals(alphabet.substring(j, j + 1).toLowerCase())) {
charCount++;
}
}
if (charCount != (i + 1)) {
System.out.println("\n**Invalid input! Enter alpha values**\n");
return false;
}
}
return true;
}
Because you don't have to run the whole aString to check if it isn't an alpha String.
private boolean isOnlyLetters(String s){
char c=' ';
boolean isGood=false, safe=isGood;
int failCount=0;
for(int i=0;i<s.length();i++){
c = s.charAt(i);
if(Character.isLetter(c))
isGood=true;
else{
isGood=false;
failCount+=1;
}
}
if(failCount==0 && s.length()>0)
safe=true;
else
safe=false;
return safe;
}
I know it's a bit crowded. I was using it with my program and felt the desire to share it with people. It can tell if any character in a string is not a letter or not. Use it if you want something easy to clarify and look back on.
Faster way is below. Considering letters are only a-z,A-Z.
public static void main( String[] args ){
System.out.println(bestWay("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(isAlpha("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(bestWay("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(isAlpha("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
}
public static boolean bettertWay(String name) {
char[] chars = name.toCharArray();
long startTimeOne = System.nanoTime();
for(char c : chars){
if(!(c>=65 && c<=90)&&!(c>=97 && c<=122) ){
System.out.println(System.nanoTime() - startTimeOne);
return false;
}
}
System.out.println(System.nanoTime() - startTimeOne);
return true;
}
public static boolean isAlpha(String name) {
char[] chars = name.toCharArray();
long startTimeOne = System.nanoTime();
for (char c : chars) {
if(!Character.isLetter(c)) {
System.out.println(System.nanoTime() - startTimeOne);
return false;
}
}
System.out.println(System.nanoTime() - startTimeOne);
return true;
}
Runtime is calculated in nano seconds. It may vary system to system.
5748//bettertWay without numbers
true
89493 //isAlpha without numbers
true
3284 //bettertWay with numbers
false
22989 //isAlpha with numbers
false
Check this,i guess this is help you because it's work in my project so once you check this code
if(! Pattern.matches(".*[a-zA-Z]+.*[a-zA-Z]", str1))
{
String not contain only character;
}
else
{
String contain only character;
}
String expression = "^[a-zA-Z]*$";
CharSequence inputStr = str;
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
{
//if pattern matches
}
else
{
//if pattern does not matches
}
Try using regular expressions: String.matches
public boolean isAlpha(String name)
{
String s=name.toLowerCase();
for(int i=0; i<s.length();i++)
{
if((s.charAt(i)>='a' && s.charAt(i)<='z'))
{
continue;
}
else
{
return false;
}
}
return true;
}
Feels as if our need is to find whether the character are only alphabets.
Here's how you can solve it-
Character.isAlphabetic(c)
helps to check if the characters of the string are alphabets or not.
where c is
char c = s.charAt(elementIndex);
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the https://www.nuget.org/packages/Extensions.cs package to your project.
Add "using Extensions;" to the top of your code.
"smith23".IsAlphabetic() will return False whereas "john smith".IsAlphabetic() will return True. By default the .IsAlphabetic() method ignores spaces, but it can also be overridden such that "john smith".IsAlphabetic(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphabetic().
To allow only ASCII letters, the character class \p{Alpha} can be used. (This is equivalent to [\p{Lower}\p{Upper}] or [a-zA-Z].)
boolean allLettersASCII = str.matches("\\p{Alpha}*");
For allowing all Unicode letters, use the character class \p{L} (or equivalently, \p{IsL}).
boolean allLettersUnicode = str.matches("\\p{L}*");
See the Pattern documentation.
I found an easy of way of checking a string whether all its digit is letter or not.
public static boolean isStringLetter(String input) {
boolean b = false;
for (int id = 0; id < input.length(); id++) {
if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') {
b = true;
} else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') {
b = true;
} else {
b = false;
}
}
return b;
}
I hope it could help anyone who is looking for such method.
Use StringUtils.isAlpha() method and it will make your life simple.

Categories