尤拉素數篩選與命令列傳參啟動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
相關文章
- Find Terrorists(素數篩選+素因子分解)Error
- 數論線性篩總結 (素數篩,尤拉函式篩,莫比烏斯函式篩,前n個數的約數個數篩)函式
- [演算法]: 素數篩法演算法
- 二維陣列動態開闢與傳參陣列
- ACdream 1112 Alice and Bob (博弈&&素數篩選優化)優化
- Diff-prime Pairs(思維+素數篩)AI
- 動態篩選
- 命令列與C++命令列C++
- 【C】 33_main 函式與命令列引數AI函式命令列
- 命令列CALL程式時傳遞數字引數總結(轉)命令列
- Android開商品屬性篩選與商品篩選Android
- Mac命令列啟動MySQLMac命令列MySql
- Pandas根據篩選條件對指定excel列進行篩選!神器!Excel
- CoffeeScript攻略4.9:篩選陣列陣列
- [IOS]instruments命令列啟動iOS命令列
- 使用jquery篩選和過濾陣列程式碼例項jQuery陣列
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- C語言中的命令列引數C語言命令列
- 陣列多重篩選條件排序方法陣列排序
- JS中的陣列過濾,從簡單篩選到多條件篩選JS陣列
- C# 基於索引的篩選C#索引
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- 二維陣列傳參做形參陣列
- w10篩選器在哪_win10怎麼開啟篩選器Win10
- 二維陣列傳參陣列
- KVC原理與資料篩選
- 用grub命令列啟動系統命令列
- js從字串中篩選出數字程式碼例項JS字串
- POJ 2262 Goldbach's Conjecture (求解素數的一般篩和線性篩)Go
- C語言 將函式(有參、無參)作為引數傳遞C語言函式
- 關鍵詞庫建立與篩選
- windows下命令列啟動tika的方法Windows命令列
- Java方法04:命令列傳遞引數、可變引數Java命令列
- 7 Oracle DataGuard 命令列參考Oracle命令列
- 如何使用kubelet 啟動命令限制Pod 啟動數量?
- c++ -- 二維陣列引數傳遞C++陣列
- 使用GDB命令列偵錯程式除錯C/C++程式命令列除錯C++
- C++ main函式命令列引數使用C++AI函式命令列