2023年12月20日 星期三

自動號碼產生器 FAQ

 /*

//---A N G E L Program FAQ---
FAQ (ANGEL program 10 years anniversary)
FAQ (自動號碼產生器10週年紀念)

Q: 自動號碼產生器是什麼?
A: 自動號碼產生器是基於電腦科學中
的八皇后問題而產生的演算法,
用來計算當使用者需要進行計算活動,
而計算活動適合排列演算法時,
可以用這個電腦程式自動產生所有解,
並且一個一個的秀出來!
未來可望應用在所有排列相關的問題上!

Q: MAXQUEEN字面翻譯是皇后數,
皇后數是什麼?
A:皇后數是八皇后問題與遞迴運算的
一種程式工程上的寫法,
它真正的意思是DIMENSION數,
也就是維度數字!
但是維度是相對於使用者而成立的,
如果使用者要求跟感受的維度不高,
就不需要非常多層次的維度,
也不需要那麼多的維度數字!
這個程式一開始的時候,
是來降低維度,降低難度的。

Q: 維度數字?難道宇宙真的是十一維度嗎?
最大值真的是11維嗎?
A: 並非如此!
我的程式因為有ARRAYSIZE,
SLOTNUMBER數字限制了
最大有10個SLOT,
所以加上數字0的維度,
一共只有11個維度。
未來工業化以後,
則可以提高成為更多的數字。
你只要把所有int變數改成long long
就可以擴充非常多維度。
未來還可以擴充到win32的size_t,
不同變數去進行各種改寫都有。
通常跑程式碼以後,是硬體跟不上,
不是軟體跟不上。
這個陽春版的宗運版產生器,
可以用各種方式向上擴充。
擴充的難點在於,
switch只有0到9這十個阿拉伯數字,
雖然可以像美國ASCII碼一樣,
多加幾個case,
擴充成16進位,
甚至unicode那種10萬以上的字符,
但是人類生命短暫,
如何不吃不喝不睡覺看完所有解呢?
因此本程式改成免費方式公布,
有多餘時間再來觀看就可以了!
並且可以自己修改數字,
1到10之內要算多少維度都可以。
至於宇宙是否為11維度,
要由物理學家來判定才對!

Q: 0階乘怎麼不是1呢?怎麼跑不出來?
A: 這有兩個原因:第一,
實際的工程問題並非學校裡的簡單數學。
這次產生器完成以後,
0階乘它是無解的,
既然跑成功了,它可以執行一次以上,
它就不需要拿來算0階乘。
函數大於等於1的時候它就不會是0函數。
妳若想擴充時,
都可以自己加入if-else或其他#define敘述
去額外定義0階乘會等於1這樣。
第二,0階乘不是1,
是因為MyErrorHandler的數學意義
直接改變了0的價值。
所以在本程式中,
0的意義和價值被分散了,
反而使得工程和數學,
在新的演算法下重新成立,
並且讓這個程式成為永遠可用的
新一代演算法程式。

Q: 為什麼不用linked-list來寫?
怎麼用陣列來寫呢?
A: 本程式引用的arrays.h
提供了可以push pop的新型陣列!
它在結構上不輸給linked-list而且
可以增加與刪減元素!
如果用linked-list來寫,
找尋元素速度上則會降低。
至於對工業界的人士來說
當然很慢!不合用!
因為他們用工業電腦特別快!
但是回頭來看,
這陽春程式碼可以在記憶體很小的
舊型電腦上面跑,
檔案大小也是超級小的!
並且時間過了多少,
就計算多少排列數裝進記憶體,
所以連小型計算機都有可能裝的下。
因此,有空的使用者,
都歡迎來使用本程式!


Q: 那些pragma是什麼?
MyErrorHandler是什麼?
A: 那是程式框架的一部份,
是一種提高安全性的寫法,
避免鍵盤和光碟機和工業電腦,
使用系統訊號
改寫程式裡的公用變數與數字,
造成不精準或是無法運算。
因為在國內沒有人這樣寫,
我在這裡把它稱為‘‘宗運框架’’。
在舊版的XP系統,
不使用MyErrorHandler
曾經是完全無法計算遞迴數字,
但是電腦計算機不可以連遞迴都算不出來,
所以我進行研究以後,
從外國文獻找到這個寫法,
經過工程化之後,
成功完成這個產生器。

Q: 不太能理解,這個框架會怎樣嗎?
A: 當時的鍵盤和光碟機常常
阻止與封印開發人員計算遞迴,
發出一種電子訊號使編譯不能成功,
經過測試以後!
這個框架可以有效阻擋你的光碟機
弄壞你的程式,是VC++2005的一種
安全性寫法。
隨著時間過去,
現在的光碟機越來越便宜,
如果你光碟機會影響編譯器亂跑,
都可以嘗試這個宗運框架的寫法。
當然!已經過時了,
只對WIN XP電腦
和2005年左右的光碟機有效!
現在仍然不穩定的編譯器雖然可以試試看,
不保證還能成功。

Q: pragma很討厭!
我要clean architecture不可以嗎?
A: 在遞迴運算,我只能這樣寫,
以符合XP電腦的VC++2005規格,
這是我的陽春作品!
我當時還連絡了兩三個其他的工程師
寫了一些其他程式碼,
妳可以多多詢問他人,
並且查閱現在20年後的文獻!
這個程式它不會是clean architecture,
因為當時的蘋果系統封印了微軟遞迴運算!
為了達成遞迴運算的教學和使用,所以
公布這個演算法這樣子。
我們如果寫成clean architecture,
蘋果公司又要封印微軟一次,
會有更多問題,
所以這次的程式碼不會是clean architecture。


Q: 可是你算的又慢又不準啊!
有組合跟重複的情形都沒有算!
A: 是否要計算重複要看需求,
我提供的是大量的可能性(possibilities)!
讓使用者有機會比對數學公式
與實際工程後的真正數量,
一個情況一個情況一個情況的算出來以後,
可以真正提高大家能力,
這才是這個教學系列的目標!
未來把int改寫成long long以後,
淘汰掉那些跑不動的硬體,
交給工業電腦的專業寫碼人員,
就可以開發更多也算的更多了!
維度可以提升的程式,
才是真正的程式。
我們都是主張多多討論,
如果只有酸民心態是無法團隊合作的。

Q: 宗運框架有實際用途嗎?
不要寫奇怪的pragma?
A: 要知道連接SQL2005,
一樣可以用這個框架!
雖然2005版以後有C#,更好用,
但是舊版電腦要連線要維護,
只有使用宗運框架。
如果有大量讀者詢問,
人氣夠多,我再另外寫文章敘述
如何連接宗運框架。
未來有時間,可能會寫?
一開始看起來很難,
但是這是工業級的遞迴程式,
工業化以後,
對電信業的工廠工頭來說不會是問題!


Q: 你的路走偏了!
現在已經進步到python了,誰還要C++啊?
A: 有哦!那就是簡單計算機:calculator。
不論是陽春的CASIO或是ARDUINO,
都採用類似電腦語言的程式在運作,
這些都是這個程式碼的潛在使用者!
語言要能讓它自己的話容量變小濃縮的,
才是真正的電腦語言。C語言就是這樣。
反觀python現在是龐大怪獸,容量巨大,
在濃縮自己語言這一點上面,
python還早咧。

Q: HASKELL一下子就算好遞迴了,
程式碼更精簡!
A: 很高興看到工業化
能夠做出更短篇幅的其他廠商程式!
只要是可以提高討論熱度,
我是不會反對這些未來工業發展的,
妳要想起來現在不是2005年,
已經過了很久了!

Q: VC++是單執行緒!
比不上python多執行緒!快停止開發吧!
A: 錯了!多執行緒會流行,
是因為有影片網路公司和
有線電視公司的寫碼人員。
但是簡單計算機不需要在短缺的記憶體,
儲存任何有線電視影片和程式吧?
越簡單越好!所以單執行緒跟超小EXE空間,
反而變成首選了。

Q: 那是EMBEDDED C++不是VC++ ?
A: 很高興20年後,
已經發展出EMBEDDED C++。
我樂觀看待未來發展。
至於VC++如何的比不過EMBEDDED C++,
其實不會啊!那都是C語言相容的,
妳要不要多借幾本教科書?
這些語言都有它的用途。

Q: 那麼到底是怎麼連接的?
A: EMBEDDED C++你要另外
查詢他們的技術書籍喔!
我樂觀看待未來發展。
別擔心!伺服器人員工作能力強大,
他們自然會發展其他新程式語言。
我已經沒有在工程師領域裡面了,
我還常常需要新書新知識呢!

Q: 那我不就要把它逆向工程
變成組合語言,
然後拿去裝在簡單計算機?
A: 當然有可能啊!
ARDUINO與逆向工程現在很有名。
我樂觀看待未來發展。

Q: 大家小台的都用iPhone,
簡單計算機也不需要算排列啊?
A: 嗯!2013年公布這個算法以後,
2023年的需求自然會降低囉!
任何工程問題計算好以後,
工業電腦就會拿去算新的問題,
不代表舊的計算沒有用啊!
這是時代會進步,應該樂觀看待!

Q: 到底幫助了哪家公司嗎?
A: 2013年公布算法以後,
現在不就需求變少了嗎?
演算法科技是否推動科技進步?
可以拿數據參考一下,
幫助電腦設備降價才是目標啊!

Q: 可是iPhone要貴一點啊!
A: VC++是微軟產品,微軟不是蘋果公司喔!
想通了嗎,
妳要不要參考更多教科書?
微軟現在市值比蘋果公司低,
蘋果比較貴,微軟比較便宜,
目標有達成喔!

Q: 這亂七八糟算法怎麼會是對的呢?
A: 階乘運算之所以會算出
無限多跟非常大的數字,
因為他在關鍵運算只用了乘法律和加法律!
而且他是正整數。
因為關鍵階乘運算沒有減沒有除,
所以正整數足夠加到無限多。
可以參考排列組合數學書籍的說明
來理解就可以了。
你要是改寫成亂除亂減,就會算錯囉!

Q: 最後請問怎麼沒有寫ASSERT?
A: 我沒有那麼多的工廠ASSERT技術哩!
這是一個陽春版的程式。
如果我來寫ASSERT,
還沒有機器就寫的話會是負面評價!
因為會減分!我不能寫,
要給下一棒接力,
交給工廠原廠工頭來寫才對!
而且,妳要不要多借幾本教科書?
iPhone現在太多人買,太貴了。
妳要不要考慮改用SAMSUNG手機?

Q: 找不到windows.h?
A: 可以下載並安裝微軟DirectX 9.0c SDK
安裝到windows XP系統。

//---End of Files---
*/





