Search code examples
c++algorithmc++14stdvectorstdstring

MayI know why this code is not giving any output?


Please help me to solve the query that this code runs infinitely at a particular line.

It does not give any output as at the end of the code I write the code to print the vector. Even after I assign any value to vector "result" manually still it is not giving any output. why is it so?

#include<bits/stdc++.h>
using namespace std;

bool authorize(int strValue, int value, int M) 
{
   long int newValue = (strValue - (value * 131) % M);
   if (newValue >= 48 && newValue <= 57)
      return true;
   if (newValue > 65 && newValue <= 90)
      return true;
   if (newValue >= 97 && newValue <= 122)
      return true;
   return false;
}

int hashingfunct(string str, int M) 
{
   long int P, F, sum = 0;
   int len = str.length();
   for (int i = 0; i < len; i++)
   {
      P = pow(131, len - i - 1);
      F = (int)str[i];
      sum += (F * P) % M;
   }
   sum = sum % M;
   return sum;
}

int main()
{
   int n = 5;
   string str1, str2;
   vector<vector<string> > events;
   for (int i = 0; i < n; i++) {
      cin >> str1 >> str2;
      vector<string > temp;
      temp.push_back(str1);
      temp.push_back(str2);
      events.push_back(temp);
   }
   for (int i = 0; i < n; i++) {
      cout << events[i][0] << events[i][1];
   }
   /*
   INPUT FORMAT:
   setpassword 1
   setpassword 2
   setpassword 3
   authorize 49
   authorize 50
   */
   vector<int> result;
   int j = 0;
   long int m = pow(10, 9);
   long int M = m + 7;
   long int value, strValue;
   for (int i = 0; i < events.size(); i++)
   {
      strValue = stoi(events[i][1]);
      if (events[i][0] == "setPassword") {
         value = hashingfunct(events[i][1], M);
      }
      else if (strValue == value)
         result[j++] = 1;
      else if (authorize(strValue, value, M))
         result[j++] = 1;
      else
         result[j++] = 0;
   }

   for (int i = 0; i < result.size(); i++) {
      cout << result[i];
   }
}

Solution

  • Your program has complete Undefined Behaviour.

    Let's get started with the first problem. In the following check code

    long int value, strValue;  // not initialised
    for (int i = 0; i < events.size(); i++)
    {
       // ... 
       // here it should have been "setpassword" (i.e. all are small letters)
       if (events[i][0] == "setPassword")
       {
           // if the check fails the `value` never get initialised!
           value = hashingfunct(events[i][1], M);
       }
       // If the `value` not been initialised, check happens with any garbage value here!
       else if (strValue == value) 
    
       // ...other code
    }
    

    You are checking whether the string is "setPassword" instead of "setpassword" (i.e. see in the events vector, all the strings are small letters).

    If that goes wrong, the value will never get initialized, meaning it holds any garbage value and hence conducting this check else if (strValue == value) can cause any behaviour to your program (aka Undefined Behaviour).

    Secondly, the vector<int> result; is empty at the beginning. Therefore accessing elements via std::vector::operator[] later

    result[j++] = 1;
    // ...
    result[j++] = 1;
    // ...
    result[j++] = 0;
    

    triggers the access out of bounds (UB). There you need just result.emplace_back(/*value*/); or result.push_back(/*value*/);, and no need of redutant variable j.

    In short, you need

    #include <iostream>
    #include <vector>
    #include <string>
    
    // ..other functions
    int main()
    {
       std::vector<std::vector<std::string> > events { 
          {"setpassword", "1"}, // can be also user input, like in your example
          {"setpassword", "2"},
          {"setpassword", "3"},
          {"authorize", "49" },
          {"authorize", "50" }
       };
    
       std::vector<int> result;
       const long int M = pow(10, 9) + 7;
       long int value{ 0 }, strValue{ 0 }; // default initialization
       for (const std::vector<std::string> row: events) // better use range-based loop
       {
          strValue = std::stoi(row[1]);
          if (row[0] == "setpassword") {
             value = hashingfunct(row[1], M);
    
             if (strValue == value)
                result.emplace_back(1);
             else if (authorize(strValue, value, M))
                result.emplace_back(1);
          }
          else
             result.emplace_back(0);
       }
    }
    

    As a side note,