格雷码:
格雷码是指,通过0-1的串来求出对应位数的所有可能。例如2的格雷码:00、01、10、11
//格雷码 例如2:00 01 10 11
void print(vector<int> &veNum)
{
for (int i = 1; i < veNum.size(); ++i)
cout << veNum[i] << " ";
cout << endl;
}
void printallnum(int iNum)
{
if (iNum <= 0)
return;
vector<int> veNum(iNum + 1);
int ipos = iNum;
while (true)
{
ipos = iNum;
while (ipos > 0 && veNum[ipos] == 1) veNum[ipos--] = 0;
if (ipos == 0)
break;
else
veNum[ipos] = 1;
print(veNum);
}
}
int main()
{
int iNum = 0;
cin >> iNum;
printallnum(iNum);
return 0;
}
求n个元素的所有可能的组合:
给定n个元素,求着n个元素的所有可能,也就是他的所有子集。这可以看成是格雷码问题的一种变形问题:
//所有可能的集合 12-> 1 2 12 格雷码的变形
void print(vector<int> &veNum, int ar[], int iLen)
{
for (int i = 1; i < veNum.size(); ++i)
{
if (veNum[i])
cout << ar[i - 1];
}
cout << endl;
}
void allprint(int ar[], int iLen)
{
if (ar == NULL || iLen <= 0)
return;
vector<int> veNum(iLen + 1);
while (true)
{
int iPos = iLen;
while (iPos > 0 && veNum[iPos] == 1) veNum[iPos--] = 0;
if (iPos == 0)
return;
else
veNum[iPos] = 1;
print(veNum, ar, iLen);
}
}
int main()
{
int ar[] = { 1, 2, 3, 4 };
int iLen = sizeof(ar) / sizeof(ar[0]);
allprint(ar, iLen);
return 0;
}
m个元素中求n个元素的所有集合:
求m个元素的集合中,任意n个元素对应的所有集合。
void allprint(int iAllLen, int n)
{
if (iAllLen < n)
return;
else if (iAllLen == n)
{
for (int i = 0; i < n; ++i)
cout << i+1;
cout << endl;
}
else
{
vector<int> veNum(iAllLen + 1);
for (int i = 0; i <= iAllLen; ++i) veNum[i] = i;
//打印初始值
for (int i = 1; i <= n; ++i)
cout << veNum[i];
cout << endl;
int iposition = n ;
while (1)
{
if (veNum[n] == iAllLen)
iposition--;
else
iposition = n;
veNum[iposition]++;
for (int i = iposition + 1; i <= n; ++i)
veNum[i] = veNum[i - 1] + 1;
for (int i = 1; i <= n; ++i)
cout << veNum[i];
cout << endl;
if (veNum[1] >= iAllLen - n + 1)
break;
}
}
}
int main()
{
int iAllLen = 6;
int n = 4;
allprint(iAllLen, n);
return 0;
}
上边的求解是假设初始的m的集合是从1开始并且顺序增加的数字。如果是任意的数组集合,可以根据求出的数字来确定对应的下标进行求解该问题。
//m个元素中n个元素的所有集合 改问题的变形 详情参考该问题
void allprint(int ar[], int iAllLen, int n)
{
if (iAllLen < n)
return;
else if (iAllLen == n)
{
for (int i = 0; i < n; ++i)
cout << ar[i];
cout << endl;
}
else
{
vector<int> veNum(iAllLen + 1);
for (int i = 0; i <= iAllLen; ++i) veNum[i] = i;
//打印初始值
for (int i = 1; i <= n; ++i)
cout << ar[veNum[i] - 1];
cout << endl;
int iposition = n;
while (1)
{
if (veNum[n] == iAllLen)
iposition--;
else
iposition = n;
veNum[iposition]++;
for (int i = iposition + 1; i <= n; ++i)
veNum[i] = veNum[i - 1] + 1;
for (int i = 1; i <= n; ++i)
cout << ar[veNum[i] - 1];
cout << endl;
if (veNum[1] >= iAllLen - n + 1)
break;
}
}
}
int main()
{
int ar[] = { 3, 5, 9, 1, 0, 5 };
int iAllLen = sizeof(ar) / sizeof(ar[0]);
int n = 3;
allprint(ar, iAllLen, n);
return 0;
}
--------------------------------------------------------------------------优雅分界线-------------------------------------------------------------------------------
约瑟夫环问题:
m个士兵,因为被敌人包围却不想俘虏,决定报数决定生死。没报数到3的人自杀,剩下的人继续报数,求最后活下的两个人。
//思路:新开辟一个空间 用于存储
int nextpos(int ipos, int iRingNum, vector<int> &veNum)
{
ipos = ipos + 1 >= iRingNum ? 0 : ipos + 1;
while (ipos < iRingNum)
{
if (veNum[ipos] == 1)
ipos++;
else
return ipos;
if (ipos == iRingNum)
ipos = 0;
}
}
void printring(int iRingNum, int iLiveNum)
{
if (iRingNum <= 0 || iLiveNum <= 0 || iRingNum < iLiveNum)
return;
vector<int> veNum(iRingNum); //存储的vector
int iAllNum = 0; //总体多少个
int iNum = 0; //对iLiveNum求余之后下标
int j = 1;
for (int i = 0;;) //下标
{
j++;
i = nextpos(i, iRingNum, veNum);
if (j == iLiveNum) //要死的宝宝
{
veNum[i] = 1;
iAllNum++; //共死了多少个宝宝
if (iRingNum - iAllNum <= iLiveNum - 1) //存活的宝宝
break;
j = 0;
}
}
for (int i = 0; i < veNum.size(); ++i)
cout << veNum[i] << " ";
cout << endl;
}
int main()
{
int iRingNum = 0;
int iLiveNum = 0;
cin >> iRingNum;
cin >> iLiveNum;
printring(iRingNum, iLiveNum);
return 0;
}
全排列:
//全排列
/库方法
int main()
{
int ar[] = { 1, 2, 3 };
int iLen = sizeof(ar) / sizeof(ar[0]);
do
{
for (int i = 0; i < iLen; ++i)
cout << ar[i];
cout << endl;
} while (next_permutation(ar, ar + iLen));
return 0;
}
/普通方法
void allprint(int ar[], int iLen, int iLeft)
{
if (iLeft >= iLen)
{
for (int i = 0; i <= iLen; ++i)
cout << ar[i];
cout << endl;
}
else
{
for (int i = iLeft; i <= iLen; ++i)
{
int iTmp = ar[iLeft];
ar[iLeft] = ar[i];
ar[i] = iTmp;
allprint(ar, iLen, iLeft + 1);
iTmp = ar[iLeft];
ar[iLeft] = ar[i];
ar[i] = iTmp;
}
}
}
void allprint(int ar[], int iLen)
{
if (ar == NULL || iLen <= 0)
return;
allprint(ar, iLen-1, 0);
}
int main()
{
int ar[] = { 1, 2, 3 };
int iLen = sizeof(ar) / sizeof(ar[0]);
allprint(ar, iLen);
return 0;
}
此致
敬礼