找到数字数组的所有可能解释

时间:2013-09-10 13:46:42

标签: c++ algorithm recursion dynamic-programming

考虑一个字母到整数的编码系统,其中'a'表示为1,'b'表示为2,..'z'表示为26.给定一个数字数组(1到9)作为输入,写一个函数打印输入数组的所有有效解释。

/*Examples

Input: {1, 1}
Output: ("aa", 'k") 
[2 interpretations: aa(1, 1), k(11)]

Input: {1, 2, 1}
Output: ("aba", "au", "la") 
[3 interpretations: aba(1,2,1), au(1,21), la(12,1)]

Input: {9, 1, 8}
Output: {"iah", "ir"} 
[2 interpretations: iah(9,1,8), ir(9,18)]*/

我的c代码

#include<iostream>
using namespace std;
#include<string.h>
int a[10]={2,3,4,4,2,4,2,8,9};
char c[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

void func(int i,char result[10])
{
    if(i==10)
    {
       int l=strlen(result);
       for(int j=0;j<l;j++)
           cout<<result[j];
    }

    else
    {
        if(10*a[i]+a[i+1]<26)
        {
            strcat(result,"c[10*a[i]+a[i+1]]");
            func(i+2,result);
        }

        strcat(result,"c[a[i]]");
        func(i+1,result);
    }
}

int main()
{

    func(0,"");
}

我无法找出错误。你能救我吗?

4 个答案:

答案 0 :(得分:2)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[9]={2,3,4,4,2,4,2,8,9};
char c[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

void func(int i,char result[11])
{
    if(i==10)
    {
      printf ("%s\n", result);
    }
    else
    {
        char * temp = (char *)malloc(11);
        sprintf(temp, "%s%c", result, c[a[i] - 1]);
        func(i+1,temp);
        free(temp);

        if(i < 9 && 10*a[i]+a[i+1] < 26)
        {
            char * temp = (char *)malloc(11);
            sprintf(temp, "%s%c", result, c[10*a[i]+a[i+1] - 1]);
            func(i+2, temp);
            free (temp);
        }
    }
}
int main()
{
    func(0,"");
}

<强>输出

bcddbdbhi
bcddxbhi
wddbdbhi
wddxbhi

您的代码可能存在致命问题

  1. strcat(result,"c[10*a[i]+a[i+1]]");strcat(result,"c[a[i]]");您将这些字符串连接到大小仅为10的result,而不是连接与该数字对应的字符。
  2. 其他问题

    1. if(10*a[i]+a[i+1]<26)内部,您正在更改result的内容,当递归结束时,结果的值与进入函数时的值不同。因此,最好在内部创建新的字符串,并在任务结束时释放它们。
    2. <强>建议

      1. 尽量不要混合使用C和C ++函数。

答案 1 :(得分:1)

我看到的一个错误是你的结果数组可能没有10个字符。

for(int j=0;j<10;j++)
cout<<result[j];

这将导致分段错误。

编辑:如果您愿意使用C ++元素,那么我更倾向于使用std :: string而不是char数组来获得结果。

答案 2 :(得分:1)

你问过错误。这是:

  1. 在其他包含之前放置“using namespace”,这可能会导致编译器在其他项目中出现非常奇怪的错误。
  2. a [10]未定义,但在call func(9,result);
  3. 上进行评估
  4. 另外,调用func(9,result)可能会调用func(9 + 2,结果)。
  5. strcat的(因此, “C [10 * A [1] + A [1 + 1]]”);将字符串“c [10 * a [i] + a [i + 1]]”添加到结果中。我怀疑这是你想要的结果。此外,编译器应该建议您使用strncat()代替。
  6. 最好使用std :: string和std :: stringstream,除非你有一些很好的理由要避免它们。
  7. 变量 a 用于func(),但不作为参数传递。一般来说,这是一个好主意。
  8. 示例代码(这使用了一些其他技巧):

        void PrintDecodings(const int* a, size_t length, std::string acc){
            static const char* alphabet = "0abcdefghijklmnopqrstuvwxyz";
            if(length == 0){
                std::cout << acc << std::endl;
                return;
            }
            if(length == 1){
                std::cout << acc << alphabet[*a] << std::endl;
                return;
            }
            if(10*a[0]+a[1] <= 26){ //At this point, length>=2, so a[1] is OK
                PrintDecodings(a+2, length-2, acc+alphabet[10*a[0]+a[1]]);
            }
            return PrintDecodings(a+1, length-1, acc+alphabet[*a]);
        }
    
        //...
            PrintDecodings(a, 9, "");
    

答案 3 :(得分:0)

#include<iostream>
using namespace std;
#include<string.h>
int a[3]={1,2,1};
char c[]={'NULL','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

void func(int i,char result[3],int r)
{
    if(i==3)
    {
      for(int j=0;j<r;j++)
           cout<<result[j];
       cout<<"\n";
       return;
    }
    if(10*a[i]+a[i+1]<26)
    {
      result[r]=c[10*a[i]+a[i+1]];
      func(i+2,result,r+1);
    }
    result[r]=c[a[i]];
    func(i+1,result,r+1);

}


int main()
{
    char result[10];
    func(0,result,0);
}