Skip to content

Instantly share code, notes, and snippets.

@tofuso
Last active January 1, 2019 06:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tofuso/0e2ed927b2407ab720ace9bc59f2c375 to your computer and use it in GitHub Desktop.
Save tofuso/0e2ed927b2407ab720ace9bc59f2c375 to your computer and use it in GitHub Desktop.
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort_visualize.h"
int _order_evaluation(int*, int);
void _make_swapline(char*);
int* watched_array; /*監視対象の配列*/
int watched_array_num; /*監視対象の配列の要素数*/
int swap_count; /*何回入れ替え操作を行ったのかをカウントする*/
void start_sort(void(*sort_func)(int*, int), int* int_array, int array_num) {
watched_array = int_array; /*引数の配列を監視対象に加えるため、保管しておく。*/
watched_array_num = array_num;
swap_count = 0; /*入れ替え回数の変数を初期化*/
/*初回、表示処理*/
for (int i = 0; i < array_num; i++) {
printf(" %5d", int_array[i]);
}
sort_func(int_array, array_num); /*実行する*/
/*終了を知らせる*/
printf("\n");
printf("完了\n");
printf("入れ替え回数:%d\n", swap_count);
/*ソート結果を判定*/
switch (_order_evaluation(int_array, array_num)) {
case -1:
printf("昇順降順の判定ができませんでした:失敗\n");
break;
case 1:
printf("昇順:成功\n");
break;
case 2:
printf("降順:成功\n");
break;
}
return;
}
void visualize_swap(int* a, int* b) {
/*視覚化された配列の入れ替えアニメーション*/
int target1 = -1; /*入れ替え対象その1のインデックス値*/
int target2 = -1; /*入れ替え対象その2のインデックス値*/
/*引数に渡された対象のアドレスを検索*/
for (int i = 0; i < watched_array_num; i++) {
/*一致したらそのインデックス値を記録*/
if (a == watched_array + i) {
target1 = i;
}
else if (b == watched_array + i) {
target2 = i;
}
else if (target1 != -1 && target2 != -1) {
/*2つの対象についての検索を終えたら、検索終了*/
break;
}
}
int frame = abs(target1 - target2) * 6 + 1; /*アニメーションフレームを設定*/
char* swapline; /*表示用文字列*/
/*入れ替え対象の文字列*/
char target1_str[7];
char target2_str[7];
sprintf(target1_str, " %-5d", watched_array[target1]);
sprintf(target2_str, " %-5d", watched_array[target2]);
int dir = (target2 - target1) / abs(target2 - target1); /*移動方向*/
/*アニメーション*/
for (int i = 1; i < frame; i++) {
swapline = (char*)malloc(sizeof(char) * 6 * watched_array_num + 1); /*メモリ確保*/
_make_swapline(swapline); /*表示用文字列を作成*/
for (int j = 0; j < 5; j++) {
/*入れ替え対象の表示を空白で塗りつぶして消去*/
swapline[target1 * 6 + j] = ' ';
swapline[target2 * 6 + j] = ' ';
}
for (int j = 0; j < 5; j++) {
/*入れ替え対象の現フレームの位置に上書きで描画*/
/*入れ替え対象の文字で空白のものは描画処理を行わない*/
if (target1_str[j] != ' ') {
swapline[target1 * 6 + i * dir + j] = target1_str[j];
}
if (target2_str[j] != ' ') {
swapline[target2 * 6 - i * dir + j] = target2_str[j];
}
}
printf("\r%s", swapline); /*描画*/
Sleep(80); /*待機時間*/
free(swapline); /*メモリ解放*/
}
Sleep(80); /*入れ替え終了時の一時停止*/
swap_count++; /*入れ替え回数をカウント*/
/*入れ替え処理*/
int temp = *a;
*a = *b;
*b = temp;
return;
}
/*
*文字列を作成する
*引数(swapline) 表示する文字列を入れる対象
*/
void _make_swapline(char* swapline) {
/*表示列を文字列情報に変換*/
char damp_swapline[7]; /*アニメーション行に関連する文字列のキャッシュ*/
for (int i = 0; i < watched_array_num; i++) {
/*アニメーション行の表示に用いる文字列を作成*/
sprintf(damp_swapline, " %-5d", watched_array[i]);
if (i > 0) {
strcat(swapline, damp_swapline);
}
else {
strcpy(swapline, damp_swapline);
}
}
}
/*
* 並び替えが成功しているか確認する
* @ return -1:失敗 1:昇順 2:降順
*/
int _order_evaluation(int* arr, int arr_num) {
int order_mode = 0; /*昇順:1 降順:-1 未判定:0*/
int value1, value2; /*昇順降順判定サンプル*/
for (int i = 0; i < arr_num; i++) {
/*2つの値をサンプルとして取得*/
if (i == 0) {
value1 = arr[i];
continue;
}
else if (order_mode == 0) {
value2 = arr[i];
}
/*判定可能なら判定し、判定済みなら判定通りに並んでいるか確認*/
if (order_mode == 0) {
/*未判定*/
if (value1 != value2) {
/*判定*/
order_mode = (value1 < value2) ? 1 : -1;
}
}
else if (order_mode == 1) {
/*判定済み・昇順の時*/
/*一つ前の値から確認*/
if (arr[i - 1] > arr[i]) {
return -1; /*失敗判定*/
}
}
else if (order_mode == -1) {
/*判定済み・降順の時*/
/*一つ前の値から確認*/
if (arr[i - 1] < arr[i]) {
return -1; /*ソートできてない判定*/
}
}
}
/*一通り配列を見た結果に従って戻り値を返す*/
switch (order_mode) {
case 0:
return -1; /*すべての値が同じ*/
case 1:
return 1; /*昇順*/
case -1:
return 2; /*降順*/
}
return -1;
}
/**
* @file sort_visualize.h
* @brief int型配列のソートを視覚化する(したい)
*/
/**
* @fn
* ソート関数を与えられた配列に対して実行する
* @brief ソート関数実行
* @param (sort_func) ソートを実行する関数。引数にはint型配列と配列の要素数が与えられる。
* @param (array) ソートを行う対象
* @param (array_num) arrayの要素数
*/
void start_sort(void(*sort_func)(int*, int), int*, int);
/**
* @fn
* ソート関数内で位置を入れ替えるときに実行すると入れ替えアニメーションが見られる。
* @brief ソート内のアニメーション付き入れ替え関数
* @param (a) 入れ換える対象
* @param (b) 入れ換える対象
*/
void visualize_swap(int*, int*);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment