Консультация № 185796
09.04.2012, 20:36
111.00 руб.
0 14 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Из входного потока вводится произвольное число строк. Длина строки не ограничена. Каждая строка представляет собой последовательность двоичных кодов, разделённых одним или несколькими пробелами и/или знаками табуляции. Строка представлена списком (первое поле элемента списка - символ строки, второе указатель на следующий элемент списка или NULL в конце списка). Конец ввода определяется кнцом файла.
Для каждой строки сформировать новую строку, поместив в неё исходные двоичные коды, дополненные БИТОМ ЧЁТНОСТИ.
Бит сётности устанавливается 0 или 1 так, чтобы общее количество единиц в полученном коде было чётным. В полученной строке коды разделять ТОЛЬКО ОДНИМ пробелом. Полученную строку вывести в выходной поток.

[i]Примечания[/i]:
  • Ввод строк неопределённой длины должен быть организован с помощью метода cin.getline (куда, максимум_сколько). Метод cin >>
  • [i]куда не использовать![/i]

  • Структурв программы должна быть следующей: пока не обнаружен кнец файла { ввести строку с помощью cin.getline(...)
; сформировать список; обработать список в соответствии с условием задачи; вывести результат, освободить память, выделенную под список}.
  • Новый список формировать, модифицируя исходный список

Обсуждение

Неизвестный
11.04.2012, 20:56
общий
Так надо читать из файла или из консоли? Если из консоли, то при чём тут конец файла... Если из файла, то при чём тут cin...
давно
Профессор
230118
3054
11.04.2012, 21:14
общий
Бит четности всей строки, каждого символа?
Неизвестный
11.04.2012, 21:38
общий
Асмик, бит четности для каждого символа.
Неизвестный
11.04.2012, 21:41
общий
Из консоли
Неизвестный
12.04.2012, 21:57
общий
это ответ
Здравствуйте, Denis!
Программа для GCC C++
Длина строки ограничена 256 байтами, переполнение не контролируется. Комментарии в коде.
Код:

#include <iostream>
#include <string.h>

using namespace std;

struct Line { //Элемент списка
char s[256];
Line *next;
};

int main(int argc, char** argv)
{
char s[256]; //Временная строка
Line *Line0, *LineTemp, *LinePrev;
LinePrev=0; //Ссылка на предыдущий элемент
while (cin.getline(s,255)) { //Считаем строку
LineTemp = new Line; //Выделим память для элемента списка
strcpy(LineTemp->s, s); //Скопировать считанную строку в элемент списка
if (LinePrev) { //Если определён предыдущий элемент
LinePrev->next=LineTemp; //Сослаться на текущий элемент
} else {
Line0=LineTemp; //Или запомнить как первый элемент
}
LinePrev=LineTemp;
}

//Обработка строк
LineTemp=Line0; //Первый элемент списка
while (LineTemp) { //Переберём все элементы
int i=0; //Индекс символов исходной строки
int j=0; //Индекс символов результирующей строки
char ch,ch1;
char b[256]; //Результирующая строка
int spaces=0; //Флаг окончания двоичного числа
int ones=0; //Количество единиц в двоичном числе
while (1) { //Пробежимся по исходной строке
ch=LineTemp->s[i++]; //Очередной символ
if ((ch=='\t')||(ch==' ')||(ch==0)) { //Если встретился разделитель или конец строки
if (!spaces&&j) { //и не начало строки, значит число закончилось
ch1='0';
if (ones&1) ch1='1'; //Если нечётное количество единиц, то добавить единицу
b[j++]=ch1;
ones=0;
}
if (ch==0) break; //Если конец строки, то прервать цикл
spaces=1; //Поднять флаг разделителя
} else { //число
if (spaces&&j) b[j++]=' '; //Заменить все разделители на пробел
spaces=0;
if (ch=='1') ones++; //Считаем единицы
b[j++]=ch; //Заполняем результирующую строку
}
}
b[j]=0; //Не забудем обозначить конец строки
strcpy(LineTemp->s,b); //Заменить строку на обработанную
LineTemp = LineTemp->next; //Следующий элемент
}

//Вывод результата
LineTemp=Line0;
while (LineTemp) {
cout<<LineTemp->s<<endl;
LineTemp = LineTemp->next;
}

//Очистить память
LineTemp=Line0;
while (LineTemp) {
Line0=LineTemp;
LineTemp = LineTemp->next;
delete(Line0);
}


Для исходного файла text.txt:
Код:

1001011010 1010010101 0101010010 1000010101010
00101010101001 101010010 101010010101 10101010
10011001 01010 01 0011 010


Результат работы:
Код:

bizin:~/RFpro/185796$ cat text.txt | ./main
10010110101 10100101011 01010100100 10000101010101
001010101010010 1010100100 1010100101010 101010100
100110010 010100 011 00110 0101

Файл text.txt передаётся в поток как входной для нашей программы. Можно просто запустить программу и вводить строки вручную.
Если есть вопросы, спрашивайте.
5
давно
Посетитель
7438
7205
13.04.2012, 14:27
общий
Тут Вам сообщение от Denis-а
Цитата: 393119
13.04.2012, 08:33 (04 час. 49 мин. назад)
Михаил Анатольевич, в очередной раз спасибо за грамотную помощь)) Всё понятно, ничего лишнего в коде) Вы программист по специальности, или это Ваше хобби?)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
13.04.2012, 14:29
общий
Вы думаете, что Михаил Анатольевич увидел бы Ваше сообщение, адресованное модераторам?
Есть же мини-форум...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
13.04.2012, 15:47
общий
Адресаты:
)) Я случайно так отправил, сидел со смартфона)
Неизвестный
13.04.2012, 19:52
общий
Я немного ленивый и мне приходится много программировать для микроконтроллеров по работе, поэтому выработалась привычка писать компактный код и придумывать оптимальные алгоритмы. К тому же гораздо легче воспринимать написанную функцию, если её листинг умещается в экран целиком.
Неизвестный
17.04.2012, 17:09
общий
Уважаемы эксперты, можете помочь переделать функцию main() В теле этой функции должно быть только вызов таких функций как: создать список, реорганизовать список, вывод, освобождение памяти, а сами функции должны быть отдельно. Спасибо.
давно
Профессор
230118
3054
17.04.2012, 17:17
общий
Это сделать элементарно. Скопируйте куски, окружите кнопками и заголовком функции. Если не можете, составьте новый вопрос.
Неизвестный
17.04.2012, 20:36
общий
То же в виде функций.
Код:

#include <iostream>
#include <string.h>

using namespace std;

struct Line { //Элемент списка
char s[256];
Line *next;
};

//Создать список
Line *GetLines()
{
char s[256]; //Временная строка
Line *Line0, *LineTemp, *LinePrev;
LinePrev=0; //Ссылка на предыдущий элемент
while (cin.getline(s,255)) { //Считаем строку
LineTemp = new Line; //Выделим память для элемента списка
strcpy(LineTemp->s, s); //Скопировать считанную строку в элемент списка
if (LinePrev) { //Если определён предыдущий элемент
LinePrev->next=LineTemp; //Сослаться на текущий элемент
} else {
Line0=LineTemp; //Или запомнить как первый элемент
}
LinePrev=LineTemp;
}
return Line0;
}

//Обработка строк
void ProcessLines(Line *LineTemp)
{
while (LineTemp) { //Переберём все элементы
int i=0; //Индекс символов исходной строки
int j=0; //Индекс символов результирующей строки
char ch,ch1;
char b[256]; //Результирующая строка
int spaces=0; //Флаг окончания двоичного числа
int ones=0; //Количество единиц в двоичном числе
while (1) { //Пробежимся по исходной строке
ch=LineTemp->s[i++]; //Очередной символ
if ((ch=='\t')||(ch==' ')||(ch==0)) { //Если встретился разделитель или конец строки
if (!spaces&&j) { //и не начало строки, значит число закончилось
ch1='0';
if (ones&1) ch1='1'; //Если нечётное количество единиц, то добавить единицу
b[j++]=ch1;
ones=0;
}
if (ch==0) break; //Если конец строки, то прервать цикл
spaces=1; //Поднять флаг разделителя
} else { //число
if (spaces&&j) b[j++]=' '; //Заменить все разделители на пробел
spaces=0;
if (ch=='1') ones++; //Считаем единицы
b[j++]=ch; //Заполняем результирующую строку
}
}
b[j]=0; //Не забудем обозначить конец строки
strcpy(LineTemp->s,b); //Заменить строку на обработанную
LineTemp = LineTemp->next; //Следующий элемент
}
}

//Вывод результата
void PrintLines(Line *LineTemp)
{
while (LineTemp) {
cout<<LineTemp->s<<endl;
LineTemp = LineTemp->next;
}
}

//Очистить память
void FreeLines(Line *LineTemp)
{
Line *Line0;
while (LineTemp) {
Line0=LineTemp;
LineTemp = LineTemp->next;
delete(Line0);
}
}

int main(int argc, char** argv)
{
//Создать список
Line *LineFirst = GetLines();
//Обработка строк
ProcessLines(LineFirst);
//Вывод результата
PrintLines(LineFirst);
//Очистить память
FreeLines(LineFirst);
}
Неизвестный
18.04.2012, 01:44
общий
Спасибо
Неизвестный
27.04.2012, 10:08
общий
У меня ещё такой вопрос, по клавише Enter производится перевод строки с последующим вводом новой строки битов, а мне нужно так, что бы по клавише Enter выводился результат, то есть каждый бит - это элемент списка, я переделал строчку while (!(cin.getline(s,255))) {
if (cin.eof()) break; тогда после запуска программы и нажатия клавиши ENTER программа аварийно завершается и ругается на строку ch=LineTemp->s[i++];
Форма ответа