2018年3月31日 星期六

Re: n 取 n 逆時鐘旋轉排列法(水果盤排列程式)

// test004.cpp: 定義主控台應用程式的進入點。
//(水果盤排列程式)
//恭喜你設計出新的排列組合程式,
//我幫你做了一個有define變數的水果盤排列程式,
//n--->A , r--->B ,
//並且計算出Cnr的組合數字,取名為N3。
//設定組合總數為N2,排列所有組合的數量為N3,
//預估N = N3 + 1。
//詹宗運製作,版本: Visual C++ 2017 20180403新版
//

#include "stdafx.h"
#include <functional>  // std::function
#include <memory>    // std::shared_ptr
#include <vector>
#include <iostream>
#include <exception>    // exception
#include <stdexcept>    // exception
#include <new>          // exception
#include <typeinfo>     // exception
//#include <windows.h>//myerrorhandler
//#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
//#include <rtcapi.h>//myerrorhandler

//#include <ostream>//fopen

#include <stdlib.h>//calloc
#include <iostream>//cout
using namespace std;
#include <iomanip>//setw()
//
//
//#include <fstream>//fopen
//#include <memory.h>//typeinfo
//#include <typeinfo>//typeinfo
//#include <string.h>//string
//#include <cstring>//string
//#include <cstddef>//string

//using namespace std;

#define A 10
#define B 5
#define SLOT_SIZE 10

//從1開始遞增
int N = 1;
//新增例外類別

const exception* Logic_Error = new exception("Logic_Error");

//if ((int)A > (int)SLOT_SIZE) throw Logic_Error;
//if ((int)B > (int)SLOT_SIZE) throw Logic_Error;


const char* Make_Slot(int);
//---
//儲存節目名稱的結構
struct show_slot
{
int id;
const char* name;
};


show_slot s_slot[SLOT_SIZE - 1];

void load_slot() {
for (int i = 0; i < (SLOT_SIZE - 1); i++)
{
s_slot[i].id = i;
}
//這裡是儲存水果名稱的結構
//可以透過修改字串來改變水果的名稱
s_slot[0].name = "蘋果";
s_slot[1].name = "香蕉";
s_slot[2].name = "番茄";
s_slot[3].name = "橘子";
s_slot[4].name = "柳丁";
s_slot[5].name = "西瓜";
s_slot[6].name = "芭樂";
s_slot[7].name = "哈密瓜";
s_slot[8].name = "火龍果";
s_slot[9].name = "葡萄";
}

// n 取 r 做排列
// 採用逆時旋轉排列法
// 必須 n >= r
class Permutation_nPn
{
// 回報結果
function<void(const shared_ptr<vector<unsigned char> > &, size_t)> m_Report;
// 放置要排列的數字
shared_ptr <vector<unsigned char> > m_Digital_Array;
// 要做排列的數目值
size_t m_r;

void v(size_t n, size_t r)
{
size_t i = n + 1;
while (i--)
{
if (r == 0)
m_Report(m_Digital_Array, m_r);
else
v(n - 1, r - 1);
unsigned char tmp = m_Digital_Array->at(n);
for (size_t j = n; j > 0; --j)
m_Digital_Array->at(j) = m_Digital_Array->at(j - 1);
m_Digital_Array->at(0) = tmp;
}
}

public:
// Permutation_nPn() {}

Permutation_nPn(const function<void(const shared_ptr<vector<unsigned char> > &, size_t)> &Receive)
:m_Report(Receive)
{}

void nPr(size_t n, size_t r)
{
m_r = r;
m_Digital_Array = shared_ptr<vector<unsigned char> >(new vector<unsigned char>(n));
size_t i = n;
while (i--)
{
m_Digital_Array->at(i) = i;
}
v(n - 1, r - 1);
}
};

void startmsg()
{
cout << "簡易水果排列程式!" << endl;
cout << "從" << A << "種水果任取" << B << "種水果的排列如下所示:" << endl;

}

void Show(const shared_ptr<vector<unsigned char> > &Digital_Array, size_t r)
{
cout << "第\t" << N << "組:\t\t";
for (size_t i = Digital_Array->size() - 1; r > 0; --i, --r)
cout << Make_Slot((int)Digital_Array->at(i)) << ' '; //利用此行輸出水果的種類
cout << endl;
++N;
}

const char* Make_Slot(int s)
{

if (s > SLOT_SIZE) throw Logic_Error;

int tmp003 = s;
if (tmp003 < 0) throw Logic_Error;

return s_slot[tmp003].name;

}

int cnt(int tmp001)
{
int i;
int num001 = 1;
for (i = 0; i < tmp001; i++)
num001 = num001 * (i + 1);
return num001;
}

int cntN(int tmpA, int tmpB)
{
int tmp002;
if (tmpA < tmpB)throw Logic_Error;
try {
int tmpC = cnt(tmpA);
int tmpD = cnt(tmpB);
int tmpE = cnt(tmpA - tmpB);
tmp002 = tmpC / (tmpD*tmpE);

//tmp002 = cnt(tmpA) / cnt(tmpB)*cnt(tmpA - tmpB);
}
catch (const exception& e) {
cout << e.what() << endl;
system("PAUSE");
exit(-1);
}
if (tmp002 > 0) {
return tmp002;
}
else { throw Logic_Error; }
}

int main()
{
//function<void(const shared_ptr<vector<unsigned char> > &, size_t)> Reprot(Show);
Permutation_nPn P(Show);

startmsg(); //秀出起始訊息
load_slot();   //載入水果結構名稱

   //進行計算
   //N從1開始遞增
N = 1;
int N2 = cntN(A, B);
int N3 = cnt(B)*N2;
//if (N2 != N) {
cout << "A=" << A << endl;
cout << "B=" << B << endl;
cout << "N2=" << N2 << endl;
cout << "N3=" << N3 << endl;

if (N3 > 40000) {
cout << "N3組合數字過大,取消顯示,程式結束。" << endl;
system("PAUSE");
exit(-1);
}
cout << "將開始計算,請準備。" << endl;

system("PAUSE");

//主程式
P.nPr(A, B);
//驗算
N2 = cntN(A, B);

cout << "A=" << A << endl;
cout << "B=" << B << endl;
cout << "N=" << N << "( = N3 + 1 )" << endl;  // N = N3+1 ,否則就是算錯了
cout << "N2=" << N2 << endl;
cout << "N3=" << N3 << endl;

cout << "計算完成。" << endl;


system("PAUSE");

return 0;
}

2018年3月27日 星期二

Re: n 取 n 逆時鐘旋轉排列法


// test002.cpp: 定義主控台應用程式的進入點。
//

#include "stdafx.h"
#include <functional>  // std::function
#include <memory>    // std::shared_ptr
#include <vector>
#include <iostream>
#include <exception>    // exception
#include <stdexcept>    // exception
#include <new>          // exception
#include <typeinfo>     // exception

using namespace std;

//下面是主要改數字的區域,A就是 Cnr 的n, B就是 Cnr 的r。
//可以透過更改A和B的數字來計算Cnr的結果。
//改成A和B變數可以符合國中數學的二元方程式教學以及帕斯卡三角形教學。

#define A 10
#define B 5

//從1開始遞增
int N = 1;
//新增例外類別
const exception* Logic_Error = new exception("Logic_Error");


