Break statement not taking me outside of loop java - java

I am solving this problem on code forces.
https://codeforces.com/contest/1675/problem/B
The break statement I have doesn't break out of the while loop.
When I use this input:
It outputs -1 one twice in the same case, which shows that the break statement isn't taking me outside the loop?
Why is this happening?
public class vanita {
public static void main (String[]args) {
Scanner in = new Scanner(System.in);
int cases = in.nextInt();
for (int i = 0; i < cases; i++) {
boolean test = true;
int arrLength = in.nextInt();
int arr[] = new int[arrLength];
for (int j = 0; j < arrLength; j++) {
arr[j] = in.nextInt();
}
int operations = 0;
int after;
for (int j = arrLength-1; j >= 1 ; j--){
after = arr[j-1];
while (arr[j] <= after) {
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if (arr[j] == 0 && arr[j-1] == 0) {
//System.out.println("current: " + arr[j]);
//System.out.println("after: " + arr[j-1]);
//System.out.println("Case " + i);
System.out.println("-1");
test = false;
break;
}
}
}
for (int s = 0; s < arrLength; s++) {
//System.out.print(arr[s] + " ");
}
//System.out.println(" ");
if (test == true) {
System.out.println(operations);
}
}
}
}

i think it breaks out of the inner while loop, but not the outer for loop. So the inner while loop runs multiple times.

Problems
Normally a break; will always break out of the most recent loop. If you can't break out of your loop, the problem is your algorithm or your condition.
Solutions
First, always debug to see if you enter your if statement.
Second, use something else as condition of your while loop. You could use a boolean and change its value to break the while condition. Ex:
boolean hasFoundDuplicate = false;
while(!hasFoundDuplicate){
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if(arr[j] == 0 && arr[j-1] == 0){
hasFoundDuplicate = true;
}
}

Related

How to continue 2 loops at the same time? [duplicate]

This question already has answers here:
Continue at first loop , inside the second loop
(7 answers)
Closed 1 year ago.
For this code kata I need to continue 2 for loops at the same time. How can I do that?
public class StringMerger {
public static boolean isMerge(String s, String part1, String part2) {
StringBuilder MergedWord = new StringBuilder("");
String Whole = part1+part2;
for(int j = 0; j < Whole.length(); j++){
for(int I = 0; I < part1.length(); I++){
if((Character.compare(s.charAt(j), part1.charAt(I)) == 0) && (j == I)){
MergedWord.append(s.charAt(I)+"");
continue;
}
else
break;
}
for(int i = 0; i < part2.length(); i++){
if((Character.compare(s.charAt(j), part2.charAt(i)) == 0) && (j == i)){
MergedWord.append(part2.charAt(i) + "");
continue;
}
else
break;
}
}
return s.equals(MergedWord.toString())? true : false;
}
}
I noticed when one of the for loops continue it only continues the internal loop, but labels would continue the upper loop and would be inefficient. Could I continue 2 for loops at the same time a.k.a continue the inner and upper loop in this nested for loop?
The task is to match each character in the target string, so you only need one loop, which iterates over the characters in the string. You do need two other loop variables to track how much of the two source strings have been used up.
My solution below is looping over three things at once: the target string and the two 'part' strings. The rate it moves over the 'part' strings isn't constant, but it does progress over them monotonically.
It wasn't clear to me whether the source strings could include extra characters not used in the target string. As the example didn't show any, I assumed not.
public class MergedStringChecker {
public static void main(String[] args) {
String target = "codewars";
String part1 = "cdw";
String part2 = "oears";
for (int i = 0, p1 = 0, p2 = 0; i < target.length(); ++i) {
if (p1 < part1.length() && target.charAt(i) == part1.charAt(p1)) {
++p1;
} else if (p2 < part2.length() && target.charAt(i) == part2.charAt(p2)) {
++p2;
} else {
throw new RuntimeException("No matching characters at index " + i);
}
}
}
}
The above solution is not Unicode safe if the string contains > 16 bit code points.
Try this.
public static boolean isMerge(String s, String part1, String part2) {
int length = s.length();
int length1 = part1.length();
int length2 = part2.length();
int i1 = 0, i2 = 0;
for (int i = 0; i < length; ++i)
if (i1 < length1 && s.charAt(i) == part1.charAt(i1))
++i1;
else if (i2 < length2 && s.charAt(i) == part2.charAt(i2))
++i2;
else
return false;
return i1 == length1 && i2 == length2;
}
public static void main(String[] args) throws IOException {
System.out.println(isMerge("codewars", "cdw", "oears"));
System.out.println(isMerge("codewars", "codewars", ""));
System.out.println(isMerge("codewars", "cdw", "oearsEXTRA"));
}
output:
true
true
false
you have an error on the first part loop you must append from the part not the s char
you don't need to chek the id of the part with the inital word (remove this check (j == I) and this one (j == i)
Use counter to avoid looping many times
Try this code :
public static boolean isMerge(String s, String part1, String part2) {
StringBuilder MergedWord = new StringBuilder("");
String Whole = part1+part2;
int counter1=0;
int counter2=0;
for(int w = 0; w < Whole.length(); w++){
for(int c1 = counter1; c1 < part1.length(); c1++){
if((s.charAt(w) == part1.charAt(c1)) ){
MergedWord.append(part1.charAt(c1)+"");
counter1++;
continue;
}
else
break;
}
for(int c2 = counter2; c2 < part2.length(); c2++){
if((s.charAt(w) == part2.charAt(c2)) ){
MergedWord.append(part2.charAt(c2) + "");
counter2++;
continue;
}
else
break;
}
}
return s.equals(MergedWord.toString())? true : false;
}

How to check if every odd index in a string has the same letter?

I'm working on this program where I need to verify if every odd index in a String has the letter "X". For example if my String is: AXFXTX then I should get a message: "GOOD", if not I should get a message: "BAD". Can anyone tell me what I'm missing please. Thank you in advanced.
Here's my code
import java.util.Random;
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Random rand = new Random();
Scanner scan = new Scanner(System.in);
int min = 1;
int max = 10;
int randomNum = rand.nextInt((max - min) + 1) + min;
System.out.println("Random number = " + randomNum);
System.out.print("Enter a word of " + randomNum + " characters:");
String myString = scan.nextLine();
while(myString.length() != randomNum){
System.out.print("Enter a word of " + randomNum + " characters:");
myString = scan.nextLine();
}
char[] c = myString.toCharArray();
for(int i = 0 ; i < c.length ; i++){
if(c[i] == 'X'){
System.out.println("GOOD!");
}
else{
System.out.println("BAD");
}
}
}
}
If I understand your question, then it's important to note that the first odd index is 1. So you can start at 3 and check if that, and every subsequent odd number (index += 2), is the same as the first. Something like,
boolean sameLetter = true;
for (int index = 3; index < c.length && sameLetter; index += 2) {
sameLetter = (c[1] == c[index]);
}
System.out.println(sameLetter ? "GOOD!" : "BAD");
Simply evaluate odd indices only:
char[] c = myString.toCharArray();
boolean good = true;
for(int i = 3 ; i < c.length ; i+=2){
if(c[i] != c[i-2]){
good = false;
break;
}
}
if(good) System.out.println("GOOD");
else System.out.println("BAD");
I would simply use a regular expression here
str.matches(".(\\w)(.\\1)+") //true is GOOD
Try
booelan allGood = true;
for(int i = 2 ; i < c.length ; i = i + 2){
if(c[i] != c[0]){
allGood = false;
break;
}
}
To start with, you need a boolean variable here to track if it's consistent across all characters. Second, you need to improve your loop
boolean testSucceed = true;
for(int i = 1 ; i < c.length ; i += 2){
if (c[i] != 'X') testSucceed = false;
break;
}
if(testSucceed){
System.out.println("GOOD!");
} else{
System.out.println("BAD");
}
Change the for loop to :
for(int i = 0 ; i < c.length ; i+=2)
so that it goes over alternate characters.
//If NOT divisible by 2- Check only ODD number
Edited: You are suppossed to use modulus % and not division %. My bad
for(int i = 0 ; i < c.length ; i++){
if(c[i]%2 != 0){
if(c[i] == 'X'){
System.out.println("GOOD!");
}
else{
System.out.println("BAD");
}
}
}

Binary to decimal, error message

