我正在尝试找到一种算法,该算法对于字符串中未知数量的字符,会生成用星号替换某些字符的所有选项。
例如,对于字符串" abc",输出应为:
*bc
a*c
ab*
**c
*b*
a**
***
使用已知数量的星星很简单,只需使用for循环遍历所有选项,但我在使用所有选项时遇到了困难。
答案 0 :(得分:1)
这基本上是二进制增量问题。 您可以创建一个整数变量向量来表示二进制数组isStar,并为每次迭代向向量“添加一个”。
bool AddOne (int* isStar, int size) {
isStar[size - 1] += 1
for (i = size - 1; i >= 0; i++) {
if (isStar[i] > 1) {
if (i = 0) { return true; }
isStar[i] = 0;
isStar[i - 1] += 1;
}
}
return false;
}
这样你在替换字符时仍然有原始字符串
答案 1 :(得分:1)
每个星组合对应二进制数,因此您可以使用简单循环
for i = 1 to 2^n-1
其中n是字符串长度
并将星号设置为i的二进制表示的1位的位置
例如:i = 5 = 101b => * b *
答案 2 :(得分:1)
这是一个简单的二进制计数问题,其中*
对应1
,原始字母对应0
。所以你可以用一个计数器,对字符串应用一个位掩码,但它也很容易做到"计数"到位。
这是C ++中的一个简单实现:
(编辑:)原始问题似乎暗示至少必须用星号替换一个字符,因此计数应从1开始而不是0.或者,在下文中,帖子-test do
应替换为预测试for
。)
#include <iostream>
#include <string>
// A cleverer implementation would implement C++'s iterator protocol.
// But that would cloud the simple logic of the algorithm.
class StarReplacer {
public:
StarReplacer(const std::string& s): original_(s), current_(s) {}
const std::string& current() const { return current_; }
// returns true unless we're at the last possibility (all stars),
// in which case it returns false but still resets current to the
// original configuration.
bool advance() {
for (int i = current_.size()-1; i >= 0; --i) {
if (current_[i] == '*') current_[i] = original_[i];
else {
current_[i] = '*';
return true;
}
}
return false;
}
private:
std::string original_;
std::string current_;
};
int main(int argc, const char** argv) {
for (int a = 1; a < argc; ++a) {
StarReplacer r(argv[a]);
do {
std::cout << r.current() << std::endl;
} while (r.advance());
std::cout << std::endl;
}
return 0;
}