Решение Задачи TEST

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем paulgryshchiuk, 8 ноя 2018.

  1. Код (C++):
    #include <windows.h>
    #include <iostream>



    using namespace std;

    int main() {                                      
        int ans = 5, a;                                
        int temp = 0;                                
        string s ="sqis";                

     
        for ( int i = 0;i < s.length();i++)

        {                                                      
            if (s[i] == 's') {                  
                for ( int j = i + 1;j < s.length();j++) {      
                                                               
                    if (s[j] == 'i') {
                        for ( int h = j + 1;h < s.length();h++) {
                                                               

                            if (s[h] == 's') {

                                if (i > 1) {

                                    temp++;
                                 

                                }
                                if (j - 1 > 1) {
                                    temp++;
                                 
                                }
                                if (h - 1 > 1) {
                                    temp++;
                                 
                                 

                                    if (ans != s.length() >= 4) {
                                        cout << "1";
                                    }
                                    else if (a = min(ans, temp));
                                    {
                                 
                                        cout <<"0";
                                    }

                                 
                                }

                            }
                        }
                    }
                }
            }
        }
        system("pause");
    }
     

    Вложения:

  2. BAR__MEN

    BAR__MEN Гуру

    Сразу пара вопросов:
    1. Почему в разделе про JS?
    2. Как это относится к форуму?
    3. Нафига нам этот код?
    4. Что он делает?
     
  3. DIYMan

    DIYMan Гуру

    Не увидел вопроса. Но вот это - неправильно:
    Код (C++):
    if (ans != s.length() >= 4)
    И вот это - тоже:
    Код (C++):
    else if (a = min(ans, temp));
    - у вас для else if просто пустой оператор (уберите точку с запятой в конце строки).

    Лучшим вариантом будет рассказать: что вам нужно получить от кода, на словах. У меня подозрения, что всё можно сделать сильно проще.
     
  4. BAR__MEN

    BAR__MEN Гуру

    Это ж спам =)
    Если не в том разделе - спам³
     
  5. нет не спам
     
  6. DIYMan

    DIYMan Гуру

    Не, это не спам, это товарищ в ВК попросил меня помочь с решением задачи, я порекомендовал Амперку. Не выкидывай покудова ;)
     
  7. вообщем, я закрепил скриншот , там описана суть этого задания
     
  8. у вас отображается закреп. скриншот?
     
  9. BAR__MEN

    BAR__MEN Гуру

    Рад бы, да прав нет..

    О не.. Это ж олимпиада... Там надо своими мозгами думать, так не честно

    ЗЫ: Так почему тема не во флудилке, а в рандомном разделе?
     
  10. эт не олимпиада, просто сайт з заданиями, я уже 2 часа туплю как ее решить
     
  11. DIYMan

    DIYMan Гуру

    Ок, понял. Как-то так, навскидку:

    Код (C++):

    int findSIS(const std::string& s)
    {
        int result = -1;

        size_t sPos = s.find('s');
        if(sPos == std::string::npos) // не найдено ни одной s
            return result;

        size_t iPos = s.find('i',sPos);

        if(iPos == std::string::npos) // не найдено ни одной i, следующей за s
            return result;

        size_t sPos2 = s.find('s', iPos);

        if(sPos2 == std::string::npos) // не найдено ни одной s, следующей за i
            return result;

        // теперь считаем кол-во вычёркиваний
        if((iPos - sPos) == 1 && (sPos2 - iPos) == 1) // есть подстрока "sis"
        {
            result = 0;
           if(s.length() > 3)
           {
               if(sPos > 0)
                   result++;
           
               if(iPos < s.length() -1)
                   result++;
               
           }
        }
        else
        {
            result = sPos > 0 ? 1 : 0;

            if(iPos - sPos > 1)
                result++;

            if(sPos2 - iPos > 1)
                result++;
        }

        return result;
    }
     
    На компилируемость не проверял, передал только суть. У std::string достаточно методов, чтобы обойтись без кучи вложенных циклов ;) Какие-то проверки мог пропустить, естественно. В общем, подход с использованием find - я показал, не стоит спрашивать у меня на 100% рабочий код сходу ;)
     
    Последнее редактирование: 8 ноя 2018
  12. Спасибо огромное, пытаюсь сейчас переварить весь этот код, правда выдает одну ошибку: undefined refrerence to `WinMain@16
     
  13. я так понял, это из за того что не об'явлена функция main
     
  14. DIYMan

    DIYMan Гуру

    Я вам привёл только функцию, которая на вход получает строку, и возвращает кол-во вычёркиваний. Притом - с заведомо неполными проверками. Вы же не думаете, что всё сделают за вас? ;) Был продемонстрирован метод, как отказаться от вложенных циклов, используя только методы класса std::string, и простейшие проверки.
     
  15. Ок, всеравно большое спасибо!
     
  16. DIYMan

    DIYMan Гуру

    Смотрите, чтобы было более понятно, я откупирую код:
    Код (C++):
    int findSIS(const std::string& s)
    {
        int result = -1;

        size_t sPos = s.find('s');
        if(sPos == std::string::npos) // не найдено ни одной s
            return result;
        size_t iPos = s.find('i',sPos);

        if(iPos == std::string::npos) // не найдено ни одной i, следующей за s
            return result;

        size_t sPos2 = s.find('s', iPos);

        if(sPos2 == std::string::npos) // не найдено ни одной s, следующей за i
            return result;

        // теперь считаем кол-во вычёркиваний
        result = 0;
     
        // вот тут надо вставить проверки!!!

        return result;
    }
    Вариантов у нас несколько, рассмотрим некоторые из них:

    1. Когда символы 's', 'i', 's' - следуют друг за другом, т.е. промежуточных вычёркиваний между ними нет. В этом случае, если длина строки равна 3 - ноль вычеркиваний. Если длина строки больше трёх, то два варианта: либо одно вычёркивание, либо - два, в зависимости от того, в какой позиции находятся sPos и sPos2.

    2. Когда символы 's', 'i', 's' - НЕ следуют друг за другом, в этом случае - надо смотреть, как далеко они друг от друга, не забывая про возможные вычёркивания в начале и конце строки.

    Я просто набросал кусок кода, проверки там неполные, это точно. Полные проверки - описаны выше словами, позиции найденных символов - даны в переменных, дальше - простая арифметика.

    З.Ы. Там, кстати, описка вкралась, я поправил код в сообщениях выше. Было, в третьей проверке:
    Код (C++):
        size_t sPos2 = s.find('s', iPos);

        if(iPos == std::string::npos) // не найдено ни одной s, следующей за i
            return result;
     
    Стало:
    Код (C++):
        size_t sPos2 = s.find('s', iPos);

        if(sPos2 == std::string::npos) // не найдено ни одной s, следующей за i
            return result;
     
     
  17. DIYMan

    DIYMan Гуру

    Короче: вот документированный код, вроде всё учёл, пробуйте:
    Код (C++):
    int findSIS(const std::string& s)
    {
        int result = -1;

        size_t sPos = s.find('s');

        if(sPos == std::string::npos) // не найдено ни одной s
            return result;

        size_t iPos = s.find('i',sPos);

        if(iPos == std::string::npos) // не найдено ни одной i, следующей за s
            return result;

        size_t sPos2 = s.find('s', iPos);

        if(iPos == std::string::npos) // не найдено ни одной s, следующей за i
            return result;

        // теперь считаем кол-во вычёркиваний
        result = 0;
     
        if(s.length() == 3) // просто строка "sis"
            return result;
        else // строка с вычёркиваниями
        {
            if(sPos > 0) // позиция первого символа 's' - не первая в строке, до него - есть вычёркивание
                result++;
             
            if(sPos2 < s.length() -1) // позиция второго символа 's' - не последняя в строке, после него - есть вычёркивание
                result++;
             
            // теперь смотрим - есть ли вычёркивания между символами
            if(iPos - sPos > 1) // есть символы между первой 's' и 'i'
                result++;
             
            if(sPos2 - iPos > 1) // есть символы между 'i' и второй 's'
                result++;
        }

        return result;
    }
    Это читабельный вариант. Можно написать сильно короче, да и кучей других способов, но мы не будем заморачиваться, правда? ;)
     
  18. DIYMan

    DIYMan Гуру

    Вашим способом, через кучу циклов - это ненаглядно, очень. По сути, вам надо знать всего три вещи:

    1. Позиция первого 's';
    2. Позиция 'i';
    3. Позиция второго 's'.

    Далее идёт - простая арифметика. Чтобы найти все позиции - достаточно ОДНОГО цикла:

    Код (C++):
    int findSIS(const char* str)
    {
       const char *sPos = NULL, *iPos = NULL, *sPos2 = NULL, *s = str;
    int cntr = 0;

       while(*s)
      {
          if(cntr == 0 && *s == 's') { cntr++; sPos = s; }
          if(cntr == 1 && *s == 'i') {cntr++; iPos = s;}
          if(cntr == 2 && *s == 's') {sPos2 = s; break;}

        s++;
      }

       // проверяем индексы
      if(!sPos || !iPos || !sPos2) return -1;

      int result = 0;
      // тут - простая арифметика подсчёта вычеркиваний

      return result;
    }