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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

Q&A

解決済

5回答

2885閲覧

少し変わった二重ループ

pppepo

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

0グッド

1クリップ

投稿2016/06/23 14:35

for文を2回重ねておこなうループで

for(y=0;y<100;y++){ for(x=0;x<100;x++){ } } コード

というループ、つまり四角形の領域をラスタスキャンなんですけどこれを
1:(0,0)
2:(1,0)
3:(0,1)
4:(1,1)
5:(2,0)
6:(0,2)
7:(2,1)
8:(1,2)
9:(2,2)
.
.
.

みたいな段々と大きくさせる上手な書き方があれば教えて下さい
どうも自分で考えたアルゴリズムが汚いです。

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

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

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

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

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

guest

回答5

0

もう一つ。速度完全無視で。ループは一重、if を使わない縛り。

C

1#include <stdio.h> 2#include <math.h> 3 4int main(void) 5{ 6 int a[2]; 7 for (int i = 0; i < 100; i++) 8 { 9 a[0] = sqrt(i); 10 a[1] = (i - pow(a[0], 2)) / 2; 11 printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]); 12 } 13 return 0; 14}

math.h を使わないパターン。少し高速化されるはず。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 int a[2] = { 0, 0 }; 6 for (int i = 0; i < 100; i++) 7 { 8 a[0] += i / (a[0] * (a[0] + 2) + 1); 9 a[1] = (i - a[0] * a[0]) / 2; 10 printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]); 11 } 12 return 0; 13}

投稿2016/06/23 23:08

編集2016/06/24 00:15
Zuishin

総合スコア28656

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

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

0

例えばこんな感じですか?

C

1char* s = "%d,%d\n"; 2for (i = 0; i < 100; i++) 3{ 4 for (j = 0; j < i; j++) 5 { 6 printf(s, i, j); 7 printf(s, j, i); 8 } 9 printf(s, i, i); 10}

###追記
関数はこうやって使います。

C