I wrote a program that convert a binary number to decimal number.
When I run the program with some binary number, the program give me the decimal number but with an error message.
my code:
public class ohad {
public static void main(String[] args) {
String bin = "10011";
int length = bin.length();
int j = 0;
int sum = 0;
if (length != 0) {
for (int i=0; i < bin.length(); i++){
if (bin.charAt(i) == '0' || bin.charAt(i) == '1'){
for (int t = (length - 1); t >= 0; t--){
String s = bin.charAt(j) + "";
sum = (int)(sum + (Integer.valueOf(s)) * (Math.pow(2, t)));
j++;
}
System.out.println(sum);
}
else {
System.out.println("illegal input.");
}
}
} else {
System.out.println("illegal input.");
}
}
}
error message:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5
at java.lang.String.charAt(String.java:646)
at ohad.main(ohad.java:15)
I think it's something with my j index. What should I do?
What should I do?
I would use Integer.parseInt(String,int) like
String bin = "10011";
System.out.println(Integer.parseInt(bin, 2));
Output is
19
Do you need j index? Looking at this quickly, I think you can use i index instead j.
String s = bin.charAt(j) + "";
String s = bin.charAt(i) + "";
You need to reset your j variable.
in the second iteration of the i for loop that is for (int i=0; i < bin.length(); i++){
j goes out of bounds as it is not set to zero again try the following code :
for (int i=0; i < bin.length(); i++){
j=0; // add this
if (bin.charAt(i) == '0' || bin.charAt(i) == '1'){
for (int t = (length - 1); t >= 0; t--){
String s = bin.charAt(j) + "";
sum = (int)(sum + (Integer.valueOf(s)) * (Math.pow(2, t)));
j++;
}
System.out.println(sum);
} else {
System.out.println("illegal input.");
}
}
While Elliott's answer is absolutely correct and gives a much easier way of solving the problem of converting a binary number to its decimal equivalent, it does not tell you what is causing the error.
You are correct that the exception is thrown because of the j variable, the issue lies in that the j variable is never set back to 0 when the inner loop (with index variable t). I changed your code to reflect this:
for (int t = (length - 1); t >= 0; t--){
String s = bin.charAt(j) + "";
sum = (int)(sum + (Integer.valueOf(s)) * (Math.pow(2, t)));
j++;
}
j = 0; //this is the added code
System.out.println(sum);
This prevents the exception being thrown however causes another issue with the loop being called again, printing each time until you hit 95. I'll let you fix this problem.
You've got one loop too much. That's why j keeps increasing causing the error message.
Delete the t loop:
public static void main(String[] args) {
String bin = "10011";
int length = bin.length();
int j = 0;
int sum = 0;
if (length != 0) {
for (int i = length - 1; i >= 0; i--) {
if (bin.charAt(i) == '0' || bin.charAt(i) == '1') {
String s = bin.charAt(j) + "";
sum = (int) (sum + (Integer.valueOf(s)) * (Math.pow(2, i)));
j++;
} else {
System.out.println("illegal input.");
}
}
System.out.println(sum);
} else {
System.out.println("illegal input.");
}
}

Find the Last Digit In An Array

I need to find the last digit in a array and see if it is equal to zero. Here is the code I'm using;
import java.util.Scanner;
public class NrOccurrence
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter the integers between 1 and 100: ");
int[] numbers = new int[100], times = new int[100];
boolean zero = false;
while (zero == false)
{
for (int a = 0; a <= numbers.length; a++)
{
numbers[a] = scan.nextInt();
times[a]++;
if (numbers.equals(0))
{
zero = true;
}
}
}
for (int b = 0; b <= numbers.length; b++)
{
System.out.println(numbers[b] + " occurs " + times[b] + " times");
}
scan.close();
}
}
Create a method like this:
private boolean isLastItemZero(int[] numbers)
{
boolean isLastItemZero = false;
if ((numbers != null) && (numbers.length > 0))
{
isLastItemZero = numbers[numbers.length - 1] == 0;
}
return isLastItemZero;
}
And call it once you're done reading in all of the numbers from the user.
First of all for (int a = 0; a <= numbers.length; a++) will give youIndexOutOfBoundsException .Java uses 0 bases indexing which means that an array of size n has indices up to and including n-1. Change it tofor (int a = 0; a < numbers.length; a++) . Same thing here for (int b = 0; b <= numbers.length; b++)
Second i am not sure what you are trying to check here :
if (numbers.equals(0))
{
zero = true;
}
but you could simply do :
if(numbers[i] == 0);
Now if you wanna check if the last element in the array is 0you can simply do:
if(numbers[numbers.length - 1] == 0)
//do something
By definition, if the remainder of a number divided by 10 is 0, then the last digit must be 0. So you just need;
if(numbers[i] % 10 == 0) { zero = true; }
Hope this helps.

