Having trouble with a for loop evaluating incorrectly - java

I was having this problem today and I'm not sure what causes it. The following code:
int totWidth = 19;
String header = "Kalle's Numbers";
if (totWidth > header.length()) {
for (int j = 0; j < totWidth / 2 - header.length() / 2; j++) {
header += " ";
}
}
System.out.println(header + "|");
should yield
Kalle's Numbers |
but instead yields
Kalle's Numbers |
I modified the code a little bit by adding a variable "rightSpaces"
int totWidth = 19;
String header = "Kalle's Numbers";
if (totWidth > header.length()) {
int rightSpaces = totWidth / 2 - header.length() / 2;
for (int j = 0; j < rightSpaces; j++) {
header += " ";
}
}
System.out.println(header + "|");
and suddenly it yields the correct output. Why is this?

Because as it iterates through your for loop, you change the length of header by adding a space. So header.length() / 2 in your loop's continuation condition is potentially a different value each time.
What you've done in your second example fixes this problem by evaluating it once.

Related

How sum byte array with for loop?

This works!
Array lenght is 8
int crc = (bin[1] + bin[2] + bin[3] + bin[4] + bin[5] + bin[6]) & 0Xff;
the problem is that receive data length may vary.
and i try calculate the checksum with loop, but i dont get it work.
byte crc = 0;
for (int i = 1; i < bin.length - 2; i++) {
crc += bin[i];
}
int crcI = crc & 0xff;
this usually gives wrong values, but sometimes they are correct
This check:
i < bin.length - 2
evaluates to:
i < 8 - 2
ie
i < 6
ie the last element to be taken into account is at index 5, not 6.
If you are trying to get the sum of every byte except the first and the last one, then you should probably use:
for (int i = 1; i < bin.length - 1; i++) {
...
}
or, change your < operator to <=, like so:
for (int i = 1; i <= bin.length - 2; i++) {
...
}
An example when the result may be correct in the code you gave in your question is if the element at index 6 (ie bin[6]) is equal to 0 (and that's because 0 will not contribute to a sum).

toCharArray in Java works but sum of elements not

I am testing the following piece of code:
static int superDigit(String n, int k) {
char[] concatenatedN = n.toCharArray();
int superDigit = 0;
int sumDigits = 0;
char[] totalSum;
if (n.length() > 0) {
sumDigits = 0;
for (int j = 0; j < concatenatedN.length; j++) {
sumDigits = sumDigits + (int)concatenatedN[j];
System.out.println(" sumDigits: " + sumDigits + " ,concatenatedN[j]: " + concatenatedN[j]);
}
totalSum = String.valueOf(sumDigits * k).toCharArray();
superDigit = sumDigitsRecursive(totalSum);
} //end if
return superDigit;
}
For some reason that I don't know sumDigits variable must be the sum of array elements (concatenatedN[j]) but something weird happens and instead of sum, the following output is showed (when I do System.out.println):
sumDigits: 53 ,concatenatedN[j]: 5
sumDigits: 104 ,concatenatedN[j]: 3
sumDigits: 154 ,concatenatedN[j]: 2
sumDigits: 203 ,concatenatedN[j]: 1
Result must be ---> array is 5,3,2,1 ---> result = 5 + 3 + 2 + 1
When you cast a char to an int it gets converted to its underlying int value, which is its acsii value. This is clearly not what you want. Instead you can use Character.getNumericValue() to get the int value:
sumDigits = sumDigits + Character.getNumericValue(concatenatedN[j]);
You are adding the numeric unicode values of the characters of the string. Luckily, these values are consecutive, so you can convert these face values to the numbers they represent by subtracting the values of '0':
for (int j = 0; j < concatenatedN.length; j++) {
sumDigits = sumDigits + (int)(concatenatedN[j] - '0');
}

Why does the for loop output this?

I am just very confused from this homework problem. I do not understand why the values of i and sum come out this way. I just do not understand the concept of the algorithm here, can someone please explain this?
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
The output is:
5
10
----jGRASP: operation complete.
5 - because there are 5 iterations
10 - because the sum is 10 :)
Sum
Iteration 1: 0 + 0 = 0
Iteration 2: 0 + 1 = 1
Iteration 3: 1 + 2 = 3
Iteration 4: 3 + 3 = 6
Iteration 5: 6 + 4 = 10
Verification code
int i = 0;
int sum = 0;
for (i = 0; i < 5; i++) {
System.out.println(String.format(
"Iteration %s: %s + %s = %s", (i + 1), sum, i, (sum + i)));
sum += i;
}
This code :
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
output in sum this : 0 + 1 + 2 + 3 + 4 which is equal to 10 and i the number of iterations = 5.
You have created a variable i with value of 0 and then incrementing it 5 times in for-loop. So you got i's value as 5.
Now the value of sum is 0+1+2+3+4 which is 10
Because you iterate through your loop, which makes i == 5, then print it,
Sum goes as below, you are adding i to the previously calculated sum
0 + 1 = 1
1 + 2 = 3
3 + 3 + 6
6 + 4 = 10
Try put your print command inside the loop, they you can see better what's going on.
The only non-obvious thing is (in my opinion): i will be 5, because you used i++, which also incremented i by 1 even though the body did not execute after the last iteration. Inside the body i only can be maximum 4.
int sum = 0; int i = 0;
for (i = 0; i < 5; i++)
{
sum += i;
if (i == 5)
System.out.println("never executed");
};
Other answers tell the other things.

