标签 c++ 下的文章

数据结构、算法与应用 C++语言描述

第一章 习题25

子集生成法(Subset Generation)

三元素集{a,b,c}的子集是:{},{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c}。 这些子集又可以使用01序列来表示,分别是000,100,010,001,110,101,011,111。 0/1分别代表着 含有/不含 原集合中的对应元素。

输出n个元素的所有子集(以01序列的形式)。

在网上看了一下基本上最终输出的都是数组,但并没有按照题目输出01序列。所以我这里严格按照题目来解。

分析

子集生成是一个完全排列组合问题,包括退化情况空集,以及极限情况自身。 其他的情况分别是[1,n)个元素的任意组合。 所以如果递归的话,也就是每一次元素数量+1 或者是-1,如果不是输出01序列,那么输出的元素个数就刚好等于递归中的n。输出序列的时候,只需要在其他位置补0即可。而补0逻辑也可以反过来考虑,即默认是n个0 e.g. 0000,随着循环的i改变,在不同的位置上填1e.g. 0001,0010,0100,1000,这样更加便捷。

至此,已经有了算法的模型了:

/* Subset Generation */
#include <iostream>
#include <string>

using namespace std;

template <typename T>
void subsetGeneration( T* const A, int len, string code = "", int focus = 0 ){

    if( focus > len ) return;
    if( focus == len ){ cout << string(len,'1') << endl; return; }
    if( focus == 0 ){ cout << string(len,'0') << endl; }

    if( code == "" ){ code = string(len,'0'); }

    code[focus] = '1';
    for( int i = focus; i<len; i++ ){
        code[i] = '1';
        cout << code << endl;
        code[i] = '0';
    }

    subsetGeneration( A, len, code, focus + 1 );
}
int main(){

    subsetGeneration( "abcd", 4 );
    return 0;
}

思考1 上述算法已经成功解题,但是思维略显复杂,直觉上就感觉不是一个优质解。

- 阅读剩余部分 -

遇到这个问题的时候在网上搜索 绝大部分都是同样的一个解决方案 就是改一下软件的某个设置。 这个方法是十分不严谨的,所以网仔细琢磨了一下这个错误说明。

首先看一下官方给的说明: 微软 - 编译器错误 C2760

有多种方法可导致此错误。 通常,它是由编译器无法识别的令牌序列引起的。
There are several ways to cause this error. Usually, it's caused by a token sequence that the compiler can't make sense of.

这里实际上是表示有某个标识符,无法被编译器识别。而问题不一定出在最后的“;”。

这个时候我也是很头大,因为我的代码简单明了,没有任何有问题的字符。

这里最好的方式是检查一下类的定义和使用 比如说你定义了一个 A类,但是在引入这个类声明之前,就已经在使用了,就会报这个错误。

最终,我找到了问题,由于我使用的 FibonacciHelper类,定义在了使用之后,这个时候类还没有定义,所以会被当成一个标识符,而此时编译器不认识这个标识符所以出现了一些难以理解的错误说明。

把类的定义放到该文件的上方,( 有的时候这种问题和 .h文件导入位置有关系。 ) 譬如导入的 .h文件中的类 在导入之前就使用,也会有同样的问题。

int main{
    TestClass t;
}

class TestClass{
    // ...
}
// 报错
TestClass c;

#include "TestClass.h";
// 也会报错