Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 利用dp进行耦合_Algorithm_Dynamic Programming - Fatal编程技术网

Algorithm 利用dp进行耦合

Algorithm 利用dp进行耦合,algorithm,dynamic-programming,Algorithm,Dynamic Programming,给定两个字符串,S1和S2。给定得分方案,其中差距惩罚、不匹配分数和匹配分数 找到与S2最匹配的S1 我的想法是列出所有可能的S1,然后逐个与S2匹配。使用蛮力列出所有可能的S1。然后使用dp将每个可能的S1与S2匹配 有没有更快的方法?或者建议任何参考?使用维基百科和一点思考可以编写如下代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #ifndef MAX #define MAX

给定两个字符串,S1和S2。给定得分方案,其中差距惩罚、不匹配分数和匹配分数

找到与S2最匹配的S1

我的想法是列出所有可能的S1,然后逐个与S2匹配。使用蛮力列出所有可能的S1。然后使用dp将每个可能的S1与S2匹配


有没有更快的方法?或者建议任何参考?

使用维基百科和一点思考可以编写如下代码:

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

#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif

#define MATCH_SCORE     2
#define MISMATCH_SCORE  -1
#define GAP_SCORE       0

// Calculates the match score recursively.
long MatchScore(const char* p/* in: may contain 'x' */,
                const char* s/* in: doesn't contain 'x' */)
{
  long res;

  if (*p && *s)
  {
    if ((*p == *s) ||
        ((*p == 'x') && (*s >= 'a') && (*s <= 'f')))
    {
      res = MatchScore(p + 1, s + 1) + MATCH_SCORE;
    }
    else
    {
      long s1 = MatchScore(p + 1, s + 1) + MISMATCH_SCORE;
      long s2 = MatchScore(p, s + 1) + GAP_SCORE;
      long s3 = MatchScore(p + 1, s) + GAP_SCORE;
      res = MAX(s1, MAX(s2, s3));
    }
  }
  else
  {
    res = GAP_SCORE * (long)(strlen(p) + strlen(s));
  }

  return res;
}

// Calculates the best matching string and the match score
// using dynamic programming, the score must be the same
// as returned by MatchScore().
void FindBestMatch(const char* p/* in: may contain 'x' */,
                   const char* s/* in: doesn't contain 'x' */,
                   long* score/* out: match score */,
                   char** match/* out: best matching string */)
{
  size_t lp = strlen(p) + 1;
  size_t ls = strlen(s) + 1;
  size_t i, j;
  long* table = (long*)malloc(lp * ls * sizeof(long));

  for (i = 0; i < lp; i++)
    table[0 * lp + i] = GAP_SCORE * i;

  for (j = 0; j < ls; j++)
    table[j * lp + 0] = GAP_SCORE * j;

  for (j = 1; j < ls; j++)
  {
    for (i = 1; i < lp; i++)
    {
      if ((p[i-1] == s[j-1]) ||
          ((p[i-1] == 'x') && (s[j-1] >= 'a') && (s[j-1] <= 'f')))
      {
        table[j * lp + i] = table[(j-1) * lp + (i-1)] + MATCH_SCORE;
      }
      else
      {
        table[j * lp + i] =
          MAX(table[(j-1) * lp + (i-1)] + MISMATCH_SCORE,
              MAX(table[(j-1) * lp + i] + GAP_SCORE,
                  table[j * lp + (i-1)] + GAP_SCORE));
      }
    }
  }

  *score = table[lp * ls - 1];

  // Now, trace back the score table and construct the best matching string

  *match = (char*)malloc(lp);
  (*match)[lp - 1] = '\0';

  for (j = ls, i = lp; j || i;)
  {
    if ((p[i-1] == s[j-1]) ||
        ((p[i-1] == 'x') && (s[j-1] >= 'a') && (s[j-1] <= 'f')))
    {
      (*match)[i-1] = s[j-1];
      j--;
      i--;
    }
    else
    {
      if (table[(j-1) * lp + i] > table[j * lp + (i-1)])
      {
        j--;
      }
      else
      {
        (*match)[i-1] = p[i-1];
        i--;
      }
    }
  }

  free(table);
}

int main(void)
{
  const char* pattern = "acdxdcxecxf";
  const char* str = "abdfdaaed";
  long score;
  char* match;
  char* match2;

  printf("pattern=\"%s\" str=\"%s\"\n", pattern, str);
  FindBestMatch(pattern, str, &score, &match);
  printf("score=%ld (recursive)\n", MatchScore(pattern, str));
  printf("score=%ld best match=\"%s\"\n", score, match);

  // Now repeat with the best match we've just found,
  // the result must be the same
  printf("\nRepeating with pattern=best match:\n\n");

  printf("pattern=\"%s\" str=\"%s\"\n", match, str);
  FindBestMatch(match, str, &score, &match2);
  printf("score=%ld (recursive)\n", MatchScore(match, str));
  printf("score=%ld best match=\"%s\"\n", score, match2);

  free(match);
  free(match2);
  return 0;
}

我想知道是否有任何错误(除了明显缺乏错误检查)。

什么是“最佳匹配”?“a”、“f”是否可以重复用于几个“x”?问题不清楚,你指的是最长的公共子序列(即非连续的)?如果不定义“匹配度”函数,你所能做的就是尝试各种可能性,看看哪个得分最高。@Steve Jessop,是的。.匹配度没有给出,所以我的想法是正确的,对吗?或者有更快的方法吗?@savinos,是的..类似于最长公共子序列。。
pattern="acdxdcxecxf" str="abdfdaaed"
score=14 (recursive)
score=14 best match="acdfdcaecdf"

Repeating with pattern=best match:

pattern="acdfdcaecdf" str="abdfdaaed"
score=14 (recursive)
score=14 best match="acdfdcaecdf"