콘솔에 삼각형
* * * * * * * * * * * * * * * *****************
을 출력하는 C# 애플리케이션을 만들어 보자. 이런 소스 코드의 작성은 학원이나 학교에서 프로그래밍 입문자에게 과제로 많이 주어지는 것 중의 하나이다. 코끼리를 보거나 만진 사람들이 저마다 그 생김새를 말할 때 제각기 다르게 표현할 수 있듯이 이런 소스 코드의 작성도 알고 보면 얼마든지 많은 방법이 있을 것이다. 여기서는 쉬운 코드 부터 작성해 보고 차츰차츰 소스를 바꾸어 가면서 C# 프로그래밍의 기초부분을 터득해 보기로 한다.
우선 첫번 째로 다음 예제는 컨솔 출력 메소드 System.Console.WriteLine()의 사용법만 알면 누구나 코딩할 수 있는 매우 단순한 소스 코드이다.
삼각형 출력 예제 1
/*
* Filename: PrintTriangleApp1.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp1.cs
* Execute: PrintTriangleApp1
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
namespace MyTestApplication1 {
public class PrintTriangleApp1 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
Console.WriteLine(" * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine(" * * ");
Console.WriteLine("*****************");
}
}
}
위의 소스 코드는 아무 알고리즘도 없는 너무 단순한 코드이다. 이런 코드를 작성했다간 출력 모양이나 크기를 변경해야 하는 상황을 맞이하면 워드프로세서로 문서 만드는 것 이상으로 많은 수작업을 하거나 아니면 포기하는 지경에 이를 수도 있다. 그래서 다음처럼 좀 더 나은 소스 코드를 작성하였다.
삼각형 출력 예제 2
/*
* Filename: PrintTriangleApp2.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp2.cs
* Execute: PrintTriangleApp2
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
namespace MyTestApplication1 {
public class PrintTriangleApp2 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
for (int i = 0; i < 8; i++) {
for (int k = 0; k < 8 - i; k++) {
Console.Write(" ");
}
for (int k = 0; k < 2*i + 1; k++) {
if (k == 0 || k == 2*i)
Console.Write("*");
else
Console.Write(" ");
}
for (int k = 0; k < 8 - i; k++) {
Console.Write(" ");
}
Console.WriteLine();
}
for (int i = 0; i < 17; i++) {
Console.Write("*");
}
Console.WriteLine();
}
}
}
위의 소스 코드는 출력 메소드 Console.WriteLine()과 Console.Write() 그리고 for 구문을 적절히 사용하여 구현되었다. 숫자 몇 곳만 수정하면 출력되는 삼각형의 크기를 바꿀 수 있다. 한 줄에 출력될 문자를 구성하는 알고리즘은 위의 예제와 근본적으로 같지만 Console.Write()를 사용하지 않고, 그대신 System.Text.StringBuilder 클래스를 적절히 사용하여 한 즐씩 출력하는 소스 코드를 다음 예제와 같이 작성해 보았다. 아래의 소스 코드에서 사용된 문자치환 메소드 StringBuilder.Replace()의 사용법은 다음과 같다.
using System.Text;
public StringBuilder StringBuilder.Replace(string oldValue, string newValue, int startIndex, int count);
삼각형 출력 예제 3
/*
* Filename: PrintTriangleApp3.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp3.cs
* Execute: PrintTriangleApp3
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp3 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
string line = " ";
StringBuilder line2 = new StringBuilder("");
for (int i = 0; i < 8; i++) {
line2 = new StringBuilder(line);
line2.Replace(" ", "*", 8-i, 1);
line2.Replace(" ", "*", 8+i, 1);
Console.WriteLine(line2);
}
line2 = new StringBuilder(line);
for (int i = 0; i < 17; i++) {
line2.Replace(" ", "*", i, 1);
}
Console.WriteLine(line2);
}
}
}
별(*) 문자를 이용하여 삼각형을 출력하는 일은 빈칸 문자와 별 문자를 적당한 좌표(위치)에 촐력하는 일이다. StringBuilder를 사용하더라도 한 줄의 출력을 빈칸 만으로로 구성된 string(소스 코드에서 변수 whites가 참조하는 string 값)을 기본으로 하고, 이 string에 한 두 개의 빈칸을 바꾸어 출력하는 기법으로 작성한 것이 다음 소스 코드이다. 단, 마지막 줄에 츨력될 string은 stars라는 별도의 변수로 처리하였다.
삼각형 출력 예제 4
/*
* Filename: PrintTriangleApp4.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp4.cs
* Execute: PrintTriangleApp4
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp4 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
String whites = " ";
String stars = "*****************";
StringBuilder line2 = new StringBuilder(whites);
line2.Replace(" ", "*", 8, 1);
Console.WriteLine(line2);
for (int i = 1; i < 8; i++) {
line2 = new StringBuilder(whites);
line2.Replace(whites.Substring(8-i, 1), stars.Substring(8-i, 1), 8-i, 1);
line2.Replace(whites.Substring(8+i, 1), stars.Substring(8+i, 1), 8+i, 1);
Console.WriteLine(line2);
}
Console.WriteLine(stars);
}
}
}
빈칸 문자를 별(*) 문자로 바꾸기 위해, 위의 소스 코드에서는 StringBuilder.Replace() 메소드를 이용하였지만, 다음 소스 코드에서는 StringBuilder[index] = char 메소드를 이용하였다.
삼각형 출력 예제 5
/*
* Filename: PrintTriangleApp5.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp5.cs
* Execute: PrintTriangleApp5
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp5 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
String whites = " ";
String stars = "*****************";
StringBuilder line = new StringBuilder(whites);
int start = 8;
line[start] = stars[8];
Console.WriteLine(line);
for (int i = 1; i < 8; i++) {
line = new StringBuilder(whites);
line[start - i] = stars[start - i];
line[start + i] = stars[start + i];
Console.WriteLine(line);
}
Console.WriteLine(stars);
}
}
}
출력되는 삼각형이 좌우 대칭이라는 사실에 착안하여, 다음 소스 코드에서는 각 줄을 처음 8자, 중앙 한 문자, 끝 8자(처음 8자의 역순)로 string을 만들어 출력하였다.
Java 언아에는 StringBuffer.reverse()라는 메소드가 있어서 유익하였지만,
C# 언어에는 StringBuilderRreverse()라는 메소드가 없기에
Java 소스 코드
line.reverse();
System.out.println(line);
가 C# 소스 코드
arrRev = line.ToString().ToCharArray();
Array.Reverse(arrRev);
Console.WriteLine( new String(arrRev) );
처럼 여러 단계를 거쳐 역순 문자열이 출력되었다.
삼각형 출력 예제 6
/*
* Filename: PrintTriangleApp6.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp6.cs
* Execute: PrintTriangleApp6
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp6 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
char[] arrRev;
String whites = " ";
String stars = "********";
int start = 8;
StringBuilder line = new StringBuilder(whites);
line.Append('*');
line.Append(whites);
Console.WriteLine(line);
for (int i = 1; i < 8; i++) {
line = new StringBuilder(whites);
line[start - i] = stars[start - i];
Console.Write(line);
Console.Write(" ");
arrRev = line.ToString().ToCharArray();
Array.Reverse(arrRev);
Console.WriteLine( new String(arrRev) );
}
line = new StringBuilder(stars);
Console.Write(line);
line.Append("*");
Console.WriteLine(line);
}
}
}
다음 소스 코드는 한 줄에 출력될 문자열의 데이터를 17비트 이진법 수로 구성하고, 이 이진법수의 비트가 0인 곳에는 빈칸을, 1인 곳에는 별(*)을 출력하는 기법으로 작성되었다.
int 타입을 2진법 표현 문자열로 표현하는 C# 소스 코드는 어떻게 될까?
Java 소스 코드는
String strValue = Integer.parseInt(intValue, 2);
이다. 이를 C# 소스 코드로 재작성하면
String strValue = System.Convert.ToString(intValue, 2);
이 된다.
삼각형 출력 예제 7
/*
* Filename: PrintTriangleApp7.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp7.cs
* Execute: PrintTriangleApp7
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp7 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
int start = 0x100;
int total = 0;
int val = start;
String data;
for (int k = 0; k < 8; k++) {
val = (start << k) | (start >> k);
data = Convert.ToString(val, 2);
for (int i = 0; i < 17 - data.Length; i++) {
Console.Write(' ');
}
for (int i = 0; i < data.Length; i++) {
if (data[i] == '0')
Console.Write(' ');
else
Console.Write('*');
}
Console.WriteLine();
total += val;
}
val = (start << 8) | (start >> 8);
total += val;
data = Convert.ToString(total, 2);
for (int i = 0; i < 17 - data.Length; i++) {
Console.Write(' ');
}
for (int i = 0; i < data.Length; i++) {
if (data[i] == '0')
Console.Write(' ');
else
Console.Write('*');
}
Console.WriteLine();
}
}
}
기본적인 원리는 위의 소스 코드와 같지만 이진법수의 한 비트 마다 한 문자씩 츨력하는 대신에 출력된 한 줄의 string을 완성하여 이를 Sytem.out.println()으로 출력하는 기법으로 재작성한 것이 다음의 소스 코드이다. String.replaceAll() 메소드를 이용하여, 모든 0을 빈칸으로, 모든 1을 별(*) 문자로 바꾸었으며, 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 total을 준비하였다. for 반복 구문의 블럭 내에서 구문
total |= val;
이 하는 일이 무엇인지 이해할 수 있으면 좋겠다.
삼각형 출력 예제 8
/*
* Filename: PrintTriangleApp8.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp8.cs
* Execute: PrintTriangleApp8
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
namespace MyTestApplication1 {
public class PrintTriangleApp8 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
String zeros = "00000000";
int start = 0x100;
int total = 0;
int val = start;
String line = "";
String data;
for (int k = 0; k < 8; k++) {
val = (start << k) | (start >> k);
data = Convert.ToString(val, 2);
line = zeros.Substring(0, 17 - data.Length) + data;
line = line.Replace("0", " ");
line = line.Replace("1", "*");
Console.WriteLine(line);
total |= val;
}
val = (start << 8) | (start >> 8);
total |= val;
line = Convert.ToString(total, 2);
line = line.Replace("0", " ");
line = line.Replace("1", "*");
Console.WriteLine(line);
}
}
}
소스 코드가 처음 것 보다 매우 복잡해졌지만 저너릭(generics)을 지원하는 리스트(System.Collections.Genericl.List)를 이용해서도 할 수 있다는 것을 보여주기 위해서 일부러 작성해보았다. C# 2.0 부터 등장한 저너릭를 이용한 소스 코드이므로 C# 2.0 이상에서 컴파일되어야 한다. 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 last를 준비하였다.
삼각형 출력 예제 9
/*
* Filename: PrintTriangleApp9.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp9.cs
* Execute: PrintTriangleApp9
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace MyTestApplication1 {
public class PrintTriangleApp9 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
int start = 8;
List<String> data = new List<String>();
List<String> last = new List<String>();
for (int k = 0; k < 17; k++) {
data.Add(" ");
last.Add(" ");
}
data[start] = "*";
last[start] = "*";
for (int i = 0; i < data.Count; i++) {
Console.Write(data[i]);
}
Console.WriteLine();
data[start] = " ";
for (int k = 1; k < 8; k++) {
data[start - k] = "*";
last[start - k] = "*";
data[start + k] = "*";
last[start + k] = "*";
for (int i = 0; i < data.Count; i++) {
Console.Write(data[i]);
}
Console.WriteLine();
data[start - k] = " ";
data[start + k] = " ";
}
last[start - 8] = "*";
last[start + 8] = "*";
for (int i = 0; i < last.Count; i++) {
Console.Write(last[i]);
}
Console.WriteLine();
}
}
}
다음 예제는 수학에서 xy-좌표평면에 점을 찍듯이 논리 구문
(x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0)
가 참이 되는 위치에 별(*) 문자를 표시하는 기법으로 작성된 소스 코드이다.
삼각형 출력 예제 10
/*
* Filename: PrintTriangleApp10.cs
* Print a triangle on console.
*
* Compile: csc PrintTriangleApp10.cs
* Execute: PrintTriangleApp10
*
* Date: 2009/01/24
* Author: PH Kim [ pkim (AT) scripts.pe.kr ]
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace MyTestApplication1 {
public class PrintTriangleApp10 {
// Java 언어의 main 메소드에 해당하는 C# 언어의 Main 메소드
public static void Main(string[] args) {
char a;
for (int y = 0; y <= 8; y++) {
for (int x = 0; x <= 16; x++) {
if ((x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0))
a = '*';
else
a = ' ';
Console.Write(a);
}
Console.WriteLine();
}
}
}
}
'프로그래밍 > C#' 카테고리의 다른 글
손으로 만드는 나눗셈 계산표 with C# (0) | 2009.01.24 |
---|---|
클래스 상속(subclassing) 예제 with C# (0) | 2009.01.24 |
7비트 ASCII 코드표 만들기 예제 with C# (0) | 2009.01.19 |
진법(radix) 표 만들기 예제 with C# (0) | 2009.01.19 |
대화형 모드의 진법(radix) 변환 예제 with C# (0) | 2009.01.16 |