Pre- and postincrement in Java

I just wanted to create a little Java-Puzzle, but I puzzled myself. One part of the puzzle is:
What does the following piece of code do:
public class test {
public static void main(String[] args) {
int i = 1;
i += ++i + i++ + ++i;
System.out.println("i = " + i);
}
}
It outputs 9.
My (at least partly) wrong explanation:
I'm not quite sure, but I think the term after i += gets evaluated like this:
So
int i = 1;
i += ++i + i++ + ++i;
is the same as
int i = 1;
i += ((++i) + (i++)) + (++i);
This gets evaluated from left to right (See Pre and postincrement java evaluation).
The first ++i increments i to 2 and returns 2. So you have:
i = 2;
i += (2 + (i++)) + (++i);
The i++ returns 2, as it is the new value of i, and increments i to 3:
i = 3;
i += (2 + 2) + ++i;
The second ++i increments i to 4 and returns 4:
i = 4;
i += (2 + 2) + 4;
So you end up with 12, not 9.
Where is the error in my explanation? What would be a correct explanation?
i += ++i + i++ + ++i; is the same as i = i + ++i + i++ + ++i;
The right-hand side is calculated from left-to-right, yielding i = 1 + 2 + 2 + 4; (which yields i = 9).
The output is 9 (try it)
int i = 1;
i += ++i + i++ + ++i;
becomes
i = 1 + 2 + 2 + 4
You're right regarding the right part evaluation, but you're missing a detail regarding the assignment.
Run this :
i = i++;
or this :
i += i++;
After both operations, i still has its original value.
That's because i is evaluated on the left before the right part of the assignment.
So in your case, you're adding 8 to 1, not to 4.
it's very easy to understand how it works if you imagine it how java stores values in registers! he puts 1 in the first register, and than goes through = sign, and increments the i(++i), so now in i you have 2, and in the second register you have 2, but the first register is not updated, in the third register you'll have 2 and then i is incremented, and then i is incremented and in the last register you'll have 4. So you'll have something like this
1 = 2 + 2 + 4 == 9
The code
int i = 1;
i += ++i + i++ + ++i
is equivalent to
int tmp1 = i // 1, +=
i ++; // 2
int tmp2 = i; // 2
int tmp3 = i; // 2
i ++; // 3
i ++; // 4
int tmp4 = i; // 4
i = tmp1 + tmp2 + tmp3 + tmp4; // 9
i += ++i + i++ + ++i;
i=1 at start
i += X -> i = i + X -> i = 1 + X (so lets count X)
++i will be incremented to 2 and return 2
i++ will return 2 and then be incremented to 3
++i will be incremented from 3 to 4 and return 4
X = 2 + 2 + 4 = 8
So i = 1 + 8 -> i=9
You would get 12 if your code would be something like this
int i = 1;
int tmp = ++i + i++ + ++i;
i += tmp;
because then your code would be i=1, and after calculating tmp i would be i=4, then i+=tmp -> i=4+8=12

