尤拉素數篩選與命令列傳參啟動C程式
尤拉素數篩選與命令列傳參啟動C程式
不出所料,期末考試我選的就是素數篩選這道題
寫了一下午,邊學邊寫,現把成果發出來
有些邏輯還不是很好,不過就這樣吧不改了
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <time.h>
#define MaxArray 100000001
extern char *optarg;
int Prime[MaxArray], PrimeCounter = 0;
bool Composite[MaxArray] = {false};
void eulerSieve (int N)
{
for (int NumCounter = 2; NumCounter <= N; NumCounter++)
{
if (Composite[NumCounter] == false)
Prime[PrimeCounter++] = NumCounter;
for (int Poller = 0; Poller < PrimeCounter; Poller++)
{
if (NumCounter * Prime[Poller] > N)
break;
Composite[NumCounter * Prime[Poller]] = true;
if (NumCounter % Prime[Poller] == 0)
break;
}
}
}
int primeSieve (int start, int end)
{
int s, e;
double Times;
clock_t st, et;
if (start > end)
{
s = end;
e = start;
}
else if (start == end)
{
printf ("The start and end cannot be the same number.\n");
return -1;
}
else
{
s = start;
e = end;
}
st = clock();
eulerSieve (e);
et = clock();
Times = (double)(et-st)/CLOCKS_PER_SEC;
for (int Num = 0, Row = 0; Num < PrimeCounter; Num++)
{
if (Prime[Num] > s)
{
printf ("%d\t", Prime[Num]);
Row++;
if (Row %10 == 0)
printf ("\n");
}
else continue;
}
printf ("\n\nIt took %.06f seconds to filter all prime numbers from %d to %d.\n"
"Written by Aloento, Bye.\n\n", Times, s, e);
return 0;
}
int isdigitstr (char *str)
{
if (strspn(str, " 0123456789") == strlen(str))
return atoi (str);
else
{
printf ("Please enter a Positive Integer.\n");
exit (-1);
}
}
int help (char *name)
{
printf ("usage: %s [-h] [-s] [-e]\n"
"\n-h: Help to use Prime Sieve."
"\n-s: The starting number for filtering, optional, default is 0."
"\n-e: The number where the filtering ends, required.\n"
"\nFor example: "
"\n./%s -s 100 -e 200\n"
"\nWritten by Aloento\n", name, name);
return 1;
}
int menu (int argc, char *argv[])
{
int opt = 0, start = 0, end = -1;
while (EOF != (opt = getopt(argc, argv, "hs:e:")))
{
switch (opt)
{
case 's':
start = isdigitstr (optarg);
break;
case 'e':
end = isdigitstr (optarg);
return primeSieve (start, end);
break;
case '?':
printf ("Unsupported parameters, Please check your input.\n");
case 'h':
default:
return help (basename(argv[0]));
break;
}
}
return help(basename(argv[0]));
}
int main (int argc, char *argv[])
{
return menu (argc, argv);
}
//Written by Aloento.
關於為什麼main函式只有一行
因為我們老師的要求是main函式不得超過5行
我不是很能理解他的腦回路
所以我就嘗試著讓他也不能理解我的腦回路(?
關於尤拉篩的註釋都在上一篇文章了,這裡就不重複放了
這個演算法有個大問題就是每次都要從0算起,無論你要求的起始點在哪
但是看在它線性時間複雜度的面子上就不再造輪子了
算一億位只要半秒我個人覺得還行
再大的數字在Windows上會崩潰,得在Linux上跑
那個判斷起始點的if段寫的也不好,不過我就不拿空間換時間了
反正看的是篩選效率又不是列印效率(ε=ε=ε=┏(゜ロ゜;)┛
主要的知識點除了尤拉篩以外還有:
getopt傳參啟動,atoi把char轉int等
getopt的optarg很神奇,它會判斷你是第幾次請求
每請求一次就會指向下一個argv
我這裡最開始被坑了一下
atoi等一系列操作在失敗的時候只會返回0
這一點不是很好,得在最開始的時候判斷一下是否是數字
關於為什麼" 0123456789"裡面零的前面有個空格
那是因為optarg傳回的引數就帶個空格在前面
但是如果你在後面加個空格,比如 -e 10 100
那個100就是下一個argv,所以不用擔心出問題
要讀取100,再請求一次optarg就好了
後面要是還想起啥就下一篇再說吧
最近在玩命學JavaFX,寫這玩意的時候老是在想
我現在要是在寫Java的話這個就簡單了那個也輕鬆了(而且還下意識的打了sysout
相關文章
- 素數篩(埃氏篩法與尤拉篩)
- 素數個數 <埃式篩 && 尤拉篩>
- 尤拉篩線性篩質數
- 尤拉篩
- 尤拉篩(線性篩)
- 信奧日記——數論(快速冪、埃氏篩、尤拉篩)
- 素數篩
- 【數論】素數篩法
- 素數篩 : Eratosthenes 篩法, 線性篩法
- wenbao與篩法素數及判斷模板
- Sum of Consecutive Prime Numbers POJ - 2739(線性尤拉篩+尺取法)
- 尤拉計劃700:尤拉幣
- 二維陣列動態開闢與傳參陣列
- Java方法04:擴充命令列傳參Java命令列
- [演算法]: 素數篩法演算法
- 尤拉計劃698:123數
- 尤拉計劃719:拆分數
- 命令列與C++命令列C++
- 尤拉計劃725:數位之和數
- 尤拉計劃699:三腳數
- 尤拉計劃706:三象數
- 尤拉計劃718:不可達數
- 尤拉計劃709:偶數袋
- 尤拉計劃712:指數差
- 尤拉方程
- 尤拉定理
- 【C】 33_main 函式與命令列引數AI函式命令列
- 動態篩選
- Prime Path(POJ - 3126)【BFS+篩素數】
- Diff-prime Pairs(思維+素數篩)AI
- 從尤拉捐贈中,讀懂數字基建與數字中國
- 尤拉五邊形數定理小記
- 尤拉計劃694:立方滿因數
- Note -「因數的尤拉函式求和」函式
- Android開商品屬性篩選與商品篩選Android
- 尤拉計劃714:兩種數位的數
- 尤拉降冪
- 尤拉函式φ函式