【问题标题】:all possible combinations in a string in CC中字符串中的所有可能组合
【发布时间】:2011-09-16 07:40:56
【问题描述】:

我正在尝试使用 C 打印字符串 'abc' 的所有可能组合。有人可以帮助指出我在这段代码中哪里出错了吗?我正在使用这里提到的算法: http://hackercs.com/videos/Combinations-of-a-String-Part-2/ 感谢您的时间和帮助。 (顺便说一句,目标是在这里使用递归)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


 void combination(char **curString,int allowedStart,char **outBuffer,int length)
{
//check for allowed chars.
// if not return.
// else
// for each char in the allowed char
// copy into buffer
//print buffer
//combine buffer and over next allowed chars
//remove from buffer.

if (allowedStart == length)
    return;
else    
   {
int curr;
for (curr = allowedStart;curr<length; curr++){
//need to copy 'a' into outbuffer and keep appending to outbuffer.
printf("allowedStart = %d\n",allowedStart);
printf("curr = %d\n",curr);

(*outBuffer)[curr] = (*curString)[allowedStart];
printf("outbuff is %s\n",*outBuffer);       

combination(curString,curr+1,outBuffer,length);
    printf("return\n");
(*outBuffer)[length-1] = '\0';

   } //else
} //for 
}

 main()
 {
 char *var = "abc";
 int length = strlen(var);
 printf("length = %d\n",length);

 char *outBuffer = malloc ( length * sizeof (char));
 bzero(outBuffer,3);
 combination(&var,0,&outBuffer,length);

  }

【问题讨论】:

  • 你可能想修正你的代码格式 - 否则很难阅读。
  • 那么它有什么问题呢?我不想为了弄清楚这一点而自己运行代码,你也不应该期望我们也这样做。
  • 输出是a,ab,abc,abb,aa,aac,aaa 所以它经过第一次迭代,在失败前打印了几个组合。
  • 这是作业吗?如果是,请标记它
  • 没有。只是想更好地学习递归。我知道这段代码在 Java 中非常容易编写,但我只是想提高我的 C 技能。

标签: c string


【解决方案1】:

对于初学者来说,你错了:

 char *var = "abc";
 int length = strlen(var);
 printf("length = %d\n",length);

 char *outBuffer = malloc ( length * sizeof (char));
 bzero(outBuffer,3);

这是非常混乱的代码。它将动态缓冲区长度处理(strlen() 调用)与静态缓冲区长度处理(bzero() 调用中的3)混合在一起。通过使用sizeof (char)(C 语言保证为 1,因此只会增加噪音和混乱),这也是做错了。此外,在 C 中保存 3 个字符的可打印字符串所需的字符数不是 3,而是 4,因为您需要一个字符来终止 '\0'

【讨论】:

【解决方案2】:

搞定了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void combination(char **curString,int allowedStart,char **outBuffer,int length)
{
    //check for allowed chars.
    // if not return.
    // else
    // for each char in the allowed char
    // copy into buffer
    //print buffer
    //combine buffer and over next allowed chars
    //remove from buffer.
    int curr;

    if ( allowedStart == length )
        return;
    else    {

            for (curr = allowedStart;curr<length; curr++){
        //need to copy 'a' into outbuffer and keep appending to outbuffer.
        //      printf("allowedStart= %d  curr= %d \n",allowedStart,curr);

                (*outBuffer)[curr] = (*curString)[allowedStart];
                //adjust for appending.

                int i = 0;
                while (i < length)
                {
                    if ( ((*outBuffer)[i] == '\0') && ((*outBuffer)[i+1] != '\0') )
                    {
        //              printf("in here\n");
                        (*outBuffer)[i] = (*outBuffer)[i+1];
                        (*outBuffer)[i+1] = '\0';
                    }
                    i++;
                }

        //      printf("added curr%d %c \n",curr, (*outBuffer)[curr]);
                printf("***************************************COMBO: %s\n",*outBuffer);        
                allowedStart = curr+1;
        //      printf("allowedStart%d %c \n",allowedStart,(*curString)[allowedStart]);

                combination(curString,allowedStart,outBuffer,length);
        //      printf("removing%d %c\n",curr,(*outBuffer)[curr]);
                (*outBuffer)[curr] = ' ';   
        //      printf("**************RETURNCOMBO: %s\n",*outBuffer);       

        } //else
    } //for 
}

main()
{
    char *var = "abcd";
    int length = strlen(var);
    printf("length = %d\n",length);
//  printf("Intial word is %s\n",var);
    char *outBuffer = malloc ( (length+1) * sizeof (char));
    bzero(outBuffer,length);
    combination(&var,0,&outBuffer,length);

}

【讨论】:

    【解决方案3】:
    #include <iostream>
    
    #define PRINTLN(STR) std::cout << STR << std::endl
    #define SWAP(ARRAY, I, J) if(I != J) { ARRAY[I] ^= ARRAY[J]; ARRAY[J] ^= ARRAY[I]; ARRAY[I] ^= ARRAY[J]; }
    
    void PrintCombinations_Rec(char* str, size_t idx)
    {
        const size_t len = strlen(str);
        if( len == idx)
            PRINTLN(str);
        else
        {
            for (size_t i = idx; i < len; ++i)
            {
                SWAP(str, idx, i);
                PrintCombinations_Rec(str, idx + 1);
                SWAP(str, i, idx);
            }
        }
    }
    
    void PrintCombinations(const char* input)
    {
        const size_t len = strlen(input);
        char* str = new char[len + 1];
        strncpy_s(str, len + 1, input, len);
    
        // Recursive call
        PrintCombinations_Rec(str, 0);
    
        delete[] str;
    }
    
    int main(int argc, char** argv)
    {
        PrintCombinations("ABCD");
        return EXIT_SUCCESS;
    }
    

    【讨论】:

    • 我认为这不是 C。
    猜你喜欢
    • 2017-11-11
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多