Консультация № 186146
22.05.2012, 16:16
400.10 руб.
0 15 1
Здравствуйте! У меня возникли сложности с таким вопросом:
Из входного потока вводится произвольное число строк. Длина строки не ограничена. Каждая строка представляет собой последовательность многоразрядных десятичных чисел, разделённых одним или несколькими пробелами и/или знаками табуляции. Строка представлена списком (первое поле элемента списка - символ строки, второе указатель на следующий элемент списка или NULL в конце списка). Конец ввода определяется кнцом файла.
Для каждой строки сформировать новую строку, поместив в неё те числа исходной строки, которые представлены не убывающей последовательностью десятичных цифр.
В полученной строке числа разделять ТОЛЬКО ОДНИМ пробелом. Полученную строку вывести в выходной поток.

ПРИМЕЧАНИЕ:
1. Ввод строк неопределённой длины должен быть организован с помощью метода cin.getline
2. Структура программы должна быть следующей: пока не обнаружен конец файла {ввести строку (с помощью cin.getline(...)); сформировать список; обработать список в соответствии с условием задач; вывести результат; освободить память, выделенную под список}.
3.Новый список формировать, модифицируя исходный список.

Обсуждение

давно
Профессор
399103
482
22.05.2012, 16:26
общий
22.05.2012, 16:26
многоразрядных

Это как?

Строка представлена списком (первое поле элемента списка - символ строки, второе указатель на следующий элемент списка или NULL в конце списка)

Можно пояснить, что имеется в виду?
Неизвестный
22.05.2012, 17:01
общий
как я понял задание многоразрядные числа это к примеру число 1000 и каждая цифра обозначает отдельный разряд.

на второй вопрос я сам затрудняюсь ответить на данный момент.
давно
Профессор
399103
482
22.05.2012, 17:07
общий
Цитата: 393681
как я понял задание многоразрядные числа это к примеру число 1000 и каждая цифра обозначает отдельный разряд.

Т.е. не длинная арифметика?
давно
Посетитель
7438
7205
22.05.2012, 19:19
общий
22.05.2012, 19:20
Тут все просто:
1) числа воспринимаем, как последовательность цифр-символов
2) из каждой строки файла формируем список строк-чисел, заканчивающийся NULL
3) начала всех строк объединены в массив указателей.
4) дальше очевидно...

Орт Кирилл Валерьевич:
Вопрос: надо ли проверять введенные символы на нецифры? И что делать, если попадутся?
Или считаем, что будут исключительно цифры?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
22.05.2012, 19:59
общий
Да, проверка нужна. Если введены не цифры вывести ошибку и открыть строку ввода, чтоб пользователь мог ввести числа.
давно
Посетитель
7438
7205
22.05.2012, 20:03
общий
Числа вводятся из файла или с консоли?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
22.05.2012, 21:00
общий
с консоли.
Неизвестный
22.05.2012, 23:33
общий
Были похожие по сути вопросы, могут пригодиться 185796, 185944.
Неизвестный
23.05.2012, 09:40
общий
мною были рассмотрены все эти вопросы и проработаны, после чего и решил обратиться за помощью.
Неизвестный
24.05.2012, 11:04
общий
мне очень нужна эта программа.
давно
Посетитель
7438
7205
24.05.2012, 17:34
общий
Я сделаю Вам программу, только чуть позже. Время, надеюсь, еще терпит?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
24.05.2012, 20:02
общий
Адресаты:
Если Вы ещё не начали работать над вопросом, могу взяться, модифицировав свою программу 185944
давно
Посетитель
7438
7205
24.05.2012, 20:49
общий
Да пожалуйста, я не возражаю
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
25.05.2012, 08:30
общий
время уже не особо терпит, желательно конечно в ближайшее время.
Неизвестный
25.05.2012, 13:24
общий
это ответ
Здравствуйте, Орт Кирилл Валерьевич!
Программа написана с использованием компилятора GCC.
Работает как в интерактивном режиме, так и в потоковом (например так: cat text.txt | ./main)
После ввода строки и нажатии Enter, для каждого символа строки создаётся элемент списка. Затем обрабатывается, выводится, очищается, ждёт следующей строки. Любой символ в числе кроме цифры воспринимается как нарушение критерия неубывающей последовательности цифр, и число подлежит удалению.
Остальные комментарии в коде. Удачи.
[code h=200]#include <iostream>
#include <string.h>

using namespace std;

struct Elem { //Элемент списка
char ch; //символ строки
Elem *next; //Указатель на следующий элемент
};

//Создать список
Elem *GetLine()
{
char s[256]; //Временная строка
Elem *Elem0 = 0; //Указатель на первый элемент
Elem *ElemCurr = 0; //Указатель на текущий элемент
Elem *ElemPrev = 0; //Указатель на предыдущий элемент
cin.getline(s,256); //Считаем строку
for (int i=0; i<strlen(s); i++) { //Пробежимся по каждому символу строки
ElemCurr = new Elem; //Выделим память для элемента списка
ElemCurr->ch = s[i]; //Сохранить символ в списке
if (ElemPrev) { //Если определён предыдущий элемент
ElemPrev->next=ElemCurr; //Сослаться на текущий элемент
} else {
Elem0=ElemCurr; //Или запомнить как первый элемент
}
ElemPrev=ElemCurr;
}
if (Elem0) ElemCurr->next=0; //Если список не пустой, то завершить как NULL
return Elem0;
}

