整数n的划分是将n写成正整数和的一种方式。对于
例如,对于n=7,一个分区是1 1 5。我需要一个程序来查找所有
使用“r”整数对整数“n”进行分区。例如,n=7的所有分区
使用
r=3
整数是15
,14
,13
,23
。
这就是我目前的情况:
#include <iostream>
#include <vector>
using namespace std;
void print (vector<int>& v, int level){
for(int i=0;i<=level;i++)
cout << v[i] << " ";
cout << endl;
}
void part(int n, vector<int>& v, int level){
int first; /* first is before last */
if(n<1) return ;
v[level]=n;
print(v, level);
first=(level==0) ? 1 : v[level-1];
for(int i=first;i<=n/2;i++){
v[level]=i; /* replace last */
part(n-i, v, level+1);
}
}
int main(){
int num;
cout << "Enter a number:";
cin >> num;
vector<int> v(num);
part(num, v, 0);
}
该程序的输出为:
Enter a number:5
5
1 4
1 1 3
1 1 1 2
1 1 1 1 1
1 2 2
2 3
Process returned 0 (0x0) execution time : 1.837 s
Press any key to continue.
我怎样才能更改代码,这样我就可以拥有那个“r”变量?
编辑:
如果不清楚,“r”值代表每个分区的整数。所以在上面的情况下,如果r=2,那么分区只能有两个整数。分区将是4 1和3 2。“r”值应该由用户输入。
一种"hack"将使r
成为part
的参数,递归地传递它,如果level
等于r
,则只打印输出。
下面列出的函数满足您的要求——它有效地枚举整数myInt
的所有分区,其大小为PartitionSize
,其部分始终为
此函数使用std::vector来存储每个分区,但可以用固定大小的数组代替该向量,以便于直接移植到
普通C
。
这不是递归函数!这就是为什么它的代码要长得多、复杂得多,但作为一个额外的好处,对于长分区,它的速度更快,堆栈使用的内存更少,每个分区的部分/元素都按升序(从左到右)列出,分区本身按字典顺序排列(从上到下)。
void GenPartitions(const unsigned int myInt,
const unsigned int PartitionSize,
unsigned int MinVal,
unsigned int MaxVal)
{
if ((MaxVal = MaxPartitionVal(myInt, PartitionSize, MinVal, MaxVal)) == 0)
return;
if ((MinVal = MinPartitionVal(myInt, PartitionSize, MinVal, MaxVal)) == unsigned int(-1))
return;
std::vector<unsigned int> partition(PartitionSize);
unsigned int idx_Last = PartitionSize - 1;
unsigned int idx_Dec = idx_Last; //The point that needs to be decremented
unsigned int idx_Spill = 0; //Index where the remainder starts spilling leftwise
unsigned int idx_SpillPrev; //Copy of the old idx_Spill for optimization of the last "while loop".
unsigned int LeftRemain = myInt - MaxVal - (idx_Dec - 1)*MinVal; //The remaining value that needs to be spilled leftwise
partition[idx_Dec] = MaxVal + 1; //Initialize first partition. It will be decremented as soon as it enters the "do" loop.
//std::cout << std::setw(idx_Dec * 3 + 1) << "" << "v" << std::endl; //Show the first Decrement Point
do {
unsigned int val_Dec = partition[idx_Dec] - 1; //Value AFTER decrementing
partition[idx_Dec] = val_Dec; //Decrement at the Decrement Point
idx_SpillPrev = idx_Spill; //For optimization so the last "while loop" does not do unnecessary work.
idx_Spill = idx_Dec - 1; //Index where the remainder starts getting spilled. Before the Decrement Pint (not inclusive)
while (LeftRemain > val_Dec) //Spill the remainder leftwise while limiting its magnitude, in order to satisfy the left-to-right ascending ordering.
{
partition[idx_Spill--] = val_Dec;
LeftRemain -= val_Dec - MinVal; // Adjust remainder by the amount used up (minVal is assumed to be there already)
//std::cout << std::setw(((idx_Spill + 1) * 3) + 1) << "" << "-" << std::endl; //Show the remainder spillage
} //For platforms without hardware multiplication, it is possible to calculate the expression (idx_Dec - idx_Spill)*val_Dec inside this loop by multiple additions of val_Dec.
partition[idx_Spill] = LeftRemain; //Spill last remainder of remainder
//std::cout << std::setw((idx_Spill * 3) + 1) << "" << "*" << std::endl; //Show the last remainder of remainder
char a = (idx_Spill) ? ~((-3 >> (LeftRemain - MinVal)) << 2) : 11; //when (LeftRemain == MinVal) then it computes to 11
char b = (-3 >> (val_Dec - LeftRemain));
switch (a & b) //Switch depending on relative magnitudes of elements before and after the partition[idx]. Cases 0, 4, 8 can never occur.
{
case 1:
case 2:
case 3: idx_Dec = idx_Spill;
LeftRemain = 1 + (idx_Spill - idx_Dec + 1)*MinVal;
break;
case 5: for (++idx_Dec, LeftRemain = (idx_Dec - idx_Spill)*val_Dec; (idx_Dec <= idx_Last) && (partition[idx_Dec] <= MinVal); idx_Dec++) //Find the next value, that can be decremented while satisfying the left-to-right ascending ordering.
LeftRemain += partition[idx_Dec];
LeftRemain += 1 + (idx_Spill - idx_Dec + 1)*MinVal;
break;
case 6:
case 7:
case 11:idx_Dec = idx_Spill + 1;
LeftRemain += 1 + (idx_Spill - idx_Dec + 1)*MinVal;
break;
case 9: for (++idx_Dec, LeftRemain = idx_Dec * val_Dec; (idx_Dec <= idx_Last) && (partition[idx_Dec] <= (val_Dec + 1)); idx_Dec++) //Find the next value, that can be decremented while satisfying the left-to-right ascending ordering.
LeftRemain += partition[idx_Dec];
LeftRemain += 1 - (idx_Dec - 1)*MinVal;
break;
case 10:for (LeftRemain += idx_Spill * MinVal + (idx_Dec - idx_Spill)*val_Dec + 1, ++idx_Dec; (idx_Dec <= idx_Last) && (partition[idx_Dec] <= (val_Dec - 1)); idx_Dec++) //Find the next value, that can be decremented while satisfying the left-to-right ascending ordering. Here [idx_Dec] == [cur]+1.
LeftRemain += partition[idx_Dec];
LeftRemain -= (idx_Dec - 1)*MinVal;
break;
}
while (idx_Spill > idx_SpillPrev) //Set the elements where the spillage of the remainder did not reach. For optimization, going down only to idx_SpillPrev
partition[--idx_Spill] = MinVal; //For platforms without hardware multiplication, it is possible to calculate the expression idx_Spill*MinVal inside this loop by multiple additions of MinVal, followed by another "while loop" iterating from idx_SpillPrev to zero (because the optimization skips these iterations). If, so, then both loops would need to be moved before the "switch statement"
DispPartition(partition); //Display the partition ...or do sth else with it
//std::cout << std::setw((idx_Dec * 3) + 1) << "" << "v" << std::endl; //Show the Decrement Points
} while (idx_Dec <= idx_Last);
}
下面是此函数的输出示例:
SAMPLE OUTPUT OF: GenPartitions(20, 4, 1,10):
1, 1, 8,10
1, 2, 7,10
1, 3, 6,10
2, 2, 6,10
1, 4, 5,10
2, 3, 5,10
2, 4, 4,10
3, 3, 4,10
1, 1, 9, 9
1, 2, 8, 9
1, 3, 7, 9
2, 2, 7, 9
1, 4, 6, 9
2, 3, 6, 9
1, 5, 5, 9
2, 4, 5, 9
3, 3, 5, 9
3, 4, 4, 9
1, 3, 8, 8
2, 2, 8, 8
1, 4, 7, 8
2, 3, 7, 8
1, 5, 6, 8
2, 4, 6, 8
3, 3, 6, 8
2, 5, 5, 8
3, 4, 5, 8
4, 4, 4, 8
1, 5, 7, 7
2, 4, 7, 7
3, 3, 7, 7
1, 6, 6, 7
2, 5, 6, 7
3, 4, 6, 7
3, 5, 5, 7
4, 4, 5, 7
2, 6, 6, 6
3, 5, 6, 6
4, 4, 6, 6
4, 5, 5, 6
5, 5, 5, 5
如果要编译它,助手函数如下:
#include <iostream>
#include <iomanip>
#include <vector>
unsigned int MaxPartitionVal(const unsigned int myInt,
const unsigned int PartitionSize,
unsigned int MinVal,
unsigned int MaxVal)
{
if ((myInt < 2)
|| (PartitionSize < 2)
|| (PartitionSize > myInt)
|| (MaxVal < 1)
|| (MinVal > MaxVal)
|| (PartitionSize > myInt)
|| ((PartitionSize*MaxVal) < myInt )
|| ((PartitionSize*MinVal) > myInt)) //Sanity checks
return 0;
unsigned int last = PartitionSize - 1;
if (MaxVal + last*MinVal > myInt)
MaxVal = myInt - last*MinVal; //It is not always possible to start with the Maximum Value. Decrease it to sth possible
return MaxVal;
}
unsigned int MinPartitionVal(const unsigned int myInt,
const unsigned int PartitionSize,
unsigned int MinVal,
unsigned int MaxVal)
{
if ((MaxVal = MaxPartitionVal(myInt, PartitionSize, MinVal, MaxVal)) == 0) //Assume that MaxVal has precedence over MinVal
return unsigned int(-1);
unsigned int last = PartitionSize - 1;
if (MaxVal + last*MinVal > myInt)
MinVal = myInt - MaxVal - last*MinVal; //It is not always possible to start with the Minimum Value. Increase it to sth possible
return MinVal;
}
void DispPartition(const std::vector<unsigned int>& partition)
{
for (unsigned int i = 0; i < partition.size()-1; i++) //DISPLAY THE PARTITON HERE ...or do sth else with it.
std::cout << std::setw(2) << partition[i] << ",";
std::cout << std::setw(2) << partition[partition.size()-1] << std::endl;
}
P. S.
我的动机是为一个微控制器创建这个非递归函数,这个微控制器留给堆栈的空闲内存只有很少的字节(尽管它有很多程序内存)。
基本上是Codor所说的,而且一旦找到目标长度的分区,就不需要进一步递归到part()
,因为它们会更长:
#include <iostream>
#include <vector>
using namespace std;
void print (vector<int>& v, int level){
for(int i=0;i<=level;i++)
cout << v[i] << " ";
cout << endl;
}
void part(int n, vector<int>& v, int level, int r){
int first; /* first is before last */
if(n<1) return ;
v[level]=n;
if( level+1 == r ) {
print(v, level);
return;
}
first=(level==0) ? 1 : v[level-1];
for(int i=first;i<=n/2;i++){
v[level]=i; /* replace last */
part(n-i, v, level+1, r);
}
}
int main(){
int num,r;
cout << "Enter a number:";
cin >> num;
cout << "Enter size (r):";
cin >> r;
vector<int> v(num);
part(num, v, 0, r);
}
输出:
Enter a number:5
Enter size (r):2
1 4
2 3
我试图找到或开发Python的整数分区代码。 仅供参考,整数分区将给定的整数n表示为小于n的整数之和。例如,整数5可以表示为 我已经找到了很多解决方案。http://homepages.ed.ac.uk/jkellehe/partitions.php和http://code.activestate.com/recipes/218332-generator-for-integer-partition
我是cosmos Db的新手,需要删除一个完整的分区。在做了一个简短的研究后,我发现drop分区不是一件事。因此,我偶然发现了以下链接,这是一个用于批量删除的存储过程 https://github.com/Azure/azure-cosmosdb-js-server/blob/master/samples/stored-procedures/bulkDelete.js 我在我的集合上创建了这个存储
对于排列,给定和,我有一个函数,可以按字典顺序查找th排列。另外,给定一个排列,我有一个函数,可以在的所有排列中找到该排列的词典索引。为此,我使用了这个答案中建议的“阶乘分解”。 现在我想对的整数分区做同样的事情。例如,对于,我希望能够在索引(左)和分区(右)之间来回: 我试过一些方法。我想到的最好的是 其中给出了以下内容: 这不太管用,但似乎在正确的轨道上。我之所以想到这一点,是因为它计算了我必
问题内容: (重新发布,因为我没有对之前的帖子做出任何回应) 我试图编写一个Python代码以将数字为’n’的弱整数组合(分区)转换为’k’部分,但要使用MINIMUM和MAXIMUM每个分区上的值约束(请参见下面的示例)。同样,必须按字典顺序生成分区。我发现了一些相关的帖子,但无法实现。任何帮助将不胜感激。 范例: n = 5的整数分割区(k = 3): [5,0,0],[4,1,0],[4,0
问题内容: 我想要两个整数,一个除以另一个以获得小数或百分比。如何获得这两个整数的百分比或小数?(例如,我不确定是否正确。我可能离…): 这就是我以为自己可以做到的方式,但是它没有用…我想将小数(如果有的话)设为100的百分数,例如,在这种情况下为%25。有任何想法吗? 这是正确的代码(感谢Salvatore Previti!): (顺便说一句,我正在使用此项目进行测验程序,这就是为什么我需要百分
在Apache Spark中, -允许将RDD精确划分为分区。 而是如何将给定的RDD划分成分区,使得所有分区(最后一个分区除外)都具有指定数量的元素。鉴于RDD元素的数量是未知的,做<代码>。count()的开销很大。 预期: