標準入力で2進列の末尾に改行がついたものが与えられる。連続する1の並びの両端をすべて0で置き換えて表示する。

C言語関連49閲覧xmlns="http://www.w3.org/2000/svg">250

ベストアンサー

1

1人がナイス!しています

その他の回答(3件)

0

#include <stdio.h> int main(void) { int c, f = 0; while(1){ c = getchar(); if(c != '1'){ if(f == 2) putchar('0'); putchar(c); if(c == '\n') break; f = 0; } else{ if(f == 0){ putchar('0'); f = 1; } else if(f == 1) f = 2; else putchar('1'); } } return 0; }

0

>標準入力で2進列の末尾に改行がついたものが与えられ・・・ >配列を用いないという制約の元で作成・・・ 与えられる2進列が何桁か書かれていませんが、質問の1000 1100 1110 1111だと、16桁です。 配列に格納できないということなので、最大値9223372036854775807の19桁まで扱える long int型の変数や、最大値18446744073709551615の20桁まで扱えるunsigned long int型の変数へ、単なる10進数として格納します。1000 1100 1110 1111だと、1京1100億1110万1111。 与え得られる2進列が21桁以上なら、この方法は使えません。 >連続する1の並びをどう判定すれば良いか 格納した変数値を10で割って商と余りを求め、商は次回の割り算の割られる数にするという一連の処理を下記のように反復することで、余り1の連続並びが始まる箇所や終わる箇所を、添付図のように判定できます。 ①1回目の10での割り算の余りは1で、その商に対する2回目の割り算の余りも1。 計算開始時に、余り1が2つ続いたので、2回目の余り1は次サイクルの判定に回し、1回目の余り1は0に変更する。 添付図の上で、右端の赤になっている1がそれで、添付図の下ではピンクの0。 ②連続する1並びが見つかって「1→0」が行われたので、ここからは1並びの終了を見つけて「1→0」を行なおうとする。 2回目の割り算の商に対して、3回目の割り算を行い、商と余りを求める。 並び判定は、①で保持された2回目の余りの横(添付図でいえば左)に、3回目の余りを並べると11。 2回目の割り算の余り1そのままにし、3回目の余り1は次サイクルの判定に回す。 ③3回目の割り算の商に対して、4回目の割り算を行い、商と余りを求める。 3回目の余りの横に、4回目の余りを並べると11。 3回目の割り算の余り1そのままにし、4回目の余り1は次サイクルの判定に回す。 ④4回目の割り算の商に対して、5回目の割り算を行い、商と余りを求める。 4回目の余りの横に、5回目の余りを並べると10。(添付図では、右から左へと並べているので01) 前述の②で、1並びの終了を見つける処理になっていたので、4回目の余り1を0に変更する。 添付図の上で、右端から2番目の赤になっている1がそれで、添付図の下ではピンクの0。 5回目の余り0は、1が並ぶかどうかの判定には不要なので、次サイクルでは使わない。 ⑤連続する1並びの終端が見つかって「1→0」が行われたので、ここからは1並びの開始を見つけて「1→0」を行なおうとする。 6回目の10での割り算の余りは1で、その商に対する7回目の割り算の余りも1。 1並びが終了している時点で、余り1が2つ続いたので、7回目の余り1は次サイクルの判定に回し、6回目の余り1は0に変更する。 添付図の上で、右端の青になっている1がそれで、添付図の下ではピンクの0。 以下は、省略。 添付図

画像

この返信は削除されました