연재 완료/C Lang 예제코드 모음

C언어 구조체 및 공용체 실습문제1 (선형 연결 리스트에서 특정문자 삭제하기)

라이피 (Lypi) 2018. 5. 28. 22:12
반응형

입력된 데이터 중에서 특정 문자를 지울 수 있는 프로그램

// practics.cpp: 콘솔 응용 프로그램의 진입점을 정의합니다.
//

#include "stdafx.h"

//linear linked list example

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

#define MAXLINE 100

typedef char DATA;	// will use char in examples

struct linked_list {
	DATA			d;
	linked_list*	next;
};

typedef linked_list ELEMENT;
typedef ELEMENT*	LINK;

void concatenate(LINK a, LINK b);
int count(LINK head);
int count_it(LINK head);
LINK string_to_list(char s[]);
void delete_list(LINK head);
void wrt_list(LINK hp);
void print_list(LINK head);
void delete_char(LINK head, char c);
LINK create_list();

int main()
{
	LINK hp = NULL;			//hp = head pointer
	LINK p = hp;

	printf("This program will do the following repeatedly and then delete the linked list before exiting : \n");
	printf("\n");
	printf("\t1. cereate a linked list from a line of text \n");
	printf("\t2. concatinate the list to what we already have \n");
	printf("\t3. print the data in the linked list\n");

	int input = 0;

	while (input != 4) {
		printf("원하는 동작을 선택하세요. \n");
		if (input == 0) {
			printf("1. 리스트 생성 \n");
			printf("4. 종료 \n");
		}
		else {
			printf("1. 리스트 생성 \n");
			printf("2. 리스트 출력 \n");
			printf("3. 리스트에서 특정 문자 삭제 \n");
			printf("4. 종료 \n");
		}

		do {
			scanf_s("%d", &input);
			while (getchar() != '\n') {}
			if (0 > input && input > 5) {
				printf("1~4 사이의 숫자를 입력하세요. \n");
			}
		} while (0 > input && input > 5);
		

		switch (input) {
		case 1:
			p = create_list();
			break;
		case 2:
			if (p == NULL) {
				input = 0;
				break;
			}
			print_list(p);
			break;
		case 3:
			if (p == NULL) {
				input = 0;
				break;
			}
			char c;
			printf("삭제할 문자를 입력하세요 :"); scanf_s("%c", &c, sizeof(char));
			while (getchar() != '\n') {}
			delete_char(p, c);
			break;
		case 4:
			break;
		}
	}

	delete_list(hp);
	printf("\n bye! \n\n");

	return 0;
}

LINK create_list()
{
	char line[MAXLINE];
	LINK hp = NULL;			//hp = head pointer
	LINK rp;
	LINK p;

	while (1) {
		printf("\n Type in a line of text : ");
		assert(fgets(line, MAXLINE, stdin) != NULL);

		if (*line == '\n') {
			break;
		}

		p = string_to_list(line);

		if (hp == NULL) {
			hp = p;
			rp = p;
		}
		else {
			concatenate(hp, p);
		}
		putchar('\n');
		wrt_list(hp);
		putchar('\n');
	}

	return rp;

}

//concatenate list a and b with as head.
//리스트의 마지막에 b를 연결시키는 함수
void concatenate(LINK a, LINK b)
{
	assert(a != NULL); // a가 NULL이면 프로그램을 종료시킨다.

	if (a->next == NULL) {
		a->next = b;
	}
	else {
		concatenate(a->next, b);
	}
}

//count a list recursively.
//재귀 호출을 이용해서 리스트에 연결된 ELEMENT들의 개수를 세는 함수
int count(LINK head)
{
	if (head == NULL) {
		return 0;
	}
	else {
		return (1 + count(head->next));
	}
}

//count a list iteratively.
//반복문을 이용해서 리스트에 연결된 ELEMENT들의 개수를 세는 함수
int count_it(LINK head)
{
	int cnt = 0;

	for (; head != NULL; head = head->next) {
		++cnt;
	}

	return cnt;
}

//list creation using recursion.
//재귀 호출을 이용해서 리스트를 만든다.
LINK string_to_list(char s[])
{
	DATA	d;
	LINK	head;

	if (s[0] == '\0') { //base case
		return NULL;
	}
	else {
		head = (LINK)malloc(sizeof(ELEMENT));
		d = (s[0] == '\n') ? ' ' : s[0];
		head->d = d;
		head->next = string_to_list(s + 1);
		return head;
	}

}

//recursive deletion of a list
//재귀를 이용해서 리스트를 삭제한다.
void delete_list(LINK head) {
	if (head != NULL) {
		delete_list(head->next);
		free(head);
	}
}

//write data in list iteratively.
//리스트에 데이터를 쓰는 함수.
void wrt_list(LINK hp)
{
	LINK	p;
	for (p = hp; p != NULL; p = p->next) {
		putchar(p->d);
	}
}

//print a list recursively.
//재귀호출을 이용해서 리스트의 내용을 출력
void print_list(LINK head)
{
	if (head == NULL) {
		printf("NULL \n");
	}
	else {
		printf("%c -> ", head->d);
		print_list(head->next);
	}
}

//삭제하기.
void delete_char(LINK head, char c)
{

	if (head == NULL) {
		return;
	}
	else {
		if (head->next == NULL) {
			return;
		}

		LINK dp = head->next;

		if (dp->d == c) {
			head->next = head->next->next;
			free(dp);
		}
	}
	delete_char(head->next, c);
}

// 선형 연결 리스트 자체를 직접 짜도록 합시다. 

// 그리고 단순 연결 리스트에서 첫번째 노드는 삭제할 수 없는것인가...

// 제대로 이해못한게 분명하다.

반응형