Is it possible in Java to use syntax like (i++, ++i) for boolean logic operators?
I have a boolean variable that is true only for the first iteration of a foreach loop. That iteration has to be skipeed.
Full syntax is
for (...)
{
if (bool)
{
bool &= false;
continue;
}
}
I wonder if there is any way to shorten the syntax without using AtomicBoolean. For example construct if (bool &= false) is syntactically correct but I think it will compare the final result and not the original value.
Google is not my friend because the search query is misleading
Personally I would simplify your current code to:
for (...)
{
if (bool)
{
bool = false;
continue;
}
// Rest of code
}
... but if you really want to do it in the if condition as a side-effect, you could use:
for (...)
{
if (bool && !(bool = false))
{
continue;
}
// Rest of code
}
Here the first operand of the && operator covers subsequent operations, and !(bool = false) will always evaluate to true and set bool to false.
Another option, from comments:
for (...)
{
if (bool | (bool = false))
{
continue;
}
// Rest of code
}
This performs the assignment on each iteration, but it still gives the right result each time.
I really, really wouldn't use either of these last two options though.
Your code is the usual thing to do. However, there's an alternative:
for (SomeType thing : Iterables.skip(things, 1)) {
// process thing
}
This uses Google Guava's Iterables.skip() method and produces your expected output - a for-each loop iterating over the collection and skipping the first element.
Alternatively, just use an integer variable and use ++ to post-increment it.
int iter = 0;
for (...) {
if (iter++ == 0) {
continue;
}
...
}
If you want to skip the first iteration, this might even be easier to understand.
Don't use increments for boolean types If you must use a boolean, either toggle it, such as !bool, or just set it to false:
for (...){
if (bool) {
bool = false;
continue;
}
}
Ideally, if all you want is to skip the first, last or nth iteration, do not use a boolean at all but an int instead ...
int skipIndex = 0;
for(int index=0; index < 5; index++){
if(index != skipIndex) {
System.out.println(index);
}
}
... or the following to only skip the first iteration:
int[] values = new int[]{0, 1, 2, 3, 4};
for (int index = 1; index < values.length; index++) {
System.out.println(values[index]);
}
If (and only if) you are really so certain that you will always need to continue on the first iteration, why not just skip that iteration? Instead of starting with i=0, start with
for(i=1....
I've been struggling to see why the OP is trying to use bool &= false; when bool = false will obviously do. In that sense, Jon Skeet's answer is (unsurprisingly) correct.
What I think the OP actually wants to do is set the variable to false and test it in one step. That's the reason for the reference to AtomicBoolean. It's nothing per-se to do with loops. IE he wants to do the same as:
int a=0;
for ( ... ) {
if (a++ == 0 ) { // works if we aren't doing too many iterations
continue;
}
...
}
i.e. he wants the equivalent of a post-increment operator.
If I'm right, it's not the loop he's worried about, it's the fact that a here is being read once, then separately read again.
This is a case of premature optimisation. The Java compiler is very likely (no I haven't tested it) to produce a single read and test and of the code with
boolean a=false;
for ( ... ) {
if (!a) {
a = true;
continue;
}
}
as Jon Skeet suggested.
The answer (for completeness) is that there is no post-increment operator that works on boolean and I couldn't work out how to define a function that does that without at least mentioning the variable twice. However, that should not be a design consideration.
Note in a real for loop you can just do:
int i;
boolean skip;
for (i=0, skip=true; i<10; i++, skip=false) {
if (skip)
continue;
}
for (int i = 0, boolean doIt = false; i < 10; i++, doit = true) {
if (doIt) {
doStuff();
}
}
Related
This method, moreVowels, is intended to be able to count the amount of vowels and consonants in the String entered, and return true if the amount of vowels is greater than the amount of consonants. Sadly this code always returns false, and I cannot understand why. Here is the method stated:
public Boolean moreVowels()
{ vowelCount = 0;
consonantCount = 0;
for(int i = 0; i < word.length(); i++)
{
if ("AEOIUY".contains(word.substring(i,i++)) || "aeoiuy".contains(word.substring(i,i++)))
{
vowelCount++;
}
if ("BCDFGHJKLMNPQRSTVWXZ".contains(word.substring(i,i++)) || "abcdefghijklmnopqrstuvwxyz".contains(word.substring(i,i++)))
{
consonantCount++;
}
}
if (vowelCount > consonantCount)
{
return true;
}
else
{
return false;
}
}
I believe it is always returning false due to the loop not actually increasing the counts, but I'm not quite sure why not. Thank you for reading, I'm sure the answer is something silly that I failed to recognize.
First, you should not use substring(i,i++), but substring(i,i+1). Otherwise, you'll increase i, making your code skip letters.
"abcdefghijklmnopqrstuvwxyz".contains(word.substring(i,i+1)) looks like a mistake. It will cause consonantCount to increase in each loop for every lowercase letter.
If you're only dealing with words (no spaces etc.), then every word is either a consonant or a vowel, so you don't need the second if. You could get consonant count by subtracting vowelCount from length.
Furthermore, if you convert the i-th character to uppercase, you can omit the || "aeoiuy".contains(...) part.
The other answer and comment already show the problems with your code. I just want to add a possible stream based solution that can reduce the possibilty for errors by repacing the index based looping and local variables:
private static boolean moreVowels(String word)
{
return word.chars()
.mapToObj(c -> Character.toString((char) c).toUpperCase())
.mapToInt(c -> "AEIOUY".contains(c) ? 1 : "BCDFGHJKLMNPQRSTVWXZ".contains(c) ? -1 : 0)
.sum() > 0;
}
You can apply the use of toUpperCase() to your own implementation as well to make the if statements a bit shorter (again avoiding possible errors).
How to improve the performance of this code, reducing the compile time and keeping the functionality of the code same ?
The code is to extract two sub-strings from different strings and concatinating them to provide the largest possible palindromic string.
the Question was :You have two strings, (a) and (b). Find a string, (c), such that: (c)=(d)+(e).
(d),(e) can be expressed as where (d) is a non-empty substring of (a) and (e) is a non-empty substring of (b).
(c) is a palindromic string.
The length of is as long as possible.
For each of the pairs of strings (a) and (b) received as input, find and print string on a new line. If you're able to form more than one valid string , print whichever one comes first alphabetically. If there is no valid answer, print -1 instead.
import java.io.*;
import java.util.*;
public class Solution {
boolean isPalindrome(String s) {
int n = s.length();
for (int i=0;i<(n / 2);++i) {
if (s.charAt(i) != s.charAt(n - i - 1)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
String result="";
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int a=0; a<n; a++)
{int length1, length2, i,c,d,j;
int max_length=0;
String string1 = in.next();
String sub1,sub2;
String string2 = in.next();
length2=string2.length();
length1 = string1.length();
for( c = 0 ; c <length1 ; c++ )
{
for( i = length1-c ; i >0 ; i-- )
{
sub1 = string1.substring(c, c+i);
for( d = 0 ; d < length2 ; d++ )
{
for( j = length2-d ; j >0 ; j-- )
{
sub2 = string2.substring(d, d+j);
String temp=sub1+sub2;
Solution obj= new Solution();
if(temp.length()>=max_length && obj.isPalindrome(temp)==true)
{
if (max_length==temp.length())
{ if(temp.compareTo(result)<0)
{
result=temp;
}}
else {
max_length=temp.length();
result=temp;
}
}
}
}
}
}
if(max_length==0)
System.out.println(-1);
else
{
System.out.println(result);
result="";
}
} /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
}
}
I assume you want to reduce execution time, as opposed to compile time.
It is always best to avoid guessing, and rather determine exactly how the time is spent.
This is a good example.
If you do have a guess, this will prove it, or disprove it by showing you what the real problem is.
I have a guess (and it's only a guess).
You have a three-level nested loop, and inside the innermost loop I see a bunch of things that look suspicious.
The biggest one is new Solution().
That hits the memory manager, which can be very costly, not only to make the objects, but to clean them up.
Maybe you could move that out of the inner loop.
After that comes String temp=sub1+sub2;, which also hits the memory manager to make a new string.
Maybe you could make use the the string builder.
After that comes isPalindrome.
Whether that is efficient or not, I don't know.
Finally, your code needs much more disciplined indentation.
That alone can cause all kinds of bugs due to not being able to follow what you're doing.
I have this problem:
I wrote this function because I need to get the index of the occurrence of a particular string st in a String array
static public int indicestring(String[] array, String st) {
int ret = -1;
for (int i = 0; i < array.length; i++){
if (st.equals(array[i])) {
ret=i;
break;
}
}
return ret;
}
I then called:
System.out.println("indicestring(NODO,"ET2"));
and I got the correct number.
But then when I do:
String[] arcos2 = linea.split("-");//reading from a file and separating by "-"
String aux = arcos2[1];
System.out.println(arcos2[1]);
System.out.println(aux);
if (aux.equals(arcos2[1])) {
System.out.println("Is equal 1");
}
if (aux.equals("ET2")) {
System.out.println("Is equal 2");
}
if ("ET2".equals(aux)) {
System.out.println("is equal 3");
}
The first two prints were ET2, but then it only printed of the 3 ifs is "Is equal 1".... The thing is I have nearly 200 nodes like "ET2" and only 3 are failing and giving me -1 in the first function...
My question is....Am I using wrong the arrays to save and compare the data, because if aux=arcos2[1]="ET2", why is 'aux.equals("ET2") 'or 'arcos2[1].equals("ET2)' not working
? Is ther another function you can recommend to try?(I tried changing equals with compareTo() == 0 and that didn't work either and trimming was also recommended).
Before, I had a similar error where I compare two arrays like this:
if(a[0] == b[0] && a[1] == b[1])
There was a case that clearly was correct but it was ignored...
But it got corrected when a i changed it to:
if (Arrays.equals(a, b))
Is there maybe some change like that
You should put a debug break point in the code and add expression watches to identify the root cause of the problem.
So, I just want to know if its possible to slip in any code or a ternary operator inside the termination bit of a for loop. If it is possible, could you provide an example of a ternary operator in a for loop? Thanks!
for (initialization; termination; increment) {
statement(s)
}
The termination clause in the for statement (if supplied - it's actually optional) can be any expression you want so long as it evaluates to a boolean.
It must be an expression, not an arbitrary code block.
Yes you can since only thing here is termination should be a boolean
for (int i=0; i==10?i<5:i<6; i++) {
}
But what is the point of this?
Things to remember. Termination condition of a for loop should be a boolean
Absolutely, it is possible:
for (int i = 0 ; i < someCondition ? first : second ; i++) {
...
}
you can use ternary operators or any expressions in all three parts of the loop header:
for (int i = flag ? a : -a ; i != (flag ? 2*b : -2*b) ; i += flag ? 1 : -1 ) {
...
}
If you need to insert more complex logic into the termination condition, a good approach would be to define a method: it usually improves readability of your loop:
boolean checkCondition(int i) {
...
}
...
for (int i = 0 ; checkCondition(i) ; i++) {
...
}
The termination part of the for loop requires a boolean condition. You can pass anything that gives a boolean value for the termination part.
For ex:
for (int i = 0; i<5?true:false; i++)
{
}
Very new to Java: Trying to learn it.
I created an Array and would like to access individual components of the array.
The first issue I am having is how to I print the array as a batch or the whole array as indicated below? For example: on the last value MyValue4 I added a line break so that when the values are printed, the output will look like this: There has to be a better way to do this?
MyValue1
MyValue2
MyValue3
MyValue4
MyValue1
MyValue2
MyValue3
MyValue4
The next thing I need to do is, manipulate or replace a value with something else, example: MyValue with MyValx, when the repeat variable is at a certain number or value.
So when the repeat variable reaches 3 change my value to something else and then change back when it reaches 6.
I am familiar with the Replace method, I am just not sure how to put this all together.
I am having trouble with changing just parts of the array with the while and for loop in the mix.
My Code:
public static String[] MyArray() {
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
return MyValues;
}
public static void main(String[] args) {
int repeat = 0;
while (repeat < 7) {
for (String lines : MyArray()) {
System.out.println(lines);
}
repeat = repeat + 1;
if (repeat == 7) {
break;
}
}
}
Maybe to use for cycle to be shorter:
for (int i = 0; i < 7; i++) {
for (String lines : MyArray()) {
// Changes depended by values.
if (i > 3) {
lines = MyValx;
}
System.out.println(lines); // to have `\n` effect
}
System.out.println();
}
And BTW variables will start in lower case and not end withenter (\n). So use:
String myValues[] = {"MyValue1", "MyValue2", "MyValue3", "MyValue4"};
instead of:
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
and add System.out.println(); after eache inside cycle instead of this:
MyValues[n] = "value";
where n is the position in the array.
You may consider using System.out.println() without any argument for printing an empty line instead of inserting new-line characters in your data.
You already know the for-each loop, but consider a count-controlled loop, such as
for (int i = 0; i < lines.length; i++) {
...
}
There you can use i for accessing your array as well as for deciding for further actions.
Replacing array items based on a number in a string might be a bit trickier. A regular expression will definitely do the job, if you are familiar with that. If not, I can recommend learning this, because it will sure be useful in future situations.
A simpler approach might be using
int a = Integer.parseInt("123"); // returns 123 as integer
but that only works on strings, which contain pure numbers (positive and negative). It won't work with abc123. This will throw an exception.
These are some ideas, you might try out and experiment with. Also use the documentation excessively. ;-)