1void main() 2{ 3 for (i = 0; i < 100; i++) 4 { 5 for (j = 0; j < i; j++) 6 { 7 f(i, j); 8 f(j, i); 9 } 10 f(i, i); 11 } 12} 13 14void f(int i, int j) 15{ 16 // ややこしい処理 17 printf("%d,%d\n", i, j); 18 // 込み入った処理 19}

投稿2016/06/23 14:47

編集2016/06/23 15:29
Zuishin

総合スコア28656

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

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

pppepo

2016/06/23 15:21

できれば中身を書くのは一回で抑えたい(書こうと思ってる中の部分は結構膨大)です 質問文通りに表示したいのであればこれで良いのですが・・・ 実際には関数が入り組んでいるのです・・・
Zuishin

2016/06/23 15:22

中に何度も書かなくても別の関数にまとめて呼び出せばいいんですよ。
guest

0

c でなくて、 ruby でかいてますが、アルゴリズムの意図は伝わると思います。
4 x 4 の四角領域をスキャンして、1.. 16 の数字を埋めていきます。
4つのスキャン方法を書いていますが、最後のものが質問への回答に相当すると思います。
a.rb

ruby

1@count = 1 2@board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 3 4def show_board 5 @board.each do |vec| 6 puts vec.map { |x| format('%2d', x) }.join(', ') 7 end 8 puts 9end 10 11def action(x, y) 12 @board[y][x] = @count 13 @count += 1 14end 15 16# 水平線でスキャン 17@count = 1 18(0..3).each do |y| 19 (0..3).each do |x| 20 action(x, y) 21 end 22end 23show_board 24 25# 斜め線でスキャン 26@count = 1 27(0..3 * 2).each do |z| 28 (0..z).each do |y| 29 action(z - y, y) if y < 4 && z - y < 4 30 end 31end 32show_board 33 34# J 型でスキャン 35@count = 1 36(0..3).each do |z| 37 (0..z).each do |t| 38 action(z, t) 39 end 40 (1..z).each do |t| 41 action(z - t, z) 42 end 43end 44show_board 45 46# J 型でスキャンの変形 47@count = 1 48(0..3).each do |z| 49 action(z, z) 50 (0..z - 1).each do |t| 51 action(z, t) 52 action(t, z) 53 end 54end 55show_board

実行結果

$ ruby a.rb 1, 2, 3, 4 5, 6, 7, 8 9, 10, 11, 12 13, 14, 15, 16 1, 2, 4, 7 3, 5, 8, 11 6, 9, 12, 14 10, 13, 15, 16 1, 2, 5, 10 4, 3, 6, 11 9, 8, 7, 12 16, 15, 14, 13 1, 3, 6, 11 4, 2, 8, 13 7, 9, 5, 15 12, 14, 16, 10

渦巻状にスキャンしていくという方法もあります。
参考 - JavaScriptで渦巻き上に数字を並べたい https://teratail.com/questions/20868

追記:
順番があっていないとコメントがありました。
次のものではどうでしょう?

ruby

1 @count = 1 2(0..3).each do |z| 3 (0..z - 1).each do |t| 4 action(z, t) 5 action(t, z) 6 end 7 action(z, z) 8end 9show_board

実行結果

1, 2, 5, 10 3, 4, 7, 12 6, 8, 9, 14 11, 13, 15, 16

投稿2016/06/23 19:56

編集2016/06/24 12:12
katoy

総合スコア22324

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

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

pppepo

2016/06/24 09:29

最後のものではないか?とのことですが、求めているものと少し違います (一番下の番号で) 1→3→4→2→6→7→8→9→5 という順番ですね
guest

0

ベストアンサー

こんな感じかな?

C

1for(int p=0; p<100; p++){ 2 int x = p; 3 int y = 0; 4 5 for(int c=0; ; c++){ 6 7 // ここで(x, y)になんかする 8 9 if(x == y){ 10 break; 11 } 12 13 x += c & 1; 14 15 int t = x; 16 x = y; 17 y = t; 18 } 19}

投稿2016/06/23 17:11

toki_td

総合スコア2850

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

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

pppepo

2016/06/24 09:30

x+=c&1はどのような意味があるのでしょうか?
toki_td

2016/06/24 17:10

あれ?ほかのコメントを見ると順番違う? ある横、または縦のp列(行)について考えると処理の順は (p, n) (n, p) (p, n+1) (n+1, p) (p, n+2) (n+2, p) ..... (p, p) と思いました。 ここから (p, n) --- x, y 交換 --> (n, p) --- n+1, x,y交換 --> (p, n+1) --- x, y交換 --> (n+1, p).... となるのでx, yは点を処理するごとに交換され、n は2回に1回1足せばいいことになります。 cは1点ごとに単純に増加するので c & 1 は 0, 1, 0, 1.... と繰り返すため、2回に1回xは1増加します。その後 x と y をスワップしているので↑の走査順になります。
pppepo

2016/06/25 11:35

いえ、その処理結果順番であってます &1は01を交互に繰り返しているのですね (見た目が)最もシンプルで使いやすいのでこの方法を使わさせていただきます。ありがとうございました
guest

0

頭の体操で、二重ループを一重ループにしてみました。
条件文が増えているので、効率は落ちてます。

C

1int level = -1; 2int start = -1; 3int end = 0; 4for (int i = 0; i < 100; i++) 5{ 6 int x, y; 7 if (i % 2 == start % 2) 8 { 9 x = (i - start) / 2 - 1; 10 y = level + 1; 11 } 12 else 13 { 14 x = level + 1; 15 y = (i - start - 1) / 2; 16 } 17 f(x, y); 18 if (i == end) 19 { 20 level++; 21 start = end; 22 end = level * (level + 4) + 3; 23 } 24}

投稿2016/06/23 16:28

編集2016/06/23 16:32
Zuishin

総合スコア28656

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問