// n 取 r 做排列
// 採用逆時旋轉排列法
// 必須 n >= r
class Permutation_nPn
{
// 回報結果
function<void(const shared_ptr<vector<unsigned char> > &, size_t)> m_Report;
// 放置要排列的數字
shared_ptr <vector<unsigned char> > m_Digital_Array;
// 要做排列的數目值
size_t m_r;

void v(size_t n, size_t r)
{
size_t i = n + 1;
while (i--)
{
if (r == 0)
m_Report(m_Digital_Array, m_r);
else
v(n - 1, r - 1);
unsigned char tmp = m_Digital_Array->at(n);
for (size_t j = n; j > 0; --j)
m_Digital_Array->at(j) = m_Digital_Array->at(j - 1);
m_Digital_Array->at(0) = tmp;
}
}

public:
Permutation_nPn() {}

Permutation_nPn(const function<void(const shared_ptr<vector<unsigned char> > &,\
 size_t)> &Receive):m_Report(Receive){}

void nPr(size_t n, size_t r)
{
m_r = r;
m_Digital_Array = shared_ptr<vector<unsigned char> >\
(new vector<unsigned char>(n));
size_t i = n;
while (i--)
{
m_Digital_Array->at(i) = i;
}
v(n - 1, r - 1);
}
};

void startmsg()
{
cout << A << "P" << B << "的排列:" << endl;
}

void Show(const shared_ptr<vector<unsigned char> > &Digital_Array, size_t r)
{
cout << N << ":\t";
for (size_t i = Digital_Array->size() - 1; r > 0; --i, --r)
cout << (int)Digital_Array->at(i) << ' ';
cout << endl;
++N;
}

int cnt(int tmp001)
{
int i;
int num001 = 1;
for (i = 0; i < tmp001; i++)
num001 = num001 * (i + 1);
return num001;
}

int cntN(int tmpA, int tmpB)
{
int tmp002;
if (tmpA < tmpB)throw Logic_Error;
try {
int tmpC = cnt(tmpA);
int tmpD = cnt(tmpB);
int tmpE = cnt(tmpA - tmpB);
tmp002 = tmpC / (tmpD*tmpE);

//tmp002 = cnt(tmpA) / cnt(tmpB)*cnt(tmpA - tmpB);//error
}
catch (const exception& e) {
cout << e.what() << endl;
system("PAUSE");
exit(-1);
}
if (tmp002 > 0) {
return tmp002;
}
else { throw Logic_Error; }
}


int main()
{

Permutation_nPn P(Show);

startmsg();
N = 1;


int N2 = cntN(A, B);
int N3 = cnt(B)*N2;

cout << "A=" << A << endl;
cout << "B=" << B << endl;
cout << "N2=" << N2 << endl;
cout << "N3=" << N3 << endl;

if (N3 > 40000) {
cout << "N3組合數字過大,取消顯示,程式結束。" << endl;
//為了方便展示所以取消顯示所有解
system("PAUSE");
exit(-1);
}
cout << "將開始計算,請準備。" << endl;

system("PAUSE");
//主程式
P.nPr(A, B);
//驗算

cout << "A=" << A << endl;
cout << "B=" << B << endl;
cout << "N=" << N << " ( = N3 + 1)" << endl;  // N = N3+1 ,否則就是算錯了
cout << "N2=" << N2 << endl;
cout << "N3=" << N3 << endl;

cout << "計算完成。" << endl;


system("PAUSE");

return 0;
}

2016年12月13日 星期二

(教學)Visual C++ 2005程式設計:運動頻道節目排列組合產生器的排球版本

Auto Number Generator Electronic List實作範例:
運動頻道節目排列組合產生器排球專用版本(Channel Arranger Version2)
詹宗運製作
版本:Visual C++ 2005以上都可以使用

這是為了推廣排球運動特別製作的排球專用版本!
各位網友不必著急,
如果你有多餘的時間,再觀看本程式碼就可以了。


自動號碼產生器是一項超越時代的程式,
這裡A4element已經完全電腦化,
不需要用紙,不需要人力,也不需要印表機。
想想看可以在工業界節省多少費用。
為了要應用這一個好用的程式碼,
筆者特別開發了新的模組,
用來計算運動頻道節目的排列組合,
可以利用這個產生器做初步的排列組合計算與評估。
最多10個運動頻道節目的排列組合,
將可以有高達3628800種的排列組合結果,
顯示全部結果可以長達幾個星期之久,
是相當大型的程式。
歡迎各種公司行號利用本程式提到的程式技術,
應用開發更高層次工業化的程式,
拼經濟救台灣。

為了補足原先的程式沒有計算到排球的缺失,
筆者特別準備了這一個排球專用的版本,
本程式計算的內容有排球游泳越野拉力賽車滑雪田徑等等,
歡迎大家參考使用。
程式碼裡面有註明運動與時間名稱的結構,
可以透過修改字串的方式來自己定義運動項目或是時間,
運用起來相當方便,
歡迎大家多多利用與推廣本程式碼。

為了節省時間方便展示所以MAXQUEEN預設數字為6,
最多10個數字的排列組合會有3628800組結果,
只要是有時間的網友都可以試試看!
請大家依照下面的說明指示更改MAXQUEEN數字到10,
再更改SOLUTION數字到3628800,
更改ARRAYSIZE數字到11,
親眼體驗本程式讓電腦計算好幾個星期的壯觀畫面。


使用方式:
建立一個Visual C++ 2005 WIN32主控台程式專案,
名稱設定成"Channel_Arranger_Version2"。
這時候會自動生成空白檔案Channel_Arranger_Version2.cpp 與stdafx.h,
再建立一個空白標頭檔案名稱為"arrays.h"
然後把下面的Channel_Arranger_Version2.cpp 與arrays.h所有文字內容,
分別拷貝貼上到你的同樣名稱的空白檔案裡面,
就可以使用了。
歡迎公司行號利用本程式提到的技術開發更高規模的工業化程式,
拼經濟救台灣。


//如果要計算運動頻道節目5個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 5
#define TRUE 1
#define FALSE 0
#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 6//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算運動頻道節目6個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 6
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 7//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算運動頻道節目7個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 7
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 8//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算運動頻道節目8個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 8
#define TRUE 1
#define FALSE 0
#define SOLUTION 40320//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 9//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算運動頻道節目9個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 9
#define TRUE 1
#define FALSE 0
#define SOLUTION 362880//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 10//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算運動頻道節目10個節目排列組合請修改參數如下:
//-------------------------------
#define MAXQUEEN 10
#define TRUE 1
#define FALSE 0
#define SOLUTION 3628800//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 11//ARRAYSIZE1 = MAXQUEEN+1

//-------------------------------
//第一個版本,適用於Visual C++ 2017 與 Windows 10
//------------以下是Channel_Arranger_Version2.cpp 程式碼 (2017新版)

// Channel_Arranger_Version2.cpp : 定義主控台應用程式的進入點。
//
//
//

#include "stdafx.h"

//Auto Number Generator Electronic List (ANGEL程式)範例
//Channel_Arranger_Version2.cpp
//詹宗運製作
//這是一個修改ANG_Prototype的範例,
//用來計算運動頻道節目組合問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2017 版本: 20180315新版

#include "arrays.h"

//用來運算的結構,可以想成是一疊計算紙
typedef struct a4element
{
int identity;
int a_content[3];
} A4element;

//儲存時間名稱的結構
typedef struct time_slot
{
int id;
const char* name;
}time_slot;

//儲存節目名稱的結構
typedef struct show_slot
{
int id;
const char* name;
}show_slot;

#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

//#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






//#include <fstream>//fopen
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string



//這裡是改數字的主要區域
//可以透過改變數字來計算更多的排列組合

#define MAXQUEEN 6//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 7//ARRAYSIZE = MAXQUEEN+1

#define SLOTNUMBER 10//一共有10個欄位

using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number = 0;//計算總共有幾組解的總數
   //決定皇后存放的位置
   //輸出所需要的結果
#include "arrays.h"
//---
UnorderedArray<int> array01(4);
//---

//新增這一行
//定義每次顯示系統要間隔多少毫秒
int DELAYTIME;//暫停多少毫秒

int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int, int);

#pragma runtime_checks("", off)



void print_table()
{

//遞迴運算式,建議不要更改參數
int x = 0, y = 0;
number += 1;


remain = SOLUTION - number;

cout << "自動產生" << MAXQUEEN << "個號碼組合的第" << setw(7) << number;
cout << "組號碼,進度為剩下" << remain << "組尚未處理。" << endl << "\t";
system("CLS");


int k = 0;
for (x = 0; x<MAXQUEEN; x++)
{
for (y = 0; y<MAXQUEEN; y++)
if (x == queen[y])
{
k = y + 1;
array01.push(k);
}

}


}


//遞迴運算式,建議不要更改參數
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

void decide_position(int value)
{
int i = 0;// i=行
while (i<MAXQUEEN)
{
//是否受到攻擊的判斷式
if (calculate(i, value) != TRUE)
{
queen[value] = i;//只有在未受攻擊時將計算值存入皇后陣列

if (value == MAXQUEEN - 1)//列已到末端
print_table();//只有在未受攻擊時列已到末端時才印出結果
else
decide_position(value + 1);
//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)
}
//受攻擊時值不能存入陣列
i++;//不論是否遭受攻擊都換行重新執行函數 i=行
}
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++



//遞迴運算式,建議不要更改參數
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

int calculate(int row, int col)
{
int i = 0, flag = FALSE;
//int offset_row=0,offset_col=0;
while ((flag != TRUE) && i<col)//當未遭受攻擊與i計算值小於VALUE
{
//offset_col=abs(i-col);//不需要運算此行程式碼
//offset_row=abs(queen[i]-row);//不需要運算此行程式碼
//判斷兩皇后是否在同一列在同一對角線上
//if((queen[i]==row)||(offset_row==offset_col))//不需要運算此行程式碼
if ((queen[i] == row))//

flag = TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
i++;//逐行檢查
}
return flag;
}



#pragma runtime_checks("", off)


int speedswitch()
{
char b;


while (1)
{
system("CLS");
cout << "請按下數字鍵,選擇播放速度:" << endl;
cout << "1.慢速  2.快速  0.繼續  請選擇(0-2):";
cin.get(b);
switch (b)
{
case '1':
cout << endl;
cout << "已選擇慢速播放。" << endl;
return 1500;
break;

case '2':
cout << endl;
cout << "已選擇快速播放。" << endl;
return 10;
break;
case '0':
goto Here;

}
}

Here:
return 10;

}


#pragma runtime_checks("", off)

//主程式
void construct_A4element() {
//定義結構名稱
time_slot t_slot[SLOTNUMBER - 1];

for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
t_slot[i].id = i;
}
//主要修改時間名稱的欄位
//可以自己更改名稱

t_slot[0].name = "上午八點";
t_slot[1].name = "上午十點";
t_slot[2].name = "下午一點";
t_slot[3].name = "下午三點";
t_slot[4].name = "下午五點";
t_slot[5].name = "晚上八點";
t_slot[6].name = "晚上十點";
t_slot[7].name = "凌晨十二點";
t_slot[8].name = "凌晨兩點";
// t_slot[9].name = "凌晨四點";

show_slot s_slot[SLOTNUMBER - 1];

for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
s_slot[i].id = i;
}

//主要修改運動名稱的欄位
//可以自己更改名稱

s_slot[0].name = "男子排球";
s_slot[1].name = "女子排球";
s_slot[2].name = "男子游泳";
s_slot[3].name = "女子游泳";
s_slot[4].name = "越野拉力賽車";
s_slot[5].name = "職業摔角";
s_slot[6].name = "加拿大滑雪";
s_slot[7].name = "划龍舟比賽";
s_slot[8].name = "男子田徑";
// s_slot[9].name = "女子田徑";

//開始遞迴運算
int f = 0;
int g = 0;
int h = 0;

remain = 0;


A4element *a = (A4element*)calloc(SOLUTION, sizeof(A4element));

while (f<SOLUTION)
{


while (g<(ARRAYSIZE1 - 1))
{
a->identity = f;
a->a_content[g] = array01[h];

//cout<<"目前核對a["<<f<<"]->a_content["<<\
  //g<<"]="<<(a->a_content[g])<<endl;//顯示內容

SNum[f][g] = array01[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch (SNum[f][g])
{
case 10:
SChar[f][g] = '0';

break;
case 1:
SChar[f][g] = '1';
break;
case 2:
SChar[f][g] = '2';
break;
case 3:
SChar[f][g] = '3';
break;
case 4:
SChar[f][g] = '4';
break;
case 5:
SChar[f][g] = '5';
break;
case 6:
SChar[f][g] = '6';
break;
case 7:
SChar[f][g] = '7';
break;
case 8:
SChar[f][g] = '8';
break;
case 9:
SChar[f][g] = '9';
break;

}


buf[h] = SChar[f][g];

h++;
g++;
}
g = 0;
f++;
remain = SOLUTION - f;
cout << "核對資料結構還剩下" << remain << "組。" << endl;
system("CLS");


}

cout << "計算完成" << endl;

//----------------------------------------------------------------------------

//string str(SOLUTION*MAXQUEEN,' ');

cout << "號碼產生的數量是 " << h << "個。" << endl;
cout << "接下來你可以按下數字鍵加上ENTER鍵選擇播放速度," << endl;
cout << "自動號碼產生器已經計算完成。請按下按鍵顯示結果。" << endl;
system("pause");


//--------------------------------------------------------

//切換速度
DELAYTIME = speedswitch();//切換速度



  //-------------make SNum----------------------------------

  //cout<<"計算SNum當中"<<endl;
int m = 0;
int n = 0;
int p = 0;
remain = 0;

while (m<SOLUTION)
{
while (n<MAXQUEEN)
{
a->identity = m;
a->a_content[n] = array01[p];



SNum[m][n] = a->a_content[n];




p++;

n++;
}
n = 0;
//---遞迴顯示自動號碼----

system("CLS");
cout << "" << "運動頻道節目排列組合產生器" << ":" << endl;
cout << "第" << (m + 1) << "組" << "運動頻道節目組合" << "是:  首先," << endl;
for (int i2 = 0; i2<MAXQUEEN; i2++) {
cout << t_slot[i2].name;
cout << "的時候收看" << s_slot[SNum[m][i2] - 1].name;
cout << "。" << endl;
}

cout << "就收看完了全部節目。" << endl;
//-----------------------
m++;
remain = SOLUTION - m;

cout << "以上是" << "運動頻道節目";
cout << "的第" << m << "組的組合,剩下" << remain << "組。" << endl;

Sleep(DELAYTIME);
}

cout << "以上是" << "運動頻道節目排列組合產生器" << "實作," << endl;



//取消了輸出檔案的功能

cout << "array的型態 = " << typeid(array01).name() << endl;
cout << "感謝Allen Sherrod的資料結構教科書,僅此致謝。" << endl;
cout << "Auto Number Generator: Visual C++ 2017版," << endl;
cout << "詹宗運製作," << endl;
cout << "免費授權Microsoft公司進行進一步的修改與工業化," << endl;
cout << "用來攤平記憶體缺損所造成的工業損失," << endl;
cout << "並且提供VC++社群做為討論與修改的使用。" << endl;
system("pause");

//將共用變數進行釋放與歸零

memset(&a, NULL, sizeof(&a));
a = NULL;
free(a);
memset(&SNum, NULL, sizeof(&SNum));
for (int i = 0; i<SOLUTION; i++)
{
for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{
SNum[i][j] = NULL;

}
}

//delete *SNum;   //不刪除變數可以避免return引起的問題

memset(&SChar, NULL, sizeof(&SChar));

for (int i = 0; i<SOLUTION; i++)
{
for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{
SChar[i][j] = NULL;

}
}




//delete *SChar;   //不刪除變數可以避免return引起的問題


f = NULL;
g = NULL;
h = NULL;
remain = NULL;
m = NULL;
n = NULL;
p = NULL;



// delete t_slot;    //不刪除變數可以避免return引起的問題
// delete s_slot;

//直接結束關閉,此技術也可以避免return引起的問題。
//exit(1);

//return; //不使用return可以避免問題。

}

#pragma runtime_checks("", off)

//顯示起始畫面訊息
void startmessage() {

cout << "自動號碼生成器應用:" << endl;
cout << "運動頻道節目排列組合產生器," << endl;
cout << "詹宗運製作。" << endl;
cout << "接下來會自動運算出許多訊息,";
cout << "請耐心等待訊息停止以後," << endl;
cout << "再按下按鍵繼續運算。" << endl;
cout << "運算好以後你可以按下數字鍵加上ENTER鍵選擇播放速度," << endl;
cout << "然後收看排列組合的顯示結果。" << endl;
cout << endl;

cout << "開始運算,請準備。" << endl;
system("pause");
system("CLS");

//cout<<"\t";
}



//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
const char* module, const char* format, ...)
{
// 1. Prevent re-entrance
static long IsRunning = 0;
while (InterlockedExchange(&IsRunning, 1))
Sleep(1);

// 2. Get the RTC error number from the var_arg list
va_list ArgList;
va_start(ArgList, format);
_RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
va_end(ArgList);

char s[1024];
// 3. Get the error description
const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
  \nFile: %s\nModule:\
  %s\nClick OK to break into debugger.", \
ErrorDesc, line, file ? file : \
"Unknown", module ? module : "Unknown");

// 4. Display message box
MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
// 5. Go ahead and break into the debugger
return 1;
}
#pragma runtime_checks("", restore)




int main()
{
//顯示起始畫面訊息
startmessage();

//關掉.NET錯誤
_RTC_error_fn OldHandler;
OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);


//主程式
decide_position(0);
//主程式
construct_A4element();

//恢復.NET運作
_RTC_SetErrorFunc(OldHandler);


//直接結束關閉,此技術可以避免return引起的問題。
exit(1);

return EXIT_SUCCESS;   //出現了return可能會引起debugger中斷的問題
}

//------------Channel_Arranger_Version2.cpp檔案到此為止
//-------------------------------------------------------------------------






//-------------------------------
//第二個版本
// Channel_Arranger_Version2.cpp : 定義主控台應用程式的進入點。
// 版本: 適用於Visual C++ 2005與Windows XP

//------------以下是Channel_Arranger_Version2.cpp 程式碼

// Channel_Arranger_Version2.cpp : 定義主控台應用程式的進入點。
//
//
//

