Страница 1 из 1

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

СообщениеДобавлено: 04 апр 2015, 10:24
Vladislav_133
Здесь будет обсуждение

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

СообщениеДобавлено: 05 апр 2015, 01:32
hardcore_test
Сразу несколько замечаний по коду
Т.к использовал сканер, то код оказался очень медленным, другой способ ввода информации исправил бы ситуацию
Можно было бы не суммировать все строки в одну, а по символьно проходить каждую строчку, что сделало бы программу менее затратной по памяти
Кавычки в комментариях названы скобками
Но самое главное это как обрабатывать строку:
Если встретили открытие комментария и при этом сейчас кавычки закрыты, то это значит, что начался новый комментарий.
Если встретили закрытие комментария и при этом сейчас кавычки закрыты, то это либо ошибка вторая, либо закрытие комментария
Если встретили закрытие комментария и при этом сейчас кавычки открыты, то это закрытие комментария
Если закончили просмотр всего входного файла и у нас остался открытый комментарий, то это ошибка два
сам код:
Код: Выделить всё
// задача №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();
   }

}

С подсветкой синтаксиса, тык

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

СообщениеДобавлено: 05 апр 2015, 18:12
Vladislav_133
Вот мое скромное решение.

Подсветка синтаксиса: [ Загрузить ] [ Скрыть ]
Подсветка синтаксиса языка 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;
}

 

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

СообщениеДобавлено: 05 апр 2015, 18:15
Vladislav_133
На мой взгляд в этой задаче есть только один момент, который сходу можно упустить при программировании.
Если программа нашла начало или конец комментария, то далее следует пропустить один символ,
чтобы проверять уже за началом или концом. Мне кажется большинство ошибок у участников в этом и состояли.

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

СообщениеДобавлено: 08 апр 2015, 00:10
[DD]
Vladislav_133 писал(а):На мой взгляд в этой задаче есть только один момент, который сходу можно упустить при программировании.
Если программа нашла начало или конец комментария, то далее следует пропустить один символ,
чтобы проверять уже за началом или концом. Мне кажется большинство ошибок у участников в этом и состояли.


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

в солвере выдается Error1. Хотя все корректно так как открывающая пара находится в кавычках.

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

СообщениеДобавлено: 08 апр 2015, 09:19
Vladislav_133
Ну вот, кто должен проверять решения.
Замечательно. Вот эту тонкость я не увидел.
Текст я подправил. Сейчас отправлю на солвер.
Спасибо, Дмитрий!

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

СообщениеДобавлено: 08 апр 2015, 13:01
xdsl
Исправления внесены в Солвер

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

СообщениеДобавлено: 08 апр 2015, 20:04
[DD]
продолжаю выкладывать то, что имеется
Подсветка синтаксиса: (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");

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

СообщениеДобавлено: 08 апр 2015, 21:10
Vladislav_133
Хороший прием: последний символ приклеить в начало следующей порции символов.