难以打印转置排序算法的每次迭代

Difficulty printing each iteration of a transposition sorting algorithm

我是新手,正在学习“C by Dissection”,我正在尝试打印出转置排序算法的每次迭代,预期结果为:

   Unordered: 7 3 66 3 -5 22 -77 2
After pass 1: -77 7 66 3 3 22 -5 2    
After pass 2: -77 -5 66 7 3 22 3 2    
...    
     Ordered: -77 -5 2 3 3 7 22 66  

但是我只能打印出来:

   Unordered: 7 3 66 3 -5 22 -77 2
After pass 1:
After pass 2:
...
     Ordered: -77 -5 2 3 3 7 22 66

因此我错过了练习的要点。我试图放置一个 printf("%d", a[i]);在许多地方,但它没有给出预期的结果,因此我们将不胜感激。

#include <stdio.h>

void swap (int *p, int *q);
void transposition (int a[], int n);

#define SIZE 8

int main (void)
{
   int arr[SIZE] = {7, 3, 66, 3, -5, 22, -77, 2};
   int i;

   printf("   Unordered: ");
   for (i = 0; i < SIZE; i++) {
      printf("%d ", arr[i]);
   }

   transposition(arr, SIZE);


   printf("\n     Ordered: ");
   for (i = 0; i < SIZE; i++) {
      printf("%d ", arr[i]);
   }
   printf("\n");

   return 0;
}

void swap (int *p, int *q)
{
   int tmp;

   tmp = *p;
   *p = *q;
   *q = tmp;
}

void transposition (int a[], int n)
{
   int i, j;

   for (i = 0; i < n; i++) {
      for (j = i + 1; j < n; j++) {
         if (a[i] > a[j]) {
            swap(&a[i], &a[j]);
         }
      }
      printf("\nAfter pass %d: ", i);

   }
}

要打印序列,您必须添加语句来打印序列。

void transposition (int a[], int n)
{
   int i, j;

   for (i = 0; i < n; i++) {
      for (j = i + 1; j < n; j++) {
         if (a[i] > a[j]) {
            swap(&a[i], &a[j]);
         }
      }
      printf("\nAfter pass %d: ", i);

      /* add this */
      for (j = 0; j < n; j++) {
         printf("%d ", a[j]);
      }

   }
}

要从 main()

中的代码更改的要点
   for (i = 0; i < SIZE; i++) {
      printf("%d ", arr[i]);
   }

是:

  • i改成j因为i用在了外层循环
  • 根据参数把arr改成a
  • 根据参数把SIZE改成n

通过将有用的代码封装到函数中来避免重复代码

由于打印数组是您需要多次执行的操作,因此您应该编写一个函数来执行此操作:

void print_array(int arr[], int n, char const *title)
{
   printf("\n     %s: ", title);
   for (i = 0; i < SIZE; i++) {
      printf("%d ", arr[i]);
   }
   printf("\n");
}

使用我们的函数print_array

然后你可以在任何时候想要打印数组时调用该函数:

  • 排序前一次,标题为“Unordered”;
  • 排序后一次,标题“已订购”;
  • for 循环的每次迭代中,标题指定 i 的值。
#include <stdio.h>

void swap (int *p, int *q);
void sort_by_transpositions (int a[], int n);
void print_array (int a[], int n, char const *title);

#define SIZE 8

int main (void)
{
   int arr[SIZE] = {7, 3, 66, 3, -5, 22, -77, 2};
   int i;

   print_array(arr, SIZE, "Unordered");

   sort_by_transpositions(arr, SIZE);

   print_array(arr, SIZE, "Ordered");

   return 0;
}

void swap (int *p, int *q)
{
   int tmp;

   tmp = *p;
   *p = *q;
   *q = tmp;
}

# define BUFFERSIZE 100

void sort_by_transpositions (int a[], int n)
{
   int i, j;
   char after_pass_i_title[BUFFERSIZE];

   for (i = 0; i < n; i++) {
      for (j = i + 1; j < n; j++) {
         if (a[i] > a[j]) {
            swap(&a[i], &a[j]);
         }
      }
      snprintf(after_pass_i_title, BUFFERSIZE, "After pass %d", i);
      print_array(a, n, after_pass_i_title);
   }
}

注意 header stdio.h 中函数 snprintf 的使用,它类似于 printf 但打印到字符串而不是打印到标准输出。

允许用户选择他们希望排序是无声还是冗长

也许用户想要对数组进行排序,但不想因为排序而收到大量的输出行。您可以在排序函数中添加一个参数,指定是否进行所有打印:

void sort_by_transpositions (int a[], int n, int verbose)
{
   int i, j;
   char after_pass_i_title[BUFFERSIZE];

   if (verbose)
      print_array(arr, SIZE, "Unordered");

   for (i = 0; i < n; i++)
   {
      for (j = i + 1; j < n; j++)
      {
         if (a[i] > a[j])
         {
            swap(&a[i], &a[j]);
         }
      }
      if (verbose)
      {
          snprintf(after_pass_i_title, BUFFERSIZE, "After pass %d", i);
          print_array(a, n, after_pass_i_title);
      }
   }

   if (verbose)
      print_array(arr, SIZE, "Ordered");
}

然后您可以从 main 调用您的函数并指定详细 (1) 或不详细 (0):

# define VERBOSE 1
# define SILENT  0

int main (void)
{
   int arr[SIZE] = {7, 3, 66, 3, -5, 22, -77, 2};
   int i;

   sort_by_transpositions(arr, SIZE, VERBOSE);

   return 0;
}

请注意,我将对 print_array 的所有调用都移到了函数 sort_by_transpositions 内部,而不是在 sort_by_transpositions 内部进行一些调用,而在 main 内部进行一些其他调用。如果所有的打印语句都位于同一个函数内而不是散布在各处,那就更容易了。