#include "stdafx.h"

//Auto Number Generator Electronic List (ANGEL程式)範例
//Channel_Arranger_Version2.cpp
//詹宗運製作
//這是一個修改ANG_Prototype的範例,
//用來計算運動頻道節目組合問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005 版本: 20180315新版

#include "arrays.h"

//用來運算的結構,可以想成是一疊計算紙
typedef struct a4element
{
 int identity;
 int a_content[3];
} A4element;

//儲存時間名稱的結構
typedef struct time_slot
{
 int id;
 const char* name;
}time_slot;

//儲存節目名稱的結構
typedef struct show_slot
{
 int id;
 const char* name;
}show_slot;

#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

//#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






//#include <fstream>//fopen
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string



//這裡是改數字的主要區域
//可以透過改變數字來計算更多的排列組合

#define MAXQUEEN 6//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 7//ARRAYSIZE1 = MAXQUEEN+1

#define SLOTNUMBER 10//一共有10個欄位

using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number=0;//計算總共有幾組解的總數
//決定皇后存放的位置
//輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);


//新增這一行
//定義每次顯示系統要間隔多少毫秒
int DELAYTIME;//暫停多少毫秒

int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)



void print_table()
{

  //遞迴運算式,建議不要更改參數
     int x=0,y=0;
     number+=1;


  remain = SOLUTION-number;

     cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"<<setw(7)<<number;
  cout<<"組號碼,進度為剩下"<<remain<<"組尚未處理。"<<endl<<"\t";
  system("CLS");


  int k=0;
  for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
     {
    k=y+1;
      array.push(k);
     }

     }


}


//遞迴運算式,建議不要更改參數
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);
   //只有在未受攻擊時將計算值存入皇后陣列,
   //計算完成以後,列+1遞迴重新執行函數( value=列)
      }
   //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   }
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++



//遞迴運算式,建議不要更改參數
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

int calculate(int row,int col)
{
    int i=0,flag=FALSE;
    //int offset_row=0,offset_col=0;
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
       //offset_col=abs(i-col);
       //offset_row=abs(queen[i]-row);
       //判斷兩皇后是否在同一列在同一對角線上
       //if((queen[i]==row)||(offset_row==offset_col))
       if((queen[i]==row))//

     flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
    //當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}



#pragma runtime_checks("", off)


int speedswitch()
{
 char b;


 while(1)
 {
 system("CLS");
 cout<<"請按下數字鍵,選擇播放速度:"<<endl;
 cout<<"1.慢速  2.快速  0.繼續  請選擇(0-2):";
 cin.get(b);
 switch(b)
 {
 case '1':
  cout<<endl;
  cout<< "已選擇慢速播放。"<<endl;
  return 1500;
 break;

 case '2':
  cout<<endl;
  cout<< "已選擇快速播放。"<<endl;
  return 10;
 break;
 case '0':
  goto Here;

 }
 }

Here:
return 10;

}


#pragma runtime_checks("", off)

//主程式
void construct_A4element(){
//定義結構名稱
time_slot t_slot[SLOTNUMBER-1];

for(int i=0;i<(SLOTNUMBER-1);i++)
{
t_slot[i].id = i;
}
//主要修改時間名稱的欄位
//可以自己更改名稱

t_slot[0].name = "上午八點";
t_slot[1].name = "上午十點";
t_slot[2].name = "下午一點";
t_slot[3].name = "下午三點";
t_slot[4].name = "下午五點";
t_slot[5].name = "晚上八點";
t_slot[6].name = "晚上十點";
t_slot[7].name = "凌晨十二點";
t_slot[8].name = "凌晨兩點";
t_slot[9].name = "凌晨四點";

show_slot s_slot[SLOTNUMBER-1];

for(int i=0;i<(SLOTNUMBER-1);i++)
{
s_slot[i].id = i;
}

//主要修改運動名稱的欄位
//可以自己更改名稱

s_slot[0].name ="男子排球";
s_slot[1].name ="女子排球";
s_slot[2].name ="男子游泳";
s_slot[3].name ="女子游泳";
s_slot[4].name ="越野拉力賽車";
s_slot[5].name ="職業摔角";
s_slot[6].name ="加拿大滑雪";
s_slot[7].name ="划龍舟比賽";
s_slot[8].name ="男子田徑";
s_slot[9].name ="女子田徑";

//開始遞迴運算
 int f=0;
 int g=0;
 int h=0;

 remain=0;


 A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

 while(f<SOLUTION)
 {


 while(g<(ARRAYSIZE1-1))
 {
  a->identity=f;
  a->a_content[g]=array[h];

  //cout<<"目前核對a["<<f<<"]->a_content["<<\
  //g<<"]="<<(a->a_content[g])<<endl;//顯示內容

  SNum[f][g]=array[h];

  //如果要超過10階乘就要加大下面這個switch case敘述
  switch(SNum[f][g])
  {
  case 10:
   SChar[f][g]='0';

   break;
  case 1:
   SChar[f][g]='1';
   break;
  case 2:
   SChar[f][g]='2';
   break;
  case 3:
   SChar[f][g]='3';
   break;
  case 4:
   SChar[f][g]='4';
   break;
  case 5:
   SChar[f][g]='5';
   break;
  case 6:
   SChar[f][g]='6';
   break;
  case 7:
   SChar[f][g]='7';
   break;
  case 8:
   SChar[f][g]='8';
   break;
  case 9:
   SChar[f][g]='9';
   break;

  }


  buf[h]=SChar[f][g];

  h++;
  g++;
 }
 g=0;
 f++;
 remain=SOLUTION - f;
  cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;
  system("CLS");


 }

 cout<<"計算完成"<<endl;

//----------------------------------------------------------------------------

 //string str(SOLUTION*MAXQUEEN,' ');

 cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;
 cout<<"接下來你可以按下數字鍵加上ENTER鍵選擇播放速度,"<<endl;
 cout<<"自動號碼產生器已經計算完成。請按下按鍵顯示結果。"<<endl;
 system("pause");


//--------------------------------------------------------

 //切換速度
 DELAYTIME = speedswitch();//切換速度



 //-------------make SNum----------------------------------

 //cout<<"計算SNum當中"<<endl;
 int m=0;
 int n=0;
 int p=0;
    remain=0;

 while(m<SOLUTION)
 {
 while(n<MAXQUEEN)
 {
  a->identity=m;
  a->a_content[n]=array[p];



  SNum[m][n]=a->a_content[n];




  p++;

  n++;
 }
 n=0;
 //---遞迴顯示自動號碼----

 system("CLS");
 cout<<""<<"運動頻道節目排列組合產生器"<<":"<<endl;
 cout<<"第"<<(m+1)<<"組"<<"運動頻道節目組合"<<"是:  首先,"<<endl;
 for(int i2=0;i2<MAXQUEEN;i2++){
  cout<<t_slot[i2].name;
  cout<<"的時候收看"<<s_slot[SNum[m][i2]-1].name;
  cout<<"。"<<endl;}

 cout<<"就收看完了全部節目。"<<endl;
 //-----------------------
 m++;
 remain=SOLUTION-m;

 cout<<"以上是"<<"運動頻道節目";
 cout<<"的第"<<m<<"組的組合,剩下"<<remain<<"組。"<<endl;

 Sleep(DELAYTIME);
 }

 cout<<"以上是"<<"運動頻道節目排列組合產生器"<<"實作,"<<endl;



//取消了輸出檔案的功能

 cout<<"array的型態 = "<<typeid(array).name()<<endl;
 cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
 cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
 cout<<"詹宗運製作,"<<endl;
 cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
 cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
 cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
 system("pause");

 //將共用變數進行釋放與歸零

memset(&a,NULL, sizeof(&a));
a = NULL;
delete a;
memset(&SNum,NULL, sizeof(&SNum));
for(int i = 0; i<SOLUTION;i++)
{
for(int j = 0; j < (ARRAYSIZE1-1); j++)
{
      SNum[i][j] = NULL;

}
}

//delete *SNum;   //不刪除變數可以避免return引起的問題

memset(&SChar,NULL, sizeof(&SChar));

for(int i = 0; i<SOLUTION;i++)
{
for(int j = 0; j < (ARRAYSIZE1-1); j++)
{
      SChar[i][j] = NULL;

}
}


//delete *SChar;   //不刪除變數可以避免return引起的問題


 f=NULL;
 g=NULL;
 h=NULL;
 remain=NULL;
 m=NULL;
 n=NULL;
 p=NULL;



// delete t_slot;    //不刪除變數可以避免return引起的問題
// delete s_slot;

 //直接結束關閉,此技術可以避免return引起的問題。
exit(1);

return;

}

#pragma runtime_checks("", off)

//顯示起始畫面訊息
void startmessage(){

 cout<<"自動號碼生成器應用:"<<endl;
 cout<<"運動頻道節目排列組合產生器,"<<endl;
 cout<<"詹宗運製作。"<<endl;
 cout<<"接下來會自動運算出許多訊息,";
 cout<<"請耐心等待訊息停止以後,"<<endl;
 cout<<"再按下按鍵繼續運算。"<<endl;
 cout<<"運算好以後你可以按下數字鍵加上ENTER鍵選擇播放速度,"<<endl;
 cout<<"然後收看排列組合的顯示結果。"<<endl;
 cout<<endl;

 cout<<"開始運算,請準備。"<<endl;
 system("pause");
 system("CLS");

    //cout<<"\t";
}



//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
  \nFile: %s\nModule:\
  %s\nClick OK to break into debugger.", \
  ErrorDesc, line, file ? file : \
  "Unknown",    module ? module : "Unknown");

 // 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{
 //顯示起始畫面訊息
 startmessage();

 //關掉.NET錯誤
 _RTC_error_fn OldHandler;
 OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);


 //主程式
 decide_position(0);
 //主程式
 construct_A4element();

 //恢復.NET運作
 _RTC_SetErrorFunc(OldHandler);


 //直接結束關閉,此技術可以避免return引起的問題。
  exit(1);

 return EXIT_SUCCESS;   //出現了return可能會引起debugger中斷的問題
}

//------------Channel_Arranger_Version2.cpp檔案到此為止
//-------------------------------------------------------------------------



//------------以下是arrays.h程式碼
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//------------arrays.h檔案到此為止

//---------以下是stdafx.h程式碼

// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#ifndef _WIN32_WINNT // 允許使用 Windows XP (含) 以後版本的特定功能。
#define _WIN32_WINNT 0x0501 // 將它變更為針對 Windows 其他版本的適當值。
#endif

#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭

2016年11月6日 星期日

(教學)Visual C++ 2005程式設計:如何實作運動頻道節目排列組合產生器

Auto Number Generator Electronic List實作範例:
運動頻道節目排列組合產生器(Channel Arranger)
詹宗運製作
版本:Visual C++ 2005以上都可以使用

自動號碼產生器是一項超越時代的程式,
這裡A4element已經完全電腦化,
不需要用紙,不需要人力,也不需要印表機。
想想看可以在工業界節省多少費用。
為了要應用這一個好用的程式碼,
筆者特別開發了新的模組,
用來計算運動頻道節目的排列組合,
可以利用這個產生器做初步的排列組合計算與評估。
最多10個運動頻道節目的排列組合,
將可以有高達3628800種的排列組合結果,
顯示全部結果可以長達幾個星期之久,
是相當大型的程式。
歡迎各種公司行號利用本程式提到的程式技術,
應用開發更高層次工業化的程式,
拼經濟救台灣。

為了節省時間方便展示所以MAXQUEEN預設數字為6,
最多10個數字的排列組合會有3628800組結果,
只要是有時間的網友都可以試試看!
請大家依照下面的說明指示更改MAXQUEEN數字到10,
再更改SOLUTION數字到3628800,
更改ARRAYSIZE數字到11,
親眼體驗本程式讓電腦計算好幾個星期的壯觀畫面。


使用方式:
建立一個Visual C++ 2005 WIN32主控台程式專案,
名稱設定成"Channel_Arranger"。
這時候會自動生成空白檔案Channel_Arranger.cpp 與stdafx.h,
再建立一個空白標頭檔案名稱為"arrays.h"
然後把下面的Channel_Arranger.cpp 與arrays.h所有文字內容,
分別拷貝貼上到你的同樣名稱的空白檔案裡面,
就可以使用了。
歡迎公司行號利用本程式提到的技術開發更高規模的工業化程式,
拼經濟救台灣。

//如果要計算運動頻道節目5個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 5

#define TRUE 1

#define FALSE 0

#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 6//ARRAYSIZE1 = MAXQUEEN+1









//如果要計算運動頻道節目6個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 6

#define TRUE 1

#define FALSE 0

#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 7//ARRAYSIZE1 = MAXQUEEN+1









//如果要計算運動頻道節目7個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 7

#define TRUE 1

#define FALSE 0

#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 8//ARRAYSIZE1 = MAXQUEEN+1









//如果要計算運動頻道節目8個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 8

#define TRUE 1

#define FALSE 0

#define SOLUTION 40320//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 9//ARRAYSIZE1 = MAXQUEEN+1









//如果要計算運動頻道節目9個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 9

#define TRUE 1

#define FALSE 0

#define SOLUTION 362880//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 10//ARRAYSIZE1 = MAXQUEEN+1









//如果要計算運動頻道節目10個節目排列組合請修改參數如下:

//-------------------------------

#define MAXQUEEN 10

#define TRUE 1

#define FALSE 0

#define SOLUTION 3628800//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040

#define ARRAYSIZE1 11//ARRAYSIZE1 = MAXQUEEN+1






//第一個版本: 適用於Visual C++ 2017 與 Windows 10
// Channel_Arranger.cpp : 定義主控台應用程式的進入點。
//
//
//

#include "stdafx.h"

//Auto Number Generator Electronic List (ANGEL程式)範例
//Channel_Arranger.cpp
//詹宗運製作
//這是一個修改ANG_Prototype的範例,
//用來計算運動頻道節目組合問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2017 , 版本:20180322新版

#include "arrays.h"

//用來運算的結構,可以想成是一疊計算紙

typedef struct a4element
{
int identity;
int a_content[3];
} A4element;

//儲存時間名稱的結構
struct time_slot
{
int id;
const char* name;
};



//儲存節目名稱的結構
struct show_slot
{
int id;
const char* name;
};

#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

//#include <ostream>//fopen

#include <stdlib.h>//calloc
#include <iostream>//cout
using namespace std;
#include <iomanip>//setw()
//
//
//#include <fstream>//fopen
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string



//這裡是改數字的主要區域
//可以透過改變數字來計算更多的排列組合

#define MAXQUEEN 6     //定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 720   //SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 7    //ARRAYSIZE1 = MAXQUEEN+1
#define SLOTNUMBER 10  //一共有10個欄位


//以上是改數字的主要區域
//可以透過改變數字來計算更多的排列組合

using namespace std;
int queen[MAXQUEEN];   //存放8個皇后之列位置
int number = 0;          //計算總共有幾組解的總數

//決定皇后存放的位置

//輸出所需要的結果

#include "arrays.h"
UnorderedArray<int> array01(4);

//新增這一行
//定義每次顯示系統要間隔多少毫秒

int DELAYTIME;//暫停多少毫秒

int SNum[SOLUTION][MAXQUEEN];   //SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN]; //SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];    //buf = bufferNumber

int remain;   //remain = remain number
int calculate(int, int);

#pragma runtime_checks("", off)

void print_table()
{

//遞迴運算式,建議不要更改參數
int x = 0, y = 0;
number += 1;

remain = SOLUTION - number;

cout << "自動產生" << MAXQUEEN << "個號碼組合的第" << setw(7) << number;
cout << "組號碼,進度為剩下" << remain << "組尚未處理。" << endl << "\t";
system("CLS");

int k = 0;
for (x = 0; x<MAXQUEEN; x++)
{
for (y = 0; y<MAXQUEEN; y++)
if (x == queen[y])
{
k = y + 1;
array01.push(k);
}
}
}


//遞迴運算式,建議不要更改參數
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

void decide_position(int value)
{
int i = 0;// i=行
while (i<MAXQUEEN)
{
//是否受到攻擊的判斷式
if (calculate(i, value) != TRUE)
{
queen[value] = i;//只有在未受攻擊時將計算值存入皇后陣列
if (value == MAXQUEEN - 1)//列已到末端
print_table();//只有在未受攻擊時列已到末端時才印出結果
else
decide_position(value + 1);

//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)
}
//受攻擊時值不能存入陣列
i++;//不論是否遭受攻擊都換行重新執行函數 i=行
}
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++

//遞迴運算式,建議不要更改參數
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

int calculate(int row, int col)
{

int i = 0, flag = FALSE;
//int offset_row=0,offset_col=0;//此行跳過不用

while ((flag != TRUE) && i<col)//當未遭受攻擊與i計算值小於VALUE
{

//offset_col=abs(i-col);//此行跳過不用
//offset_row=abs(queen[i]-row);//此行跳過不用
//判斷兩皇后是否在同一列在同一對角線上
//if((queen[i]==row)||(offset_row==offset_col))//此行跳過不用
if ((queen[i] == row))//
flag = TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
i++;//逐行檢查
}
return flag;
}

#pragma runtime_checks("", off)

//選擇播放速度

int speedswitch()

{
char b;
while (1)
{
system("CLS");
cout << "請按下數字鍵,選擇播放速度:" << endl;
cout << "1.慢速  2.快速  0.繼續  請選擇(0-2):";
cin.get(b);

switch (b)
{
case '1':
cout << endl;
cout << "已選擇慢速播放。" << endl;
return 1500;
break;

case '2':
cout << endl;
cout << "已選擇快速播放。" << endl;
return 10;
break;

case '0':
goto Here;

}
}
Here:

return 10;
}





#pragma runtime_checks("", off)



//主程式

void construct_A4element() {

//定義結構名稱

time_slot t_slot[SLOTNUMBER - 1];
for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
t_slot[i].id = i;
}

t_slot[0].name = "上午八點";
t_slot[1].name = "上午十點";
t_slot[2].name = "下午一點";
t_slot[3].name = "下午三點";
t_slot[4].name = "下午五點";
t_slot[5].name = "晚上八點";
t_slot[6].name = "晚上十點";
t_slot[7].name = "凌晨十二點";
t_slot[8].name = "凌晨兩點";
// t_slot[9].name = "凌晨四點";

show_slot s_slot[SLOTNUMBER - 1];

for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
s_slot[i].id = i;
}

