質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

4回答

2005閲覧

綺麗なコードの書き方を教えてください

izuki_y

総合スコア65

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2016/02/02 12:43

requestを見てSEND_REQUESTの場合にsend dataを行う以下の様なプログラムがあります。

java

1/* 2 NON_REQUEST = 0x0101 3 START_REQUEST = 0x0102 4 SEND_REQUEST = 0x0103 5 ENDPRINT_REQUEST = 0x0104 6 CANCEL_REQUEST = 0x0200 7*/ 8 9SendConnect conn = new SendConnect(); 10 11for (;;) { 12 if (request != SEND_REQUEST) { 13 sleep(10); /* wait 10ms */ 14 continue; 15 }else{ 16 // send data 17 if (!sendData(conn)) { 18 throw new ICPException("send request error"); 19 } 20 } 21}

SEND_REQUEST でない時は10回まで10msでsleepして、
10回以上で倍々にしていき最大で1000ms sleepしたいと思っています。

皆さんならどんな風に書きますか?
ちなみに自分はこうしました。

java

1 2SendConnect conn = new SendConnect(); 3 4int b = 0; 5int cnt = 0; 6 7for (;;) { 8 if (request != SEND_REQUEST) { 9 if(cnt<10){ 10 sleep(10); /* wait 10ms */ 11 cnt++; 12 }else if((10<<b) < 1000){ 13 sleep(10<<(b++)); /* wait 20-640ms */ 14 }else{ 15 sleep(1000); /* wait 1000ms */ 16 } 17 continue; 18 }else{ 19 b=0; 20 cnt=0; 21 } 22 // send data 23 if (!sendDataRequest(conn)) { 24 throw new ICPException("send request error"); 25 } 26}

何か自分で書いてて野暮ったいなぁと思ったので質問しました。
もうひとつはこんな風に・・・。

int nt = 0; SendConnect conn = new SendConnect(); for (;;) { if (request != SEND_REQUEST) { if(request == NON_REQUEST){ cnt++; }else{ cnt = 0; } if(cnt < 10){ sleep(10); }else{ switch(cnt) case 11: sleep(20); break; casse12: sleep(40); break; casse13: sleep(80); break; casse14: sleep(160); break; casse15: sleep(320); break; casse16: sleep(640); break; default: sleep(1000); break; } } continue; }else{ cnt = 0; } // write data if (!sendDataRequest(conn)) { throw new ICPException("send request error"); } }

凄い見苦しい。

みなさんはどう書きますか?
参考にさせてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

java

1 static int[] sleeptime = new int[] { 2 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, 10000 }; 4 void loop() { 5 SendConnect conn = new SendConnect(); 6 int cnt; 7 for (;;) { 8 switch (request) { 9 case ENDPRINT_REQUEST: 10 return; 11 case CANCEL_REQUEST: 12 return; 13 case SEND_REQUEST: // 送って次 14 if (!sendData(conn)) { 15 throw new ICPException("send request error"); 16 } 17 cnt = 0; 18 continue; 19 case START_REQUEST: 20 // TODO: ATDK 21 cnt = 0; 22 continue; 23 case NON_REQUEST: // なんか処理 24 sleep(sleeptime[cnt]); 25 cnt += cnt < sleeptime.length - 1 ? 1 : 0; // 最大20 26 break; 27 default: 28 assert false; // ここには来ない 29 return; 30 } 31 } 32 }

定数テーブルが組み込みっぽい。なんかもうひといき。二重ループにしたほうがきれいかな。

投稿2016/02/03 15:41

編集2016/02/03 15:46
matobaa

総合スコア2493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

izuki_y

2016/02/04 14:41

回答ありがとうございます。 定数テーブル。 自分組み込みなんで気持ち凄いわかります。 速度的にはこちらの書き方の方が出そうですね。 NON_REQUESTの時も20超えた場合もbreakせずに周り続ける様にして動かしてみた所 期待通りの動作を得ることが出来ました。
guest

0

「美しい」という言葉だと、人によっていろんな基準があるので難しいですね。
あなたの意図からはかなり外れているような気がしますが(その上間違いがありそうな気がしますが)
私がなるべく美しくなるように考えたコードを書きます。
受信処理が無いのがすわりが悪くかんじたので、かなり勝手な解釈をしています。
この点質問の趣旨からは外れてしまっているかもしれません。
あと、「サンプルコードは可能な限りコンパイラを通したものを省略無しで」 という
ポリシーでやっていますので、若干長くなります。

Java

1public class Waiting { 2 private static final int SEND_REQUEST = 1; 3 private static final int COUNT_THRESHOLD = 10; 4 private static final int WAIT_FIRST_MS = 0; 5 private static final int WAIT_MAX_MS = 1000; 6 private static final int WAIT_COEFFICIENT = 2; 7 8 private int count; 9 private int wait; 10 11 public static void main(String[] args) throws InterruptedException, ICPException { 12 RecvConnect rconn = new RecvConnect(); 13 SendConnect sconn = new SendConnect(); 14 Waiting waiting = new Waiting(); 15 for (;;) { 16 int request = rconn.recvRequest(); 17 if (request == Waiting.SEND_REQUEST) { 18 if (!sconn.sendDataRequest(sconn)) { 19 throw new ICPException("send request error"); 20 } 21 waiting.init(); 22 } 23 waiting.waiting(); 24 } 25 } 26 27 public void init() { 28 this.count = 0; 29 this.wait = Waiting.WAIT_FIRST_MS; 30 } 31 32 public void waiting() throws InterruptedException { 33 if ( this.wait < Waiting.WAIT_MAX_MS ) { 34 ++this.count; 35 if ( this.count > Waiting.COUNT_THRESHOLD ) { 36 this.wait *= Waiting.WAIT_COEFFICIENT; 37 if ( this.wait > Waiting.WAIT_MAX_MS ) { 38 this.wait = Waiting.WAIT_MAX_MS; 39 } 40 } 41 } 42 Thread.sleep(this.wait); 43 } 44} 45

投稿2016/02/02 15:54

kozuchi

総合スコア1193

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

izuki_y

2016/02/04 14:46

回答ありがとうございます。 任意のリクエストを受けた時にループを抜ける処理を追加する事で期待する動作になる事を確認しました。 javaはやっぱり難しいですね。
guest

0

ベストアンサー

こんにちは。

私ならこんな感じで書くと思います。

Java

1SendConnect conn = new SendConnect(); 2 3int cnt = 0; 4int msec = 0; 5for (;;) { 6 if (request != SEND_REQUEST) { 7 if(cnt < 10){ 8 ++cnt; 9 msec = 10; 10 }else{ 11 msec *= 2; 12 if (1000 < msec) msec=1000; 13 } 14 sleep(msec); 15 }else{ 16 // write data 17 if (!sendDataRequest(conn)) { 18 throw new ICPException("send request error"); 19 } 20 cnt = 0; 21 } 22}

制御変数が2つあるのが今一ですが、なるべく仕様通りに記述してみました。

SEND_REQUEST でない時は10回まで10msでsleepして、
10回以上で倍々にしていき最大で1000ms sleepしたいと思っています。

投稿2016/02/02 13:35

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

izuki_y

2016/02/02 14:20

参考になりました。 期待する動きと同じだったのでベストアンサーにさせていただきました。
guest

0

Java

1 2SendConnect conn = new SendConnect(); 3 4int time = 10; 5int count = 0; 6 7while(request != SEND_REQUEST) { 8 9 10 if(count < 10) { // 1~10回までは10ms待つ. 11 sleep(10); 12 }else{ //それ以降は2倍. 13 time = getSleeptime(time); 14 sleep(time); 15 } 16 count++; 17} 18// send data 19if (!sendDataRequest(conn)) { 20 throw new ICPException("send request error"); 21} 22 23 24//*********************************************************** 25//1000ms以下なら2倍 26int getSleepTime(int time){ 27 28 if(time < 1000){ 29 time += time; 30 }else { 31 time = 1000; 32 } 33 return time; 34} 35

投稿2016/02/02 13:24

編集2016/02/02 13:40
nomorin

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

izuki_y

2016/02/02 14:18

吟味させて頂きました。 説明が足りなくてごめんなさい。 request は延々と周り続ける仕様なんです・・・(厳密に言うとCancelとEndのrequestが来たときに抜けるんですが冗長になるので抜いてました) 綺麗なソースで一発見ただけで理解出来るためとても参考になりました。
izuki_y

2016/02/04 14:48

言葉足らずでしたが、C言語で実装するなら間違いなくこちらのソースを参考にさせていただきます。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問