更改数组中的值而不遍历Java中的整个数组?

时间:2015-03-27 19:41:01

标签: java

例如:如果我的数组是arr[5] = {5,2,1,5,8};

因此,如果我必须将所有5&#s更改为-1,则可能的方法是检查每个元素if value==5,然后将其更改为-1。

JAVA还有其他方法吗?

我使用指针数组在C中找到了解决方案,但在JAVA中找不到。

这是c代码:

#include <stdio.h>

 void main()

{
int i ;

int a[7] = {0,1,2,3,4,5,6};

int *ptr[5] = { &a[2] , &a[5] , &a[1] , &a[5] , &a[5] } ;


printf("The value of array is :\n");
for(i = 0 ; i < 5 ; i++)
{

    printf("%d  ",*ptr[i]);

}printf("\n");

//////Now changing 5 ot -1 I require only one step , not to traverse entire    ///array , Here the step is : 

a[5] = -1 ;

///final array is :
for(i = 0 ; i < 5 ; i++)
{

    printf("%d  ",*ptr[i]);

}

}

6 个答案:

答案 0 :(得分:3)

正如你所说的那样,没有。您必须对数组进行排序或使用其他结构才能轻松找到所有5并更改它们。

您的指针数组揭示了您的想法:如果您的数组不是int,而是包含int s的可变对象,则可以完成此操作。然后,如果所有5都由同一个Object表示,则可以改变该对象以改变列表中的所有5。如果你真正想要的是int的数组,那么这不是正确的解决方案,因为确保所有5是同一个对象的问题,以及封装它们的低效率。

根据问题更新进行更新:

我对你所做的事情的猜测是完全正确的。我建议的对象等同于您使用的int指针(事实上,所有对象都是指针,尽管它们指的不仅仅是int)。您可以在C代码中看到我为此解决方案指出的相同问题:它仅在您指向a的元素时才有效,如果a包含数组中的每个可能的数字,并且您之后不需要将任何5插入数组中(因为尝试转到5现在发送给-1)。真的,你并没有像你想象的那样解决问题。在某些情况下,此类解决方案可能有用,但修改任意int[]不是其中之一。

答案 1 :(得分:1)

如果您希望比循环遍历所有索引更快,则需要其他数据。一个例子是使用inverted index。但是,创建数据所需的时间会更长,从而遍历整个数组。

倒排索引会将值映射到索引,即arr = {5,2,1,5,8}

1 -> {2}
2 -> {1}
5 -> {0, 3}
8 -> {4}

创建索引

Map<Integer, List<Integer>> invertedIndex = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
    int val = arr[i];
    List<Integer> l = invertedIndex.get(val);
    if (l == null) {
        l = new LinkedList<>();
        invertedIndex.put(val, l);
    }
    l.add(i);
}

替换值

int numToReplace = 5;
int newValue = -1;
//--------------------
List<Integer> l = invertedIndex.remove(numToReplace);
if (l != null) {
    // replace numbers in arr
    for (int index : l) {
        arr[index] = newValue;
    }
    // update inverted index
    List<Integer> l2 = invertedIndex.get(newValue);
    if (l2 != null) {
        l2.addAll(l);
    } else {
        invertedIndex.put(newValue, l);
    }
}

更改单个元素

int index = ...;
int newValue = ...;
//-------------------
int oldValue = arr[index];
List<Integer> oldList = invertedIndex.get(oldValue);
oldList.remove(index);
if (oldList.isEmpty()) {
    invertedIndex.remove(oldValue);
}
List<Integer> l = invertedIndex.get(newValue);
if (l == null) {
    l = new LinkedList<>();
    invertedIndex.put(newValue, l);
}
l.add(index);

答案 2 :(得分:0)

如果你想在没有遍历的情况下这样做,那么可能不是一个合适的数据结构。使用Map代替以下方式 -

Map<Integer, Integer> map = new HashMap<Integer, Integer>();  

之后你可以像这样把数字放进去 -

map.put(5,5);
map.put(2,2);
map.put(1,1)

答案 3 :(得分:0)

决定将我的两分钱投入。当然不会更有效率,但如果提问者在这里寻找替代解决方案,那就去吧!

public static void main(String[] args){
    //52158
    int[] arr = {5,2,1,5,8};
    String strArr = Arrays.toString(arr);
    strArr = strArr.replaceAll("5", "-1");
    strArr = strArr.replaceAll("\\[", "");
    strArr = strArr.replaceAll("\\]", "");
    strArr = strArr.replaceAll(",", "");
    strArr = strArr.replaceAll(" ", "");
    ArrayList<Integer> endArr = new ArrayList<Integer>();
    for (int i = 0; i < strArr.length(); i++){
        if (strArr.substring(i, i + 1).equals("-")) {
            endArr.add(Integer.parseInt(strArr.substring(i, i + 2)));
            i++;
        }
        else endArr.add(Integer.parseInt(strArr.substring(i, i + 1)));
    }   
}

我刚刚转换为一个字符串,将它们全部替换掉​​然后将其转换回来。是的几乎完全没用,你必须非常天真地实现这个解决方案,但它是不同的,因为我使用字符串操作与数组操作。我知道的差别不大,但确实如此。

答案 4 :(得分:-1)

使用数据结构,使值按降序排序。然后遍历直到你找到5#s。改变这些价值观。维奥拉,你没有穿过整个阵列,尽管你可能还是会做更多的工作。

我建议使用max-heap。在Java中,PriorityQueue会做你想要的。

虽然知道这不会比单次遍历数组更有效地运行。保持有序的数据结构并对其执行操作非常耗时。

答案 5 :(得分:-1)

Java只使用指针,但你看不到它。为此,您需要对所有阵列进行分散处理,或者另外执行另一个阵列。