【问题标题】:Sort numbers according to n-th term根据第 n 项对数字进行排序
【发布时间】:2014-11-07 19:02:27
【问题描述】:

我知道如何对数组进行排序(即冒泡排序),但我不知道如何根据第 n 项对数组进行排序。如果有,你能给我想法或例子吗?感谢您对所有赞赏的回答。 @edit: 程序如何感应到一个带有零的数字,我的意思是 1 个程序感应 0001 或 00001 ....?

Example:
2 --> nth digit
4 45 62 1 900 105 --> inputs

输出: 001 004 105 900 045 065


void bubble_sort(int iarr[], int num) {
   int i, j, k, temp;

   printf("\nUnsorted Data:");
   for (k = 0; k < num; k++) {
      printf("%5d", iarr[k]);
   }

   for (i = 1; i < num; i++) {
      for (j = 0; j < num - 1; j++) {
         if (iarr[j] > iarr[j + 1]) {
            temp = iarr[j];
            iarr[j] = iarr[j + 1];
            iarr[j + 1] = temp;
         }
      }

      printf("\nAfter pass %d : ", i);
      for (k = 0; k < num; k++) {
         printf("%5d", iarr[k]);
      }
   }
}

【问题讨论】:

  • 为什么投了反对票?我认为这是一个很好的问题。请注意。
  • 把冒泡排序代码贴出来,我们可以调整一下。
  • @chux 已添加
  • 要感知“0001”和“00001”之间的区别,代码需要将数据读入除int之外的其他内容。这使得问题大不相同,因为int 在从文本转换为int 时不区分前导'0' 的数量。如果这是一个问题,建议发布示例输入和读取输入的代码。

标签: c arrays string sorting


【解决方案1】:

快速回答是,您的比较函数需要查看第 n 位而不是整数。

所以如果你最初的比较是这样的:

if (a < b)     // handle a before b case
elseif (b < a) // handle b before a case

您需要将其更改为:

aDigit = getNthDigit(a, n);
bDigit = getNthDigit(b, n);

if (aDigit < bDigit)     // handle a before b case
elseif (bDigit < aDigit) // handle b before a case

您还必须实现getNthDigit,这将涉及整数除法和取模运算符。

【讨论】:

  • 它正在工作,但程序无法将 1 感知为 001 我该怎么办?
  • int getNthDigit(int x,int y){ return fmod((x / power(10, y)), 10);} 对吗?
  • @user3674483 你的意思是pow()pow() may be imprecise 并导致整数数学问题。这种方法也可以返回 + 和 - 答案。 OP 还没有发布示例输入,所以我们不知道负数是否重要。
  • int getNthDigit(int x,int y){ return (abs(x) / pow(10, y)) % 10;} ?
【解决方案2】:

查看qsort 了解通用排序函数的要求。对于您的具体问题,请查看您要实现的排序算法(即冒泡排序),并将元素的比较替换为对排序函数的函数调用。然后,您的比较函数应该提取第二个数字并比较这些数字。

根据您的代码,您应该将if (iarr[j] &gt; iarr[j + 1]) 更改为if(comp_gt(iarr[j], iarr[j + 1]))。而且,我会通过

实现comp_gt
int comp_gt(int a, int b)
{
    int a_second_digit = (a / 10) % 10;
    int b_second_digit = (b / 10) % 10;

    return (a_second_digit < b_second_digit);
}

