240 likes | 486 Views
583 - Prime Factors. 99703032 資科二 陳宣耀 99703034 資科二 鍾佳樺 99703045 資科二 陳乃藩. Outline. Primality Test Prime Table Prime Factors. Primality Test. int isPrime_s1a( int n){ int m; if(n<=1) return 0; for(m=2;m<n;++m) if( n%m ==0) return 0;
E N D
583 - Prime Factors 99703032 資科二 陳宣耀 99703034 資科二 鍾佳樺 99703045 資科二 陳乃藩
Outline • Primality Test • Prime Table • Prime Factors
Primality Test • int isPrime_s1a(int n){ • int m; • if(n<=1) • return 0; • for(m=2;m<n;++m) • if(n%m==0) • return 0; • return 1; • }
Primality Test • The larger n is, the larger time complexity will be. • Time complexity = θ(n) • Running time > 2s for multi-input in one of OJs. • How to modify?
Primality Test • every even number except 2 is not a prime number. • int isPrime_s1b(int n){ • int m; • if(n==2) • return 1; • if((n<=1)||(n%2==0)) • return 0; • for(m=3;m<n;m+=2) • if(n%m==0) • return 0; • return 1; • }
Primality Test • Time complexity is still θ(n) • Running time > 2s for multi-input in the same OJ. • How to modify?
Primality Test • Theorem: • if x mod n≠ 0 • for all 2 ≦ x≦ , • then n is a prime number. • Because that there exist no prime number of n which is larger then .
Primality Test • int isPrime_s1c(int n){ • intm,sqrt_n=sqrt(n); • if(n==2) • return 1; • if((n<=1)||(n%2==0)) • return 0; • for(m=3;m<=sqrt_n;m+=2) • if(n%m==0) • return 0; • return 1; • }
Primality Test • Time complexity = θ( ) • Running time ≈ 0.20s for multi-input in the OJ. • Advantage: a fast solution for one input. • Any other solution?
PrimeTable • Eratosthenes: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3031 2 → 1 2 3 5 7 9 11 13 15 17 19 21 23 25 27 2931 3 → 123571113171923252931 5 → 1235711131719232931 . . .
PrimeTable • Eratosthenes: • void eratosthenes(int sieve[],int size){ • inti,j,sqrt_size=sqrt(size); • sieve[0]=sieve[1]=0; • for(i=2;i<size;++i) • sieve[i]=1; • for(i=2;i<=sqrt_size;++i) • if(sieve[i]==1) • for(j=i*i;j<size;j+=i) • sieve[j]=0; • }
PrimeTable • Build a prime table from the sieve: • int table(int prime[], • const int sieve[], • intsizeOfSieve) • { • inti,j=0; • for(i=0;i<sizeOfSieve;++i) • if(sieve[i]==1) • prime[j++]=i; • return j; • }
PrimeTable • Time complexity = O(n log(log n)) • n is the size of sieve. • Usage: • Primality Test • Factorization
PrimeTable • Use prime table for Primality Test: • int isPrime_s2a(intn,int prime[]){ • inti,sqrt_n=sqrt(n); • if(n<=1) • return 0; • for(i=0;prime[i]<=sqrt_n;++i) • if(n%prime[i]==0) • return 0; • return 1; • }
PrimeTable • Use prime table for Primality Test: • Let x be the number of primes smaller then • Time complexity = O(x) ≦ O( ) • Running time ≈ 0.15s for multi-input in the OJ.
PrimeTable • If n isn’t too large: • intcmp(const void*n1,const void*n2){ • return*(int*)n1-*(int*)n2; • } • int isPrime_s2a(intn,int prime[],intsizeOfPrime){ • return(bsearch(&n,prime,sizeOfPrime,sizeof(int),cmp)!=NULL); • }
PrimeTable • Use prime table for Primality Test: • Time complexity = O(log sizeOfPrime) = O(1) • Running time ≈ 0.10s for multi-input in the OJ.
Prime Factors • Webster defines prime as: • prime (prim) n.[ME, fr. MF, fem. of prin first, L primus; akin to L prior] 1 :first in time: original 2 a : having no factor except itself and one 3 is a number b : having no common factor except one 12 and 25 are relatively 3 a : first in rank, authority or significance : principal b : having the highest quality or value television time [from Webster's New Collegiate Dictionary] • The most relevant definition for this problem is 2a: An integer g>1 is said to be prime if and only if its only positive divisors are itself and one (otherwise it is said to be composite). For example, the number 21 is composite; the number 23 is prime. Note that the decompositon of a positive number g into its prime factors, i.e., • is unique if we assert that fi > 1 for all i and for i<j. • One interesting class of prime numbers are the so-called Mersenne primes which are of the form 2p- 1. Euler proved that 231 - 1 is prime in 1772 -- all without the aid of a computer.
Prime Factors • Input • The input will consist of a sequence of numbers. Each line of input will contain one number g in the range -2^31 < g <2^31, but different of -1 and 1. The end of input will be indicated by an input line having a value of zero. • Output • For each line of input, your program should print a line of output consisting of the input number and its prime factors. For an input number , where each fi is a prime number greater than unity (with for i<j), the format of the output line should be • When g < 0, if , the format of the output line should be
Prime Factors • Sample Output • -190 = -1 x 2 x 5 x 19 • -191 = -1 x 191 • -192 = -1 x 2 x 2 x 2 x 2 x 2 x 2 x 3 • -193 = -1 x 193 • -194 = -1 x 2 x 97 • 195 = 3 x 5 x 13 • 196 = 2 x 2 x 7 x 7 • 197 = 197 • 198 = 2 x 3 x 3 x 11 • 199 = 199 • 200 = 2 x 2 x 2 x 5 x 5 • Sample Input • -190 • -191 • -192 • -193 • -194 • 195 • 196 • 197 • 198 • 199 • 200 • 0
Prime Factors #include<stdio.h> #include<math.h> int buildTable(int prime[],int sizeOfSieve); int factor(int num,int output[],const int table[],int sizeOfPrime); int main(void){ const int sizeOfArray=sqrt(pow(2,31)-1); int prime[sizeOfArray],sizeOfPrime; int output[sizeOfArray],sizeOfOutput; int input,i; sizeOfPrime=buildTable(prime,sizeOfArray); while(scanf("%d",&input)==1){ if(input==0) break; sizeOfOutput=factor(input,output,prime,sizeOfPrime); printf("%d = %d",input,output[0]); for(i=1;i<sizeOfOutput;++i){ printf(" x %d",output[i]); } printf("\n"); } return 0; } /*continue*/
Prime Factors void sieveOfEratosthenes(int sieve[],int size){ int i,j,sqrt_size=sqrt(size); sieve[0]=sieve[1]=0; for(i=2;i<size;++i) sieve[i]=1; for(i=2;i<=sqrt_size;++i) if(sieve[i]==1) for(j=i*i;j<size;j+=i) sieve[j]=0; } int buildTable(int prime[],int sizeOfSieve){ int i,j=0; sieveOfEratosthenes(prime,sizeOfSieve); for(i=0;i<sizeOfSieve;++i) if(prime[i]==1) prime[j++]=i; return j; } /*continue*/
Prime Factors int factor(int num,int output[],const int table[],int sizeOfPrime){ int i,sqrt_num,sizeOfOutput=0; if(num<0){ output[sizeOfOutput++]=-1; num*=-1; }else if(num==1){ output[0]=1; return 1; } sqrt_num=sqrt(num); for(i=0;table[i]<=sqrt_num;++i){ if(i==sizeOfPrime) break; while(num%table[i]==0){ output[sizeOfOutput++]=table[i]; num/=table[i]; } } if(num!=1) output[sizeOfOutput++]=num; return sizeOfOutput; } /*end*/