#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
char str[100];// /포함하여 99자
Node * next; //다음 노드 가르키는 포인터
}Node;
Node *head=NULL; //헤드를 전역으로 선언
void insert(int c); //위치삽입 함수
void del(int c); //삭제함수
void move(int c ,int dc); //옮기기 함수
void exchange(int c ,int dc); //교환함수
void show(int c);//출력함수
void playexchange(int c ,int dc);//교환함수에서 실질적으로 돌리는 함수
int main()
{
int N=0,i=0,dc, c;
char a;
scanf("%d",&N);
if(N<=1000&&N>=1)//1<= N <=1000이아니면 프로그램 종료
{
while(N!=i) //반복문이다.
{
scanf(" %c",&a); //실행할 함수
scanf("%d",&c); //원하는 위치
switch(a)
{
case 'I':
{
insert(c);
break;
}
case 'D':
{
del(c);
break;
}
case 'M':
{
scanf("%d",&dc); // c에서 dc로 옮기는 것이다.
move(c,dc);
break;
}
case 'E':
{
scanf("%d",&dc); //c노드와 dc노드를 교환
exchange(c,dc);
break;
}
case 'S':
{
show(c);
break;
}
}
i+=1;
}
}
else
{
return -1;
}
return 0;
}
void insert(int c)
{
Node* m = head; //m에 head를 복사해놓음
Node* p;
int n;
Node * r = (Node*)malloc(sizeof(Node)); //동적할당
r->next=NULL; //초기화
scanf("%s",&r->str); //값 입력
if(head== NULL) //head가 비어있을시에 헤드에 삽입
{
head = r;
}
else if(c<=1) //헤드가 삽입되었을때 헤드에 넣고 기존헤드는 다음노드에 삽입하기.
{
r->next=head;
head=r;
}
else// 넣을 위치에 앞노드 p를 이용해 묶는다.
{
for(n=0; n<c-1; n++)
{
p=m;
m=m->next;
}
r->next = p->next;
p->next=r;
}
}
void show(int c)
{
int n=1;
Node * m;
m = head;
while( n!=c) //c번 반복
{
m = m->next;
n++;
}
printf("%s\n",m->str); //반복후에 그 노드의 값을 출력
}
void del(int c)
{
Node *m = head;
Node *p;
Node *s;
int n;
if(c>1)
{
for(n=0; n<c-1; n++)
{
s=m;
m=m->next;
}
p=m;
s->next = m->next; //전 노드와 앞노드 묶기
free(p);
}
else if(c==1) //헤드를 삭제할경우 헤드 앞에 노드가 없기에 위와는 다름 형식이된다.
{
p =head->next; //헤드의 다음노드 저장
free(head);//헤드 날림
head = p; //헤드에 저장한 p를 붙이기
}
}
void move(int c,int dc)
{
Node* m = head;
Node* s,*y,*x,*ny,*nx;
int n=1;
if(c==1) //헤드자리노드를 다른 자리로 옮길시 함수
{
for(n=0; n < dc-1; n++)
{
s=m;
m=m->next;
}
y = head;
head = head->next; //헤드를 한칸 앞당김
s->next = y;
y->next = m; //s와 m사이에 헤드노드 삽입
}
else if(dc == 1) //다른 자리 노드를 헤드에 옮길시
{
for(n=0; n < c-1; n++)
{
s=m;
m=m->next;
}
y = head;
x = m;
head = m;//헤드에 다른자리노드 복사
s->next = m->next;//다른자리노드의 부재를 메꾼다.
m->next = y;//다른자리 노드 다음노드를 월레헤드로 연결
}
else
{
while(m->next!=NULL)
{
n++;
s=m;
m=m->next;
if(n==c)
{
y = s;
x = m; //옮길 자리 노드의 앞노드와 그 자체노드를 따로 복사
}
if(n==(dc-1))
{
ny = m;
nx = m->next; //옮겨질위치 자리 노드의 앞노드와 그 자체노드를 따로 복사
}
}
y->next = x->next;
ny->next = x;
x->next = nx;//c노드를 cd노드의 앞 ny - c - nx이런식으로 삽입한다.
}
}
void exchange(int c ,int dc)
{
Node* m = head;
Node* s,*o,*k,*y,*x,*ny,*nx;
int n=1;
if(c==1)
{
playexchange(c ,dc);
}
else if(dc == 1)
{
playexchange(dc ,c);
}
else
{
while(m->next!=NULL)
{
n++;
s=m;
m=m->next;
if(n==c)
{
y = s;
x = m; //교환할 1번 노드 앞노드와 그 자체노드 복사
}
if(n==dc)
{
ny = s;
nx = m; //교환할 2번 노드 앞노드와 그 자체노드 복사
}
}
k=x;
o=nx;
y->next = nx;
ny->next = x;
nx->next = k->next;
x->next = o->next;//두 노드를 교환 정보가 엉키지않게 차례를 조율한다.
}
}
void playexchange(int c ,int dc)
{
int n;
Node *m = head;
Node *s,*k,*y;
for(n=0; n < dc-1; n++)
{
s=m;
m=m->next;
}
k = m;
y = head;
s->next = head;
m->next = k->next;
head = k;
k->next = y->next;//앞노드가 없는 헤드자리에 노드와 다른자리의 노드를 교환한다. c와 dc둘중 하나가 1이면 파라매터를 바꾸어서 넣으면 되기에 둘의 함수가 같다.
}
이거 과제로 컴퓨터가 체점하는건데 돌리니까 70퍼센트 맞았다고 뜨네요....명세서에 있는 예시대로 쳐보면 맞게 나오는데 대체 왜이러는걸까여......2시간 남았는데 죽고 싶지않습니다
------------------명세서 에요,,,-=---------------------------
연결된 리스트를 사용하여 다음과 같은 라인 편집기를 만들고자 한다. 이 편집기에서 지원되는 연
산은 삽입(Insert), 삭제 ,이동(Move), 교환(Exchange), 보기(Show) 다섯 개이고, 이들은 모
두 라인(line) 단위로 수행된다.
각 연산에 대한 구체적인 설명은 다음과 같다. 여기서 x는 양의 정수이고, str은 문자열이다.
1. 삽입: I x str
x번 라인 앞에 문자열 str을 삽입한다. 즉, 삽입 후 str이 x번 라인이 된다. 예를 들어, x가 2이면
2번 라인에 str이 삽입되고, 기존의 2번 이후의 라인은 하나씩 뒤로 밀린다.
2. 삭제: D x
x번 라인을 삭제한다.
3. 이동: M x y
x번 라인을 y번 라인 앞으로 이동한다. 기존의 y번 이후의 라인은 하나씩 뒤로 밀린다.
4. 교환: E x y
x번 라인과 y번 라인을 서로 바꾼다.
5. 보기: S x
x번 라인의 내용을 화면에 출력한다. 화면에 출력하는 유일한 연산이다.
예를 들어, 아래 왼쪽 연산들이 차례로 입력된 후, 텍스트의 내용은 오른쪽과 같다.
I 1 This_is_line_A.
I 1 This_is_line_B.
I 3 This_is_line_C.
I 3 This_is_line_D.
D 3
I 1 This_is_line_E.
⇨
1: This_is_line_E.
2: This_is_line_B.
3: This_is_line_A.
4: This_is_line_C.
(보기 쉽게 맨 앞에 라인 번호를 표시함)
계속해서 아래 연산이 연이어서 입력될 때, 각 연산 이후의 텍스트 내용은 오른쪽과 같다.
M 2 5 ⇨
1: This_is_line_E.
2: This_is_line_A.
3: This_is_line_C.
4: This_is_line_B.
(주의!! 이동 후 5번 라인이 아닌 4번 라인이 됨에 유의)
M 3 1 ⇨
1: This_is_line_C.
2: This_is_line_E.
3: This_is_line_A.
4: This_is_line_B.
15
E 3 4 ⇨
1: This_is_line_C.
2: This_is_line_E.
3: This_is_line_B.
4: This_is_line_A.
프로그램이 만족하는 (혹은 만족해야 하는) 가정 및 조건은 다음과 같다. (조건을 만족시키지 않는
경우 감점 처리)
1. 각 라인은 영문자와 기호들로 이루어져 있으며, 공백이나 탭은 없다. (즉, scanf로 처리하면 됨)
2. 한 라인에 저장되는 글자 수는 최대 99자이고, 라인의 총 수에는 제한이 없다.
3. 라인 번호는 1번부터 시작한다.
4. 텍스트의 내용은 연결 리스트로 유지해야 한다. 텍스트의 한 라인의 내용 연결 리스트의 한 노드
에 저장되도록 한다. 연결 리스트의 형태는 단순, 원형, 이중 연결리스트 등 어떤 것이든 상관없다.
5. 모든 연산은 리스트 상에서 수행되어야 한다. 예를 들어, 5번 교환연산의 경우, 해당 두 노드에
저장된 문자열 값만 서로 바꿔주는 식으로 구현해서는 안 되고, 두 노드 자체를 리스트 상에서 교환
해야 한다.
위 설명에 따라 동작하는 프로그램을 작성하시오.
다음 정보가 표준입력으로 주어진다. 첫째 줄에는 연산의 총 개수 N이 주어진다(1≤N≤1,000).
두 번째 줄부터는 연산의 정보가 한 줄에 하나씩 주어진다. 연산의 형식은 위의 설명을 참조하시오.
잘못된 연산은 주어지지 않는다. 예를 들어, 현재 라인이 5개 존재할 때, "M 1 7"과 같은 연산은 주
어지지 않는다.
다음 정보를 표준출력(stdin)으로 출력한다. 보기 연산에 의해 출력되는 정보를 화면에 출력한다.
각 줄의 맨 앞과 맨 끝에 공백은 존재하지 않는다.
※ 테스트 데이터의 개수: 10개 (아래 입출력 예 2개 포함)
※ 테스트 데이터의 분포
- 데이터의 30%는 삽입, 보기 연산만 존재
- 데이터의 50%는 삽입, 삭제, 보기 연산만 존재
- 데이터의 70%는 삽입, 삭제, 이동, 보기 연산만 존재