关于递归回溯的练习 - 无法让它工作

时间:2018-02-05 11:44:08

标签: c recursion backtracking

我正在尝试用C解决递归练习。 有一个包含一些双面卡的文件。每侧由1-9的数字表示,每张卡都有唯一的ID。文件格式如下:

2 1-2
5 9-9
3 5-2
4 2-3
1 6-5

目标是从这个文件中读取,并且从特定元素开始(在示例中它是" 4 2-3")生成最长的组合,因此每个方面都是卡具有与下一个和前一个相同的编号(例如:2-3 - > 3-5 - > 5-9 - > 9-1 - > 1-4)。你也可以转牌(例如2-3可以变成3-2)。 例如,此文件的解决方案是:

4 3-2
3 2-5
1 5-6

这是我写的代码:

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

#define N 100

struct Piece {
  int id;
  int left;
  int right;
};

void shift_sides(struct Piece *piece);

void copy_pieces(struct Piece *dest, struct Piece orig);

int read_pieces(struct Piece *pieces);

void print_pieces(struct Piece *pieces, int size);

void find_sequence(
  int current,
  int orig,
  struct Piece *pieces,
  struct Piece *sequence,
  int size,
  int *mark,
  int *count,
  int *max,
  struct Piece *max_seq
);

int main(int argc, char *argv[]) {
  int i, size, *mark;
  struct Piece pieces[N], sequence[N], max_seq[N];;
  int value = 4;
  int count = 0;
  int orig;
  int max;

  size = read_pieces(pieces);

  mark = malloc(size*sizeof(*mark));
  for (i = 0; i < size; i++) {
    mark[i] = 1;
  }

  for (i = 0; i < size; i++) {
    if(pieces[i].id == value) {
      value = i;
      orig = i;
      break;
    }
  }
  //mark first element
  mark[value] = 0;
  copy_pieces(&sequence[0], pieces[value]);
  count++;
  max = count;
  find_sequence(value,
                orig,
                pieces,
                sequence,
                size,
                mark,
                &count,
                &max,
                max_seq);

  shift_sides(&pieces[value]);
  copy_pieces(&sequence[0], pieces[value]);
  find_sequence(value,
                orig,
                pieces,
                sequence,
                size,
                mark,
                &count,
                &max,
                max_seq);

  print_pieces(sequence, count);

  return 0;
}

void find_sequence(int current,
                   int orig,
                   struct Piece *pieces,
                   struct Piece *sequence,
                   int size,
                   int *mark,
                   int *count,
                   int *max,
                   struct Piece *max_seq)
{
  int i, j;

  for (i = 0; i < size; i++) {
    if(mark[i] == 1) {
      if(pieces[current].right == pieces[i].left) {
        mark[i] = 0;
        copy_pieces(&sequence[(*count)], pieces[i]);
        (*count)++;
        find_sequence(i,
                      orig,
                      pieces,
                      sequence,
                      size,
                      mark,
                      count,
                      max,
                      max_seq);
        mark[i] = 1;
      }
      if(pieces[current].right == pieces[i].right) {
        mark[i] = 0;
        shift_sides(&(pieces[i]));
        copy_pieces(&sequence[(*count)], pieces[i]);
        (*count)++;
        printf("Current: %d %d ---> %d %d\n",
               pieces[current].left,
               pieces[current].right,
               pieces[i].left,
               pieces[i].right);

        find_sequence(i,
                      orig,
                      pieces,
                      sequence,
                      size,
                      mark,
                      count,
                      max,
                      max_seq);

        shift_sides(&(pieces[i]));
        mark[i] = 1;
      }
    }
  }
}

void copy_pieces(struct Piece *dest, struct Piece orig) {
  dest->id = orig.id;
  dest->left = orig.left;
  dest->right = orig.right;
}

void shift_sides(struct Piece *piece) {
  int tmp = piece->left;
  piece->left = piece->right;
  piece->right = tmp;
}

int read_pieces(struct Piece *pieces) {
  FILE *fp;
  int i = 0;
  fp = fopen("a.txt", "r");
  while(fscanf(fp, "%d %d-%d",
               &pieces[i].id,
               &pieces[i].left,
               &pieces[i].right) != EOF)
  {
    i++;
  }
  return i;
}

void print_pieces(struct Piece *pieces, int size) {
  int i;
  printf("Size: %d\n", size);
  for (i = 0; i < size; i++) {
    printf("%d %d-%d\n", pieces[i].id, pieces[i].left, pieces[i].right);
  }
}

它似乎可以生成所有组合,但我不知道如何单独识别每个单独的序列,以便我只能存储最长的序列。

现在打印:

Current: 3 2 ---> 2 1
Current: 3 2 ---> 2 5
Current: 2 5 ---> 5 6
3 2 --> 2 1           one possible combination
3 2 --> 2 5 --> 5 6   another possible combination

我不知道我的方法是否正确。我对递归有一些严重的问题,它对我来说并不自然。

0 个答案:

没有答案