아침에 깜짝 공지가 있었다 사실 과제 제출이 6시가 아니라 2시까지라는 것..!!!
다들 6시로 알고 있었는데 이게 머선일
맘 편하고 싶어서 그냥 어제 제출했는데, 어제 제출하길 잘한 것 같다.. 휴!
오늘은 문법종합반 5주차 강의 듣기 시작~!
int Sum(int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
void PrintPairs(int n)
{
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
Console.WriteLine(i + ", " + j);
}
}
}
// 시간 복잡도 : O(n)
int FindMax(int[] arr)
{
int max = arr[0];
for (int i = 1; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
// 시간 복잡도 : O(n^2)
int FindMax2(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
bool isMax = true;
for (int j = 0; j < arr.Length; j++)
{
if (arr[j] > arr[i])
{
isMax = false;
break;
}
}
if (isMax)
{
return arr[i];
}
}
return -1;
}
int[] arr = new int[] {1, 2, 3, 4, 5};
public static int[] RemoveDuplicate(int[] array)
{
List<int> distinctList = new List<int>();
foreach (int num in array)
{
if (!distinctList.Contains(num))
{
distinctList.Add(num);
}
}
return distinctList.ToArray();
}
int[] arr = new int[] { 5, 2, 4, 6, 1, 3 };
for (int i = 0; i < arr.Length; i++)
{
int minIndex = i;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
foreach (int num in arr)
{
Console.WriteLine(num);
}
int[] arr = new int[] {5, 2, 4, 6, 1, 3};
for (int i = 1; i < arr.Length; i++)
{
int j = i - 1;
int key = arr[i];
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
foreach (int num in arr)
{
Console.WriteLine(num);
}
static void Swap(int[] arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static int Partition(int[] arr, int left, int right)
{
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++)
{
if (arr[j] < pivot)
{
i++;
Swap(arr, i, j);
}
}
Swap(arr, i + 1, right);
return i + 1;
}
static void QuickSort(int[] arr, int left, int right)
{
if (left < right)
{
int pivot = Partition(arr, left, right);
// 2, 5, 4, 6, 1, 3
// 2, 1, 4, 6, 5, 3
// 2, 1, 3, 6, 5, 4
// 첫 pivot 인덱스는 2가 됨 (pivot 값 3)
QuickSort(arr, left, pivot - 1);
QuickSort(arr, pivot + 1, right);
}
}
static void Main(string[] args)
{
int[] arr = new int[] { 5, 2, 4, 6, 1, 3 };
QuickSort(arr, 0, arr.Length - 1);
foreach (int num in arr)
{
Console.WriteLine(num);
}
}
void MergeSort(int[] arr, int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, right);
Merge(arr, left, mid, right);
}
}
void Merge(int[] arr, int left, int mid, int right)
{
int[] temp = new int[arr.Length];
int i = left;
int j = mid + 1;
int k = left;
while (i <= mid && j <= right)
{
if (arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
}
}
while (i <= mid)
{
temp[k++] = arr[i++];
}
while (j <= right)
{
temp[k++] = arr[j++];
}
for (int l = left; l <= right; l++)
{
arr[l] = temp[l];
}
}
int[] arr = new int[] {5, 2, 4, 6, 1, 3};
MergeSort(arr, 0, arr.Length - 1);
foreach (int num in arr)
{
Console.WriteLine(num);
}
int[] numbers = {5, 2, 8, 3, 1, 9, 4, 6, 7};
Array.Sort(numbers);
Console.WriteLine(string.Join(", ", numbers));
List<string> names = new List<string> { "John", "Alice", "Bob", "Eve", "David" };
names.Sort();
Console.WriteLine(string.Join(", ", names));
int SequentialSearch(int[] arr, int target)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i[] == target)
{
return i;
}
}
return -1;
}
int BinarySearch(int[] arr, int target)
{
int left = 0;
int right = arr.Length - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] == target)
{
return mid;
}
else if (arr[mid] < target)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
깊이 우선 탐색(DFS: Depth-First Search) : 루트에서 시작하여 가능한 깊이 들어가서 노드를 탐색하고, 더 이상 방문할 노드가 없으면 이전 노드로 돌아가는 방식
너비 우선 탐색(BFS: Breadth-First Search) : 루트에서 시작하여 가까운 노드부터 방문하고, 그 다음 레벨의 노드를 방문하는 방식
예제
public class Graph
{
private int V;
private List<int>[] adj;
public Graph(int V)
{
this.V = V;
adj = new List<int>[V];
for (int i = 0; i < V; i++)
{
adj[i] = new List<int>();
}
}
public void AddEdge(int v, int w)
{
adj[v].Add(w);
}
public void DFS(int v)
{
bool[] visited = new bool[V];
DFSUtil(v, visited);
}
private void DFSUtil(int v, bool[] visited)
{
visited[v] = true;
Console.Write($"{v} ");
foreach (int n in adj[v])
{
if (!visited[n])
{
DFSUtil(n, visited);
}
}
}
public void BFS(int v)
{
bool[] visited = new bool[V];
Queue<int> queue = new Queue<int> ();
visited[v] = true;
queue.Enqueue(v);
while (queue.Count > 0)
{
int n = queue.Dequeue();
Console.Write($"{n} ");
foreach (int m in adj[n])
{
if (!visited[m])
{
visited[m] = true;
queue.Enqueue(m);
}
}
}
}
}
static void Main(string[] args)
{
Graph graph = new Graph(6);
graph.AddEdge(0, 1);
graph.AddEdge(0, 2);
graph.AddEdge(1, 3);
graph.AddEdge(2, 3);
graph.AddEdge(2, 4);
graph.AddEdge(3, 4);
graph.AddEdge(3, 5);
graph.AddEdge(4, 5);
Console.WriteLine("DFS travelsal: ");
graph.DFS(0);
Console.WriteLine();
Console.WriteLine("BFS travelsal: ");
graph.BFS(0);
Console.WriteLine();
}
다익스트라 알고리즘(Dijkstra Algorithm)
static void Dijkstra(int[,] graph, int start)
{
int[] distance = new int[V];
bool[] visited = new bool[V];
for (int i = 0; i < V; i++)
{
distance[i] = int.MaxValue;
}
distance[start] = 0;
for (int count = 0; count < V - 1; count++)
{
int minDistance = int.MaxValue;
int minIndex = -1;
for (int v = 0; v < V; v++)
{
if (!visited[v] && distance[v] <= minDistance)
{
minDistance = distance[v];
minIndex = v;
}
}
visited[minIndex] = true;
for (int v = 0; v < V; v++)
{
if (!visited[v] && graph[minIndex, v] != 0
&& distance[minIndex] != int.MaxValue && distance[minIndex] + graph[minIndex, v] < distance[v])
{
distance[v] = distance[minIndex] + graph[minIndex, v];
}
}
}
Console.WriteLine("정점\t거리");
for (int i = 0; i < V; i++)
{
Console.WriteLine($"{i}\t{distance[i]}");
}
}
static void Main(string[] args)
{
int[,] graph = {
{ 0, 4, 0, 0, 0, 0 },
{ 4, 0, 8, 0, 0, 0 },
{ 0, 8, 0, 7, 0, 4 },
{ 0, 0, 7, 0, 9, 14 },
{ 0, 0, 0, 9, 0, 10 },
{ 0, 0, 4, 14, 10, 0 }
};
int start = 0; // 시작 정점
Dijkstra(graph, start);
}
벨만-포드 알고리즘(Bellman-Ford Algorithm)
public class BellmanFord {
public static final int INF = Integer.MAX_VALUE;
public static void main(String[] args) {
int num = 5;
int[][] adj = new int[][] {
{0, -4, 5, 2, 3},
{INF, 0, INF, -1, INF},
{INF, INF, 0, -7, INF},
{INF, INF, INF, 0, 6},
{INF, INF, INF, -4, 0},
};
int src = 0;
int dst = 1;
solve(num, adj, src, dst);
}
public static void solve(int num, int[][] adj, int src, int dst) {
int[] dists = new int[num];
Arrays.fill(dists, INF);
dists[src] = 0;
for(int v=0; v < num; ++v) {
for(int w=0; w < num; ++w) {
if(adj[v][w] != INF)
dists[w] = Math.min(dists[w], dists[v] + adj[v][w]);
}
}
for(int i=0; i< num; ++i)
System.out.println(dists[i]);
}
}
A* Algorithm(A-star Algorithm)
플로이드-와샬 알고리즘(Floyd-Warshall Algorithm)
- 음수 사이클이 없다면 음의 가중치를 갖는 간선이 존재할 수 있음
- 음수 사이클 : 사이클의 모든 경로를 지나 원래 지점으로 돌아왔을 때, 최정적인 비용이 음수가 되는 경우
/*
sample input(첫 번째 숫자는 노드의 개수, 두 번째 숫자는 간선의 개수)
5
8
0 1 5
0 4 1
0 2 7
0 3 2
1 2 3
1 3 6
2 3 10
3 4 4
*/
public class Floyd {
static int N, M;
static int[][] dist;
public static void main(String[] args) throws NumberFormatException, IOException {
// 초기화
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
M = Integer.parseInt(br.readLine());
// 플로이드 초기 거리 테이블 초기화
dist = new int[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// 자기 자신으로 가는 길은 최소 비용이 0이다
if (i == j) {
dist[i][j] = 0;
continue;
}
// 자기 자신으로 가는 경우를 제외하고는 매우 큰 값
// (N개의 노드를 모두 거쳐서 가더라도 더 큰 값)
dist[i][j] = 100_000_000;
}
}
for (int i = 0; i < M; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
// 가는 경로가 하나가 아닐 수 있다. 따라서 그 중 최소 비용을 저장해두면 된다.
dist[a][b] = Math.min(dist[a][b], cost);
dist[b][a] = Math.min(dist[b][a], cost);
}
// 플로이드 워셜 알고리즘
// 노드를 1개부터 N개까지 거쳐가는 경우를 모두 고려한다
for (int k = 0; k < N; k++) {
// 노드 i에서 j로 가는 경우.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// k번째 노드를 거쳐가는 비용이 기존 비용보다 더 작은 경우 갱신
// 또는 연결이 안되어있던 경우(INF) 연결 비용 갱신
dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
// 출력
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// 연결이 안되어 있는 경우
if (dist[i][j] == 100_000_000) {
System.out.print("INF ");
} else {
System.out.print(dist[i][j] + " ");
}
}
System.out.println();
}
}
}
public int Fibonacci(int n)
{
int[] dp = new int [n+1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++)
{
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
// 주어진 동전들로 특정 금액을 만드는데 필요한 최소 동전 수를 구함
public int MinCoin(int[] coins, int amount)
{
Array.Sort(coins);
int count = 0;
for (int i = coins.Length - 1; i >= 0; i--)
{
while (amount >= coins[i])
{
amount -= coins[i];
count++;
}
}
if (amount > 0) return -1;
return count;
}