//Удалить число или разделители, начиная с текущего элемента
//где r = 0 - число, 1 - разделитель
Elem *DelElems(Elem *Elem1, int r)
{
int r1;
Elem *Elem2;
while (Elem1) { //Пока не конец списка
r1 = (Elem1->ch==' ' || Elem1->ch=='\t') ? 1 : 0; //цифра или разделитель?
if (r1!=r) break; //Досрочный выход
Elem2=Elem1; //Запомним элемент для удаления
Elem1=Elem1->next; //Перейдём на следующий элемент
delete Elem2; //Удалить элемент
}
return Elem1; //Указатель на первый неудалённый элемент
}

//Обработка строк
Elem *ProcessLine(Elem *Elem0)
{
if (!Elem0) return 0; //Если список пустой, то выйти
int NumWrong=0; //Флаг на число не прошедшее критерий
Elem *ElemCurr=Elem0; //Запомним начало списка
Elem *ElemPrev=Elem0; //Указатель на предыдущий элемент
Elem *ElemBeforeNum=0; //Указатель на элемент перед текущим числом
while (1) { //Переберём все элементы
if ((!ElemCurr)||(ElemCurr->ch=='\t')||(ElemCurr->ch==' ')) { //Если встретился разделитель или конец списка
if (ElemCurr==Elem0) { //Если элемент первый, то
Elem0=DelElems(Elem0,1); //Удалить разделители в начале списка
if (!Elem0) return 0; //Если список опустел, то выйти
ElemCurr=Elem0; //Текущий элемент - начало списка
ElemPrev=Elem0; //Предыдущий элемент - начало списка
continue; //Опять проверить первый элемент
} else { //Число закончилось
if (ElemCurr) { //Если не конец списка,
ElemCurr->next=DelElems(ElemCurr->next,1); //то удалить лишние разделители,
if (!ElemCurr->next) { //Если список закончился,
delete ElemCurr; //то удалить последний разделитель
ElemPrev->next=0;
ElemCurr=0;
} else {
ElemCurr->ch = ' '; //иначе, заменить оставшийся разделитель на пробел
}
}
if (NumWrong) { //Если число не удовлетворяет критерию, то удалить его
if (!ElemBeforeNum) { //Если число в начале строки,
Elem0=DelElems(Elem0,0); //То удалить всё число, и переместить начало списка
ElemPrev=Elem0;
ElemCurr=Elem0;
} else { //Если число не в начале строки
ElemBeforeNum->next=DelElems(ElemBeforeNum->next,0); //то удалить всё число от разделителя
ElemCurr=ElemBeforeNum; //Текущий элемент - пробел стоявший перед числом
ElemPrev=Elem0; //С начала списка
while (ElemPrev->next!=ElemCurr) ElemPrev=ElemPrev->next; //найдём элемент перед текущим
}
NumWrong=0; //Сбросить флаг критерия отбора
continue; //Опять проверим текущий элемент
}
}
} else { //цифра
if ((ElemCurr->ch<'0')||(ElemCurr->ch>'9')) NumWrong=1; //Любой другой символ кроме цифры нарушает критерий отбора.
if (ElemPrev->ch==' ') { //Если цифра первая в числе, а число не первое
ElemBeforeNum=ElemPrev; //то запомнить указатель на разделитель перед числом
} else { //цифра не первая в числе
if (ElemCurr->ch < ElemPrev->ch) NumWrong=1; //Если цифры в числе убывают, то поднять флаг нарушения критерия отбора
}
}
if (!ElemCurr) break; //Выйти, если список закончился
ElemPrev = ElemCurr; //Запомним текущий элемент как предыдущий
ElemCurr = ElemCurr->next; //Следующий элемент
}
return Elem0; //Вернуть указатель на начало списка
}

//Вывод результата
void PrintLine(Elem *ElemCurr)
{
while (ElemCurr) {
cout<<ElemCurr->ch;
ElemCurr = ElemCurr->next;
}
cout<<endl;
}

//Очистить память
void FreeElems(Elem *ElemCurr)
{
Elem *Elem0;
while (ElemCurr) {
Elem0=ElemCurr;
ElemCurr = ElemCurr->next;
delete(Elem0);
}
}

int main(int argc, char** argv)
{
while (1) {
//Создать список
Elem *ElemFirst = GetLine();
if (cin.eof()) break; //Если конец ввода/файла, то выйти
if (ElemFirst) { //Если список не пустой
//Обработка строк
ElemFirst=ProcessLine(ElemFirst);
//Вывод результата
PrintLine(ElemFirst);
//Очистить память
FreeElems(ElemFirst);
}
}
}
[/code]
Форма ответа