Задача 2 (комментарии)

Правила проведения олимпиады, условия задач и комментарии к ним, результаты олимпиады и апелляции.
Руководители: к.ф-м.н., профессор Пирогов Владислав Юрьевич, ник - Vladislav_133; к.п.н, доцент Слинкин Дмитрий Анатольевич, ник - xdsl

Задача 2 (комментарии)

Сообщение Vladislav_133 04 апр 2015, 10:24

Здесь будет обсуждение
Аватара пользователя
Vladislav_133
Elite
 
Сообщения: 1386
Зарегистрирован: 13 дек 2008, 18:08
Полное имя: П.В.Ю.

Re: Задача 2 (комментарии)

Сообщение hardcore_test 05 апр 2015, 01:32

Сразу несколько замечаний по коду
Т.к использовал сканер, то код оказался очень медленным, другой способ ввода информации исправил бы ситуацию
Можно было бы не суммировать все строки в одну, а по символьно проходить каждую строчку, что сделало бы программу менее затратной по памяти
Кавычки в комментариях названы скобками
Но самое главное это как обрабатывать строку:
Если встретили открытие комментария и при этом сейчас кавычки закрыты, то это значит, что начался новый комментарий.
Если встретили закрытие комментария и при этом сейчас кавычки закрыты, то это либо ошибка вторая, либо закрытие комментария
Если встретили закрытие комментария и при этом сейчас кавычки открыты, то это закрытие комментария
Если закончили просмотр всего входного файла и у нас остался открытый комментарий, то это ошибка два
сам код:
Код: Выделить всё
// задача №2 "комментарий"
// Быков Владислав Андреевич
// email - i596655@yandex.ru
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

public class comment {

   public static void main(String[] args) throws FileNotFoundException {
      String s = "";
      Scanner sc = new Scanner(new File("input.txt"));

      while (sc.hasNext()) {
         s = s + sc.nextLine();

      }
      s = s + " "; // добавляю пробел на случай, если последним символом
                  // окажется * или /
      boolean skobki = false; // переменная отвечает за информацию об октрытых
                        // скобках
      boolean coomment = false; // переменная отвечает за информацию о начатом
                           // комментарии
      boolean error2 = false; // переменная отвечает за информацию о второй
                        // ошибке
      int i = 0; // номер символа в строке
      while (i < s.length()) { // идем от начала до конца строки
         char t = s.charAt(i); // в т храним текущий символ
         if (t == ('\"')) // если это "
            skobki = (!skobki); // то меняем информацию о скобках
         else if ((t == '/') && (s.charAt(i + 1) == '*') && (!coomment)
               && (!skobki)) {

            coomment = true;
            i++;// т.к комментарий 2 символа, то и двигаемся на два символа
               // вперед: один здесь другой ниже
         } else if ((t == '*') && (s.charAt(i + 1) == '/')) {
            if (coomment == true) {
               coomment = false;
            } else if (!skobki) { // если комментарий не начат и скобки не
                              // открыты, то значит ошибка
               error2 = true;
            }
            i++; // т.к комментарий 2 символа, то и двигаемся на два символа
                  // вперед: один здесь другой ниже
         }
         i++; // двигаемся на 1 символ вперед
      }
      PrintWriter pw = new PrintWriter("output.txt");
      if (coomment == true)
         pw.println("Error 1");
      else if (error2 == true)
         pw.println("Error 2");
      else
         pw.println("No error");
      sc.close();
      pw.close();
   }

}

С подсветкой синтаксиса, тык
hardcore_test
 
Сообщения: 102
Зарегистрирован: 06 мар 2015, 16:10
Полное имя: Владислав Андреевич Быков

Re: Задача 2 (комментарии)

Сообщение Vladislav_133 05 апр 2015, 18:12

Вот мое скромное решение.

Подсветка синтаксиса: [ Загрузить ] [ Скрыть ]
Подсветка синтаксиса языка cpp
#include <stdio.h>
#include <string.h>
int flag1, flag2;
int main(){
    char  p=' ', p1=' ';
    flag1=flag2=0;
    while(1){
        p1=p;
        p = fgetc(stdin);
ex:    
        if(p==EOF)break;
        if(p1=='/'&&p=='*'&&flag1==0&&flag2==0){
        //на два символа вперед
            p1=fgetc(stdin);
            if(p1=='"')p=p1;
            else
            p = fgetc(stdin);
            flag1=1;
            goto ex;
        }
        if(p1=='*'&&p=='/'){
            if(flag1!=0){
        //на два символа вперед    
                p1=fgetc(stdin);
                if(p1=='"')p=p1;
                else
                p = fgetc(stdin);
                flag1=0;
                goto ex;       
            }
            if(flag2!=0)continue;
            fprintf(stdout,"Error 2\n");
            return 0;
        }
        //начало или конец строки  
        if(p=='"'){
            if(flag2!=0){
                flag2=0; continue;
            }
            if(flag2==0){
                flag2=1; continue;
            };
        }              
    }
    //комментарий не закрыт?
    if(flag1!=0){
        fprintf(stdout,"Error 1\n");       
        return 0;
    }
    fprintf(stdout,"No error\n");          
    return 0;
}

 
Последний раз редактировалось Vladislav_133 08 апр 2015, 09:18, всего редактировалось 1 раз.
Аватара пользователя
Vladislav_133
Elite
 
