소인수분해 하는 소스 코드 작성해봤는데요.
글쓴이: kknd345 / 작성시간: 목, 2004/06/17 - 2:33오후
#include<stdio.h> void getPrime(int FirstInputNumber)/*소인수 구하는 함수입니다*/ { int i,PrimeNumber,InputNumber; int Prime[50]; int X; PrimeNumber=0; InputNumber=FirstInputNumber; X=1; for(i=2;i<InputNumber;i++) { if(InputNumber%i==0) { Prime[PrimeNumber]=i; PrimeNumber++; InputNumber=InputNumber/i; i=2; } } if(FirstInputNumber==InputNumber) // 소수는 그 자체가 소인수이다. { // for식에 해당 사항이 없어서 따로 지정 X=FirstInputNumber; } i=0; while(FirstInputNumber!=X) { printf("%d ",Prime[i]); X=X*Prime[i]; i++; } } void main() { int wanted; printf("소인수분해하고 싶은 수를 입력하시오\n"); scanf("%d",&wanted); getPrime(wanted); }
실행해보니 앞에 한개만 맞고 그 다음에 이상한 숫자 -15910580 같은걸 출력하네요. 에러 메시지가 뜨네요.
배열에 값을 넣을때 저런 식으로 넣으면 안되나요??
포인터를 꼭 사용해야 하나요?
그리고 맞게 고치면 어떤식으로 되는지좀 가르쳐주세요.
댓글
[code:1]#include<stdio.h> vo
변수명너무길어 변수명읽다 지쳤다..ㅡ,.ㅡ;;옛날에.. 김수한무삼
변수명너무길어 변수명읽다 지쳤다..ㅡ,.ㅡ;;
옛날에.. 김수한무삼천각자동방석..... 이물에 빠졌는데..어쩌고 하는이야기가 생각나는...
----------------------------------------------------------------------------
정말 변수 명이 너무 기나요..?
예전프로젝트에서는 for문에 사용하는 index도 i를 쓰지 말라고 금했는데...
물런 i,j,k, x,y,z, a,b,c 로 도배하던 시절도 있었는데..
============================================================
선한 인간이냐 악한 인간이냐는 그사람의 의지에 달렸다. -에픽테토스-
의지 노력 기다림은 성공의 주춧돌이다. -파스퇴르-
============================================================
============================================================
선한 인간이냐 악한 인간이냐는 그사람의 의지에 달렸다. -에픽테토스-
의지 노력 기다림은 성공의 주춧돌이다. -파스퇴르-
============================================================
ㅋㅋㅋㅋㅋㅋ
김 수한무 삼천갑자 동방 삵 이에요ㅎ 장수하는생물들 쭉 나열하는거
음.. 소인수분해는 분해하고자 하는 수의 sqrt() 보다 작은 2이상의
음.. 소인수분해는 분해하고자 하는 수의 sqrt() 보다 작은 2이상의 정수로 모두
나누어보아야 하는 거 아닌가요?
----
Let's shut up and code.
[code:1]#include<stdio.h>void
완성 코드 예요
X=1; 이나 X=InputNumber; 나 똑같더군요.
그리고
for(i=2;i<=InputNumber;i++) 에서 =를 추가시켰습니다.
그러니 마지막 소인수가 빠지는 오류 없이 잘 되네요 .
그리고 소인수는 2이상의 수로 나누어 떨어지는게 있으면 그 뒤는 몫만 가지고 또 나누고 그런식으로 하면 소인수를 다 구할수 있죠 ^^
1%의 가능성이면 충분하다!
최선을 다하자!
펑션을 이렇게 디자인하는건 어떤가요?
어짜피 출력만 하고 끝나면 재미없으니깐,
답을 저장할 배열을 넘겨주고(배열의 크기는 부르는쪽에서 알아서 결정하기로 하고),
몇개의 prime number 가 나왔는지를 넘겨주면 훨씬 유용한 함수가 되지 않을까 생각합니다.
초보의 의견이었슴다.
삽질의 대마왕...
[quote="sangwoo"]음.. 소인수분해는 분해하고자 하는 수의
약수 구하는 거랑 헷갈렸습니다.. :oops:
덧. 심심해서 저도 한번 짜봤습니다.
출력만 하는 거라.. 배열에 넣거나 하진 않았습니다.
----
Let's shut up and code.
음 저도 한번 짜봤습니다.
2로 나누어 떨어지지 않을 때까지 나눈 후,
3부터 제곱근까지의 홀수로 나누어 가는 방식을 사용했습니다.
(속도가 약간 향상되지요.)
고정되어 있지 않은 여러개의 리턴값을 갖는 함수의 디자인은
다음과 같이 출력 반복자를 사용하면 간편합니다.
저도 대충 만들어봤습니다.
--
자본주의, 자유민주주의 사회에서는 결국 자유마저 돈으로 사야하나보다.
사줄테니 제발 팔기나 해다오. 아직 내가 "사겠다"고 말하는 동안에 말이다!
저도 한번 해 봤습니다.
하나는 약수를 구하는 함수이고, 다른 하나는 소인수분해 하는 함수입니다.[/code]
오..LISP 프로그래머다..
저도 LISP 사용자인데..반갑습니다..^^
LISP 사용자모임
http://cafe.naver.com/lisper
방송기술 개발업체
http://playhouseinc.co.kr
http://groups.google.co.kr/groups?thread
http://groups.google.co.kr/groups?threadm=3F137DB7.5B957270%40bawi.org
구글에는 일부만 있군요. 이 쓰레드로 유즈넷에 있는 글은 대략 40개 쯤인데..
2부터 끝까지 나누려니까 엄청 오래 걸리네요.[code:1]$
2부터 끝까지 나누려니까 엄청 오래 걸리네요.
정수 범위 내의 소수를 셋으로 가지고 있다가 참조하면 가장 빠르겠죠?
그 다음 빠른 방법은 뭐가 있을까요?
# emerge girl-friend
Calculating dependencies
!!! All wemen who could satisfy "girl-friend" have been masked.
2하고 홀수로만 하니까 훨씬 빨라지네요.[code:1] $ tim
2하고 홀수로만 하니까 훨씬 빨라지네요.
하지만 여전히 GNU factor와 비교해서 엄청나게 느린속도.
# emerge girl-friend
Calculating dependencies
!!! All wemen who could satisfy "girl-friend" have been masked.
페르마 인수분해
뭐 그럭저럭 쓸만한 테크닉으로 페르마 인수분해가 있습니다
만약~ 6077 을 인수분해 하려면
sqrt(6077) 보다 큰 정수 78 을 고르구요..
78^2 - 6077 = 7 = 무리수 ^2
79^2 - 6077 = 164 = 무리수 ^2
80^2 - 6077 = 323 = 무리수 ^2
81^2 - 6077 = 484 = 22^2 = 정수 ^2
이렇게 되면...
81^2 - 22^2 = 6077 로 옮기구요
(81 + 22)(81 - 22) = 6077 로 바꾸고
103 * 59 = 6077 ..
6077 은 103 과 59 의 곱이니까 103 도 만약 소수가 아니었더라면 또 페르마 인수분해 방법을 써서.. 계속..
이런식으로.. 코딩 하시면 될거에요..
예전에 코딩해 둔게 있긴 있는데 딴데 있군요..
그리고 gnu factor 같은데 쓰인 알고리즘은 엄청 복잡할듯..
FYI - GNU factor 에서 사용한 알고리즘wheel fa
FYI - GNU factor 에서 사용한 알고리즘
wheel factorization 을 사용한다고 되어있군요.
http://primes.utm.edu/glossary/page.php?sort=WheelFactorization
2 와 홀수로 나누는 것도 이 알고리즘이죠 사용 prime [2], wheel size = 2, 50% 정수를 건너 뜀.
GNU factor 에서는 [2,3,5,7,11] 다섯개의 prime 으로 wheel 을 만들고 480/2310 의 정수만 check 합니다. (2310-480)/2310 - 대략 79% 의 정수를 건너뜀.
http://hj-lee.github.io/
느리지만 재귀로
느리지만 재귀로 짜봤습니다.
----------------------------------------------------
개인 블로그: https://kangssu.com
다양한
다양한 프로그래밍언어로 작성된 소인수분해코드를 더 감상하고프신 분은 Project Euler Problem 3을 풀어서 로그인한 후 답안을 제출해보세요. 그러면 답을 맞춘 사람들만 접속할 수 있는 포럼이 나옵니다.
소인수분해하는 파이썬 코드.
파이썬 모르는 분은 다음 세 가지만 알면 위 코드를 읽을 수 있다는...
"""에서 두번째 """까지는 주석.
#로 시작하는 부분도 주석.
factors(2 * 2 * 5 * 17 * 17)를 실행할 경우 list의 값과 n의 값은
[], 2 * 2 * 5 * 17 * 17
[2], 2 * 5 * 17 * 17
[2, 2], 5 * 17 * 17
[2, 2, 5], 17 * 17
[2, 2, 5, 17], 17
[2, 2, 5, 17, 17], 1
의 순서로 변화하고 총 나눗셈연산(/, %)은 O(17)번 실행됩니다.
일반적으로 n을 나누는 가장 큰 소수가 p일 때 p * p 가 n을 나누어 떨어지는 경우는 총 나눗셈연산횟수가 O(p)이고 p * p가 n을 나누지 않는 경우는 총 나눗셈연산횟수가 O(sqrt(p)).
이보다 빠른 알고리즘은 없을 것 같다는... 아 물론 i를 돌릴 때, 2가 아닌 짝수는 뛰어넘고 3이 아닌 3의 배수도 뛰어넘는 식으로 하면 더 빨라지긴 하지만, 그래도 O()는 불변.
이보다 빠른 알고리즘이 없을 것 같다고 하시면... 많은 수연구자(number theorist)들이 슬퍼할겁니다.
http://en.wikipedia.org/wiki/Integer_factorization
큰 수의 소인수 분해 문제는 많은 연구가 이루어지고 있는 분야입니다.
공개키 알고리즘으로 종종사용되는 RSA 알고리즘이 이 문제가 어렵다는 점에 기반하고 있습니다.
물론 아직까지 polynomial 시간에 소인수분해를 할 수 있는 알고리즘은 발견되지 않았기 때문에 RSA 알고리즘을 별다른 염려 없이 사용할 수 있습니다.
GNFS(general number field sieve)가 현재까지 알려진 가장 빠른 알고리즘입니다. 물론 복잡도 측면에서 그렇다는 것이고 100 bit 이하의 숫자는 다른 알고리즘을 사용하는 것이 더 빠르다고 합니다.
복잡도는 위의 글에서
http://en.wikipedia.org/wiki/Integer_factorization#Difficulty_and_complexity
보시면 그림으로 그려져 있습니다.
님의 알고리즘은 n 이 소인수가 아닌 최악의 경우 (b/2) bit 숫자 두개의 곱인 경우입니다.
대략 O(power(2,(b/4)) =~ O(exp(b)).
--------
작은 수의 경우, wheel factorization 이라는 복잡도는 기본 방법과 별 차이가 없지만, 쉽게 이해할 수 있고, 나눗셈도 현저히 줄일 수 있는 방법이 있습니다.
http://primes.utm.edu/glossary/page.php?sort=WheelFactorization
http://en.wikipedia.org/wiki/Wheel_factorization
--------
(수정 - P.S. 글 쓰고 둘러 보다가 누군가 wheel factorization 에 대해서 먼저 썼구나 했는데... 그게 저이군요... ^^;)
--
http://hjlee-p.blogspot.com/
http://hj-lee.github.io/
댓글 달기