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

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

ただいまの
回答率

90.35%

  • C

    4212questions

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

  • Visual Studio 2010

    127questions

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

少し変わった二重ループ

解決済

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 1,443

pppepo

score 3

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)
.
.
.

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+1

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

char* s = "%d,%d\n";
for (i = 0; i < 100; i++)
{
    for (j = 0; j < i; j++)
    {
        printf(s, i, j);
        printf(s, j, i);
    }
    printf(s, i, i);
}

追記

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

void main()
{
    for (i = 0; i < 100; i++)
    {
        for (j = 0; j < i; j++)
        {
            f(i, j);
            f(j, i);
        }
        f(i, i);
    }
}

void f(int i, int j)
{
    // ややこしい処理
    printf("%d,%d\n", i, j);
    // 込み入った処理
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/24 00:21

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

    キャンセル

  • 2016/06/24 00:22

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

    キャンセル

+1

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

#include <stdio.h>
#include <math.h>

int main(void)
{
    int a[2];
    for (int i = 0; i < 100; i++)
    {
        a[0] = sqrt(i);
        a[1] = (i - pow(a[0], 2)) / 2;
        printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]);
    }
    return 0;
}

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

#include <stdio.h>

int main(void)
{
    int a[2] = { 0, 0 };
    for (int i = 0; i < 100; i++)
    {
        a[0] += i / (a[0] * (a[0] + 2) + 1);
        a[1] = (i - a[0] * a[0]) / 2;
        printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]);
    }
    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

こんな感じかな?

for(int p=0; p<100; p++){
    int        x = p;
    int        y = 0;

    for(int c=0; ; c++){

        // ここで(x, y)になんかする

        if(x == y){
            break;
        }

        x += c & 1;

        int        t = x;
        x = y;
        y = t;
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/24 18:30

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

    キャンセル

  • 2016/06/25 02: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 をスワップしているので↑の走査順になります。

    キャンセル

  • 2016/06/25 20:35

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

    キャンセル

0

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

int level = -1;
int start = -1;
int end = 0;
for (int i = 0; i < 100; i++)
{
    int x, y;
    if (i % 2 == start % 2)
    {
        x = (i - start) / 2 - 1;
        y = level + 1;
    }
    else
    {
        x = level + 1;
        y = (i - start - 1) / 2;
    }
    f(x, y);
    if (i == end)
    {
        level++;
        start = end;
        end = level * (level + 4) + 3;
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

@count = 1
@board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

def show_board
  @board.each do |vec|
    puts vec.map { |x| format('%2d', x) }.join(', ')
  end
  puts
end

def action(x, y)
  @board[y][x] = @count
  @count += 1
end

# 水平線でスキャン
@count = 1
(0..3).each do |y|
  (0..3).each do |x|
    action(x, y)
  end
end
show_board

# 斜め線でスキャン
@count = 1
(0..3 * 2).each do |z|
  (0..z).each do |y|
    action(z - y, y) if y < 4 && z - y < 4
  end
end
show_board

# J 型でスキャン
@count = 1
(0..3).each do |z|
  (0..z).each do |t|
    action(z, t)
  end
  (1..z).each do |t|
    action(z - t, z)
  end
end
show_board

# J 型でスキャンの変形
@count = 1
(0..3).each do |z|
  action(z, z)
  (0..z - 1).each do |t|
    action(z, t)
    action(t, z)
  end
end
show_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

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

@count = 1
(0..3).each do |z|
  (0..z - 1).each do |t|
    action(z, t)
    action(t, z)
  end
  action(z, z)
end
show_board


実行結果

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/24 18:29

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

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4212questions

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

  • Visual Studio 2010

    127questions

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