In a particular if-else, I have to identify if a given value falls within a range. The condition part looks like this:
else if (a==2 && b.equalsIgnoreCase("line")
&& <<Here I need to search if c falls within a range>> && d)
where a is int, b is string, c is int and d is a boolean. Now if c falls within 1 to 8, the condition is true, else it is false. How can I do that?
I think you need you this condition for c
(c > 1 && c < 8) // 1 and 8 are exclusive
(c => 1 && c <= 8) // 1 and 8 are inclusive
Full sample
else if (a==2 && b.equalsIgnoreCase("line")
&& (c > 1 && c < 8) && d)
If you need to check if the values belongs to a set of values, you need to use a Set and then check if the c belongs to that or not. In your original question, it was mentioned as a range and thus the answer. Anyways, this is how you can check a value in a set.
Integer[] arr = {1,4,9,11,13};
Set<Integer> set = new HashSet<>(Arrays.asList(arr));
...
else if (a==2 && b.equalsIgnoreCase("line")
&& (set.contains(c)) && d)
Surprise surprise, it is c >= low && c <= high
To answer to the update, you'll need to employ a set
Set<Integer> validValues = new HashSet<Integer>();
validValues.add(1);
validValues.add(4);
validValues.add(9);
validValues.add(10);
validValues.add(19);
if (validValues.contains(currentVal)) {
// do stuff
}
To curb java's verbosity you may use Guava's immutable set:
Set<Integer> validValues = ImmutableSet.of(1, 4, 9, 10, 19);
Try like this, range1 and range2 are ranges from which you need to check b.
(c < range1 && c > range2) ? d=true : d=false;
You simply need to add:
c > 1 && c < 8
If you ever feel that your conditionals are getting too complicated I'd suggest creating Boolean methods that simplify them down a little. This is a very moderate case, but for example this range problem could be represented by:
public boolean inRange(int num)
{
return (num > 1 && num < 8);
}
Unfortunately, the only way to do it would be using if else statements (as far as I know). A switch statement does not accept conditional operators, and so would not work for that. As suggested by some others, you could use seperate methods, as the methods, would allow you to check if other values were in range as well. Instead of just for this value, however, you could go for something like
public Boolean inRange(int num, int lowBound, int topBound)
{
return (num > lowBound && num < topBound);
}
and just use it in your code like this
else if (a==2 && b.equalsIgnoreCase("line")
&& inBound(c, 1, 8) && d)
It does not look too messy, and will work (you'll need to decide whether it is inclusive or exclusive bounds though).
The reason for the changed method is that it could be used in other places as well, making it useful for range checking.
Related
import java.util.*;
public class BugFixes
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
altCaps("Computer Science");
}
static void altCaps(String hi)
{
String hi2 = hi;
int locate = 0;
for(int i = 0; i < hi2.length();i++)
{
if((Character.isLetter(hi2.charAt(locate))))
{
if(hi2.charAt(locate) % 2 == 0)
{
System.out.print(hi2.toLowerCase().charAt(locate));
locate++;
}
else if(hi2.charAt(locate) % 2 == 1)
{
System.out.print(hi2.toUpperCase().charAt(locate));
locate++;
}
}
else if(hi2.charAt(locate) == ' ')
{
System.out.print(" ");
locate++;
}
}
}
}
This is one of the problems that I have on my current lab. I was able to fix a few other mistakes but I can't seem to find this one.
My question is why it is outputting "COMpUtER SCIEnCE"? I don't understand what is happening here and I've been looking through it for an hour now. My goal is to output "CoMpUtEr ScIeNcE"
I thought the (hi2.charAt(locate) % 2 == 0) and vice versa would alternate between the even and odd locations in the string, but I believe I have made a mistake somewhere. I just can't find it.
Using BlueJ V3.1.7
1 year high school Computer Science Experience and currently enrolled in AP Computer Science
Any Tips?
not really. So hi2.charAt(locate) % 2 == 0 is actually checking if the integer value of the character is odd or even, but you want to actually check if the index is odd or even if I get you right. In other words:
hi2.charAt(2) % 2 == 0
Is check if m is odd or even. However, I think you want to check if 2 (the index) is odd or even. I guess from here it's easy to assume that you need to change:
if(hi2.charAt(locate) % 2 == 0)
//...
else if(hi2.charAt(locate) % 2 == 1)
//...
to
if(locate % 2 == 0)
//...
else if(locate % 2 == 1)
//...
This won't give you exactly the output you want, but it's just a matter of inverting the if conditions or the body as you wish. Also, there's no other cases for the operation % 2, meaning you'd only get either an odd or even index, so you could simplify the code by just doing:
if(locate % 2 == 0)
//...
else
//...
Which reads better. Hope this helps!
I would strongly advise refactoring your code to reduce repetative calls, and make inspection of values possible (rather than comparison of function evaluation).
For example:
char currentCharacter = hi2.charAt(locate);
would replace four instances of the function call, and allow you to inspect what the actual value is (rather than what you expect the value to be). This would likely make your error more evident.
Assuming the following values:
hi2 = "Computer Science";
locate = 0;
then it may be worth stepping through the evaluation.
0. hi2.charAt(locate) % 2 == 0
1. "Computer Science".charAt(0) % 2 == 0
2. 'C' % 2 == 0
3. 67 % 2 == 0
4. 1 == 0
5. false
The fundamental problem is that by never assigning your value to a variable, you never take the time to understand what is in it. By assigning it to the variable, you are able to inspect the value using a debugger.
By inspecting the values, we can see that you probably want the mod of 0, not 'C', therefore you probably wanted
0. locate % 2 == 0
1. 0 % 2 == 0
2. 0 == 0
3. true
Bonus
Refactoring your code to reduce repetition, would also highlight other errors. For example, try the following:
assert "CoMpUtEr sCiEnCe".equals(BugFixes.altcaps("Computer Science"));
assert "CoMpUtEr-sCiEnCe 201".equals(BugFixes.altcaps("Computer-Science 201"));
KISS: removal of needless logic would reduce the chance of things going wrong.
For starters, you don't need to reassign the string, or the locate variable, or check if a character is already a character. Just use the iteration integer, if you need it, and the parameter.
Secondly, you're modding the character, not the position.
Anyways, a simple boolean toggle would be easier to understand than modding.
void altCaps(String hi) {
boolean caps = true;
for (char ch : hi.toCharArray()) {
if (ch == ' ') {
System.out.print(ch);
}
else if (Character.isLetter(ch)) {
if (caps) System.out.print(Character.toUpperCase(ch));
else System.out.print(Character.toLowerCase(ch));
caps = !caps; // switch between upper and lower every character
}
I have a quick question on an assignment I'm trying to finish up. I'm writing a boolean method that takes three digit parameters (0-9) and returns true if they can be re arranged to make up a sequence. The hard part, for me at least, is that 0 can make a sequence with 8, 9, or 1,2. The three numbers are assumed to all be different. To be clear, the number 5,7,6 would be true because it can be rearranged to be 5, 6, 7, a sequence. Also 8,0,9 would return true, but 2,4,7 would not. I'm hoping someone can point me in the right direction with this, any help at all would be much appreciated!
You only need to check the validity of two tests:
Are all numbers different?
Is the absolute difference between the extremes 2?
This would give you the following method:
public static boolean isSequence(int a, int b, int c) {
if(a == 0) a = 10;
if(b == 0) b = 10;
if(c == 0) c = 10;
//Add the commented-out lines to make it safe to use with non-different numbers.
//boolean allDifferent = !(a == b) && !(b == c) && !(a == c);
boolean extremesIsTwo = Math.abs(Math.max(Math.max(a, b), c)
- Math.min(Math.min(a, b), c)) == 2;
//return allDifferent && extremesIsTwo;
return extremesIsTwo;
}
When you look at it, it's only a matter of simple logic, and finding the shortest path to the answer. There might be more optimized ways to do this, but this is clear, readable and works just fine.
Now, if you really want to get grinding on a problem of the like, you could either try to optimize this algorithm, or find another way to check that the three numbers are a sequence.
EDIT This version is scalable. And even though your requirements are for three arguments, I would still consider this solution, because it uses OOP to avoid repetition of code. As requested, it also doesn't check for duplicates.
public static boolean isSequenceScalable(List<Integer> list) {
list = list.stream().map(i -> i = (i == 0) ? 10 : i).collect(Collectors.toList());
list.sort(Integer::compareTo);
if (Math.abs(list.get(0) - list.get(list.size() - 1)) == 2) return true;
return false;
}
I was reviewing some Java code with this line
if ( list.size() == 1 || list.size() <= 4) {...}
I commented that I do not see how that is any different from just doing
if (list.size() <= 4) {...}
he said it matters and needs to be the first. I don't understand. Perhaps if it were something like
if (list.size() == 1 || list.size() <= someVeryCostlyFunction() ) {...}
and the size was expected to be 1 most of the time you might use both, if someVeryCostlyFunction() always returns some positive number >= 1. Otherwise I can't see the difference. We are supposed to check for efficiency.
The code smells with those two conditions:
if (list.size() == 1 || list.size() <= 4)
Perhaps the author have that in mind:
if there is some number of elements in the list that is 4 or less.
More over the current code allows to satisfy the condition even if the list has zero elements - which is most likely wrong.
Another problem with this condition is use of magic number 4?
What is so important about it and why it is not 5?
It should be self documented and distinguished from other 4's that could appear in the code:
int MAX_HANDLED = 4;
if ( list.size() > 0 && list.size() <= MAX_HANDLED )
:
:
int ALL_TIRES = 4;
if (car.getTires() < ALL_TIRES) {
car.stop();
}
As for the performance, I do not see any significant reason why existing condition should be any faster then yours proposed one (even the second would be faster when list.size > 1). See this question of similar concern.
I can't seem to get this figured out, or I already made it work but somewhere in my code is another bug...
My question is, can someone translate this C++ code
if (!fmod(x[i][j], 1) && x[i][j]) {
to the Java equivelent.
The variable x has doubles in it's list.
Thanks alot for your help!
if (x[i][j] % 1 == 0 && x[i][j] != 0 ) {
Java doesn't do automatic coercions to the Boolean type, so you have to make Boolean values with != and ==, etc. This just checks to that the double at x[i][j] is a non-zero whole number. (In C++, anything non-zero is true and zero is false.)
You can just use the % operator instead of fmod:
if ((x[i][j] % 1.0 == 0) && (x[i][j] != 0)) {
Is following true in java:
In java if you use || then after getting first true condition it neglects the rest conditions. That is If you write if(a || b || c) in java and java finds a is true then it will not check for b and c, just go into the if case.
Yes this is called short circuiting, if you put less expensive checks to the left you might avoid the expensive ones to follow.
This works for || and &&
one of the best uses is checking a value from an object that might be null:
if(myList != null && myList.size() > 6)
the previous line is null safe, reversing the condition will cause a null pointer exception in case myList is null
This is correct. || is called short-circuit OR evaluation, or an OR-ELSE operator.
This is important in situations when evaluating the right-hand side may cause an undesirable consequence:
if (myString == null || myString.indexOf("hello") != -1)
...
would crash if it were not for short-circuiting.
Yes, This way the compiler avoids unnecessary checking and calculation overhead.
That's correct, and that's not just laziness on part of the language implementation, but rather it is a crucial feature - short-circuiting allows you to write something like this:
if (myarray.length > 10 && myarray[10] == 5) { /* ... */ }
Here the second condition may only even be evaluated if the first one is true. Thanks to short-circuiting, if the first condition is false the second is never touched.
YES
(AFAIK)
The same things applies to && but in reverse manner.(for first false).
The same rule as in circuits for AND and OR gates.
Yes, it's called short-circuiting. It also will short circuit &&, i.e.
if (a && b && c)
If a is false then the condition cannot be true, neither b nor c are checked.
This can be problematic if you call methods that return booleans. To get around this, you can use bitwise & and |.
Yes it is correct. If you use | this operator to check OR condition then it checks rest all conditions. It also applied on AND(&) operator.
Yes, and one important thing, if you do any operations in the second part, they will not be made. For example:
int a = 5;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 5
//b = 5
BUT in case:
int a = 3;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 4
//b = 5
I tried to make a simple example, but sometimes you call a method in the second part, (which will not be called if first part was true in case of ||), or the first part was false in case of &&