2021年7月5日 星期一

多機率分佈

 這個小程式方便產生不同機率分佈的亂數,建構函數接受 vector<double> 含陣列各位置的機率分佈權值,實際運作時會傳回命中的陣列的索引

#include <chrono>
#include <random>
#include <iostream>
#include <vector>

using namespace std;

// 多機率分佈
class Multi_probability_distribution
{  
  size_t Max;
  vector<double> m_Probability_accumulation;
public:
  // Constructor
  Multi_probability_distribution(const vector<double> &Probability_distribution)
    :Max(Probability_distribution.size()-1),
    m_Probability_accumulation(Probability_distribution.size())
  {
    m_Probability_accumulation[0] = Probability_distribution[0];
    for (size_t i = 1; i <= Max; ++i)
      m_Probability_accumulation[i] = m_Probability_accumulation[i - 1] +
      Probability_distribution[i];

    double Max_v = m_Probability_accumulation[Max];

    for (double& v : m_Probability_accumulation)
      v /= Max_v;
  }

  size_t operator()()
  {
    static minstd_rand0 Generator((unsigned)
      chrono::system_clock::now().time_since_epoch().count());
    static uniform_real_distribution<double> Distribution(0.0, 1.0);
    double number = Distribution(Generator);

    size_t Start = 0, End = Max;

    // 二分搜尋加快速度
    while (Start != End)
    {
      size_t Sel = (Start + End)/2;
      if (number < m_Probability_accumulation[Sel])
        End = Sel;
      else
        Start = Sel + 1;
    }

    return Start;
  }
};

int main()
{
  vector<double> pd{1,3,5}; // 期望陣列各位置的機率分佈權值
  vector<size_t> Score(pd.size(),0); // 累記實際亂數產生所處位置

  Multi_probability_distribution MPD(pd);

  for (int i = 0; i < 100; ++i)
    ++Score[MPD()];

  for (int i = 0; i < Score.size(); ++i)
    cout << "[" << i << "] = " << Score[i] << endl;

}







2021年7月3日 星期六

UnassocWin10 解除檔案關聯

這個程式只能用於 Win10,若要用於 Win7,可上網找一套 unassoc 1.4。

我這程式主要參考 删除Windows10后缀名关联程序.cpp ,其實那個程式已經足夠輕巧好用了。我寫的須要包裹一堆程式庫,有點大包。

我寫這程式的目的為了保留和測試一些技術。

原始檔案包,須用最新版 CxxlMan2 先建構好開發環境
Unassociate_File_Types_1.0.0_Src.7z

64位元版完整檔案包,可直接執行 UnassocWin10.exe
UnassocWin10.7z

另外程式支援多國語言,但能力有限只提供繁中語言檔,其他的語言會用內建的英語顯示,若有人願意轉譯他國語言,可到 MLedit 多國語言編輯器  下載工具,這 UnassocWin10 的多國誩言檔放在 Lang 資料夾中。




2021年7月2日 星期五

取得 Windows 的版本

 在這找到好辦法 C++ How to detect Windows 10 - Stack Overflow ,保留一份

#include <iostream>
#include <windows.h>

using namespace std;

// 回報 Windows 的版本 (7, 8, 8.1, 10)
double getSysOpType()
{
    double ret = 0.0;
    NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
    OSVERSIONINFOEXW osInfo;

    *(FARPROC*)&RtlGetVersion = 
      GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");

    if (NULL != RtlGetVersion)
    {
        osInfo.dwOSVersionInfoSize = sizeof(osInfo);
        RtlGetVersion(&osInfo);
        ret = (double)osInfo.dwMajorVersion;
    }
    return ret;
}

int main()
{
    cout << getSysOpType() << endl;
    return 0;
}





2021年6月30日 星期三

正則表達式檢測

編輯 C++ 正則表達式須要不斷嘗式,網路上找到一個簡單的程式碼(一時找不到在哪看到)蠻不錯的,留一份在這

#include <iostream>
#include <regex>

using namespace std;

int main()
{

  // regex reg("[\\.]|[\\b]+$");
  //regex reg("([.]*)([\\.]+)([.]*)");

  //regex reg(".*(\\.+).*");
  //regex reg(".*(\\s$)");
  //regex reg(".*(\\.+).*|.*(\\s$)");
  //regex reg("[\\s]+");
  regex reg("Applications\\\\.+_\\.bbbbb");

  string input;

  smatch sm;

  while(true)
  {
    cout << "Enter: ";
    getline(cin, input);
    if(input == "quit")
      break;

    if( regex_match(input, sm , reg) )
    {
      cout << "Match!" << endl;
      for( unsigned int i = 0 ; i < sm.size() ; ++i )
      {
        cout << i << ": [" << sm[i] << ']' << endl;
      }

    }
    else
    {
      cout << "Not Match!" << endl;
    }
  }

    return 0;
}

2021年3月18日 星期四

把 GLAD 編譯成 dll

因 LearnOpenGL 採用 GLAD 來抓取 OpenGL API,所以也研究了一下,GLAD 的好處是可以明確指定你開發程式所要支援的 OpenGL 版本,在初始化時可以檢查顯示卡是否能支援。

GLAD 可到 https://glad.dav1d.de 下載,但拿到的會是原始檔,因 GLAD 只是把 OpenGL API 的函數位址抓出來存放到程式可觸及的記憶體空間中,若採用把 glad.c 和你的專案一起編譯,則主程式(exe) 和各用到 OpenGL API 的 dll 都得把 glad.c 一起編譯,並各別呼叫 gladLoadGL() 做初始化,既浪費空問(因得各別保存 OpenGL API 的函數位址)又沒人性(因得各別 gladLoadGL() 初始化)。

我想最完美的做法是把 GLAD 編譯成 dll,這樣 GLAD 的 OpenGL API 函數位址就放在這個 dll 獨立空間中,而 gladLoadGL() 只要由主程式呼叫一次就可以了。