s_slot[0].name = "大聯盟棒球";
s_slot[1].name = "台灣職棒";
s_slot[2].name = "美國職籃NBA";
s_slot[3].name = "高爾夫球";
s_slot[4].name = "女子體操";
s_slot[5].name = "F1賽車";
s_slot[6].name = "歐洲足球";
s_slot[7].name = "日本職棒";
s_slot[8].name = "職業摔角";
// s_slot[9].name = "溫布頓網球";



//開始遞迴運算
int f = 0;
int g = 0;
int h = 0;

remain = 0;

A4element *a = (A4element*)calloc(SOLUTION, sizeof(A4element));

while (f<SOLUTION)
{

while (g<(ARRAYSIZE1 - 1))
{

a->identity = f;
a->a_content[g] = array01[h];

//cout<<"目前核對a["<<f<<"]->a_content["<<\
//g<<"]="<<(a->a_content[g])<<endl;//顯示內容

SNum[f][g] = array01[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch (SNum[f][g])
{
case 10:
SChar[f][g] = '0';
break;

case 1:
SChar[f][g] = '1';
break;

case 2:
SChar[f][g] = '2';
break;

case 3:
SChar[f][g] = '3';
break;

case 4:
SChar[f][g] = '4';
break;

case 5:
SChar[f][g] = '5';
break;

case 6:
SChar[f][g] = '6';
break;

case 7:
SChar[f][g] = '7';
break;

case 8:
SChar[f][g] = '8';
break;

case 9:
SChar[f][g] = '9';
break;

}
buf[h] = SChar[f][g];

h++;
g++;
}
g = 0;
f++;
remain = SOLUTION - f;
cout << "核對資料結構還剩下" << remain << "組。" << endl;
system("CLS");

}
cout << "計算完成" << endl;

//----------------------------------------------------------------------------
//string str(SOLUTION*MAXQUEEN,' ');

cout << "號碼產生的數量是 " << h << "個。" << endl;
cout << "接下來你可以按下數字鍵加上ENTER鍵選擇播放速度," << endl;
cout << "自動號碼產生器已經計算完成。請按下按鍵顯示結果。" << endl;
system("pause");

//--------------------------------------------------------
//切換速度

DELAYTIME = speedswitch();//切換速度


    //-------------make SNum----------------------------------
    //cout<<"計算SNum當中"<<endl;

int m = 0;
int n = 0;
int p = 0;

remain = 0;

while (m<SOLUTION)
{

while (n<MAXQUEEN)
{

a->identity = m;
a->a_content[n] = array01[p];

SNum[m][n] = a->a_content[n];

p++;
n++;

}
n = 0;

//---遞迴顯示自動號碼----
system("CLS");
cout << "" << "運動頻道節目排列組合產生器" << ":" << endl;
cout << "第" << (m + 1) << "組" << "運動頻道節目組合" << "是:  首先," << endl;

for (int i2 = 0; i2<MAXQUEEN; i2++) {
cout << t_slot[i2].name;
cout << "的時候收看" << s_slot[SNum[m][i2] - 1].name;
cout << "。" << endl;
}
cout << "就收看完了全部節目。" << endl;

//-----------------------
m++;
remain = SOLUTION - m;

cout << "以上是" << "運動頻道節目";
cout << "的第" << m << "組的組合,剩下" << remain << "組。" << endl;

Sleep(DELAYTIME);
}

cout << "以上是" << "運動頻道節目排列組合產生器" << "實作," << endl;

//取消了輸出檔案的功能

cout << "array的型態 = " << typeid(array01).name() << endl;
cout << "感謝Allen Sherrod的資料結構教科書,僅此致謝。" << endl;
cout << "Auto Number Generator: Visual C++ 2017版," << endl;
cout << "詹宗運製作," << endl;
cout << "免費授權Microsoft公司進行進一步的修改與工業化," << endl;
cout << "用來攤平記憶體缺損所造成的工業損失," << endl;
cout << "並且提供VC++社群做為討論與修改的使用。" << endl;

system("pause");

//將共用變數進行釋放與歸零
// free(a);
memset(&a, NULL, sizeof(&a));
a = NULL;
free(a);

memset(&SNum, NULL, sizeof(&SNum));
for (int i = 0; i<SOLUTION; i++)
{

for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{

SNum[i][j] = NULL;

}
}

//delete *SNum;   //不刪除變數可以避免return引起的問題

memset(&SChar, NULL, sizeof(&SChar));

for (int i = 0; i<SOLUTION; i++)
{
for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{
SChar[i][j] = NULL;
}
}

//delete *SChar;   //不刪除變數可以避免return引起的問題

f = NULL;
g = NULL;
h = NULL;
remain = NULL;
m = NULL;
n = NULL;
p = NULL;

// delete t_slot;    //不刪除變數可以避免return引起的問題
// delete s_slot;



//直接結束關閉,此技術可以避免return引起的問題。
//exit(1);     //有需要時可以使用這一行程式碼。

//return;     //取消可以避免return引起的問題。

}

#pragma runtime_checks("", off)

//顯示起始畫面訊息
void startmessage() {

cout << "自動號碼生成器應用:" << endl;
cout << "運動頻道節目排列組合產生器," << endl;
cout << "詹宗運製作。" << endl;
cout << "接下來會自動運算出許多訊息,";
cout << "請耐心等待訊息停止以後," << endl;
cout << "再按下按鍵繼續運算。" << endl;
cout << "運算好以後你可以按下數字鍵加上ENTER鍵選擇播放速度," << endl;
cout << "然後收看排列組合的顯示結果。" << endl;
cout << endl;

cout << "開始運算,請準備。" << endl;
system("pause");
system("CLS");
// cout<<"\t";

}


//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
const char* module, const char* format, ...)
{

// 1. Prevent re-entrance
static long IsRunning = 0;
while (InterlockedExchange(&IsRunning, 1))
Sleep(1);

// 2. Get the RTC error number from the var_arg list
va_list ArgList;
va_start(ArgList, format);
_RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
va_end(ArgList);

char s[1024];
// 3. Get the error description
const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
        \nFile: %s\nModule:\
        %s\nClick OK to break into debugger.", \
ErrorDesc, line, file ? file : \
"Unknown", module ? module : "Unknown");

// 4. Display message box
MessageBoxA(NULL, s, "Run-Time Error", MB_OK);

// 5. Go ahead and break into the debugger

return 1;
}

#pragma runtime_checks("", restore)



int _tmain(int argc, _TCHAR* argv[])
{

//關掉.NET錯誤
_RTC_error_fn OldHandler;

// Set new RTC error handler and save the old one
OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);

//顯示起始畫面訊息
startmessage();

//主程式
decide_position(0);

//主程式
construct_A4element();

//恢復.NET運作
_RTC_SetErrorFunc(OldHandler);

//直接結束關閉,此技術可以避免return引起的問題。
exit(1);

return EXIT_SUCCESS;     //出現了return可能會引起debugger中斷的問題

}


//------------檔案到此為止
//--------------------------------------------------------









//第二個版本: 適用於Visual C++ 2005 與 Windows XP
// Channel_Arranger.cpp : 定義主控台應用程式的進入點。
//
//
//

#include "stdafx.h"

//Auto Number Generator Electronic List (ANGEL程式)範例
//Channel_Arranger.cpp
//詹宗運製作
//這是一個修改ANG_Prototype的範例,
//用來計算運動頻道節目組合問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005 , 版本:20180315新版

#include "arrays.h"

//用來運算的結構,可以想成是一疊計算紙
typedef struct a4element
{
 int identity;
 int a_content[3];
} A4element;

//儲存時間名稱的結構
struct time_slot
{
 int id;
 const char* name;
};

//儲存節目名稱的結構
struct show_slot
{
 int id;
 const char* name;
};

#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

//#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
using namespace std;
#include <iomanip>//setw()
//
//


//#include <fstream>//fopen
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string



//這裡是改數字的主要區域
//可以透過改變數字來計算更多的排列組合

#define MAXQUEEN 6     //定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 720   //SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 7    //ARRAYSIZE = MAXQUEEN+1

#define SLOTNUMBER 10  //一共有10個欄位

using namespace std;
int queen[MAXQUEEN];   //存放8個皇后之列位置
int number=0;          //計算總共有幾組解的總數
                       //決定皇后存放的位置
                       //輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);


//新增這一行
//定義每次顯示系統要間隔多少毫秒
int DELAYTIME;//暫停多少毫秒

int SNum[SOLUTION][MAXQUEEN];   //SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN]; //SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];    //buf = bufferNumber

int remain;   //remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)



