Вопрос № 178994: Написать программу генерации m-последовательностей 0 и 1 таких что а) число единиц было четно б) число единиц было больше числа нулей ...
Вопрос № 178994:
Написать программу генерации m-последовательностей 0 и 1 таких что а) число единиц было четно б) число единиц было больше числа нулей
Отвечает amnick, Студент :
Здравствуйте, Евтеев Алексей Николаевич.
Как отмечено в мини-форуме, похожий вопрос уже задавался: вопрос 178704. Чтобы не повторяться, приведу другое решение (см. приложение) — с использованием битовых массивов. При этом, сгенерированная последовательность компактно хранится в памяти.
m-последовательност
ь — это такой термин, а не m последовательностей. Но раз Вы так хотите, то я зациклил программу, так что теперь генерируется запрошенное число последовательностей.
Вот новая версия с использованием битовых массивов (178994B.PAS):
Код:
{ Программа генерации m-посл
едовательностей 0 и 1 таких, что число единиц четно и больше числа нулей }
program q178994b;
{ ---------------------------------------------------------- } { работа с битовыми массивами }
{ В качестве базового типа для битового массива можно использовать или байт, или тип, соответствующий машинному слову. В Turbo Pascal - это WORD или INTEGER. }
const bits_in_elem = sizeof(word)*8; { число битов в элементе базового типа }
{$R-} {отключаем контроль индексов
} type t_bit_array = array[0..0] of word; tp_bit_array = ^t_bit_array;
{ Устанавливает бит (bit) массива, на который указывает p, в заданное значение (0, если value=0; иначе в 1) Тип value можно изменить на BOOLEAN } procedure setBit( p: tp_bit_array; bit: longint; value: word ); var i: word; begin i := bit div bits_in_elem; { индекс элемента массива } if value <> 0 then { bit mod bits_in_elem = номер бита в word } p^[i] := p^[i] or (1 shl (bit mod bits_in_elem)) { бит 1 } else p^[i] := p^[i] and not (1 shl (bit mod bits_in_elem)); { бит 0 } end;
{ возвращает значение бита массива, на который указывает p } function getBit( p: tp_bit_array; bit: longint ): word; var s: word; begin s := bit mod bits_in_elem; getBit := (p^[bit div bits_in_elem] shr s) and 1; end;
{ Вывод битового массива на экран. nBits - размер массива в битах } procedure printSet( p: tp_bit_array;
nBits: longint ); var i: longint; begin for i := nBits-1 downto 0 do write( getBit( p, i )); end; { ---------------------------------------------------------- }
var p : tp_bit_array; numOnes, size, b : word; nBits, nSeq, i, limit : longint;
begin WriteLn( 'Генерация последовательности 0 и 1 такой, что'#13#10'число единиц четно и больше числа нулей.' ); Write( 'Введите длину последовательности (не бо
льше 524224): '); ReadLn( nBits ); write( 'Введите количество генерируемых последовательностей: ' ); readln( nSeq
);
nBits := abs(nBits); { на всякий случай } { предел определяется максимальным размером блока памяти, который можно выделить динамически } if nBits > 524224 then begin { = 65528*8 } Writeln( 'Введено слишком большое число. Используется предел = 524224.' ); nBits := 524224; end else if nBits < 3 then nBits := 3; { минимальная длина для первой подзадачи }
size := (nBits+7) div 8; { размер массива в байтах } GetMem( p, size ); { выделяем
память под массив } { fillchar( p^, size, 0 ); - можно заполнить массив нулями, но в данной реализации это необязательно }
Randomize; { инициализируем генератор псевдослучайных чисел }
repeat { генерируем хотя бы одну последовательность независимо от введенного числа nSeq } numOnes := 0; { число единиц } limit := (nBits-1) div 2; { предельное число нулей } { чтобы обеспечить четное число единиц большее числа нулей,
нужно, чтобы разность (nBits-limit) была четной } dec( limit, (nBits - limit) and 1 );
{ бит (nBits-1) оставляем "на потом", для выравнивания числа единиц (чет/нечет) } i := nBits-2; while (i >= 0) and (limit > 0) do begin b := random(2); { псевдослучайная генерация 0 или 1 } numOnes := numOnes + b; { подсчитываем число единиц } if b = 0 then dec(limit); { вариант вместо 2-х предыдущих строк: if b = 0 then dec(limit) else inc(numOnes); } setBit(
p, i, b ); dec(i); end; { остаток заполняем единицами } inc( numOnes, i+1 ); { подсчитываем число единиц } while i >= 0 do begin setBit( p, i, 1 ); dec(i); end; if odd(numOnes) then { если число единиц нечетно } setBit( p, nBits-1, 1 ) { то устанавливаем старший бит в 1 } else setBit( p, nBits-1, 0 );
{ выводим результат } printSet( p, nBits ); writeln; dec( nSeq ); until nSeq <= 0;
если можно то решите пожайлуста как у "вопрос
178704@? а не с помощью битов
Можно, конечно. Вот, пожалуйста (178994C.PAS):
Код:
{ Программа генерации m-последовательностей 0 и 1 таких, что число единиц четно и больше числа н
улей }
program q178994c;
var numOnes, b : word; nBits, nSeq, i, limit : longint;
begin WriteLn( 'Генерация последовательности 0 и 1 такой, что'#13#10'число единиц четно и больше числа нулей.' ); Write( 'Введите длину последовательности (не больше 2147483647): '); ReadLn( nBits ); write( 'Введите количество генерируемых последовательностей: ' ); readln( nSeq );
nBits := abs(nBits); { если ввели отрицательное число или
больше 2147483647 } if nBits < 3 then nBits := 3; { минимальная длина }
Randomize; { инициализируем генератор псевдослучайных чисел }
repeat { генерируем хотя бы одну последовательность независимо от введенного числа nSeq } numOnes := 0; { число единиц } limit := (nBits-1) div 2; { предельное число нулей } { чтобы обеспечить четное число единиц большее числа нулей, нужно, чтобы разность (nBits-limit) была четно
й } dec( limit, (nBits - limit) and 1 );
{ самый младший разряд оставляем "на потом", для выравнивания числ
а единиц (чет/нечет) } i := nBits-2; while (i >= 0) and (limit > 0) do begin if random(2) = 0 then begin { псевдослучайная генерация 0 или 1 } dec(limit); write( '0' ); end else begin inc( numOnes ); { подсчитываем число единиц } write( '1' ); end; dec(i); end; { остаток заполняем единицами } inc( numOnes, i+1 ); { подсчитываем число единиц } while i >= 0 do begin write( '1' ); dec(i); end; if
odd(numOnes) then { если число единиц нечетно } write( '1' ) { то устанавливаем младший разряд в 1 } else write( '0' );
writeln; dec( nSeq ); until nSeq <= 0; end.
=================
Редактирование ответа, ответ дополнен из мини-форума по просьбе эксперта.
-----
∙ Отредактировал: deepTeNk, Модератор
∙ Дата редактирования: 11.06.2010, 02:36 (время московское)
Приложение:
Ответ отправил: amnick, Студент
Ответ отправлен: 08.06.2010, 19:23
Номер ответа: 262005
Оценка ответа: 5
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 262005
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.