Сообщения: 1386
Зарегистрирован: 13 дек 2008, 18:08
Полное имя: П.В.Ю.

Re: Задача 2 (комментарии)

Сообщение Vladislav_133 05 апр 2015, 18:15

На мой взгляд в этой задаче есть только один момент, который сходу можно упустить при программировании.
Если программа нашла начало или конец комментария, то далее следует пропустить один символ,
чтобы проверять уже за началом или концом. Мне кажется большинство ошибок у участников в этом и состояли.
Аватара пользователя
Vladislav_133
Elite
 
Сообщения: 1386
Зарегистрирован: 13 дек 2008, 18:08
Полное имя: П.В.Ю.

Re: Задача 2 (комментарии)

Сообщение [DD] 08 апр 2015, 00:10

Vladislav_133 писал(а):На мой взгляд в этой задаче есть только один момент, который сходу можно упустить при программировании.
Если программа нашла начало или конец комментария, то далее следует пропустить один символ,
чтобы проверять уже за началом или концом. Мне кажется большинство ошибок у участников в этом и состояли.


В Вашем решении как раз из-за этих смещений появился баг. Если после закрывающей пары сразу идет открывающая кавычка, то Ваш код ее пропустит.
При входящих данных
Код: Выделить всё
/*asdasdasd*/"/*"

в солвере выдается Error1. Хотя все корректно так как открывающая пара находится в кавычках.
мы рождены чтоб сказку сделать кодом
[DD]
Elite
 
Сообщения: 163
Зарегистрирован: 18 мар 2009, 22:18
Откуда: from HELL
Полное имя: Зыков Д.А.

Re: Задача 2 (комментарии)

Сообщение Vladislav_133 08 апр 2015, 09:19

Ну вот, кто должен проверять решения.
Замечательно. Вот эту тонкость я не увидел.
Текст я подправил. Сейчас отправлю на солвер.
Спасибо, Дмитрий!
Аватара пользователя
Vladislav_133
Elite
 
Сообщения: 1386
Зарегистрирован: 13 дек 2008, 18:08
Полное имя: П.В.Ю.

Re: Задача 2 (комментарии)

Сообщение xdsl 08 апр 2015, 13:01

Исправления внесены в Солвер
xdsl
 
Сообщения: 1236
Зарегистрирован: 09 дек 2008, 05:16
Откуда: ВЦ ШГПИ
Полное имя: Слинкин Д.А.

Re: Задача 2 (комментарии)

Сообщение [DD] 08 апр 2015, 20:04

продолжаю выкладывать то, что имеется
Подсветка синтаксиса: (2.php) [ Загрузить ] [ Скрыть ]
Подсветка синтаксиса языка php
  1. <?php
  2. /**
  3.     коментариев тут будет ну очень мало так как все и так вроде прозрачно:-)
  4. */
  5.  
  6. function Out($result){//не более чем функция вывода результата и завершения скрипта
  7.     file_put_contents("./output.txt", $result);
  8.     die();
  9. }
  10. $chars = ['"', "/", "*"];//только эти символы нас интересуют
  11. $input = fopen("./input.txt", "r");
  12. $commentOpened = FALSE;
  13. $quoteOpened = FALSE;
  14. $lastChar = "";
  15. while(!feof($input)){
  16.     $line = $lastChar . fgets($input, 1024);//так как пых не особо скоростной читать будем по килобайту а не посимвольно
  17.     $i = 0;
  18.     $l = strlen($line);
  19.     while($i < $l - 1){//последний символ нарочно не перебираем(так как коменты проверяют текущий и следующий)
  20.         $char = $line[$i++];
  21.         if(!in_array($char, $chars)){
  22.             continue;
  23.         }
  24.         if(!$commentOpened){
  25.             if($char == '"'){
  26.                 $quoteOpened = !$quoteOpened;
  27.                 continue;
  28.             }
  29.             if($char == "/" && $line[$i] == "*" && !$quoteOpened){
  30.                 $commentOpened = TRUE;
  31.                 $i++;
  32.                 continue;
  33.             }
  34.             if($char == "*" && $line[$i] == "/" && !$quoteOpened){
  35.                 Out("Error 2");
  36.             }
  37.         }
  38.         else{
  39.             if($char == "*" && $line[$i] == "/"){
  40.                 $commentOpened = FALSE;
  41.                 $i++;
  42.                 continue;
  43.             }
  44.         }
  45.     }
  46.     /**
  47.         при такой обработке ни в коем случае нельзя забывать переносить последний символ считанных данных
  48.         в начало следующих. Поэтому и запомним его
  49.     */
  50.     $lastChar = $line[$l-1];
  51. }
  52.  
  53. Out($commentOpened? "Error 1": "No Error");
мы рождены чтоб сказку сделать кодом
[DD]
Elite
 
Сообщения: 163
Зарегистрирован: 18 мар 2009, 22:18
Откуда: from HELL
Полное имя: Зыков Д.А.

Re: Задача 2 (комментарии)

Сообщение Vladislav_133 08 апр 2015, 21:10

Хороший прием: последний символ приклеить в начало следующей порции символов.
Аватара пользователя
Vladislav_133
Elite
 
Сообщения: 1386
Зарегистрирован: 13 дек 2008, 18:08
Полное имя: П.В.Ю.


Вернуться в Олимпиада по программированию

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

cron