Как еще можно оптимизировать этот код для защитного программирования?

StackOverflow https://stackoverflow.com/questions/3756736

Вопрос

Для моих проектов структур данных цель состоит в том, чтобы прочитать в предоставленном файле, содержащем более 10000 песен с художником, заголовком и лирикой, четко обозначенными, и каждая песня разделена строкой с одной двойной цитатой. Я написал этот код для анализа текстового файла, и он работает, с течением работы чуть менее 3 секунд до
Прочитайте 422K линейки текста
Создать объект песни
Добавьте сказанную песню для арайлиста

Анаторский код, который я написал:

if (songSource.canRead()) {  //checks to see if file is valid to read
    readIn= new Scanner(songSource);
    while (readIn.hasNextLine()) {
 do {
     readToken= readIn.nextLine();

             if (readToken.startsWith("ARTIST=\"")) {
  artist= readToken.split("\"")[1];
      } 
      if (readToken.startsWith("TITLE=\"")) {
  title= readToken.split("\"")[1];
      } 
      if (readToken.startsWith("LYRICS=\"")) {
  lyrics= readToken.split("\"")[1];
      } else {
  lyrics+= "\n"+readToken;
      }//end individual song if block
 } while (!readToken.startsWith("\"")); //end inner while loop

    songList.add(new Song(artist, title, lyrics));

    }//end while not EOF 
} //end if file can be read 

Я разговаривал с моим вступлением к профессору алгоритз о Кодексе этого проекта, и он заявил, что я должен пытаться быть более защитным в моем коде, чтобы обеспечить несоответствия в данных, предоставляемых другими людьми. Первоначально я использовал, если / else блоки между полями художника, заголовка и лирики, а по его предложению я изменился на последовательные, если заявления. Хотя я вижу его точку зрения, используя этот пример этого кода, как я могу быть более защитным о разрешении несоответствий ввода?

Это было полезно?

Решение

Вы предполагаете, что вход идеально. Если вы посмотрите на то, как ваше приложение в настоящее время настроен на основе быстрого чтения вашего алгоритма, которые будут выглядеть так

ARTIST="John"
TITLE="HELLO WORLD"
LYRICS="Sing Song All night long"
"

Но рассмотрим дело

ARTIST="John"
TITLE="HELLO WORLD"
LYRICS="Sing Song All night long"
"
ARTIST="Peter"
LYRICS="Sing Song All night long"
"

На основании вашего алгоритма у вас сейчас есть 2 песни, характеризующиеся как

songList = { Song("JOHN", "HELLO WORLD", "Sing Song All night long"),
             Song("Peter", "HELLO WORLD", "Sing Song All night long") }

С текущим алгоритмом художник и название подвергаются воздействию и будут отображаться во 2-й песне, даже если они не были определены. Вам нужно сбросить ваши три переменных.

В вашем другом вы просто сбрасываете полную линию в лирику. Что, если вы уже вытащили лирику, вы сейчас переоцениваете это. Прецедент

 ARTIST="John"
 LYRICS="Sing Song All night long"
 TILET="HELLO WORLD"
 "

Рассмотрите возможность отправки этой записи состоянию ошибки. Таким образом, когда завершен партия, завершен, отчет об ошибке может быть сгенерирован и исправлен.

Также вы считаете, что EOF после того, как художник был прочитан. Что, если EOF возникает во время чтения художника, и файл не заканчивается ». Вы собираетесь получить исключение там. В вашем Do / пока добавить еще один чек на hasnextline ()

Другие советы

Я бы заменил, например:

artist= readToken.split("\"")[1];

с участием

String[] parts = readToken.split("\"");
if(parts.length >= 2) artist = parts[1];
else continue;

Другие модификации будут включать в себя:

  1. Сбросить локальные переменные (так что вы не случайно не получаете неправильный артист для песни, если для какой-то песни не поставляется артист.
  2. Решите, что делать, если бы некоторые данные отсутствуют - вы все еще хотите добавить песню в список песен?

В реальном мире есть некоторые гарантии, касающиеся целостности данных. В случае борьбы с пользовательским входом (будь то из stdin или файла) есть определенная парадигма проекта для уведомления пользователя проблемы, которая требует внимания.

Например, когда код компилятора, компилятор или оболочкой, выполняющий скрипт, сталкивается с несоответствием, он может остановить и распечатать строку, содержащую несоответствие со второй строкой ниже, что использует символ «^», чтобы указать местоположение проблемы.

Так вот какой-то основной вопрос, чтобы спросить себя:
1. Каждая ли линия гарантирована, чтобы содержать каждое поле?
2. Является ли заказы полей, гарантированных?

Если это условия входного договора и нарушены, вы должны игнорировать / сообщать об этом. Если они не являются условиями ввода, то вам нужно справиться с этим .. который вы в настоящее время не делаете.

Я вижу пару вещей, которые не хватает здесь, Джейсон.

Я думаю, что если / else было хорошо, и это не изменит логику. Однако вы должны ограничивать объем ваших переменных как можно больше. Объявляя художника, название и т. Д. Внутри цикл While, они будут инициализированы на NULL (или что-то), поэтому, если запись отсутствует, что артистка не будет получать значение последней записи.

Кроме того, что происходит, если название, артист и т. Д. У вас есть цитата? Как это обработано? Как насчет лирики, которые, кажется, имеют несколько строк, верно?

Что произойдет, если есть неизвестное поле - может быть, ошибка? Он будет добавлен к концу лирики, которые не кажутся правильными. Только после того, как место лирики было найдено, если вы должны добавить к нему. Если лирика - это значение null, то она начнется с "null".

Вот некоторые проблемы, которые могут быть адресованы:

  • Ваш код предполагает, что нет пробелов до (например) «Художника», ни один из «=» знак и так далее.

  • Ваш код предполагает, что ключевые слова находятся на всех шагах. Кто-то мог использовать строчные или смешанные случаи.

  • Ваш код предполагает, что строка, которая не начинается с keyword=\" это продолжение лирики песни. Но что, если введен пользователь ARTOST="Sting"? Или что, если пользователь попытался использовать две строки для имени художника?

Наконец, я не убежден, что замена «иначе, если« с «если» в этом случае имеет сделали любую разницу к надежности кода.

Сделка с исключениями (я думаю, сканер может бросить IgrismismatchException для неверного символа).

Похоже, do { } while (...) Может ли не работать бесконечно, если файл плохо сформирован, а конец файла достигнут.

Ничто не мешает artist или title от пустые.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top