Check if string is following ISBN-13 in Java

Im trying to check if a string (important that it is a string) that im reading is correct accoring to the rules of ISBN-13. I found a formula
For example, the ISBN-13 check digit of 978-0-306-40615-?
is calculated as follows:
s = 9×1 + 7×3 + 8×1 + 0×3 + 3×1 + 0×3 + 6×1 + 4×3 + 0×1 + 6×3 + 1×1 + 5×3
= 9 + 21 + 8 + 0 + 3 + 0 + 6 + 12 + 0 + 18 + 1 + 15
= 93
93 / 10 = 9 remainder 3
10 – 3 = 7`
My problem is i don't know how to multiply one number with 1 and every other with 3 ? Im guessing a for-loop but i don't know how to start.
You could "simply" use regular expressions:
ISBN(-1(?:(0)|3))?:?\x20+(?(1)(?(2)(?:(?=.{13}$)\d{1,5}([ -])\d{1,7}\3\d{1,6}\3(?:\d|x)$)|(?:(?=.{17}$)97(?:8|9)([ -])\d{1,5}\4\d{1,7}\4\d{1,6}\4\d$))|(?(.{13}$)(?:\d{1,5}([ -])\d{1,7}\5\d{1,6}\5(?:\d|x)$)|(?:(?=.{17}$)97(?:8|9)([ -])\d{1,5}\6\d{1,7}\6\d{1,6}\6\d$)))
You have 6 pairs of (even,odd) numbers, so go through them pairwise.
for (i = 0; i < 6; i++) {
even += array[2*i];
odd += array[2*i+1]*3;
}
checkbit = 10 - (even+odd)%10;
assuming your inputString is ascii:
int odd = 0;
int even = 0;
char[] c = (inputString + "00").replaceAll("[\\-]", "").toCharArray();
for (int i = 0; i < (c.length - 1) / 2; ++i) {
odd += c[2 * i] - 48;
even += c[2 * i + 1] - 48;
}
int result = 10 - (odd + 3 * even) % 10;
This seems to work effectively and is clear.
// Calculates the isbn13 check digit for the 1st 12 digits in the string.
private char isbn13CheckDigit(String str) {
// Sum of the 12 digits.
int sum = 0;
// Digits counted.
int digits = 0;
// Start multiplier at 1. Alternates between 1 and 3.
int multiplier = 1;
// Treat just the 1st 12 digits of the string.
for (int i = 0; i < str.length() && digits < 12; i++) {
// Pull out that character.
char c = str.charAt(i);
// Is it a digit?
if ('0' <= c && c <= '9') {
// Keep the sum.
sum += multiplier * (c - '0');
// Flip multiplier between 1 and 3 by flipping the 2^1 bit.
multiplier ^= 2;
// Count the digits.
digits += 1;
}
}
// What is the check digit?
int checkDigit = (10 - (sum % 10)) % 10;
// Give it back to them in character form.
return (char) (checkDigit + '0');
}
NB: Edited to correctly handle the 0 check digit. See Wikipedia International Standard Book Number for example isbn with check digit of 0.
Paul
Similar, with loop and awful char-to-string-to-int conversions ;]
boolean isISBN13(String s){
String ss = s.replaceAll("[^\\d]", "");
if(ss.length()!=13)
return false;
int sum=0, multi=1;
for(int i=0; i<ss.length()-1; ++i){
sum += multi * Integer.parseInt(String.valueOf(ss.charAt(i)));
multi = (multi+2)%4; //1 or 3
}
return (Integer.parseInt(String.valueOf(ss.charAt(ss.length()))) == (10 - sum%10));
}

Categories