I have to create a program in which I input 2 values simultaneously but, these values must range from 50 to 127. If the value is less than 50 or above 127 it should show an exception saying "value entered" is too low or too high. As a requirement for the program, I cannot use flow-control statements. I have not tried anything as I am lost
UPDATE: WITH THE HELP OF YOUR COMMENTS I HAVE SATISFIED THE 127 CONDITION, AND MAY BE ON THE WAY TO SATISFYING THE LOWER CONDITION WITH THE NEXT(PATTERN) METHOD. I AM CURRENTLY CONTACTING MY TEACHER AND ASKING IF SATISFYING THE 127 CONDITION IS ENOUGH. THANK YOU ALL
UPDATE 2: the 127 condition was enough!
import java.util.Scanner;
public class A1_Q1 {
public static void main(String[] args) {
// declaration of variables
double x, y, z;
int p, q;
Scanner kBoard = new Scanner(System.in);
System.out.println("Welcome to the Simple 3D-Space Program:");
System.out.println("+++++++++++++++++++++++++++++++++++++++");
System.out.print("Enter values for 'p' and 'q' simultaneously. Must be between 50 and 127:");
String input = kBoard.nextLine();
//separating first number and second number from the inputed line
String firstNum = input.substring(0, input.indexOf(" "));
String secondNum = input.substring(input.indexOf(" "), input.length());
//isolating numbers from the strings and filtering out
String numOnlyP = firstNum.replaceAll("[^0-9]", "");
String numOnlyQ = secondNum.replaceAll("[^0-9]", "");
//transforming string into integer values
p = Integer.parseInt(numOnlyP);
q = Integer.parseInt(numOnlyQ);
//to check and see if previous code was functioning correctly
System.out.println(p + " " + q);
}
}
The constraint against using flow control statements is highly artificial, but it does force you into a certain direction. For the program to behave differently for some inputs than it does for others requires flow control. If you cannot use flow control in your program then that means the needed flow control must be somewhere else. And the only "somewhere else" you are allowed to use is java.util.Scanner.
As a blooming programmer, some of the things you need to learn and have ready at all times at the tip of your brain are the powers of two, and certain ones of them especially. Among those is 27 = 128, which has special significance as one more than 127, the maximum value of an 8-bit two's complement integer, such as a Java byte (these properties are closely related). And lo and behold, the maximum value your program is supposed to accept is 127.
Read the API docs of Scanner, especially those for scanning inputs of various specific Java types. You will find some that can serve the purpose of (as a side effect) throwing an exception for inputs larger than 127. If you want to throw a custom exception instead, then you can catch the one thrown by the Scanner and throw one of your choice in its place -- provided that try / catch is not considered flow control.
Scanner could be pressed into service for an exception for violation of the lower bound, too, but that would require a very unnatural hack.
Details are left as the exercise they are intended to be.
This question is a tad disingenuous. A requirement that 50-127 is accepted, the rest is not, is not normally possible without flow control. So we need flow control, but, we're not allowed to use flow control.
Quite the dilemma.
It's a bit like an escape room. You must screw together this intricate thing, but, you don't have a screwdriver (all your pockets were emptied before entering it), so now what? Well, you look around the room. What tools do you have? Even if they are epically not suited to the job, can they be used to deliver?
So, let's look. What do we have? We have scanner.
We need to look at what you can do with those, and see if that helps, because other than Scanner you're not given much room to work.
And lo! Scanner delivers. It's a method that is almost never used with scanner, but it's there, and it'll give us a way through: The next(Pattern) method can do the job.
Quoting from the javadoc:
Returns the next token if it matches the specified pattern.
Great!
Now, I'm flabbergasted, but the docs are broken. Java is used by millions of people and the docs are taken fairly seriously, so that is mostly an indictment on how little this method is used. Nobody, apparently, noticed. The thing missing from the docs is subtle, but important: What happens if the next token in the stream does not match the specified pattern? The docs don't say. But the scanner acts the exact same way as when you call e.g. nextInt() and the next token is not an int: It throws InputMismatchException.
This means next(Pattern) is the complete package: Will pass if input 'matches the pattern' and throws if it does not, so now all we need is a pattern that matches if the input is 50-127 and fails otherwise. We can trivially do that, though we'll need to dive into Regular Expressions to do the job - as that is the 'language' for the pattern we can provide to this next method. (There is a String variant too, but it just parses your string as... a regular expression, so we can't get out of reading up on those).
Scanner s = new Scanner(System.in);
int value = s.next("[5-9][0-9]|1[0-1][0-9]|12[0-7]");
It's a rather unwieldy pattern, but it'll get the job done. This pattern says:
The input has to be one of these 3 different options (a|b|c is regexp for: either a, or b, or c)
Option 1: A 5/6/7/8/9, followed by any digit.
Option 2: A 1, followed by a 0 or a 1, followed by any digit.
Option 3: A 1, a 2, and then a 0/1/2/3/4/5/6/7.
That'll covers 50-127. If you want e.g. 00050 to be okay too, stick a 0* on the front, which regexp for 'any amount of zeroes'.
I think this exercise is quite a reach. As the answers provided so far clearly attest, no java programmer would get in their right mind to solve such a task by using the regexp pattern powers of scanner, they'd just read an int and use an if like normal. As the unwieldiness of that regexp shows, using a regex pattern to limit numeric input is not really what it is meant for. A key insight into writing readable, flexible code is to avoid doing that: Using a thing in a way that the author of the thing clearly was not at all thinking about when they wrote it is a fine way to create confusing code that runs into bugs quickly and may no longer work nearly as well in future updates of said thing. I guess it's testing if you can think creatively and read documentation, perhaps?
If you can contact the author of this question, you might want to have them read this answer too :)
I'll be filing a bug over at OpenJDK about the subtle mistake in the docs, at any rate.
Quite standard approach for such problems is to use lookup tables, something like this:
import java.util.Scanner;
public class TestProgram {
private interface Handler {
void handle(final int value);
}
private static class NullHandler implements Handler {
public void handle(final int value) { }
}
private static class TooLowHandler implements Handler {
public void handle(final int value) {
throw new IllegalArgumentException("Value " + value + " is too low");
}
}
private static class TooHighHandler implements Handler {
public void handle(final int value) {
throw new IllegalArgumentException("Value " + value + " is too high");
}
}
private static void checkLow(final int value) {
final int sign = ((value - 50) >> 31) & 1;
new Handler[]{new NullHandler(), new TooLowHandler()}[sign].handle(value);
}
private static void checkHigh(final int value) {
final int sign = ((value - 128) >> 31) & 1;
new Handler[]{new TooHighHandler(), new NullHandler()}[sign].handle(value);
}
public static void main(final String args[]) {
final Scanner scanner = new Scanner(System.in);
final int p = scanner.nextInt();
final int q = scanner.nextInt();
System.out.println(p + " " + q);
checkLow(p); checkLow(q);
checkHigh(p); checkHigh(q);
}
}
Related
I'm brand new to Java. I've been assigned a test and I'm stuck on how to complete it. So the case is like so -
Create a method that returns a patterned string from range A000 to ZZZZ. Parameter for the method is string itself, so if we pass A000 it should return A001, if we pass A001 it should return A002 and so on... A009... A999... AA00... AA99... AB00... AB01... AB99... AC00... to AZZZ.
I've been able to increment the numbers, but am unable to change them to letters when they reach 99. Let's say I input AZ99; it should return AZA0, but I don't know how I should write that logic.
I thought of using arrays, but then I'd have to save each iteration of the pattern in the array, and that seems unfeasible. Then I thought I'd use if...else and write the instances where the numbers should increment into letters, but that's unnecessarily long too. I know this can be done by proper logic, but it fails me. I've scrounged multiple threads on stackoverflow, but I can't find one quite like this one.
This is what I've got so far -
public class StringSeries {
public static String returnString (String inputString) {
String newString = inputString.substring(0,2);
String completeNewString = newString +
(Integer.parseInt(inputString.substring(1,inputString.length()))+1);
System.out.println(completeNewString);
return completeNewString;
}
public static void main (String[] args){
Scanner sc = new Scanner();
String inputString = sc.nextLine();
returnString(inputString);
sc.close();
}
}
I need suggestions on how to do this. Also, please elaborate on how a certain logic would work.
Thanks!
P.S. I've looked a lot for this type of question on forums, and haven't been able to find any. I also realize that this question may be repetitive for non-newbies. I request that you don't be rude and point out similar threads if you know where they are. Thanks.
This is much easier than it seems. All you need to do is convert the string to a number in base 36 (Integer.valueOf, Integer.parseUnsignedInt), add one to it, and convert it to an upper case base-36 string (Integer.toString plus converting that to upper case).
Given array of strings like [“crane", "drain", "refrain”] and a pattern such as *an* where * can match any number of characters.
Return the matching word in an efficient manner. (In this example, "crane")
I can solve it in very simple way:
String [] array = {"crane", "drain", "refrain"};
String pattern="an";
for(String s:array){
if(s.contains(pattern)){
System.out.println(s);
}
}
Is there a way to optimize the code performance in java? Consider array can contains a large number of strings.
You could try it with Regular Expressions (regex).
public class RegexExample3{
public static void main(String args[]){
String [] array = {"crane", "drain", "refrain"};
for(String s:array){
if(java.util.regex.Pattern.matches(".*an.*", s))
System.out.println(""+s);
}
}
}
Here is the link if someone doesn't know about regex and would want to understand it.
well, if you want to check if a word is match a pattern without using any Regex, contains..etc
i suggest to encode the pattern in way that if you encode a word will have same hashing...
but, in your case i suggest to do this:
static String EncodeString(String x){
String output="";
for(int i=0;i<x.length();i++){
// *an* == 0110
char c=x.charAt(i);
if(c=='n'|| c=='a'){
output +="1";
} else {
output +="0";
}
}
return output;
}public static void main(String args[])
{
String pattern="*an*";
String enPattern=EncodeString(pattern);
String word="xyanxvsdanfgh";
String enWord=EncodeString(word);
System.out.println(enPattern+" "+enWord);
int v1=Integer.parseInt(enPattern);
int v2=Integer.parseInt(enWord);
System.out.println(" % :"+ v2%v1);// notice here if word not match the pattern then the MOD operation will NOT return 0
}
The assignment asks for a return of the matching word, so the assumptions are, that there is one word, and only one word matching.
And if there is just one word, it is efficient to return early, instead of looping on. You have been close.
String matching (String pattern, String [] array) {
for (String s:array)
if (s.contains (pattern))
return s;
return "";
}
Think about alternatives, how to measure s.contains (pattern) against Regex.pattern.matches, how many cases you would have to generate, to find a difference. Without doing the measurement, you're not sure, that it isn't less efficient. Maybe the pattern should be precompiled?
In such assignments, supposed you cited it carefully, you usually have to take everything very carefully.
Often people have good ideas about a topic, and can't hesitate to implement their first idea to it. Don't do it!
Given array of strings like [“crane", "drain", "refrain”] and a
pattern such as an where * can match any number of characters.
Return the matching word in an efficient manner. (In this example,
"crane")
Be very sensible for every violation of your expectation. It is asked for returning the matching word. Did you notice the singular case? What might it mean in the context of efficient manner?
Of course you have to know your teacher, whether he is a bit sloppy or not and fluent in the language, he uses. But interfaces of methods which fit together are a big issue in software development and reading the specs carefully, too. You soon end up investing much time into a solution which works, but doesn't fit the problem.
Returning an empty String is probably not the best idea, but seems sufficient for the level, and without further context it is hard to decide, what an appropriate reaction would be, if nothing is found. Again, the wording suggests, that there is exactly one solution.
I'm making a word guessing game. The JTextField can't be empty, can't be longer or smaller than 5 and cannot contain numbers. How do I do the last part?
#Override
public void actionPerformed(ActionEvent e) {
if (text.getText().isEmpty()) {
showErrorMessage("You have to type something");
} else if (text.getText().length() != 5) {
showErrorMessage("Currently only supporting 5-letter words");
} else if (contains integer){
showErrorMessage("Words don't contain numbers!");
} else {
r.setGuess(text.getText());
}
}
Rather than explicitly checking for numbers, I would suggest whitelisting characters which are allowed. Would letters with accents be allowed, for example? Both upper and lower case? Punctuation?
Once you've worked out your requirements, I suggest you express them as a regular expression - and then check whether the text matches the regular expression.
For example:
private static final Pattern VALID_WORD = Pattern.compile("^[A-Za-z]*$");
...
if (!VALID_WORD.matcher(text.getText()).matches()) {
// Show some appropriate error message
}
Note that I haven't included length checks in there, as you're already covering those - and it may well be worth doing so in order to give more specific error messages.
You might also want to consider preventing your text box from accepting the invalid characters to start with - just reject the key presses, rather than waiting for a submission event. (You could also change the case consistently at the same time, for example.) As noted in comments, JFormattedTextField is probably a good match - see the tutorial to get started.
create a method that checks if the JTextField has a number like this:
private boolean isContainInt(JTextField field) {
Pattern pt = Pattern.compile("\\d+");
Matcher mt = pt.matcher(field.getText());
return mt.find();
}
if (!text.getText().matches("[a-zA-Z]*")) {
// something wrong
}
We have a combination of number where the first to numbers determine a format for the last one:
0001/0001/AF001 -> 0001/0001 == Rule for third number: two characters, three digits
0002/0001/0001 -> 0002/0001 == Rule for third number: four digits
We need to validate these numbers before storing them in a database. Since this is a common problem in several of our projects, we want to do the validation in a central service (in this case a ejb).
My first idea was to just use a method like:
public boolean isValid(String number1, String number2, String number3);
but we want to relay the rule if something is not valid, so that the user can see what went wrong, so my next idea is:
public void checkNumbers(String number1, String number2, String number3) throws DetailsException;
So one could invoke that like this:
try {
checkNumbers("0001", "0001", "AF002");
} catch(DetailsException d) {
// error handling
}
But this seems kind of ugly... What are the alternives/other ideas to solve this situation. Is there a typical pattern to use?
Well, a customary (but somewhat old-fashioned) alternative to throwing an exception is returning an error code (or error object):
ErrorInfo err = checkNumbers(n1, n2, n3);
if (err != null)
{
...
But I personally would go for the variant with exception.
A friend gave me this piece of code and said there is a bug. And yes, this code runs for ever.
The answer I got is:
It runs for >10^15 years before printing anything.
public class Match {
public static void main(String[] args) {
Pattern p = Pattern.compile("(aa|aab?)+");
int count = 0;
for(String s = ""; s.length() < 200; s += "a")
if (p.matcher(s).matches())
count++;
System.out.println(count);
}
}
I didn't really understand why am I seeing this behavior, I am new to java, do you have any suggestions?
The pattern you are using is known as an evil regex according to OWASP (they know what they're talking about most of the time):
https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
It basically matches aa OR aa or aab (since the b is optional by addition of ?)
A Regex like this is vulnerable to a ReDoS or Regex Denial of Service Attack.
So yes, sort out what you want to match. I suggest in the above example you should simply match aa, no need for groups, repitition or alternation:
Pattern p = Pattern.compile("aa");
Also as someone pointed out, who now deleted his post, you should not use += to append to strings. You should use a StringBuffer instead:
public class Match {
public static void main(String[] args) {
Pattern p = Pattern.compile("aa");
StringBuffer buffy = new StringBuffer(200);
int count = 0;
for(int i = 0; i < 200; i++){
buffy.append("a")
if (p.matcher(buffy.toString()).matches()){
count++;
}
}
System.out.println(count);
}
}
The regular expression (aa|aab?)+ is one that takes an especially long time for the regular expression engine to handle. These are colorfully called evil regexes. It is similar to the (a|aa)+ example at the link. This particular one is very slow on a string composed entirely of as.
What this code does is check the evil regex against increasingly long strings of as, up to length 200, so it certainly ought to take a long time, and it doesn't print until the loop ends. I'd be interested to know where the 10^15 years figure came from.
Edit
OK, the 10^15 (and in fact the entire piece of code in the question) comes from this talk, slide 37. Thanks to zengr for that link. The most relevant piece of information to the question is that the check for this regex takes time that is exponential in the length of the string. Specifically it's O(2^(n/2)), so it takes 2^99 (or so) times longer to check the last string than the first one.