开发者

Array in Java program bizarre behaviour [duplicate]

This question already has answers here: Why int j = 012 giving output 10? (5 answers) Closed 8 years ago.

I came across this Java program and its behaving in unexpected way. The following program computes the differences between pairs of elements in an int array.

import java.util.*;

public class SetTest
{
       public static void main(String[] args)
       {
            int vals[] = {786,678,567,456,
                          345,234,123,012};

            Set<Integer> diffs = new HashSet<Integer>();

            for(int i=0; i < vals.length ; i++)
                for(int j = i; j < vals.length; j++)
                       diffs.add(vals[i] - vals[j]);

            System.out.print开发者_如何学运维(diffs.size());
       }
}

If we analyze it seems set size should be 8 which is the size of the array. But if you ran this program it prints 14. What's going on? Any idea?

Thank you in advance.

Answer: This strange behavior happens because 012 in the array becomes octal if we change it to 12 then it prints 8 as expected.

Lesson: Never pad an integer literal with zeros.


Did you noticed that 012 (octal) is 10 (decimal) ?


Since you are running two nested loops the add() method is called multiple times. Since a set cannot contain duplicate objects the number of values in the set will be the number of unique values. The add() function returns true if the set did not already contain the element and false if the set already had the element.

Change the line

diffs.add(vals[i] - vals[j]);

to

System.out.println((diffs.add(vals[i] - vals[j])));

to see what I mean.


If we analyze it seems set size should be 8 which is the size of the array. But if you ran this program it prints 14. What's going on? Any idea?

Just trace info

1   : 786 - 786 = 0 (new one 1 )
2   : 786 - 678 = 108   (new one 2 )
3   : 786 - 567 = 219   (new one 3 )
4   : 786 - 456 = 330   (new one 4 )
5   : 786 - 345 = 441   (new one 5 )
6   : 786 - 234 = 552   (new one 6 )
7   : 786 - 123 = 663   (new one 7 )
8   : 786 - 10 = 776    (new one 8 )
9   : 678 - 678 = 0 (already contained)
10  : 678 - 567 = 111   (new one 9 )
11  : 678 - 456 = 222   (new one 10 )
12  : 678 - 345 = 333   (new one 11 )
13  : 678 - 234 = 444   (new one 12 )
14  : 678 - 123 = 555   (new one 13 )
15  : 678 - 10 = 668    (new one 14 )
16  : 567 - 567 = 0 (already contained)
17  : 567 - 456 = 111   (already contained)
18  : 567 - 345 = 222   (already contained)
19  : 567 - 234 = 333   (already contained)
20  : 567 - 123 = 444   (already contained)
21  : 567 - 10 = 557    (new one 15 )
22  : 456 - 456 = 0 (already contained)
23  : 456 - 345 = 111   (already contained)
24  : 456 - 234 = 222   (already contained)
25  : 456 - 123 = 333   (already contained)
26  : 456 - 10 = 446    (new one 16 )
27  : 345 - 345 = 0 (already contained)
28  : 345 - 234 = 111   (already contained)
29  : 345 - 123 = 222   (already contained)
30  : 345 - 10 = 335    (new one 17 )
31  : 234 - 234 = 0 (already contained)
32  : 234 - 123 = 111   (already contained)
33  : 234 - 10 = 224    (new one 18 )
34  : 123 - 123 = 0 (already contained)
35  : 123 - 10 = 113    (new one 19 )
36  : 10 - 10 = 0   (already contained)

Also, debugger is a great thing in cases when you can't analyze program's behavior ;)


For a set of 8 elements, there are 36 (8 + 7 + ... + 1) distinct pairs (if one ignores the order of elements in the pairs). So diffs may contain up to 36 elements. But apparently, some differences occur multiple times, e.g. 456-345 = 111 and 345-234 = 111. As a set can only contain each value at most once, only the 14 distinct differences remain.


Your HashSet only stores non-duplicated values. If you want duplicates, you have to use a different set type. The size of diffs should be 36 with duplicates; I get a size of 19 when I run the code as-is (19 unique different values).


It actually prints out 19 here...

You have 36 calculations out of which 17 have an identical result. The HashSet only keeps unique values, this is why we don't have a size of 36 but a size of 19 ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