简体   繁体   English

动态编程-分词

[英]Dynamic Programming - Word Break

I am trying to solve this Problem.The question is as follows 我正在尝试解决这个问题。问题如下
Given an input string and a dictionary of words, find out if the input string can be segmented into a space-separated sequence of dictionary words. 给定一个输入字符串和一个单词词典,请找出输入字符串是否可以分割成以空格分隔的词典单词序列。

Dictionary is an array of strings. 字典是一个字符串数组。

My Approach is the following recursive fn with storing of the results of recursive calls. 我的方法是在以下递归函数中存储递归调用的结果。 The output is fine but I see that the stored result is never used. 输出很好,但我发现从未使用过存储的结果。 My solution is hopefully correct as it passed the test cases.But I would be great if I know whether DP is used. 我的解决方案通过了测试用例,希望是正确的,但是如果我知道是否使用DP,那将是很棒的。

The code is: 代码是:

#include <iostream>
#include <string.h>
using namespace std;

int r[100][100] = {0};  //To Store the calculated values


bool searchWord(char q[], char D[][20], int start, int end) {
    cout << "In Search Word Loop with " << start << " " << end << endl;
    char temp[end - start + 1];
    int j = 0;

    for (int i = start; i <= end ; ++i) {
        //cout << "Looping i " << i << endl;
        temp[j] = q[i];
        j++;
    }

    // cout << "For Word " << temp << endl;
    for (int i = 0; i < 12; ++i) {
        // cout << "Comparing with " << D[i] << endl;
        if (!strcmp(temp, D[i])) {
            cout << "Found Word" << temp << " " << D[i] << endl;
            return 1;
        }
    }

    return 0;
}

bool searchSentence(char q[], char D[][20], int qstart, int qend) {
    cout << "In Search Sentence Loop" << endl;
    if (r[qstart][qend] != 0) {
        cout << "DP Helped!!!" << endl;
        return 1;
    }

    if (qstart == qend) {
        if (searchWord(q, D, qstart, qstart))
            return 1;
        else return 0;
    }
    if (qstart > qend) return 1;

    int i;
    for (i = qstart; i <= qend; i++) {
        if (searchWord(q, D, qstart, i)) {
            r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
            if (r[i + 1][qend] == 1) return 1;
        }
    }

    return 0;
}

int main() {
    char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
    char q[100] = "samsungmango";

    int index = 0; char ch;
    ch = q[0];
    while (ch != '\0') {
        index++;
        ch = q[index];
    }

    if (searchSentence(q, D, 0, index - 1))
        cout << "Yes" << endl;
    else cout << "No" << endl;
}

Is recursion mandatory? 递归是强制性的吗? I see, iterative DP-solution is easiest and compact: 我知道,迭代式DP解决方案最简单,最紧凑:

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

int main() {
  const char *D[] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango", NULL};
  const char q[] = "samsungmango";
  char dp[100];
  short d_len[20];
  memset(dp, 0, sizeof(dp));
  dp[0] = 1; // 0 element is always reacheable
  int i, j;
  // compute dict string lengths
  for(i = 0; D[i]; i++)
      d_len[i] = strlen(D[i]);

  // Compute splits using DP array
  for(i = 0; q[i] != 0; i++)
      if(dp[i])  // this index is reacheable
          for(j = 0; D[j]; j++) // try to make next reacheable indexes
              if(strncmp(&q[i], D[j], d_len[j]) == 0)
                  dp[i + d_len[j]] = 1; // That position is reacheable, too

  // if EOLN(q) is reached, then yes
  printf("Answer is %s\n", dp[i]? "YES" : "NO");

} // main

Your code is actually wrong. 您的代码实际上是错误的。 To fail your code, try input like "likeman" 要使代码失败,请尝试输入“ likeman”

Note that there are two different return values possible from function searchSentence , 0 or 1. So if you initialize the r array with 0 there's no guarantee it's a new state when r[x][y] = 0 . 请注意,函数searchSentence可能有两个不同的返回值,0或1。因此,如果将r数组初始化为0,则无法保证r[x][y] = 0时它是新状态。 Initialize r array with some impossible value like -1 or 2 for this program and test again. 用一些不可能的值(如-1或2)初始化r数组,然后再次测试。 Now you can easily confirm that if r[qbegin][qend] != -1 then this state has already been checked so you can return r[qbegin][qend] from here 现在,您可以轻松地确认,如果r[qbegin][qend] != -1那么此状态已经过检查,因此您可以从此处返回r[qbegin][qend]

Updated code : 更新的代码:

#include <iostream>
#include <string.h>
using namespace std;

int r[100][100];  //To Store the calculated values

bool searchWord(char q[], char D[][20], int start, int end)
{
    cout << "In Search Word Loop with " << start << " " << end << endl;



    char temp[end - start + 1];
    int j = 0;

    for (int i = start; i <= end ; ++i)
    {
        //cout << "Looping i " << i << endl;
        temp[j] = q[i];
        j++;
    }
    temp[j] = '\0';

    //cout << "For Word " << temp << endl;

    for (int i = 0; i < 12; ++i)
    {
        // cout << "Comparing with " << D[i] << endl;
        if (!strcmp(temp, D[i]))
        {
            cout << "Found Word" << temp << " " << D[i] << endl;
            return 1;
        }
    }

    return 0;
}

bool searchSentence(char q[], char D[][20], int qstart, int qend)
{
    cout << "In Search Sentence Loop" << endl;

    if (r[qstart][qend] != -1)
    {
        cout << "DP Helped!!!" << endl;
        return r[qstart][qend];
    }


    if (qstart == qend)
    {
        if (searchWord(q, D, qstart, qstart))
            return 1;
        else return 0;
    }
    if (qstart > qend) return 1;

    int i;

    for (i = qstart; i <= qend; i++)
    {
        if (searchWord(q, D, qstart, i))
        {
            r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
            if (r[i + 1][qend] == 1) return 1;
        }
    }
    return 0;
}

int main()
{
    char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
    char q[100] = "ilike";

    int index = 0; char ch;
    ch = q[0];
    memset(r, -1, sizeof(r));
    while (ch != '\0')
    {
        index++;
        ch = q[index];
    }

    if (searchSentence(q, D, 0, index - 1))
    cout << "Yes" << endl;
    else cout << "No" << endl;
}

PS : There are some redundant lines of codes but I didn't change them and I added a null character in the end of the character array temp in function searchWord PS:有一些多余的代码行,但是我没有更改它们,而是在函数searchWord的字符数组temp的末尾添加了一个空字符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM