Название: Алгоритмическое мышление при решении задач (Шамшев А. Б.)

Жанр: Информационные системы и технологии

Просмотров: 1394


Задача 13 (1 способ решения): из файла удалить слова, в которых содержится хотя бы одна буква предпоследней строки.

Размышления о ходе решения задачи.

1.  Первые четыре шага аналогичны первым четырем шагам в задаче 12 (1

способ  решения).  Для  работы  с  файлами  воспользуемся функциями

File.ReadAllLines и File.WriteAllLines.

2.  Для того, что бы обработать строку, надо найти последнюю строку в файле. Предположим, что мы ее нашли. Логично, что она должна находиться только один раз. Поэтому вероятнее всего, что она будет

передаваться  в  качестве  параметра  в  processString  у  StringWorker. В остальном логика обработки строки почти аналогична рассмотренной ранее обработке.

public void processString(string lastStr) {

}

3.  Для  того,  что  бы  ответить  на  вопрос,  надо  удалять  слово  или  нет,

необходимо знать последнюю строку. Пусть она будет передаваться в параметрах в needDelWord. По логике, для ответа на вопрос, содержатся ли в слове буквы предпоследней строки, надо просмотреть все буквы слова, т. е. должен появиться цикл. Если во время выполнения цикла мы встретим букву предпоследней строки, то это будет означать, что слово надо удалять и дальнейший просмотр не нужен. Сказать, что слово не содержит букв предпоследней строки, мы можем только после прохода по слову. В кодах материализация этих рассуждений будет выглядеть следующим образом:

public bool needDelWord(string word, string lastStr) {

for (int i = 0; i < word.Length;i++ ) {

if (lastStr.Contains(word[i])) {

return true;

}

}

return false;

}

4.  И  приведем  код  всего  класса,  который  ответственен  за  обработку строки:

public class StringWorker {

 

public string str;

 

public bool needDelWord(string word, string lastStr) {

for (int i = 0; i < word.Length;i++ ) {

if (lastStr.Contains(word[i])) {

return true;

}

}

return false;

}

private bool isSeparator(char c) {

string oneCharStr = "" + c;

return " .,?!".Contains(oneCharStr);

}

 

public int getWordLength(int index) {

int res = 0;

for (int i = index; i < str.Length; i++) {

if (isSeparator(str[i])) {

break;

}

res = res + 1;

}

return res;

}

 

public void processString(string lastStr) {

for (int i = 0; i < str.Length; i++) {

if (isSeparator(str[i])) {

continue;

}

int len = getWordLength(i);

string word = str.Substring(i, len);

if (needDelWord(word, lastStr)) {

str = str.Remove(i, len);

} else {

i = i + len;

}

}

}

 

}

5.  Теперь, после решения вопроса об обработке одной строки вернемся к

обработке       всего   файла. По       логике псевдокод       алгоритма       должен выглядеть так:

 

Получить все строки входного файла.

Найти последнюю строку файла.

Объявить массив обработанных строк нужного размера.

Для каждой строки входного файла

НачалоЦикла

Обработать  текущую  строку,  передав  в  параметрах  последнюю  строку

файла

 

Записать измененную строку в результирующий массив.

ОкончаниеЦикла

Записать массив обработанных строк в выходной файл.

 

6.  Отметим, что файл может быть пустым. Поэтому в этом случае надо выкинуть  исключение.  А  последняя  строка  в  массиве  имеет  номер

размер массива (data.Length) минус 1. Поэтому материализация этого псевдокода в кодах будет выглядеть следующим образом:

public class FileWorker {

 

public void processFile(string inFileName, string outFileName) {

try {

string[] content = File.ReadAllLines(inFileName);

if (content.Length == 0) {

throw   new ApplicationException("в  файле нет  строк");

}

string lastStr = content[content.Length - 1]; string[] resLines = new string[content.Length]; for (int i = 0; i < content.Length;i++ ) {

StringWorker worker = new StringWorker();

worker.str = content[i]; worker.processString(lastStr); resLines[i] = worker.str;

}

File.WriteAllLines(outFileName, resLines);

} catch { Console.WriteLine("ошибка");

}

}

}

7.  И приведем полный код задачи

using System; using System.IO; using System.Linq;

namespace ConsoleApplication17 {

class Program {

static void Main() {

Console.WriteLine("введите  имя   входного файла: ");

string inFileName = Console.ReadLine(); Console.WriteLine("введите  имя   выходного  файла: "); string outFileName = Console.ReadLine();

FileWorker fileWorker = new FileWorker();

fileWorker.processFile(inFileName, outFileName);

}

}

public class StringWorker {

public string str;

public bool needDelWord(string word, string lastStr) {

for (int i = 0; i < word.Length;i++ ) {

if (lastStr.Contains(word[i])) {

return true;

}

}

return false;

}

private bool isSeparator(char c) {

string oneCharStr = "" + c;

return " .,?!".Contains(oneCharStr);

}

public int getWordLength(int index) {

int res = 0;

for (int i = index; i < str.Length; i++) {

if (isSeparator(str[i])) {

break;

}

res = res + 1;

}

return res;

}

public void processString(string lastStr) {

for (int i = 0; i < str.Length; i++) {

if (isSeparator(str[i])) {

continue;

}

int len = getWordLength(i);

string word = str.Substring(i, len);

if (needDelWord(word, lastStr)) {

str = str.Remove(i, len);

} else {

i = i + len;

}

}

}

}

public class FileWorker {

public void processFile(string inFileName, string

outFileName) {

try {

string[] content = File.ReadAllLines(inFileName);

if (content.Length == 0) {

throw   new ApplicationException("в  файле нет  строк");

}

string lastStr = content[content.Length - 1];

string[] resLines = new string[content.Length];

for (int i = 0; i < content.Length;i++ ) {

StringWorker worker = new StringWorker(); worker.str = content[i]; worker.processString(lastStr);

resLines[i] = worker.str;

}

File.WriteAllLines(outFileName, resLines);

} catch { Console.WriteLine("ошибка");

}

}

}

}