【讨论】:

    【解决方案3】:

    这意味着您根据数字的第 n 位对数字进行排序。

    在您的示例中,您会看到粗体数字(每个数字中的第二个数字)是定义输出顺序的数字。

    这是一个解决方法的示例(我现在正在调整它,因为它用于查找数字的方法是错误的):

    #include <stdio.h>
    #include <math.h>
    
    void quickSort(int a[], int first, int last, int n_th);
    int pivot(int a[], int first, int last, int n_th);
    void swap(int* a, int* b);
    int n_th_digit(int number, int n);
    void print(int array[], const int N);
    
    int main() {
      int test[] = { 7, 9, 1, 3, 6, 5, 2, 4 };
      int N = sizeof(test) / sizeof(int);
      int n_th = 0;  // digit(from the end) to sort by
    
      printf("Size of test array : %d\n", N);
    
      printf("Before sorting : \n");
      print(test, N);
    
      quickSort(test, 0, N - 1, n_th);
    
      printf("After sorting : \n");
      print(test, N);
    
      return 0;
    }
    
    /**
     * Quicksort.
     * @param a The array to be sorted.
     * @param first The start of the sequence to be sorted.
     * @param last The end of the sequence to be sorted.
     * @param n_th The digit to sort by
     */
    void quickSort(int a[], int first, int last, int n_th) {
      int pivotElement;
    
      if (first < last) {
        pivotElement = pivot(a, first, last, n_th);
        quickSort(a, first, pivotElement - 1, n_th);
        quickSort(a, pivotElement + 1, last, n_th);
      }
    }
    
    /**
     * Find and return the index of pivot element.
     * @param a The array.
     * @param first The start of the sequence.
     * @param last The end of the sequence.
     * @param n_th The digit to sort by
     * For example the third digit of 137
     * requires n_th to be 0.
     *
     */
    int pivot(int a[], int first, int last, int n_th) {
      int i, p = first;
      int pivotElement = a[first];
    
      for (i = first + 1; i <= last; i++) {
        if (n_th_digit(a[i], n_th) <= n_th_digit(pivotElement, n_th)) {
          p++;
          swap(&a[i], &a[p]);
        }
      }
    
      swap(&a[p], &a[first]);
    
      return p;
    }
    
    /**
     * Swap the parameters.
     * @param a The first parameter.
     * @param a The second parameter.
     */
    void swap(int* a, int* b) {
      // You still can use the swap that
      // does not uses an extra variable
      // from the C++ implementation.
      int temp = *a;
      *a = *b;
      *b = temp;
    }
    
    int n_th_digit(int number, int n) {
      if (number < 0)
        number *= -1;
      return fmod((number / pow(10, n)), 10);
    }
    
    /**
     * Print an array.
     * @param a The array.
     * @param N The size of the array.
     */
    void print(int a[], const int N) {
      int i;
      for (i = 0; i < N; i++)
        printf("array[%d] = %d\n", i, a[i]);
    }
    

    我知道了如何从here 中找到第 n 位数字以及从 here 中找到快速排序。

    【讨论】:

    • 我知道根据数字的第 n 位对数字进行排序。但是如何?我想要解决的想法或方法
    【解决方案4】:

    替换

    void bubble_sort(int iarr[], int num) {
      ....
      if (iarr[j] > iarr[j + 1])
    

    void bubble_sort(int iarr[], int num, int term) {
      unsigned pow10 = upow10(term - 1);
      ....
      if (compareu(iarr[j], iarr[j + 1], pow10) > 0) 
    

    // To calculate pow(10, x) quickly
    static unsigned upow10(unsigned y) {
      unsigned z = 1;
      unsigned base = 10;
      while (y) {
        if (y & 1) {
          z *= base;
        }
        y >>= 1;
        base *= base;
      }
      return z;
    }
    
    int compareu(int a1, int a2, unsigned pow10) {
      unsigned b1 = abs(a1);
      unsigned b2 = abs(a2);
      b1 = (b1 / pow10) % 10;
      b2 = (b2 / pow10) % 10;
      if (b1 > b2) return 1;
      if (b1 < b2) return -1;
      return (a1 > a2) - (a1 < a2);
    }
    

    [编辑]每个 OP 的更新

    问:程序如何感应到一个带零的数字,我的意思是 1 个程序感应 0001 或 00001?
    答:这是读取未发布的输入的代码的一部分。如果代码需要区分“0001”和“00001”,那么整个问题是字符串而不是整数之一。在这种情况下,将每个元素保存为字符串,然后从文本的角度进行比较。

    但我怀疑这不是真正的编码目标。只需使用算术比较即可,无需担心不同的前导零。

    printf() 函数是另一回事。要打印至少 term 数字并带有前导0,请使用"%0*d"

    term = 2; // or 6 or 9, etc.
    // printf("%5d", iarr[k]);
    printf("%0*d ", term, iarr[k]);
    

    【讨论】:

    • 是的,让我们将整个内容转换为字符串以提取一个数字。哦,让我们一遍又一遍地做。
    • 如果他们使用冒泡排序,你真的认为他们会关心使用字符串提取数字吗?
    • @Daniel 已替换为数值方法。
    • 似乎更好,尽管我会亲自将其提取到它自己的函数中以获得第 n 个数字。函数调用的开销很小,但维护此代码的开销很大。
    • @Daniel 替换为更快的数值方法。当然term 可以替换为pow10 并且只计算一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多