2018年3月31日 星期六

Re: 計算組合的程式碼 (2)(水果盤排列程式)

// 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: 計算組合的程式碼(1)


// 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: 在此參考您的程式所需要的其他標頭

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