Блог пользователя krngrvr09

Автор krngrvr09, история, 8 лет назад, По-английски
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++){
    ...
}
  • Проголосовать: нравится
  • +4
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится +16 Проголосовать: не нравится

easier to read:

for(int i = 0; i < (int) vector.size() - 1; i++) { }
»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

»
8 лет назад, # |
  Проголосовать: нравится -17 Проголосовать: не нравится
#define sz(a) (int)a.size() // you'll never forgot to typecast :)
»
8 лет назад, # |
Rev. 2   Проголосовать: нравится -7 Проголосовать: не нравится
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 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

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

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      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 лет назад, # ^ |
          Проголосовать: нравится +15 Проголосовать: не нравится

        That's unreadable. Really

      • »
        »
        »
        »
        8 лет назад, # ^ |
        Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

        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 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

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

      • »
        »
        »
        »
        4 года назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Yeah.

        • »
          »
          »
          »
          »
          4 года назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Can you give more insights via bit level calculations ?

          • »
            »
            »
            »
            »
            »
            4 года назад, # ^ |
              Проголосовать: нравится +10 Проголосовать: не нравится

            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 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

or you can use

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

but this is better

for (int i = 0; i < int(vec.size()); ++i) {
   ...
}
»
4 года назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

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 :).