public static boolean isValidNumber(String a1)
{
String x = ("0123456789");
boolean valid = false;
for (int i = 0; i < 4; i++) {
char c = a1.charAt(i);
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
valid = true;
}
else {
valid = false;
}
}
}
return valid;
}
The above method checks to see whether an input of a four character string is composed of the characters 0123456789. However, regardless of what the input is, the method always returns as false.
If I were to change the valid value in the else statement to true, the method would always return as true.
What is the error that I have made in this method?
As soon as you find a non matching character, break the loop otherwise the next matching character will set valid to true.
e.g. "123a456" is considered valid.
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
valid = true;
}
else {
valid = false;
break;
}
}
If for some reason you don't want to break the loop, you could keep an "invalid counter" and make sure that is 0 at the end.
Of course for what you are doing here, Integer.parseInt() might be your best bet ;-)
a String.equals method will check these two strings in a single statement if you are permitted to use that.
public static boolean isValidNumber(String a1)
{
String x = ("0123456789");
return x.equals(a1);
}
I would rewrite your function as given below,
String x = ("0123456789");
boolean valid = false;
for (int i = 0; i < 4; i++) {
char c = a1.charAt(i);
boolean isCharOK = false;
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
isCharOK = true;
break;
}
}
if (!isCharOK) {
valid = false;
break;
}
}
return valid;
John3136 is quite correct, but I would like to propose even better solution to your whole task:
final static String x = "0123456789";
public static boolean isValidNumber(String a1) {
for (int i = 0; i < a1.length(); ++i) {
if (x.indexOf(a1.charAt(i)) == -1) return false;
}
return true;
}
In short: the above code "looks up" every character in your parameter string a1 in the string composed of digits. If it can find it, continues. If it can't, it means a1 consist not only digits and returns false. If it passes through all a1 characters then it returns true :)
And as asked and described in the comments - handling of duplicate characters in argument string:
final static String x = "0123456789";
public static boolean isValidNumber(String a1) {
for (int i = 0; i < a1.length(); ++i) {
final char currentChar = a1.charAt(i);
if (x.indexOf(currentChar) == -1 || a1.indexOf(currentChar, i+1) != -1)
return false;
}
return true;
}
The function call a1.indexOf(currentChar, i+1) essentially checks if there is any duplicate character in the rest of the string (from position i+1 and farther). Which means if it will be able to find duplicate char, the method return false :) Hope this helps, here is more info on String.indexOf(int, int) function if you want:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int, int)
You can use this one liner function to check for validity of a String as Number using Regular Expression
public static boolean isValidNumber(String a1)
{
return a1.matches("[\\d]+");
}
Hope this helps.
Related
I trying to write one string Anagram program but stuck while checking the boundary conditions.
I know there are lots of ways and programs available on internet related to String Anagrams using single loops or using collections framework, but I need the solution for my code that how can I involve boundary cases for the code.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "abc";
String strAnagram = "cba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
// TODO Auto-generated method stub
int count = 0;
char[] a = strAnagram.toCharArray();
if (str.length() != strAnagram.length()) {
return false;
}
for (int i = 0; i < str.length(); i++) {
{
System.out.println("str.charAt(i) in outer loop :" + str.charAt(i));
for (int j = 0; j < strAnagram.length(); j++) {
if (str.charAt(i) == strAnagram.charAt(j)) {
System.out.println("str.charAt(i) : " + str.charAt(i));
System.out.println("strAnagram.charAt(j) : " + strAnagram.charAt(j));
count++;
}
}
}
System.out.println(count);
if (count == str.length()) {
return true;
}
}
return false;
}
}
Code is working fine if I am inputting the input likes -
"abc" or "abcd" where each char in string is occuring only one time, but it fails when input is like "aab" can be compared to "abc" and it will show strings are anagrams.
So, how this condition I can handle in my code. Please advice.
The problem with your solution is that it only checks if each character in the first string is present in the second string. There are 2 more conditions you need to consider:
If each character in the second string is also present in the first string
If character count for each character in the first and the second string matches
Your current solution will return True for input of ("aaa", "abc") while it should return False. Implementing the first condition I mentioned above will fix this problem.
After you implement the first condition, your solution will return True for input of ("abb", "aab") while it should return False. Implementing the second condition I mentioned above will fix this problem.
Here is a simple way to make this work:
Map<Character, Integer> charCount = new HashMap<Character, Integer>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (charCount.containsKey(c)) {
charCount.put(c, charCount.get(c)+1);
} else {
charCount.put(c, 1);
}
}
for (int i = 0; i < strAnagram.length(); i++) {
char c = strAnagram.charAt(i);
if (!charCount.containsKey(c)) return false;
if (charCount.get(c) == 0) return false;
charCount.put(c, charCount.get(c)-1);
}
for (char k : charCount.keySet()) {
if (charCount.get(k) != 0) return false;
}
return true;
Since there are no nested loops, the time complexity is O(n). Even though a Map is used, the space complexity is O(1), since it is guaranteed that the total number of keys will not exceed the number of all possible characters.
This solution is even better than sorting in terms of time and space complexity.
This may still be wildly inefficient. Again I apologize for initially overlooking your requirement that no collection frameworks could be included.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
// String str = "abc";
// String strAnagram = "cba";
String str = "abcdd";
String strAnagram = "dccba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
int count = 0;
char[] a = strAnagram.toCharArray();
char[] b = str.toCharArray();
String alphaString = "abcdefghijklmnopqrstuvwxyz";
char[] alpha = alphaString.toCharArray();
System.out.println(a);
System.out.println(b);
System.out.println("");
if (str.length() != strAnagram.length()) {
return false;
}
for (int i=0; i < alpha.length; i++) {
int countA = 0;
int countB = 0;
for(int j = 0; j < a.length; j++){
if (a[j] == alpha[i]) {
countA++;
}
if (b[j] == alpha[i]) {
countB++;
}
}
if (countA != countB) {
return false;
}
}
return true;
}
}
This alternate solution makes use of a string that contains all the letters in the alphabet, and iterates through them to check if both strings have the same count of each letter. No frameworks this time :)
I have this boolean method that is supposed to compare all the characters between the "word" and "inputPlay", and update the int array to value 1 if they match as well as return true.
However, it does not loop and instead stops if it finds a match. What should I do differently?
public static boolean updateArray(String word, int[] guesses, String inputPlay) {
for (int i = 0; i < word.length(); i++) {
if (inputPlay.charAt(0) == word.charAt(i)) {
guesses[i] = 1;
}
return true;
}
return false;
}
Going off of the assumption that you should return true if any of the letters match, you'll need to use a temporary boolean that you declare outside the loop:
public static boolean updateArray(String word, int[] guesses, String inputPlay) {
boolean match = false;
for (int i = 0; i < word.length(); i++) {
if (inputPlay.charAt(0) == word.charAt(i)) {
guesses[i] = 1;
match = true;
}
}
return match;
}
Because we set match to true inside the if-statement, it will still continue iterating and return true after the for-loop terminates, assuming any of the letters match. Otherwise, it will return false.
I'm a student, and I've been working on the following challenge: find a substring (the needle) in a larger string (the haystack) without using the substring method, and using recursion. Recursion isn't my strong suit, but I have worked out the following:
public class Contains
{
public static void main(String[] args)
{
System.out.println(contains("Java programming", "ogr", false));
}
public static boolean contains(String haystack, String needle, boolean doesContain)
{
if(haystack.length() < needle.length())
{
return false;
}
else
{
for(int i = 0; i < needle.length(); i++)
{
if(haystack.charAt(i) != needle.charAt(i))
if((i + 1) == needle.length())
{
doesContain = false;
break;
}
else
break;
else
if((i + 1) == needle.length())
{
doesContain = true;
break;
}
else
continue;
}
char[] haystackChar = haystack.toCharArray();
char[] newCharArray = new char[(haystackChar.length - 1)];
for(int j = 1; j < haystackChar.length; j++)
{
newCharArray[j - 1] = haystackChar[j];
}
String newStr = new String(newCharArray);
if(doesContain == false)
contains(newStr, needle, doesContain);
}
return doesContain;
}
}
I realize this might not be the best or most elegant solution, but I am mostly just trying to get it to work. I've been running it in the Eclipse debugger, and everything is functioning as expected up until the call to if(doesContain == false) during the method call to contain where doesContain is set to true during the iteration of the for loop. The debugger is showing the value of doesContain to (correctly) be true, and it shows it skipping over the if statement, and exiting the else block. However, immediately after that, it jumps back up into the else block and only calls the recursive call to contain, instead of returning doesContain. Then, it continues to work recursively and subsequently fail and return false, because it's now searching through the rest of the string, where the "needle" is not located.
I know that StackOverflow is not a 'homework help' location per se, but I program for purposes other than school, and I'm quite perplexed as to why it's behaving this way. Does anyone know why it's doing this? Am I missing something here?
I took a look through your code and ran it in eclipse myself. A theory you will want to look into is how stacking works in recursion. Your program is finding true and then leaving the stack, but by that point it had reoccurred several times. It returned true, but then also went on to return all the false variables that were stored before it.
If you have any further questions please let me know.
EDIT
If you are really interested in getting into advanced recursion I highly recommend this video: Java Recursion
Hey, I didn't need to go that far to make it work. You can remove doesContain as a parameter and set it as a static instance variable and it worked for me.
public class Contains
{
private static boolean doesContain = false;
public static void main(String[] args)
{
System.out.println(contains("Java programming", "ogr"));
}
public static boolean contains(String haystack, String needle)
{
if(haystack.length() < needle.length())
{
return false;
}
else
{
for(int i = 0; i < needle.length(); i++)
{
if(haystack.charAt(i) != needle.charAt(i))
if((i + 1) == needle.length())
{
doesContain = false;
break;
}
else
break;
else
if((i + 1) == needle.length())
{
doesContain = true;
break;
}
else
continue;
}
char[] haystackChar = haystack.toCharArray();
char[] newCharArray = new char[(haystackChar.length - 1)];
for(int j = 1; j < haystackChar.length; j++)
{
newCharArray[j - 1] = haystackChar[j];
}
String newStr = new String(newCharArray);
if(doesContain == false)
contains(newStr, needle);
}
return doesContain;
}
}
What you had was very close, but by passing it as a parameter you were storing every time you went through another recursion. This way you only return your final value.
To find a needle in the haystack in the way you want, you don't need to use recursion.
Just remove the following lines of code from your function and it will work just fine:
char[] haystackChar = haystack.toCharArray();
char[] newCharArray = new char[(haystackChar.length - 1)];
for(int j = 1; j < haystackChar.length; j++)
{
newCharArray[j - 1] = haystackChar[j];
}
String newStr = new String(newCharArray);
if(doesContain == false)
contains(newStr, needle, doesContain);
I think you are sort of confusing yourself with the recursive function. One of the variables passed to the recursive function is doesContain, but the function is supposed to return whether the string contains it! In the lines
if(doesContain == false)
contains(newStr, needle, doesContain);
The call to contains will return if the substring contains the needle. You need to take that value, and return it back up the call stack.
Hopefully that made some sense. If that didn't, I'll give you the code so you can figure it out yourself:
public static boolean contains(String haystack, String needle)
{
if(haystack.length() < needle.length())
{
return false;
}
else
{
boolean doesContain=false;
for(int i = 0; i < needle.length(); i++)
{
if(haystack.charAt(i) != needle.charAt(i))
if((i + 1) == needle.length())
{
doesContain = false;
break;
}
else
break;
else
if((i + 1) == needle.length())
{
doesContain = true;
break;
}
else
continue;
}
char[] haystackChar = haystack.toCharArray();
char[] newCharArray = new char[(haystackChar.length - 1)];
for(int j = 1; j < haystackChar.length; j++)
{
newCharArray[j - 1] = haystackChar[j];
}
String newStr = new String(newCharArray);
if(doesContain == false)
return contains(newStr, needle);
else
return true;
}
}
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;
}
I want to check for instance if string "ABCD" contains "DC" string in it in Java. But this is not a substring example, because every time my string and checking characters will change. and I store checking characters into an array, So substring failed, it only works if I have CD, or BC. and I couldn't do match since every time I call checking character from an array. SO what should I do any suggestion
here's some pseudocode to get you started
we'll call "ABCD" the source string and "DC" the target string
change source string to list of chars
change target string to list of chars
for each char in target list of char
if source list does not contain target char
return false;
return true
I use this method for char and byte array. After you got the index of the src array where the sub is matched with, you then can store it anywhere you want.
Try this:
public static int indexOf(char[] src, char[] sub) {
int limit = src.length - sub.length;
int i, j;
for(i = 0; i < limit +1; ++i) {
for(j = 0; j < sub.length; ++j) {
if (src[i+j] != sub[j]) {
break;
}
}
if (j == sub.length)
return i;
}
return -1;
}
Get all the permutation of the source string till it contains the desired sub string
Permutation Logic based on
public static void main(String[] args) {
System.out.println(Test.checkIfContains("ABCD", "DC"));
}
public static Boolean checkIfContains(String main, String check) {
return permutation("", main, check);
}
private static Boolean permutation(String prefix, String main, String check) {
int n = main.length();
if (n == 0) {
if (checkFor(prefix, check)) {
return true;
}
} else {
for (int i = 0; i < n; i++) {
if (permutation(prefix + main.charAt(i), main.substring(0, i) + main.substring(i + 1, n), check)) {
return true;
}
}
}
return false;
}
private static boolean checkFor(String prefix, String check) {
return prefix.contains(check);
}
As I understand it, you want to see if all of the characters of the second string (which I called checkString) are contained in the first string (refString). I would proceed using a function like this
private boolean checkString(String refString, String checkString) {
boolean a;
for (int i; i < checkString.length(); i++) {
for (int j; j < refString.length(); j++) {
a |= checkString.charAt(i) == refString.charAt(j);
}
if (!a) return false;
}
return true;
}
Which return true only when all the characters in checkString are in the reference string.