【數學|算法】康託展開(Cantor expansion)及逆康託展開

2021-03-01 A91A981E
康託展開(Cantor expansion)及逆康託展開
康託展開康託展開的定義

康託展開是一個全排列到一個自然數的雙射,常用於構建哈希表時的空間壓縮。康託展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。

應用方面:求集合全排列中某一狀態的字典序

例如,給定集合Set={1,2,3}, 需要求排列213的字典序大小。易得,在Set的全排列中, 有123、132兩個排列小於213的字典序,所以213的康託展開值是2,序號為3。

排列排列康託展開值123
1
0*2!+0*1!+0*0!
132
2
0*2!+1*1!+0*0!213
31*2!+0*1!+0*0!231
4
1*2!+1*1!+0*0!31252*2!+0*1!+0*0!321
62*2!+1*1!+0*0!
計算公式

 其中,ai 為第 i 位後的 i-1 位比第 i 位小的個數(i 為從右往左)。


舉例說明

已知Set={1,2,3,4,5}, 求n==34152在Set全排列從小到大排序後在第幾位。

在34152 中,不論從左向右還是從右向左開始建立(不是 i 的順序,i 都是從右向左),我們都可以得到以下這張表。

從左向右為例解釋:

n5=3,在後面4位中,有1 和2小於n5,於是a5=2

n4=4,在後面3位中,有1和2小於n4,於是a4=2

n3=1,在後面2位中,沒有數小於n3,於是a3=0

n2=5,在後面1位中,有2小於n2,於是a2=1

n1=2,在後面0位中,沒有數小於n1,於是a1=0

根據公式可得:

所以34152前面的排列共有61個,結果就是61+1=62。

