= Programming Tips and Tricks =
자주 까먹는 자잘한 꼼수(?) 및 필수 지식들을 모아놓은 페이지입니다.
{{tag>Tips Algorithm}}
= 공통 =
== 한글 자동완성 ==
https://support.microsoft.com/ko-kr/kb/2701840
== Polymorphism(다형성) ==
[[Polymorphism]]
== 2차원배열 → 1차원배열 ==
arr[(i * j.length) + j] //= arr[i][j]
== 단위 변환 ==
=== 경위도 변환 ===
/* Language : C# */
/* 도분초 → 천분율 */
///
/// 도분초 → 천분율
/// ("128:43:47" → "34:58.105")
///
///
///
public static string DMS2Permil(string dms)
{
return Degree2Permil(DMS2Degree(dms));
}
///
/// 도분초 → 천분율
/// (128, 43, 47 → "34:58.105")
///
///
///
///
///
public static string DMS2Permil(int deg, int min, int sec)
{
return Degree2Permil(DMS2Degree(deg, min, sec));
}
///
/// 도분초 → 천분율
/// ("128:43:47" → {34, 58.105})
///
///
///
public static Tuple DMS2Permil_toTuple(string dms)
{
return Degree2Permil_toTuple(DMS2Degree(dms));
}
///
/// 도분초 → 천분율
/// (128, 43, 47 → {34, 58.105})
///
///
///
///
///
public static Tuple DMS2Permil_toTuple(int deg, int min, int sec)
{
return Degree2Permil_toTuple(DMS2Degree(deg, min, sec));
}
/* 천분율 → 도분초 */
///
/// 천분율 → 도분초 (string)
/// ("34:58.105" → "34:58:06")
///
///
///
public static string Permil2DMS(string permil)
{
return Degree2DMS(Permil2Degree(permil));
}
///
/// 천분율 → 도분초 (string)
/// (34, 58.105 → "34:58:06")
///
///
///
///
public static string Permil2DMS(int deg, double sec)
{
return Degree2DMS(Permil2Degree(deg, sec));
}
///
/// 천분율 → 도분초 (int[])
/// ("34:58.105" → {34, 58, 06})
///
///
///
public static int[] Permil2DMS_toArray(string permil)
{
return Degree2DMS_toArray(Permil2Degree(permil));
}
///
/// 천분율 → 도분초 (int[])
/// (34, 58.105 → {34, 58, 06})
///
///
///
public static int[] Permil2DMS_toArray(int deg, double sec)
{
return Degree2DMS_toArray(Permil2Degree(deg, sec));
}
/* 경위도 → 천분율 */
///
/// 경위도 → 천분율 (string)
/// (128.7297335 → 128:43.784)
///
///
///
public static string Degree2Permil(double latLng)
{
return ((int)latLng).ToString("00") + ":" + ((latLng - (int)latLng) * 60).ToString("00.000");
}
///
/// 경위도 → 천분율 (int, double)
/// (128.7297335 → {128, 43.784})
///
///
///
public static Tuple Degree2Permil_toTuple(double latLng)
{
return Tuple.Create((int)latLng, Math.Round((latLng - (int)latLng) * 60, 3));
}
/* 천분율 → 경위도 */
///
/// 천분율 → 경위도 (double)
/// ("128:43.784" → 128.729733333333)
///
///
///
public static double Permil2Degree(string permil)
{
int colonIndex = permil.IndexOf(':');
int deg = int.Parse(permil.Substring(0, colonIndex));
double min = double.Parse(permil.Substring(colonIndex + 1, permil.Length - (colonIndex + 1)));
return (double)deg + min / 60;
}
///
/// 천분율 → 경위도 (double)
/// (128, 43.784 → 128.729733333333)
///
///
///
///
public static double Permil2Degree(int deg, double min)
{
return (double)deg + min / 60;
}
/* 경위도 → 도분초 */
///
/// 경위도 → 도분초 (string)
/// (128.7297335 → 128:43:470)
///
///
///
public static string Degree2DMS(double latLng)
{
int deg = (int)latLng;
double decimalPart1 = latLng - deg;
int min = (int)(decimalPart1 * 60);
double decimalPart2 = (decimalPart1 * 60) - min;
int sec = (int)(decimalPart2 * 60);
return string.Format("{0:D02}:{1:D02}:{2:D02}", deg, min, sec);
}
///
/// 경위도 → 도분초 (int[])
/// (128.7297335 → {128, 43, 47})
///
///
///
public static int[] Degree2DMS_toArray(double latLng)
{
int deg = (int)latLng;
double decimalPart1 = latLng - deg;
int min = (int)(decimalPart1 * 60);
double decimalPart2 = (decimalPart1 * 60) - min;
int sec = (int)(decimalPart2 * 60);
return new int[3] { deg, min, sec };
}
/* 도분초 → 경위도 */
///
/// 도분초 → 경위도
/// ("128:43:47" → 128.72972222222222)
///
///
///
public static double DMS2Degree(string dms)
{
int colonIndex1 = dms.IndexOf(':');
int colonIndex2 = dms.LastIndexOf(':');
string strDeg = dms.Substring(0, colonIndex1);
string strMin = dms.Substring(colonIndex1 + 1, colonIndex2 - (colonIndex1 + 1));
string strSec = dms.Substring(colonIndex2 + 1, dms.Length - (colonIndex2 + 1));
return double.Parse(strDeg) + ((double)double.Parse(strMin) / 60) + ((double)double.Parse(strSec) / 3600);
}
///
/// 도분초 → 경위도
/// (128, 43, 47 → 128.72972222222222)
///
///
///
///
///
public static double DMS2Degree(int deg, int min, int sec)
{
return (double)deg + ((double)min / 60) + ((double)sec / 3600);
}
/* 신규 추가 */
//
/// Degree → 도분초 (단위 포함)
/// (-122.333333 → 122:20:00 W)
///
public static string Degree2DMS(double degree)
{
int deg = (int)Math.Abs(degree);
double min_temp = (Math.Abs(degree) - deg) * 60;
double min_decPart = min_temp - (int)min_temp;
int min = min_decPart >= 0.999 ? (int)Math.Round(min_temp, 1, MidpointRounding.AwayFromZero) : (int)min_temp; //소숫점이 0에 수렴하는가?
double sec_temp = (Math.Abs(degree) - deg - ((double)min / (double)60)) * 3600;
double sec_decPart = sec_temp - (int)sec_temp;
int sec = sec_decPart >= 0.999 ? (int)Math.Round(sec_temp, 1, MidpointRounding.AwayFromZero) : (int)sec_temp; //소숫점이 0에 수렴하는가?
string unit = string.Empty;
string fmt = string.Empty;
if (deg <= 90)
{
fmt = "2";
unit = degree >= 0 ? " N" : " S";
}
else
{
fmt = "3";
unit = degree >= 0 ? " E" : " W";
}
return string.Format("{0:D0" + fmt + "}:{1:D02}:{2:D2}", deg, min, sec) + unit;
}
///
/// Degree → 천분율 (단위 포함)
/// (-122.333333 → 122:20.660 W)
///
///
///
public static string Degree2Permil(double degree)
{
string unit = string.Empty;
string fmt = string.Empty;
double absVal = Math.Abs(degree);
if ((int)absVal <= 90)
{
fmt = "00";
unit = degree >= 0 ? " N" : " S";
}
else
{
fmt = "000";
unit = degree >= 0 ? " E" : " W";
}
return ((int)absVal).ToString(fmt) + ":" + ((absVal - (int)absVal) * 60).ToString("00.000") + unit;
}
///
/// 도분초 (단위포함) → Degree
/// (122:20:00 W → -122.333333)
///
///
///
public static double DMS2Degree(string dms)
{
int unitIndex = dms.LastIndexOf(' ');
string unit = dms.Substring(unitIndex + 1, 1).Trim();
string[] dmsValue = dms.Substring(0, unitIndex).Split(':');
double result = double.Parse(dmsValue[0]) + (double)(double.Parse(dmsValue[1]) / (double)60) + (double)(double.Parse(dmsValue[2]) / (double)3600);
if (unit.ToUpper().Equals("W") || unit.ToUpper().Equals("S"))
result = -result;
return result;
}
///
/// 천분율 (단위포함) → Degree
/// (122:20.660 W → -122.333333)
///
///
///
public static double Permil2Degree(string permil)
{
int unitIndex = permil.LastIndexOf(' ');
string unit = permil.Substring(unitIndex + 1, 1).Trim();
string permilValue = permil.Substring(0, unitIndex);
int colonIndex = permilValue.IndexOf(':');
int deg = int.Parse(permilValue.Substring(0, colonIndex));
double min = double.Parse(permilValue.Substring(colonIndex + 1, permilValue.Length - (colonIndex + 1)));
double result = (double)deg + min / 60;
if (unit.ToUpper().Equals("W") || unit.ToUpper().Equals("S"))
result = -result;
return result;
}
=== 거리, 속도, 주파수 변환 ===
/* 거리 계산식 */
///
/// Yard → Meter
///
public static double YD2M(double yd)
{
return yd * 0.91440183;
}
///
/// Meter → Yard
///
///
///
public static double M2YD(double m)
{
return m / 0.91440183;
}
///
/// Kiloyard → Meter
///
///
///
public static double KYD2M(double yd)
{
return 1000.0 * YD2M(yd);
}
///
/// Meter → Kiloyard
///
///
///
public static double M2KYD(double m)
{
return M2YD(m) / 1000.0;
}
///
/// Kiloyard → Hectometer
///
///
///
public static double KYD2HM(double yd)
{
return 10.0 * YD2M(yd);
}
///
/// Hectometer → Kiloyard
///
///
///
public static double HM2KYD(double m)
{
return M2YD(m) / 10.0;
}
///
/// Kiloyard → Kilometer
///
///
///
public static double KYD2KM(double yd)
{
return YD2M(yd);
}
///
/// Kilometer → Kiloyard
///
///
///
public static double KM2KYD(double m)
{
return M2YD(m);
}
///
/// Kiloyard → Nautical Mile
///
///
///
public static double KYD2NM(double kyd)
{
return kyd * 0.493737;
}
///
/// Nautical Mile → Kiloyard
///
///
///
public static double NM2KYD(double nm)
{
return nm * 2.02537183;
}
/* 심도 계산식 */
///
/// Meter → Feet
///
///
///
public static double M2FT(double m)
{
return m * 3.2808398950131233595800524934383;
}
///
/// Feet → Meter
///
///
///
public static double FT2M(double ft)
{
return ft * 0.3048;
}
/* 속도 계산식 */
///
/// Knots → Meter Per Seconds
///
///
///
public static double KTS2MS(double kts)
{
return kts * 0.51444444444444444444444444444444;
}
///
/// Meter Per Seconds → Knots
///
///
///
public static double MS2KTS(double ms)
{
return ms * 1.9438444924406047516198704103672;
}
/* 주파수 계산식 */
///
/// Hertz → Revolutions Per Minute
///
///
///
public static double HZ2RPM(double hz)
{
return hz * 60.0;
}
///
/// Revolutions Per Minute → Hertz
///
///
///
public static double RPM2HZ(double rpm)
{
return rpm / 60.0;
}
public static double M2KM(double m)
{
return m / 1000;
}
public static double KM2M(double km)
{
return km * 1000;
}
public static double M2HM(double m)
{
return m / 100;
}
public static double HM2M(double hm)
{
return hm * 100;
}
public static double HM2KM(double hm)
{
return hm / 10;
}
public static double KM2HM(double km)
{
return km * 10;
}
///
/// Meter → Nautical Mile
///
///
///
public static double M2NM(double m)
{
return KYD2NM(M2KYD(m));
}
=== 각도, 반지름 ↔ X, Y 좌표 ===
public Tuple DegreeRadius2XY(double degree, double radius)
{
double radian = Degree2Radian(degree);
return Tuple.Create(radius * Math.Cos(radian), radius * Math.Sin(radian));
}
public Tuple XY2DegreeRadius(double x, double y)
{
double degree = Math.Atan2(y, x) * (180 / 3.1415926535897932);
double radious = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
return Tuple.Create(degree, radious);
}
public double Degree2Radian(double degree)
{
return 3.1415926535897932 / (180 / degree);
}
== 재귀(Recursion) ==
[[Recursion]]
=== C# 하부 디렉토리 파일까지 탐색 (현 프로젝트 기준) ===
public static List GetFiles(string extension)
{
List result = new List();
try
{
foreach (string d in Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory))
{
foreach (string f in Directory.GetFiles(d, "*." + extension))
result.Add(f);
GetFiles(d);
}
}
catch (System.Exception)
{
return null;
}
return result;
}
== 정렬 알고리즘(Sort Algorithm) ==
=== 합병 정렬(Merge Sort) ===
[[algorithm:Merge Sort | 합병 정렬(Merge Sort)]]
= Language & FrameWork =
== Java ==
=== 양력/음력 날짜 계산 ===
{{:calendarlib.zip|}}
* http://site.icu-project.org/download
* https://github.com/JodaOrg/joda-time/releases
import org.joda.time.DateTime;
import com.ibm.icu.util.ChineseCalendar;
public class LunarDateTime {
private static int yearCorrectionValue = 2637;
private LunarDateTime() {
}
/**
*
* @return 오늘 음력날짜
*/
public static DateTime now() {
ChineseCalendar cc = new ChineseCalendar();
int year = cc.get(ChineseCalendar.EXTENDED_YEAR) - yearCorrectionValue;
int monthOfYear = cc.get(ChineseCalendar.MONTH) + 1;
int dayOfMonth = cc.get(ChineseCalendar.DAY_OF_MONTH);
int[] hms = getNowHMS();
return new DateTime(year, monthOfYear, dayOfMonth, hms[0], hms[1], hms[2]);
}
public static DateTime solarToLunar(int solarYear, int solarMonthOfYear, int solarDayOfMonth) {
int[] hms = getNowHMS();
DateTime dt = new DateTime(solarYear, solarMonthOfYear, solarDayOfMonth, hms[0], hms[1], hms[2]);
ChineseCalendar cc = new ChineseCalendar();
cc.setTimeInMillis(dt.getMillis());
int year = cc.get(ChineseCalendar.EXTENDED_YEAR) - yearCorrectionValue;
int monthOfYear = cc.get(ChineseCalendar.MONTH) + 1;
int dayOfMonth = cc.get(ChineseCalendar.DAY_OF_MONTH);
return new DateTime(year, monthOfYear, dayOfMonth, hms[0], hms[1], hms[2]);
}
public static DateTime lunar2Solar(int lunarYear, int lunarMonthOfYear, int lunarDayOfMonth) {
ChineseCalendar cc = new ChineseCalendar();
cc.set(ChineseCalendar.EXTENDED_YEAR, lunarYear + yearCorrectionValue);
cc.set(ChineseCalendar.MONTH, lunarMonthOfYear - 1);
cc.set(ChineseCalendar.DAY_OF_MONTH, lunarDayOfMonth);
int[] hms = getNowHMS();
cc.set(ChineseCalendar.HOUR_OF_DAY, hms[0]);
cc.set(ChineseCalendar.MINUTE, hms[0]);
cc.set(ChineseCalendar.SECOND, hms[0]);
return new DateTime(cc.getTimeInMillis());
}
private static int[] getNowHMS() {
DateTime now = DateTime.now();
return new int[] {now.getHourOfDay(), now.getMinuteOfHour(), now.getSecondOfMinute()};
}
}
== C ==
=== 포인터와 구조체 기초 개념 예제 ===
#include
#include
#include "stdlib.h"
struct student
{
char name[20+1];
int year;
double score;
};
typedef struct MyStruct
{
char str[10];
} hyuk_struct;
void main()
{
/* 구조체 1*/
//struct student st_lee = {"Lee",2008,95.4};
struct student st_lee = {0};
strcpy(st_lee.name, "HYUK");
st_lee.year=2008;
st_lee.score=99.7;
printf("%s %d %f\n",st_lee.name,st_lee.year,st_lee.score);
/*구조체 2 - 타입 정의*/
hyuk_struct asdf = {"Lucas"};
printf("%s\n",asdf.str);
printf("\n\n");
/* 포인터 */
float val1 = 5.23f;
float* ptr1 = NULL;
ptr1 = &val1; // 포인터이기에 주소값만 대입 가능!
printf("%d\n",ptr1); // va1 주소값 출력
printf("%f\n",val1);
printf("\n");
char val2 = 'A';
char* ptr2 = &val2;
*ptr2 = 'X'; // 포인터로 메모리 직접 접근하여 값 바꿈
val2='Y'; // 변수에 그냥 대입
printf("%d\n",ptr2);
printf("%c\n",val2); // 결과적으로 Y 출력
printf("\n");
/* 동적 메모리 할당 */
int *ptr3 = NULL;
int mem_size = 100;
ptr3=(int*)malloc(sizeof(int)*mem_size);
if(ptr3!=NULL)
{
memset(ptr3, 0, sizeof(int)*mem_size); // 메모리의 쓰레기값을 모두 0으로 초기화
printf("정수 입력 : ");
scanf("%d", ptr3); // ptr3가 포인터 변수이므로 인자값도 "&"가 아닌 "%"!!
printf("%d \n", *ptr3); // 주소값이 아닌 실제 참조값을 출력해야하기에
free(ptr3); // 해제
}
else
printf("ptr3==NULL\n");
printf("\n");
/* 포인터의 포인터 */ //2차원 이상의 다차원 배열에서 쓰인다.
int iVal = 777;
int *iPtr = &iVal;
int **iPPtr = &iPtr;
printf("%d %d \n",*iPtr, iPtr); // iVal, iVal 주소값
printf("%d %d %d \n",**iPPtr, *iPPtr, iPPtr); // iVal, iVal 주소값, iVal 주소의 주소값
printf("\n");
/* 동적 다차원 배열 */ //2차원배열은 "1차원 배열들의 배열"
int row=3, col=4;
int **iPPtrArr=NULL;
iPPtrArr=(int**)malloc(sizeof(int*)*row); // 가로(행) 수만큼 메모리 할당(확보)
for(int i=0 ; istr); // 위와 같은 표현
}
=== 동적 배열 할당 ===
//1차원
int *input;
int staticSize = 할당크기;
input = (int*)malloc(sizeof(int)*staticSize);
//2차원
int **input;
int staticSizeOfROW = 할당크기;
int staticSizeOfColumn = 할당크기;
input = (int(*)[])malloc (sizeof(int*)*staticSizeOfROW); //행
input[0] = (int*)malloc(sizeof(int*)*staticSizeOfColumn); //열
== Android ==
=== Parcelable ===
* Intent를 이용하여 **Reference Type**의 데이터를 넘길 때 사용.
http://arsviator.tistory.com/169
=== Image 압축 및 실제 경로 얻기 ===
public class ImageUtil {
private static final int MAX_IMAGE_SIZE = 1280;
private static final int MAX_IMAGE_LENGTH = 720 * 1280;
/**
* Image Uri → Compressed byte array
* (반복문으로 인하여 별도의 Thread 필요)
* @param context
* @param uri
* @return
* @throws Exception
*/
public static byte[] getCompressedByteArray(Context context, Uri uri) throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = calculateInSampleSize(options, 800, 800);
options.inJustDecodeBounds = false;
options.inPreferredConfig= Bitmap.Config.ARGB_8888;
BufferedInputStream bin = new BufferedInputStream(context.getContentResolver().openInputStream(uri));
Bitmap bitmap = BitmapFactory.decodeStream(bin, null, options);
// resize (지정한 크기보다 작은 경우만)
if(bitmap.getWidth() * bitmap.getHeight() > MAX_IMAGE_SIZE * 2)
bitmap = resizeBitmap(bitmap, MAX_IMAGE_SIZE);
int compressQuality = 100;
int streamLength;
byte[] bitmapdata;
String realPath = getRealImagePath(context, uri);
String extension = realPath.substring(realPath.lastIndexOf('.') + 1);
Bitmap.CompressFormat format;
switch (extension.toLowerCase()) {
case "jpg" :
case "jpeg" :
format = Bitmap.CompressFormat.JPEG;
break;
case "png" :
case "gif" :
format = Bitmap.CompressFormat.PNG;
break;
case "webp" :
format = Bitmap.CompressFormat.WEBP;
break;
default:
throw new Exception("Unsupported format!");
}
do {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(format, compressQuality, baos);
bitmapdata = baos.toByteArray();
streamLength = bitmapdata.length;
compressQuality -= 5;
} while (streamLength >= MAX_IMAGE_LENGTH);
Log.d("compressBitmap", "Quality: " + compressQuality);
Log.d("compressBitmap", "Size: " + streamLength/1024+" kb");
return bitmapdata;
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
Log.d("inSampleSize", String.valueOf(inSampleSize));
return inSampleSize;
}
private static Bitmap resizeBitmap(Bitmap bitmap, int maxSize) {
float ratio = Math.min((float) maxSize / bitmap.getWidth(), (float) maxSize / bitmap.getHeight());
int width = Math.round(ratio * bitmap.getWidth());
int height = Math.round(ratio * bitmap.getHeight());
return Bitmap.createScaledBitmap(bitmap, width, height, false);
}
/**
* Uri를 이용해 실제 저장소 경로 얻기
* @param context
* @param uri
* @return
*/
public static String getRealImagePath(Context context, Uri uri) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(index);
}
/**
* [0] : fileName
* [1] : extension
* @param filePath
* @return
*/
public static String[] getFileNameAndExtension(String filePath) {
return new String[] {filePath.substring(filePath.lastIndexOf(File.pathSeparator) + 1), filePath.substring(filePath.lastIndexOf('.') + 1)};
}
}
= Intellij - Git Bash 연동 =
Tools -> Terminal
"C:\Program Files\Git\bin\sh.exe" -login -i