为字符串生成不同的entires(要使用的点)

时间:2016-01-24 00:05:44

标签: c++ c algorithm

我有以下字符串:

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.

最好是使用位级别的东西,如果是的话,对它有任何建议吗?或者,如果我继续使用当前功能并将其修复正常(请提供解决方案),它会更好吗?

注意,这里确实不需要表现,这只是一次性的事情(在启动时),因此,只要它起作用,任何事情都会发生。

3 个答案:

答案 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;
}

Demo.