C/C++語言實現代碼
#include <bits/stdc++.h>using namespace std;
int cantor(int n){ const int factorial[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; stringstream ss; ss << n; string s = ss.str(); int num = s.length(), x = 0, temp; for (int i = 0; i < num; i++) { temp = 0; for (int j = i + 1; j < num; j++) if (s[i] > s[j]) temp++; x += temp * factorial[num - i - 1]; } return x + 1;}
int main(int argc, char *argv[]){ int n;
cin >> n; cout << cantor(n) << endl;
return 0;}

逆康託展開

  逆康託展開只需要將康託展開的過程反過來即可,將序號減一後,依次對階乘作商取餘。代碼如下:

#include <bits/stdc++.h>using namespace std;
int decantor(int n, vector<int> v){ const int factorial[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; int num = v.size(); stringstream ss; n--; for (int i = 0; i < num; i++) { int temp = n / factorial[num - i - 1]; n %= factorial[num - 1 - i]; ss << v[temp]; v.erase(v.begin() + temp); } return atoi(ss.str().c_str());}
int main(int argc, char *argv[]){ int n, temp; vector<int> vec; vec.clear();
cout << "input index: "; cin >> n; cout << "input set, end with -1:" << endl; while (cin >> temp, temp != -1) vec.push_back(temp); sort(vec.begin(), vec.end());
cout << decantor(n, vec) << endl; return 0;}

如有錯誤還請指出。

相關焦點

  • 字節尿性,康託展開求第K個排列!
    從數學方法說起,先講一下康託展開。那康託展開是幹嘛的?用來計算當前排列在所有由小到大全排列中的順序。臥槽,不就是本題嗎。聽不懂?就是說如果你知道 1234 是序號 1,1243 是 序號2,這個公式就可以直接告訴你 4132 的序號是多少!
  • 集合論創始人康託
    康託創立了驚世駭俗的超窮數理論掀起起了數學與哲學史上一場深刻的革命。          對於康託來說無窮是實在的,他們可以不同,可以比較大小,可以進行數學運算,甚至可以對其進行超窮歸納等等。          無窮,可以比較大小,比如說,有理數,有無窮多個,整數也有無窮多個,這兩個無窮多是相等的。
  • 【數學】泰勒展開,到底展開到幾次方
    最近,在答疑的過程中,小哥哥經常看到這種關於泰勒展開的問題。大多是同學們都不太清楚該展開到幾次方。
  • 一分鐘數學—— sin x 的泰勒展開
    今天給大家講的 sin x 的泰勒展開,可能會給大家帶來對三角函數不同的印象吧。sin x 的泰勒展開也需要大家對 「 無窮 」 有一定的了解,會用到以前沒有講過的 「 微分 」,所以大家不要害怕 「 複雜  」 的符號哦。
  • 揭秘定製衣櫃的「算法」:按「投影面積」還是「展開面積」
    這是幾種不同的算法,再綜合紛繁不一的板材,所產生的最終價格也各不相同。有時,一個折扣價算出的總價甚至可能超過原價所計。而記者在走訪時發現,商家們並不會主動告訴你以何種方法計算,不少消費者也難以弄清這其中的變化。「投影面積」還是「展開面積」?
  • 【立體展開】圓柱的側面展開圖
    昨天的圓錐側面展開圖應該是比圓柱的展開圖要難一些,圓柱展開之後就是個矩形,製作上其實更簡單。首先我們先了解下圓柱的側面的曲面方程。
  • 牛頓的數學成就——廣義二項式展開(牛頓推導過程)
    在數學方面,牛頓「明顯地推進了當時數學的每一個分支」,但他最著名的兩項發現是廣義二項式展開和微積分。圖1:左邊是牛頓46歲時的肖像,出自17世紀末18世紀初英國著名肖像畫家戈弗雷·克奈爾之手。在這篇文章中,我將重點介紹牛頓早期的數學成就。我將描述他對廣義二項式展開的推導,以及他如何應用它來得到正弦函數的冪級數展開。德裡克·懷特塞德(Derek Whiteside)被認為是「同時代最重要的數學史學家」,據他說,這是正弦(和餘弦)的冪級數首次在歐洲出現。
  • 【立體展開】圓錐的側面展開圖
    圓錐的側面展開圖的案例應該是很多老師想做,但是卻沒有頭緒的案例。其實這個案例並不是特別困難,關鍵的就是我們要知道圓錐的曲面方程。
  • 小學數學知識點每日推薦1:正方體的展開圖
    本系列內容將會涵蓋小學數學所有知識點,編寫時言簡意賅、詳略得當,緊扣考點、通俗易懂,是小學數學基礎學習、鞏固提高、期末複習的好助手!每日推薦,每天進步,輕鬆學習,歡迎關注!2、以下情況不可能是正方體展開圖(1)一條線上不過四是指在正方體展開圖中,一條直線上的小正方形不會超過四個。
  • 等價無窮小與泰勒展開式
    直接計算幾乎沒辦法,但我們只要知道sinx~x,關注數學佬公眾號的朋友或許還記得,我們在測量恆星距離的時候,就用x代替sinx進行計算。        那麼,         直到……我看見了這個公式:泰勒展開式。        超級門:我以前寫過的泰勒展開式的有趣小蚊子。        泰勒展開式        關於泰勒展開的段子        給泰勒擦屁股的數學家
  • 【初中數學教案】《圓錐的側面展開圖》
    《圓錐的側面展開圖》教學設計 一.教學目標1、知識與技能:了解圓錐的側面、底面、高、軸、母線、過軸的截面等概念,了解圓錐的側面展開圖是扇形:使學生會計算圓錐的側面積或表面積.2、數學思考:學生在老師的引導下進行自主探索、合作交流,收穫新知;通過分組訓練、深化新知,共同感受收穫的喜悅。3、情感態度:通過對圓錐側面展開圖的自主探究,讓學生獲得親自參與研究探索的情感體驗,通過與人合作、交流和解決問題的 過程,讓學生更多的展示自己,建立自信,樹立正確的價值觀。
  • 泰勒展開式
    泰勒展開式曾經數學佬寫過一篇泰勒展開式的推文,回頭看看真是簡單透了
  • 2020初三數學複習:幾何體的側面展開圖,神秘數學變得如此簡單
    #初中數學學習01閱讀說明因網頁不支持數學公式,所有試題請以圖片為準。本人是一名數學教師,也是一名公益志願者。分析:根據正方體的表面展開圖進行分析解答即可.解答:解:根據正方體的表面展開圖,兩條黑線在一列,故A錯誤,且兩條相鄰成直角,故B錯誤,中間相隔一個正方形,故C錯誤,只有D選項符合條件,故選D。點評:本題主要考查了幾何體的展開圖,注意正方體的空間圖形,從相對面入手,分析及解答問題.
  • 部分等於整體,說無窮,道無窮,無窮世界的封印,康託的悲鳴
    為了把握和認知無窮的集合,康託創造性地將一一對應和對角線方法運用到集合論的奠基性研究當中。康託極其深刻地意識到:如果兩個無窮集合的元素能建立一一對應,那麼這兩個無窮集合的個數就應該被視為同樣多。在這種思想下,康託很快就發現偶數的個數和自然數的個數一樣多,甚至和整數的個數也一樣多。換句話說,偶數的個數所組成的無窮和整數的個數所組成的無窮是一樣大!
  • 正八面體的展開圖(匯總)
    點擊上面「邵勇」後面的籃色字「數學教學研究」,訂閱本微信公眾號。每周推送兩到三篇數學趣文。
  • 【基礎數學知識】帶你理解泰勒展開式本質?
    推薦閱讀時間:5min~8min主要內容:更好的理解,並且記憶泰勒展開式我們學習泰勒展開,本質上就是為了在某個點附近
  • 小升初數學最難的13種典型題:正方體展開圖
    為了幫助大家更好的小升初,小編為大家分享下關於小升初數學難題的匯總,快來練習一下吧!希望可以幫助到你們。>>點擊查看匯總篇 一、正方體展開圖   正方體有6個面,12條稜,當沿著某稜將正方體剪開,可以得到正方體的展開圖形,很顯然,正方體的展開圖形不是唯一的,但也不是無限的。
  • 投影面積和展開面積哪個划算?
    定製柜子的價格並不像成品家具一樣明碼標價,一般有兩種算法,一個按投影面積算,還有一個是按展開面積算,到底哪個更划算呢?說心裡話,投影面積計價比展開面積計價明顯簡單很多。投影面積計算就是衣櫃立在牆上外形的寬度乘以高度就是衣櫃的投影面積,也就是按照衣櫃的長度*高度(以米為單位),然後再乘以單價和係數(投影影面積價格一般等於展開面積x(3到4的係數),三秒出價格!
  • 他的瘋狂,卻意外奠定了現代數學的基石
    原本是康託的好友,數學家施瓦茲(Swartz),甚至由於反對集合論而同康託斷交。在所有反對康託的數學家中,最激烈的莫過於他的導師克羅內克。因此克羅內克將康託的結果看成是危險的數學存在。克羅內克不能容忍數學被康託帶領進入瘋人院,他狂熱地認定自己堅持的真理才是數學的正道,因此動用他所有的權勢開始對康託展開反攻。康託論文的稿件被他長期壓制扣發,他在公開場合批判康託是神經病,是科學的騙子和叛徒,其思想不啻為"近十年來最具獸性的見解"。
  • 長方體和正方體的展開圖
    把長方體和正方體沿著稜剪開,就可以得到它的展開圖。剪的方法不同,就會得到不同的展開圖,下面分別是長方體和正方體的展開圖。