【问题标题】:Question about in-place sort关于就地排序的问题
【发布时间】:2010-05-30 13:17:02
【问题描述】:

例如,我们有以下数组:

char data[]=new char[]{'A','S','O','R','T','I','N','G','E','X','A','M','P','L','E'};

还有一个索引数组:

int  a[]=new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};

void insitu (char data[], int a[], N)
{
    for (int i=0;i<N;i++)
    {
        char v=data[i];
        int j, int k;
        for (k = i; a[k] != i; k = a[j], a[j]=j)
        {
            j=k;
            data[k]=data[a[k];
        }
        data[k]=v;
        a[k]=k;
    }
}

我的问题是应该将j 初始化为什么。当我运行这段代码时,它要求我初始化j;我该怎么办?

【问题讨论】:

  • for (k=i;a[k]!=i;k=a[j];a[j]=j) 这一行无法编译。这里有 4 个部分。
  • 这一行也无法编译data[k]=data[a[k];
  • 请将您的问题标记为作业,这显然不适合生产
  • 所以这段代码有很多错误是吗?什么是正确的形式?
  • @davit-datuashvili 那是什么?

标签: algorithm


【解决方案1】:

这是 Sedgewick 的 C++ 算法 (see page) 中就地排序的 Java 实现:

public class InSitu {
    public static void main(String[] args) {
        int[] a = { 0, 10, 8, 14, 7, 5, 13, 11, 6, 2, 12, 3, 1, 4, 9 };
        char[] data = { 'A', 'S', 'O', 'R', 'T', 'I', 'N', 'G',
            'E', 'X', 'A', 'M', 'P', 'L', 'E' };
        insitu(data, a, a.length);
        System.out.println(java.util.Arrays.toString(a));
        // prints "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]"
        System.out.println(java.util.Arrays.toString(data));
        // prints "[A, A, E, E, G, I, L, M, N, O, P, R, S, T, X]"
    }
    static void insitu(char[] data,int[] a, int N) {
        for (int i = 0; i < N; i++) {
            char v = data[i];
            int j, k;
            for (k=i; a[k] != i; k = a[j], a[j] = j) {
                j = k;
                data[k] = data[a[k]];
            }
            data[k] = v;
            a[k] = k;
        }
    }
}

关于数组声明

请不要养成这样声明数组的习惯:

int x[];

你应该把括号放在type,而不是identifier

int[] x;

相关问题


明确的任务

编译器足够聪明,可以知道何时明确分配了局部变量,并考虑了循环结构等。

以下代码编译:

        int local;
        do {
            local = 0;
        } while (local != 0);

虽然不是这样:

        int local;
        while (local != 0) { // doesn't compile!
            local = 0;
        }

类似地,编译:

        for (int local; ; local++) {
            local = 0;
        }

这是因为 for 循环的语义,其中循环体 (local = 0;) 在控制流中的循环更新 (local++) 之前,即使它在文本中可能看起来不像。

规范不允许编译器过于智能;例如以下内容无法编译:

    boolean b = false; // or whatever
    int local;
    if (b) {
        local = 0;
    }
    if (!b) {
        local = 1;
    }
    local++; // doesn't compile! 

但这确实:

    boolean b = false; // or whatever
    int local;
    if (b) {
        local = 0;
    } else {
        local = 1;
    }
    local++;

另见

【讨论】:

  • java编译器会让你在初始化之前使用j
  • Java 给所有变量一个默认值。声明初始化。这在 JLS 中定义:java.sun.com/docs/books/jls/second_edition/html/…。在此处查看更简单的解释:java.sun.com/docs/books/tutorial/java/nutsandbolts/…。所以在这种情况下,j 等于 0
  • @jasonmp85:类作用域,你是对的,方法作用域我很确定你错了。
  • @R0MANARMY:查看最新版本。
  • 你说得对,我的 JLS 链接甚至这样说:“局部变量(§14.4,§14.13)必须在使用之前显式地赋予一个值,通过初始化(§14.4)或赋值(第 15.26 节),编译器可以使用明确赋值规则(第 16 节)进行验证。”但是 poly 的回答仍然有效:j 在检查结束条件之前在循环内分配,因此不会读取未初始化的变量。
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 2013-05-11
  • 1970-01-01
  • 2011-06-05
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
相关资源
最近更新 更多