为字符串生成不同的整体(要使用的点)
Generate distinct entires for a string (dots to be used)
本文关键字:字符串 更新时间:2023-10-16
我有以下字符串:
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++ = ' ';
printf("%sn", 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.
是否最好使用位级的东西,如果是这样,有什么建议吗? 或者如果我继续使用当前并修复它以正常工作会更好(请提供解决方案)?
请注意,这里并不真正需要性能,这只是一次性的事情(在启动时),所以,只要它有效,任何事情都可以。
这个词有四个字母,所以有三个分隔符,你可以在其中插入一个点'.'
。将有 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
你现在需要做的是制作一个从 0 更改为 2n-1-1(包括 0)的"掩码",并将此掩码解释为嵌套循环中的一系列点,如下所示:
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;
}
演示。
使用整数作为位掩码:对于每个位,如果已设置,请打印一个.
。 如果迭代从 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;
}
此函数应执行您的预期操作:
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 = ' ';
puts(buf);
}
}
该解决方案背后的基本思想是将每个点位映射到具有 strlen(str)-1 位的二进制数的数字。从 0-n 开始计算此数字。数字 0 表示"不设置点",而 1 表示"设置点"