Nested loop construction

This is part of my homework. All I need is a bit of advice. I need to write some nested loop constructs, to print the following:
"122333444455555"
"+**+++****+++++"
"--***++++-----******+++++++"
Here is my code to print the first set of symbols
public static void main (String[] args)
{
int i,j;
for(i=1;i<6;++i)
{
for(j=1;j<i+1;++j)
{
System.out.print(i);
}
}
}
This works perfectly fine. I'm just having trouble figuring out the second and third set of symbols. Apologies for my lack of experience, I'm fairly new to Java.
One solution is:
final String[] arr = {"*", "+"};
And in your inner loop:
System.out.print(arr[i % 2]);
The % (Modulo) operator is responsible of the switches between * and + symbols:
For even i it'll be *, otherwise it'll be +.
Output: "+**+++****+++++".
(Regarding the second output, I'll not show you the solution, but it's very similar to this one once you understand it).
public static void main(String[] args) throws IOException {
int i, j;
for (i = 1; i < 6; ++i) {
for (j = 1; j < i + 1; ++j) {
System.out.print(i);
}
}
System.out.println();
for (i = 1; i < 6; i++) {
if (i % 2 == 1) {
for (j = 1; j < i + 1; ++j){
System.out.print("+");
}
} else {
for (j = 1; j < i + 1; ++j){
System.out.print("*");
}
}
}
System.out.println();
for (i = 2; i < 8; i++) {
if (i % 3 == 1) {
for (j = 1; j <= i; ++j){
System.out.print("+");
}
} else if (i % 3 == 2) {
for (j = 1; j <= i; ++j){
System.out.print("-");
}
} else {
for (j = 1; j <= i; ++j){
System.out.print("*");
}
}
}
}
Cycle #1:
You have to print out numbers from one to five and each number N has to be printed out N times.
for (i = 1; i < 6; ++i) { // this would set `i` to numbers from 1-5
for (j = 1; j < i + 1; ++j) { // for each cycle (next number) it prints
//it out N times where N is the cycle number. 1 is the first cycle,
//2 is the second and so on.
Cycle #2:
Same problem but instead of printing out number of the cycle you have to print out + or * based on if the cycle number is odd or even.
To check if the number is even you can use:
int number = 1;
if(number % 2 == 0){ // is true if the number is even
This checks whats the remainder from the division of number by two.
Cycle #3:
Same as #2 but you start from the second cycle, not from the first and you check for the remainder after division by 3.
If I understand, the third set is composed by sequence of "-*+" so:
String sequence = "-*+";
String s = "+**+++****+++++";
int seqI = 0;
for(i=0; i != s.size(); ++i) {
for(j=0; j < i+2; ++j) {
System.out.print(sequence[seqI]);
}
if(seqI < sequence.size()) {
++seqI;
} else {
seqI = 0;
}
}
You can define a function like this:
public static char Output(int i, int mode)
{
if (mode == 1)
{
return (char) i;
}
else if (mode == 2)
{
if (i % 2 == 0)
{
return '+';
}
else
{
return '*';
}
}
else if (mode == 3)
{
if (i % 3 == 0)
{
return '-';
}
else if (i % 3 == 1)
{
return '*';
}
else
{
return '+';
}
}
}
And use it just like:
for (int mode = 1 ; mode < 4 ; mode++)
{
for (int i = 1 ; i < 6 ; i++)
{
for (int j = 0 ; j < i + (int)(mode / 3) ; j++)
{
System.out.println(Output(i, mode));
}
}
}
Note: Yes! Actually my code is hard to read, but if you try to read it, you will learn something more than other answers!

Categories