Java数组和for循环导致错误的输出

时间:2014-08-29 04:32:33

标签: java arrays

要求是检查数组中的重复项并删除它,然后数组中的其余项必须向左移动。

我写了这个:

public class TestRepeat {

public static int deleteRepeats(char[] ch) {

    int count = 0;
    for (int x = 0; x < ch.length; x++) {
        for (int y = x + 1; y < ch.length; y++) {
            if (ch[x] == ch[y]) {
                for (int k = y; k < ch.length - 1; k++) {//shifts the array to the right if its a duplicate
                    ch[k] = ch[k + 1];
                }
                ch[ch.length - 1] = ' ';//replaces the last array with a blank
            }
        }
    }
    for (int q = 0; q < ch.length; q++) {
        if (ch[q] == ' ') {
            count++;
        }
    }
    return count;//returns the number of deleted items
}

public static void main(String[] args) {
    char[] ch = {'k', 'a', 'm', 'o', 'k', 'm', 'y', 'm', 'k', 'k', 'x', 'm', 'm', 'o'};
    System.out.print("The original array is: ");
    System.out.println(ch);
    System.out.println("Number of deleted characters: " + deleteRepeats(ch));
    System.out.print("The new array is: ");
    System.out.println(ch);
}

}

它应该返回:

  

原始数组是:kamokmymkkxmmo

     

删除的字符数:8

     

新阵列是:kamoyx

,而是返回:

  

原始数组是:kamokmymkkxmmo

     

删除的字符数:6

     

新阵列是:kamoykxm

导致问题的原因是什么?如何解决?

4 个答案:

答案 0 :(得分:1)

我发现了两个错误,其中一个导致了您的问题,另一个是推论。首先,你不能为内循环使用for循环,因为有时你正在修改你循环的数组。因此,在某些迭代中,您隐式地将y递增两次:一次实际递增y,再次将数组的一部分移到左侧。因此,当您不对数组执行更改时,您应该只实际递增y,并在删除元素时将y保留在原来的位置。其次,您必须确保不要尝试删除' ',因为它会在while循环版本中导致无限递归。错误修正如下:

public class TestRepeat {

/** Deletes index index in arr. Elements in (index, arr.length) are shifted to the left,
    And a ' ' is put at the end of arr 
    Precondition: index >= 0, index < arr.length */
private static void deleteAndShift(char[] arr, int index){
    for(int i = index; i < arr.length - 1; i++){
        arr[i] = arr[i+1];
    }
    arr[arr.length - 1] = ' ';
}

public static int deleteRepeats(char[] ch) {

    int count = 0;
    for (int x = 0; x < ch.length; x++) {
        int y = x+1;
        while(y < ch.length){
            //Delete index y. Note that this 'implicitly' increments y by shifting ch.
            if (ch[x] != ' ' && ch[x] == ch[y]) {
               deleteAndShift(ch, y);
            }
            //Only increment y if an element wasn't deleted
            else{
              y++;
            }
        }
    }
    for (int q = 0; q < ch.length; q++) {
        if (ch[q] == ' ') {
            count++;
        }
    }
    return count;//returns the number of deleted items
}

public static void main(String[] args) {
    char[] ch = {'k', 'a', 'm', 'o', 'k', 'm', 'y', 'm', 'k', 'k', 'x', 'm', 'm', 'o'};
    System.out.print("The original array is: ");
    System.out.println(ch);
    System.out.println("Number of deleted characters: " + deleteRepeats(ch));
    System.out.print("The new array is: ");
    System.out.println(ch);
}

}

此代码具有在样本输入中删除8个字符所需的输出。

答案 1 :(得分:0)

if条件块if (ch[x] == ch[y]) {替换为

if (ch[x] != ' ' && ch[x] == ch[y]) {                   
   for (int k = y; k < ch.length - 1; k++) {//shifts the array to the right if its a duplicate                      
       ch[k] = ch[k + 1];
   }                    
   ch[ch.length - 1] = ' ';//replaces the last array with a blank
   y--;
}

答案 2 :(得分:0)

将它们移到左边后,做一个y--; 这将有助于照顾连续重复的元素

答案 3 :(得分:0)

set的帮助下,我们可以轻松实现它。

char[] ch = {'k', 'a', 'm', 'o', 'k', 'm', 'y', 'm', 'k', 'k', 'x', 'm', 'm', 'o'};
System.out.print("The original array is : ");
System.out.println(ch);

// Moving in to LinkedHashSet
Set<Character> charSet = new LinkedHashSet<Character>();
for(char c : ch) 
   charSet.add(c);

System.out.println("Number of deleted characters :"+(ch.length-charSet.size()));

// Move Back to newArray
char[] newch = new char[charSet.size()];
int i = 0;
for(char c : charSet)
   newch[i++] = c;

System.out.print("The new array is :");
System.out.println(newch);

输出:

The original array is : kamokmymkkxmmo
Number of deleted characters :8
The new array is :kamoyx