ポインタによる出力

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
sim
記事: 48
登録日時: 9年前

ポインタによる出力

#1

投稿記事 by sim » 8年前

コード:

#include<stdio.h>
#include<stdlib.h>

/*構造体の宣言*/
struct node
{
	int data;
	struct node *next;
};

int main(void)
{
	/*変数宣言*/
	struct node *start, *p, *end, *num;
	int d;
	
	/*リストを初期化する*/
	start = end = NULL;
	
	/*データを入力する*/
	printf("Input Number : ");
	scanf("%d",&d);
	
	/*リストを作成する*/
	while(d > 0)
	{
       
 /*
        
        /* 新規ノードを作成する */
        p = malloc(sizeof(struct node));
        p->data = d;
        p->next = NULL;
    	
        if (start == NULL)
        {
            /* リストが空なら先頭の位置を更新する */
            start = num = p;
        }
        else
        {
            /* 新規ノードをリストの末尾に接続する */
            num->next = p;
        	
            /* リストの末尾の位置を更新する */
            num = p;
		}
		if(start->data<=p->data)
		{
			start->next = p;
			p ->next = NULL;
		}
		else
		{
			p->next=start;
			
		}

 */

		/*データを入力する*/
		printf("Input Number : ");
		scanf("%d",&d);
	}
	
 	/*リストを作成する*/
	printf("Result : ");
	for(p=start; p!=NULL; p=p->next)
	{
		printf("%d",p->data);
	}
	printf("\n");
	
	return 0;
}
こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
途中までやりました。指摘お願いします。/**/の間のみでお願いします。

box
記事: 2002
登録日時: 13年前

Re: ポインタによる出力

#2

投稿記事 by box » 8年前

sim さんが書きました: こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
リストに放り込む際に昇順にしてやればよいと思います。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: ポインタによる出力

#3

投稿記事 by かずま » 8年前

sim さんが書きました:こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
途中までやりました。指摘お願いします。/**/の間のみでお願いします。
end や num は何のためにあるのですか?

/**/の間のみという条件を満たすプログラムは、
次のプログラムを理解した上で、あなたが書いて見せてください。

入力と逆順のリストを作るプログラム

コード:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

