我有以下字符串:
char *str = "test";
我需要使用点生成不同的条目,例如将生成以下内容:
test
t.est
te.st
tes.t
t.e.s.t
t.e.st
te.s.t
...
注意:开头和结尾都不能有点。
我目前能够生成其中一些,但不是全部,我尝试了多种方法,例如:
1.在比特级别(每次迭代的点开和关闭)听起来像最合理的日期,但我有一个障碍。
2.只是一个基于相等性生成的嵌套循环,例如(x,y,并将x,y与i进行比较(其中i将作为生成新字符串的循环)。
我目前的代码:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "test";
for (int k = 0; k < sizeof(str) - 1; ++k) {
for (int x = k; x < sizeof(str) - 1; ++x) {
for (int y = x + 1; y < sizeof(str) - 1; ++y) {
char tmp[512], *p = tmp;
for (int i = 0; i < sizeof(str); ++i) {
*p++ = str[i];
if (i == x || i == y)
*p++ = '.';
}
*p++ = '\0';
printf("%s\n", tmp);
}
}
}
return 0;
}
这给出了:
t.e.st
t.es.t
t.est.
te.s.t
te.st.
tes.t.
te.s.t
te.st.
tes.t.
tes.t.
最好是使用位级别的东西,如果是的话,对它有任何建议吗?或者,如果我继续使用当前功能并将其修复正常(请提供解决方案),它会更好吗?
注意,这里确实不需要表现,这只是一次性的事情(在启动时),因此,只要它起作用,任何事情都会发生。
答案 0 :(得分:2)
使用整数作为位掩码:对于每个位,如果已设置,则打印.
。如果您将所有值从0
迭代到2 ** (len-1)
,您将使用所有可能的组合枚举点的所有可能位置:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "test";
int len = strlen(str);
for (int bits = 0; bits < (1 << (len - 1)); bits++) {
putchar(str[0]);
for (int j = 1; j < len; j++) {
if (bits & (1 << (j - 1)))
putchar('.');
putchar(str[j]);
}
putchar('\n');
}
return 0;
}
答案 1 :(得分:2)
此功能应该符合您的期望:
void dotify(char *str) {
int nr = 1 << (strlen(str)-1);
char buf[strlen(str)*2];
while (nr--) {
int i;
char *ptr = buf;
for (i = 0; i < strlen(str); i++) {
*ptr++ = str[i];
if (nr & (1 << i))
*ptr++ = '.';
}
*ptr = '\0';
puts(buf);
}
}
此解决方案背后的基本思想是将每个点位置映射到具有strlen(str)-1位数的二进制数字的数字。从0-n计算这个数字。数字0表示&#34;不设置点&#34;,而1表示&#34;设置点&#34;
答案 2 :(得分:2)
这个单词有四个字母,所以有三个中断你可以插入一个点'.'
。插入/不插入点将有2个 n-1 组合。您可以将它们编码为二进制数:
dec bin word
--- --- -------
0 000 test
1 001 t.est
2 010 te.st
3 011 t.e.st
4 100 tes.t
5 101 t.es.t
6 110 te.s.t
7 111 t.e.s.t
你现在需要做的是做一个&#34;面具&#34;从0变为2 n-1 -1,包括在内,并将此掩码解释为嵌套循环中的点序列,如下所示:
string s = "test";
for (int mask = 0 ; mask != 1 << (s.size()-1) ; mask++) {
cout << s[0];
for (int i = 0 ; i != s.size()-1 ; i++) {
if (mask & (1<<i)) {
cout << ".";
}
cout << s[i+1];
}
cout << endl;
}