krngrvr09's blog

By krngrvr09, history, 8 years ago, In English
vector<int> v;
cout<<v.size()-1;

The following will give you 18446744073709551615. This is because vector.size() returns a size_t type value, which is an alias for unsigned long int. In plain terms:

unsigned long int a=0;
cout<<a-1;

The above code will give the same result — 18446744073709551615.

Implications

for(int i=0;i<vector.size()-1;i++){
    ...
}

In the above for loop, if the vector has 0 elements, then the loop will be equivalent to:

for(int i=0;i<18446744073709551615;i++){
    ...
}

Which, I believe is not what you will be expecting. So the correct way to use for loops is the following:

for(int i=0;(i+1)<vector.size();i++){
    ...
}

---Edit---

As pointed out by Errichto and satyaki3794, we can just typecast vector.size() to an int, and use it normally. Like this:

for(int i=0;i<(int)vector.size()-1;i++){
    ...
}
  • Vote: I like it
  • +4
  • Vote: I do not like it

| Write comment?
»
8 years ago, # |
  Vote: I like it +16 Vote: I do not like it

easier to read:

for(int i = 0; i < (int) vector.size() - 1; i++) { }
»
8 years ago, # |
  Vote: I like it 0 Vote: I do not like it

You can just typecast vector.size() to an int instead. Then it will always give the correct value.

»
8 years ago, # |
  Vote: I like it -17 Vote: I do not like it
#define sz(a) (int)a.size() // you'll never forgot to typecast :)
»
8 years ago, # |
Rev. 2   Vote: I like it -7 Vote: I do not like it
for (int i = 0; i < vector.size() - 1; i++) { }

=>

for (size_t i = 1; i < vector.size(); i++) { /* use i-1 */ }

Because it's not a good idea to use signed number, when there is no need to use negative values.

  • »
    »
    8 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Suppose I need to iterate backward. I do not think making size_t unsigned was a good idea

    • »
      »
      »
      8 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      That is a matter of taste. I prefer to use the following:

      for (size_t i = a.size(); i > 0; i--) { /* use i-1 */ }
      
      • »
        »
        »
        »
        8 years ago, # ^ |
          Vote: I like it +15 Vote: I do not like it

        That's unreadable. Really

      • »
        »
        »
        »
        8 years ago, # ^ |
        Rev. 3   Vote: I like it 0 Vote: I do not like it

        you really suppose using i - 1 superior?

        I would understand if you've said for (size_t i = a.size(); i-- > 0;) but it's still not really readable

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Why does the vector.size() give correct answer when the vector has non zero elements?

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    vector.size() always gives a correct answer. If you have an empty vector, it will return size = 0. However, since it returns the answer in an unsigned format, if you minus one from 0, it overflows since unsigned numbers can't be negative.

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      So when overflows the output will be maximum value of unsigned long long?

      • »
        »
        »
        »
        4 years ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Yeah.

        • »
          »
          »
          »
          »
          4 years ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Can you give more insights via bit level calculations ?

          • »
            »
            »
            »
            »
            »
            4 years ago, # ^ |
              Vote: I like it +10 Vote: I do not like it

            Signed numbers use the first bit to tell if the number is negative or positive, while unsigned numbers use the first bit like any other bit. Ex. 101 would be 5 for an unsigned number, but -3 for a signed number. Integers use a system called two's complement to store negative numbers. Essentially how the system works is if I have a number N, -N = (reverse all bits of N) + 1. So when an unsigned long long number tries to do this with -1, it flips all the bits, changing the number like so: (binary representation of 1 = 0.....001) -> (1.....110). When you add 1 to this, all the bits are set to 1, thus giving you the maximum value of unsigned long long.

»
4 years ago, # |
  Vote: I like it +1 Vote: I do not like it

or you can use

for (size_t i = ...) {
   ...
}

but this is better

for (int i = 0; i < int(vec.size()); ++i) {
   ...
}
»
4 years ago, # |
  Vote: I like it +10 Vote: I do not like it

C++20 contains the method ssize which returns an int value for the vector size. See https://en.cppreference.com/w/cpp/iterator/size for details. I hope to see C++20 soon here on Codeforces :).