void print_table()
{

  //遞迴運算式,建議不要更改參數
     int x=0,y=0;
     number+=1;


     remain = SOLUTION-number;

  cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"<<setw(7)<<number;
  cout<<"組號碼,進度為剩下"<<remain<<"組尚未處理。"<<endl<<"\t";
  system("CLS");


  int k=0;
  for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
     {
     k=y+1; 
      array.push(k);
     }

     }


}


//遞迴運算式,建議不要更改參數
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);
   //只有在未受攻擊時將計算值存入皇后陣列,
   //計算完成以後,列+1遞迴重新執行函數( value=列)
      }
   //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   } 
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++



//遞迴運算式,建議不要更改參數
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

int calculate(int row,int col)
{
    int i=0,flag=FALSE;
    //int offset_row=0,offset_col=0;
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
       //offset_col=abs(i-col);
       //offset_row=abs(queen[i]-row);
       //判斷兩皇后是否在同一列在同一對角線上
       //if((queen[i]==row)||(offset_row==offset_col))
       if((queen[i]==row))//

     flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
    //當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}



#pragma runtime_checks("", off)

//選擇播放速度

int speedswitch()
{
 char b;


 while(1)
 {
 system("CLS");
 cout<<"請按下數字鍵,選擇播放速度:"<<endl;
 cout<<"1.慢速  2.快速  0.繼續  請選擇(0-2):";
 cin.get(b);
 switch(b)
 {
 case '1':
  cout<<endl;
  cout<< "已選擇慢速播放。"<<endl;
  return 1500;
 break;

 case '2':
  cout<<endl;
  cout<< "已選擇快速播放。"<<endl;
  return 10;
 break;
 case '0':
  goto Here;

 }
 }

Here:
return 10;

}


#pragma runtime_checks("", off)

//主程式
void construct_A4element(){
//定義結構名稱
time_slot t_slot[SLOTNUMBER-1];

for(int i=0;i<(SLOTNUMBER-1);i++)
{
t_slot[i].id = i;
}

t_slot[0].name = "上午八點";
t_slot[1].name = "上午十點";
t_slot[2].name = "下午一點";
t_slot[3].name = "下午三點";
t_slot[4].name = "下午五點";
t_slot[5].name = "晚上八點";
t_slot[6].name = "晚上十點";
t_slot[7].name = "凌晨十二點";
t_slot[8].name = "凌晨兩點";
t_slot[9].name = "凌晨四點";

show_slot s_slot[SLOTNUMBER-1];

for(int i=0;i<(SLOTNUMBER-1);i++)
{
s_slot[i].id = i;
}
s_slot[0].name ="大聯盟棒球";
s_slot[1].name ="台灣職棒";
s_slot[2].name ="美國職籃NBA";
s_slot[3].name ="高爾夫球";
s_slot[4].name ="女子體操";
s_slot[5].name ="F1賽車";
s_slot[6].name ="歐洲足球";
s_slot[7].name ="日本職棒";
s_slot[8].name ="職業摔角";
s_slot[9].name ="溫布頓網球";

//開始遞迴運算
 int f=0;
 int g=0;
 int h=0;

 remain=0;


 A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

 while(f<SOLUTION)
 {


 while(g<(ARRAYSIZE-1))
 {
  a->identity=f;
  a->a_content[g]=array[h];

  //cout<<"目前核對a["<<f<<"]->a_content["<<\
  //g<<"]="<<(a->a_content[g])<<endl;//顯示內容

  SNum[f][g]=array[h];

  //如果要超過10階乘就要加大下面這個switch case敘述
  switch(SNum[f][g])
  {
  case 10:
   SChar[f][g]='0';
 
   break;
  case 1:
   SChar[f][g]='1';
   break;
  case 2:
   SChar[f][g]='2';
   break;
  case 3:
   SChar[f][g]='3';
   break;
  case 4:
   SChar[f][g]='4';
   break;
  case 5:
   SChar[f][g]='5';
   break;
  case 6:
   SChar[f][g]='6';
   break;
  case 7:
   SChar[f][g]='7';
   break;
  case 8: 
   SChar[f][g]='8';
   break;
  case 9:
   SChar[f][g]='9';
   break;

  }


  buf[h]=SChar[f][g];

  h++;
  g++;
 }
 g=0;
 f++;
 remain=SOLUTION - f;
  cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;
  system("CLS");


 }

 cout<<"計算完成"<<endl;

//----------------------------------------------------------------------------

 //string str(SOLUTION*MAXQUEEN,' ');

 cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;
 cout<<"接下來你可以按下數字鍵加上ENTER鍵選擇播放速度,"<<endl;
 cout<<"自動號碼產生器已經計算完成。請按下按鍵顯示結果。"<<endl;
 system("pause");


//--------------------------------------------------------

 //切換速度
 DELAYTIME = speedswitch();//切換速度



 //-------------make SNum----------------------------------

 //cout<<"計算SNum當中"<<endl;
 int m=0;
 int n=0;
 int p=0;
    remain=0;

 while(m<SOLUTION)
 {
 while(n<MAXQUEEN)
 {
  a->identity=m;
  a->a_content[n]=array[p];



  SNum[m][n]=a->a_content[n];




  p++;

  n++;
 }
 n=0;
 //---遞迴顯示自動號碼----

 system("CLS");
 cout<<""<<"運動頻道節目排列組合產生器"<<":"<<endl;
 cout<<"第"<<(m+1)<<"組"<<"運動頻道節目組合"<<"是:  首先,"<<endl;
 for(int i2=0;i2<MAXQUEEN;i2++){
  cout<<t_slot[i2].name;
  cout<<"的時候收看"<<s_slot[SNum[m][i2]-1].name;
  cout<<"。"<<endl;}

 cout<<"就收看完了全部節目。"<<endl;
 //-----------------------
 m++;
 remain=SOLUTION-m;

 cout<<"以上是"<<"運動頻道節目";
 cout<<"的第"<<m<<"組的組合,剩下"<<remain<<"組。"<<endl;

 Sleep(DELAYTIME);
 }

 cout<<"以上是"<<"運動頻道節目排列組合產生器"<<"實作,"<<endl;



//取消了輸出檔案的功能

 cout<<"array的型態 = "<<typeid(array).name()<<endl;
 cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
 cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
 cout<<"詹宗運製作,"<<endl;
 cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
 cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
 cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
 system("pause");


 //將共用變數進行釋放與歸零
// free(a);
memset(&a,NULL, sizeof(&a));
a = NULL;
delete a;
memset(&SNum,NULL, sizeof(&SNum));
for(int i = 0; i<SOLUTION;i++)
{
for(int j = 0; j < (ARRAYSIZE-1); j++)
{
      SNum[i][j] = NULL;

}
}

//delete *SNum;   //不刪除變數可以避免return引起的問題

memset(&SChar,NULL, sizeof(&SChar));

for(int i = 0; i<SOLUTION;i++)
{
for(int j = 0; j < (ARRAYSIZE-1); j++)
{
      SChar[i][j] = NULL;

}
}


//delete *SChar;   //不刪除變數可以避免return引起的問題


 f=NULL;
 g=NULL;
 h=NULL;
 remain=NULL;
 m=NULL;
 n=NULL;
 p=NULL;



// delete t_slot;    //不刪除變數可以避免return引起的問題
// delete s_slot;

 //直接結束關閉,此技術可以避免return引起的問題。
exit(1);

return;

}

#pragma runtime_checks("", off)

//顯示起始畫面訊息
void startmessage(){

 cout<<"自動號碼生成器應用:"<<endl;
 cout<<"運動頻道節目排列組合產生器,"<<endl;
 cout<<"詹宗運製作。"<<endl;
 cout<<"接下來會自動運算出許多訊息,";
 cout<<"請耐心等待訊息停止以後,"<<endl;
 cout<<"再按下按鍵繼續運算。"<<endl;
 cout<<"運算好以後你可以按下數字鍵加上ENTER鍵選擇播放速度,"<<endl;
 cout<<"然後收看排列組合的顯示結果。"<<endl;
 cout<<endl;

 cout<<"開始運算,請準備。"<<endl;
 system("pause");
 system("CLS");
// cout<<"\t";

}



//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
    const char* module, const char* format, ...)
{


// 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
 // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
   sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
  \nFile: %s\nModule:\
  %s\nClick OK to break into debugger.", \
  ErrorDesc, line, file ? file : \
  "Unknown",    module ? module : "Unknown");
 
 // 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger

return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{



 //關掉.NET錯誤
 _RTC_error_fn OldHandler;
    // Set new RTC error handler and save the old one
 OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);

 //顯示起始畫面訊息
 startmessage();

 //主程式
 decide_position(0);
 //主程式
 construct_A4element();

 //恢復.NET運作
 _RTC_SetErrorFunc(OldHandler);

 //直接結束關閉,此技術可以避免return引起的問題。
  exit(1);



  return 1;     //出現了return可能會引起debugger中斷的問題
}

//------------檔案到此為止
//--------------------------------------------------------









//--------------------------------------------------------
//------------以下是arrays.h程式碼
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//------------檔案到此為止



//------------以下是stdafx.h程式碼
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once


#define WIN32_LEAN_AND_MEAN
// 從 Windows 標頭排除不常使用的成員
#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭

//------------檔案到此為止