int main(void)
{
    struct Node *head = NULL; // リストの先頭のノードを指すポインタ
    struct Node *p;  // 新規のノードを指すポインタ、または
                     // リストの中のノードを順に見ていくポインタ
    int d;
    while (scanf("%d", &d) == 1 && d != 0) {
        p = malloc(sizeof(struct Node));
        p->data = d;
        p->next = NULL;
        if (head == NULL)
            head = p;
        else {
            p->next = head;
            head = p;
        }
    }
    for (p = head; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");
    return 0;
}
実行結果

コード:

3 1 4 2 0
 2 4 1 3
入力順のリストを作るプログラム

コード:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

int main(void)
{
    struct Node *head = NULL;  // リストの先頭のノードを指すポインタ
    struct Node *tail;         // リストの末尾のノードを指すポインタ
    struct Node *p;  // 新規のノードを指すポインタ、または
                     // リストの中のノードを順に見ていくポインタ
    int d;

    while (scanf("%d", &d) == 1 && d != 0) {
        p = malloc(sizeof(struct Node));
        p->data = d;
        p->next = NULL;
        if (head == NULL)
            head = tail = p;
        else {
            tail->next = p;
            tail = p;
        }
    }
    for (p = head; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");
    return 0;
}
実行結果

コード:

3 1 4 2 0
 3 1 4 2
入力を昇順にソートしたリストを作るプログラム

コード:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

int main(void)
{
    struct Node *head = NULL;  // リストの先頭のノードを指すポインタ
    struct Node *p;  // 新規のノードを指すポインタ、または
                     // リストの中のノードを順に見ていくポインタ
    struct Node *q;  // リストの中のノードを順に見ていくポインタ

    int d;
    while (scanf("%d", &d) == 1 && d != 0) {
        p = malloc(sizeof(struct Node));
        p->data = d;
        p->next = NULL;
        if (head == NULL)           // リストが空
            head = p;
        else if (d < head->data) {  // 先頭のノードの前に挿入
            p->next = head;
            head = p;
        }
        else {                      // 先頭のノードの後で挿入位置を探す
            for (q = head; q->next != NULL; q = q->next)
                if (d < q->next->data) break;  // 挿入位置が見つかった
            if (q->next == NULL)   // 末尾に追加
                q->next = p;
            else {                 // リストの途中に挿入
                p->next = q->next;
                q->next = p;
            }
        }
    }
    for (p = head; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");
    return 0;
}
実行結果

コード:

3 1 4 2 0
 1 2 3 4

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ポインタによる出力

#4

投稿記事 by みけCAT » 8年前

普通に入力して、マージソートなどでソートをしてから出力するのがいいでしょう。

コード:

#include<stdio.h>
#include<stdlib.h>

/*構造体の宣言*/
struct node
{
	int data;
	struct node *next;
};

int main(void)
{
	/*変数宣言*/
	struct node *start, *p, *end, *num;
	int d;
	
	/*リストを初期化する*/
	start = end = NULL;
	
	/*データを入力する*/
	printf("Input Number : ");
	scanf("%d",&d);
	
	/*リストを作成する*/
	while(d > 0)
	{
       
 /*
*/

		/* 新規ノードを作成する */
		p = malloc(sizeof(struct node));
		if (p == NULL)
		{
			perror("malloc");
			return 1;
		}
		p->data = d;
		p->next = NULL;

		if (start == NULL)
		{
			/* リストが空なら先頭の位置を更新する */
			start = num = p;
		}
		else
		{
			/* 新規ノードをリストの末尾に接続する */
			num->next = p;

			/* リストの末尾の位置を更新する */
			num = p;
		}

		/*データを入力する*/
		printf("Input Number : ");
		scanf("%d",&d);
	}

	{
		/* プロトタイプ宣言 */
		struct node *sort(struct node *head);
		int print_list(struct node *start);
		/* リストをソートする */
		start = sort(start);
		/* ソートしたリストを出力する */
		print_list(start);
	}

	/* リストを開放する */
	for (p = start; p != NULL;)
	{
		num = p->next;
		free(p);
		p = num;
	}

	return 0;
}

struct node *sort(struct node *head)
{
	struct node *a = NULL, *b = NULL, *i, *result = NULL;
	struct node **ap = &a, **bp = &b, **rp = &result;
	/* 要素が1個以下ならソートする必要が無い */
	if (head == NULL || head->next == NULL) return head;
	/* リストを適当に2個に分ける */
	for (i = head;;)
	{
		/* リストAに要素を追加する */
		*ap = i;
		ap = &(*ap)->next;
		i = i->next;
		*ap = NULL;
		if (i == NULL) break;
		/* リストBに要素を追加する */
		*bp = i;
		bp = &(*bp)->next;
		i = i->next;
		*bp = NULL;
		if (i == NULL) break;
	}
	/* 分けたリストをソートする */
	a = sort(a);
	b = sort(b);
	/* ソートしたリストをマージする */
	while (a != NULL && b != NULL)
	{
		if (a->data <= b->data)
		{
			*rp = a;
			rp = &(*rp)->next;
			a = a->next;
			*rp = NULL;
		}
		else
		{
			*rp = b;
			rp = &(*rp)->next;
			b = b->next;
			*rp = NULL;
		}
	}
	if (a != NULL)
	{
		*rp = a;
	}
	else
	{
		*rp = b;
	}
	/* 結果を返す */
	return result;
}

/* リストを出力する */
int print_list(struct node *start)
{
	int d;
	struct node *p;
	if(0)
	{
/*
 */

		/*データを入力する*/
		printf("Input Number : ");
		scanf("%d",&d);
	}
	
 	/*リストを作成する*/
	printf("Result : ");
	for(p=start; p!=NULL; p=p->next)
	{
		printf("%d",p->data);
	}
	printf("\n");
	
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: ポインタによる出力

#5

投稿記事 by かずま » 8年前

入力と逆順のリストを作るプログラムですが、
「末尾に追加」を特別扱いしなくてもよいので次のようになります。

コード:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

int main(void)
{
    struct Node *head = NULL;  // リストの先頭のノードを指すポインタ
    struct Node *p;  // 新規のノードを指すポインタ、または
                     // リストの中のノードを順に見ていくポインタ
    struct Node *q;  // リストの中のノードを順に見ていくポインタ

    int d;
    while (scanf("%d", &d) == 1 && d != 0) {
        p = malloc(sizeof(struct Node));
        p->data = d;
        p->next = NULL;
        if (head == NULL)           // リストが空
            head = p;
        else if (d < head->data) {  // 先頭のノードの前に挿入
            p->next = head;
            head = p;
        }
        else {                      // 先頭のノードの後で挿入位置を探す
            for (q = head; q->next != NULL; q = q->next)
                if (d < q->next->data) break;  // 挿入位置が見つかった
            p->next = q->next;
            q->next = p;
        }
    }
    for (p = head; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");
    return 0;
}
whileループの中で場合分けをしていますが、これをしなくてもよいようにするテクニックがあります。

コード:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

int main(void)
{
    struct Node head; // リストの先頭のノードを指すポインタを持つノード
    struct Node *p;   // 新規のノードを指すポインタ、または
                      // リストの中のノードを順に見ていくポインタ
    struct Node *q;   // リストの中のノードを順に見ていくポインタ
    int d;
    head.next = NULL;
    while (scanf("%d", &d) == 1 && d != 0) {
        p = malloc(sizeof(struct Node));
        p->data = d;
        for (q = &head; q->next != NULL; q = q->next)
            if (d < q->next->data) break;  // 挿入位置が見つかった
        p->next = q->next;
        q->next = p;
    }
    for (p = head.next; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");
    return 0;
}

かずま

Re: ポインタによる出力

#6

投稿記事 by かずま » 8年前

かずま さんが書きました:入力と逆順のリストを作るプログラムですが、
すみません。訂正です。「入力を昇順にソートしたリストを作るプログラム」でした。

sim
記事: 48
登録日時: 9年前

Re: ポインタによる出力

#7

投稿記事 by sim » 8年前

コード:

while(d > 0)
	{
		/* 新規ノードを作成する */
        p = malloc(sizeof(struct node));
        p->data = d;
        p->next = NULL;
    	
        if (start == NULL)
        {
            /* リストが空なら先頭の位置を更新する */
            start = num = p;
        }
        else
        {
            /* 新規ノードをリストの末尾に接続する */
            num->next = p;
        	
            /* リストの末尾の位置を更新する */
            num = p;
		}
		if(start->data<=p->data)
		{
			start->next = p;
			p ->next = NULL;
		}
		else
		{
			p->next=start;
			
		}
このプログラムの状態からは、できないのですか?(未完成)

かずま

Re: ポインタによる出力

#8

投稿記事 by かずま » 8年前

sim さんが書きました:このプログラムの状態からは、できないのですか?(未完成)
最初のプログラムと同じ行数です。削除は一切行っていません。変更部分も追加だけです。

コード:

#include<stdio.h>
#include<stdlib.h>
 
/*構造体の宣言*/
struct node
{
    int data;
    struct node *next;
};
 
int main(void)
{
    /*変数宣言*/
    struct node *start, *p, *end, *num;
    int d;
    
    /*リストを初期化する*/
    start = end = NULL;
    
    /*データを入力する*/
    printf("Input Number : ");
    scanf("%d",&d);
    
    /*リストを作成する*/
    while(d > 0)
    {
       
 /*
 */                                                        // 追加       
        /* 新規ノードを作成する */
        p = malloc(sizeof(struct node));
        p->data = d;
        p->next = NULL;
        
        if (start == NULL)
        {
            /* リストが空なら先頭の位置を更新する */
            start = num = p;
        }
        else if (0)                                        // 変更
        {
            /* 新規ノードをリストの末尾に接続する */
            num->next = p;
            
            /* リストの末尾の位置を更新する */
            num = p;
        } else                                             // 変更
        if(start->data<=p->data)
        { if (0)                                           // 変更
            start->next = p;
            p ->next = NULL; for (num = start; num->next && num->next->data < d; num = num->next); p->next = num->next; num->next = p; // 変更
        }
        else
        {
            p->next=start;
            start = p;                                     // 追加
        }
/*                                                         // 追加
 */
 
        /*データを入力する*/
        printf("Input Number : ");
        scanf("%d",&d);
    }
    
    /*リストを作成する*/
    printf("Result : ");
    for(p=start; p!=NULL; p=p->next)
    {
        printf("%d",p->data);
    }
    printf("\n");
    
    return 0;
}
実行結果

コード:

Input Number : 3
Input Number : 1
Input Number : 4
Input Number : 2
Input Number : 0
Result : 1234

sim
記事: 48
登録日時: 9年前

Re: ポインタによる出力

#9

投稿記事 by sim » 8年前

指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。

コード:

#include<stdio.h>
#include<stdlib.h>

/*構造体の宣言*/
struct node
{
	int data;
	struct node *next;
};

int main(void)
{
	/*変数宣言*/
	struct node *start, *p, *end, *num, *q;
	int d;
	
	/*リストを初期化する*/
	start = end = NULL;
	
	/*データを入力する*/
	printf("Input Number : ");
	scanf("%d",&d);
	
	/*リストを作成する*/
	while(d > 0)
	{
		/* 新規ノードを作成する */
        p = malloc(sizeof(struct node));
        p->data = d;
        p->next = NULL;
        
        if (start == NULL)
        {
            /* リストが空なら先頭の位置を更新する */
            start = num = p;
        }
		else if(0)                                        
        {
            /* 新規ノードをリストの末尾に接続する */
            num->next = p;
            
            /* リストの末尾の位置を更新する */
            num = p;
        }
		else if(start->data<=p->data)
		{
			start->next = p;
            p ->next = NULL;
		}
		
		else if(0)
		{
			p->next = num->next;
			num->next = p;                                                          
        }
		else
		{
			p->next=start;
            start = p; 
		}
		


		/*データを入力する*/
		printf("Input Number : ");
		scanf("%d",&d);
	}
	
 	/*リストを作成する*/
	printf("Result : ");
	for(p=start; p!=NULL; p=p->next)
	{
		printf("%d",p->data);
	}
	printf("\n");
	
	return 0;
}
	

かずま

Re: ポインタによる出力

#10

投稿記事 by かずま » 8年前

sim さんが書きました:指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。
51~54行目がダメ。なぜ、意味を理解しようとしないのですか?

box
記事: 2002
登録日時: 13年前

Re: ポインタによる出力

#11

投稿記事 by box » 8年前

sim さんが書きました:指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。

コード:

		else if(0)                                        
		else if(0)
if(0)
って何ですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: ポインタによる出力

#12

投稿記事 by かずま » 8年前

コードを付けるのを忘れました。

コード:

    while (d > 0) {
        p = malloc(sizeof(struct node)); /* 新規ノードを作成する */
        p->data = d;
        p->next = NULL;
        
        if (start == NULL) {   /* リストが空なら */
            start = p;         /* 先頭の位置を更新する */
        }
        else if (start->data <= p->data) { /* 先頭が小さければ */
            struct node *q;    /* 先頭の次から、挿入位置を探し */
            for (q = start; q->next && q->next->data < d; q = q->next) ;
            p->next = q->next; /* 挿入する */
            q->next = p;
        }
        else {                 /* 先頭が大きければ */
            p->next = start;   /* 先頭の前に挿入 */
            start = p;
        }
if (0) というのは、次の文を無視するためのもので、意味を理解して削除してほしかった。

sim
記事: 48
登録日時: 9年前

Re: ポインタによる出力

#13

投稿記事 by sim » 8年前

すみません。一様、図に書いてやっていたのですがfor文がうかばなかったのです。
随時、理解していきます。また、参考にさせていただきます。

かずま

Re: ポインタによる出力

#14

投稿記事 by かずま » 8年前

sim さんが書きました:すみません。一様、図に書いてやっていたのですがfor文がうかばなかったのです。
for文は、入場所を探すというコメントを付けて、何度も指摘しています。
入力データを、先頭の前か、末尾にしか追加しないと、昇順にならないことは自明です。

ということで、最終的には次のようにするのが良いと思います。

コード:

#include <stdio.h>
#include <stdlib.h>
 
struct node {
    int data;
    struct node *next;
};
 
int main(void)
{
    struct node head, *p, *q;
    int d;

    head.next = NULL;      /* リストを初期化する */

    while (printf("Input Number : "), scanf("%d", &d) == 1 && d > 0) {
        p = malloc(sizeof(struct node));  /* 新規ノードを作成する */
        p->data = d;
        for (q = &head; q->next != NULL && q->next->data < d; q = q->next) ;
        p->next = q->next; /* 挿入場所を探して、挿入する */
        q->next = p;
    }

    printf("Result : ");   /* リストを表示する */
    for (p = head.next; p != NULL; p = p->next)
        printf(" %d", p->data);
    printf("\n");

    return 0;
}
while文の中の式が煩雑だと思うなら、次のように書くこともできます。

コード:

    while (1) {
		printf("Input Number : ");
		if (scanf("%d", &d) != 1 || d <= 0) break;
一様ではなく、一応です。

閉鎖

“C言語何でも質問掲示板” へ戻る