【问题标题】:Print only those numbers that are double of another number in the array in Java仅打印Java数组中另一个数字的两倍的数字
【发布时间】:2020-08-11 12:58:03
【问题描述】:

我正在练习算法,假设我们有一个包含元素 2, 3, 9, 12, 7, 18 的数组,那么 我只想打印 18,因为它是 9 的两倍。当我打印结果时,它总是显示更多的行,但是,打印的数字(如果有的话)很好。如何管理正确显示结果? (仅使用数组。)我知道这是一个愚蠢的问题,但我尝试了很多方法,结果只会更糟。

现在,它向我展示了这个示例(140 是正确的,但不需要另一行):

The following number is doubled of another number from the array: 0
The following number is doubled of another number from the array: 0
The following number is doubled of another number from the array: 140
The following number is doubled of another number from the array: 0
The following number is doubled of another number from the array: 0

我的代码:

public class DoubleNums {

    public static void main(String[] args) {

        Random random = new Random();

        int[] array = new int[50];
        int[] even;
        int[] doubleNum;
        int count = 0;
        int doubles = 0;

        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(200);
            System.out.println(array[i] + " ");
        }
        for (int j = 0; j < array.length; j++) { 
            even = new int[array.length];
            if (array[j] % 2 == 0) {
                even[count] = array[j];
                count++;
            }
            for (int k = 0; k < array.length; k++) {
                doubleNum = new int[array.length];
                if (array[j] / 2 == array[k]) {
                    even[doubles] = k;
                    doubles++;
                    System.out.println("The following number is doubled of another number from the array: " + even[doubles]);               
                }                
            }               
        }
        System.out.println("Number of even nums: " + count);
        }
    }

【问题讨论】:

  • 您应该检查j 不等于k。此外,您可以在第二个 for 循环(外部循环)中重用名称 i
  • 您使用 'array[j] / 2 == array[k]' 作为条件。因为一切都是整数,记住 5/2 == 2,所以最好使用 'array[j] = (array[k] * 2)'

标签: java arrays algorithm


【解决方案1】:

使用HashSet&lt;Integer&gt; 存储每个元素的双倍值:

Set<Integer> setOfArray = new HashSet<>();
for (int a : array) setOfArray.add(2 * a);

然后再次循环遍历数组,寻找匹配的元素:

for (int a : array) {
  if (setOfArray.contains(a)) {
    System.out.println(a);
  }
}

或者

IntStream.of(array).boxed().filter(setOfArray::contains)
    .forEach(System.out::println);

【讨论】:

  • 整数除法不会导致这个错误处理赔率吗?条件中可能需要 % 2 == 0。
  • 嘿,感谢您的简单性 (+1),我知道它更快,但我认为我们可以使用我的代码进行一些小的更改来找到解决方案。
【解决方案2】:

这是一个简单的任务:首先,对于每个数字 n,将 2n 存储在一个集合中。然后,遍历这些数字并检查它们中的哪一个在集合中。

import java.util.*;

public class DoubleNums {
    public static void main(String[] args) {
        int[] numbers = new int[]{2, 3, 9, 12, 7, 18};   //original array

        HashSet<Integer> h = new HashSet<Integer>();     //set

        for(int i = 0; i < numbers.length; i++) h.add(numbers[i] * 2);
        for(int i = 0; i < numbers.length; i++){
            if(h.contains(numbers[i])) System.out.println(numbers[i]);
        }
    }
}

复杂度:O(n)

HashSet&lt;Integer&gt; 的工作方式类似于简单的集合,但速度更快,因为它使用哈希表的属性来添加和查找元素。

【讨论】:

    【解决方案3】:

    我看到您要求从您自己的代码开始的解决方案...

    我知道它更快,但我认为我们可以使用我的 代码稍作改动。

    所以我试图理解你想要做什么,但我无法破译你的方法,所以从你的开始,我创建了一个更清晰的版本。


    变化

    • 我使用 ArrayList (list) 作为支持而不是您的数组 (even)。 List 在您的情况下非常方便,因为它具有 contains() 功能,而且它的大小是可变的。
    • 我在数组中取了一个偶数,并查找是否至少有一个“一半”。

    代码

    public static void main(String[] args) {
        Random random = new Random();
    
        int[] array = new int[20];
        ArrayList<Integer> list = new ArrayList<>();
        int evenNumber = 0;
    
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(100);
        }
    
        System.out.println(Arrays.toString(array));
    
        for (int i = 0; i < array.length; i++) {
            // If I found an even number and this is NOT already in the list then I'll study it
            if (array[i] % 2 == 0 && !list.contains(array[i])) {
                evenNumber = array[i];
                for (int j = 0; j < array.length; j++) {
                    // I add "evenNumber" to the list only if at least one its "half" exist in the array
                    if (array[j] * 2 == evenNumber) {
                        list.add(evenNumber);
                        // I dont need to search more, I already found its "half"!
                        break;
                    }
                }
            }
        }
    
        System.out.println("Doubled nums: " + list);
    }
    

    样本输出

    [71, 88, 45, 97, 64, 31, 54, 12, 14, 86, 22, 42, 35, 44, 70, 65, 93, 85, 99, 14]
    Doubled nums: [88, 44, 70]
    

    【讨论】:

    • 嘿@Alberto!这是迄今为止对我来说最好的解决方案(+1)。但我不想使用List,因为我没有在上面的代码中使用它,只有数组。我知道这很愚蠢,但我现在正在练习数组(到目前为止它超出了我的范围,我想更好地理解数组背后的逻辑)。我也可以使用其他方法重现此练习,但现在我只想将数组用于此方法。
    【解决方案4】:

    有序数组的二分查找

    另一种方法是对数组进行排序 (Arrays.sort),然后重复执行二进制搜索 (Arrays.binarySearch)。

    我不确定这是否比其他答案中的散列方法更快。

    使用Arrays.sort 会更改原始数组。因此,如果这对您很重要,请先复制数组。

    为了使二分搜索更快一点,请指定数组的一个子范围。

    // int streamSize = 6, randomNumberOrigin = 1, randomNumberBound = 18;
    // Half-Open: Origin is inclusive, Bound is exclusive.
    // int[] ints =
    //        ThreadLocalRandom
    //            .current()
    //            .ints( streamSize , randomNumberOrigin , randomNumberBound )
    //            .toArray();
    
    int[] ints = { 2, 3, 9, 12, 7, 18 } ;
    
    System.out.println( "array = " + Arrays.toString( ints ) );
    
    Arrays.sort( ints );
    List < Integer > doubledNumbers = new ArrayList <>();
    int index = 0;
    for ( int anInt : ints )
    {
        int doubled = ( anInt * 2 );
        // Javadoc: binarySearch​ (int[] a , int fromIndex , int toIndex ,
        // int key ). First element inclusive, last element exclusive.
        int position = Arrays.binarySearch( ints , index , ints.length , doubled );
        // If the doubled value is found, remember it.
        if ( position >= 0 ) { doubledNumbers.add( ints[ position ] ); }
        // Prepare for next loop.
        index++;
    }
    System.out.println( "doubledNumbers: " + doubledNumbers.toString() );
    

    运行时。

    数组 = [2, 3, 9, 12, 7, 18]

    doubledNumbers:[18]

    顺便说一句,我考虑过使用SortedSet,例如TreeSet。但是在快速查看OpenJDK version 14 source code 之后,contains 方法似乎使用了遍历所有元素的迭代器,没有利用按排序顺序维护的键进行优化。

    【讨论】:

    • 你好@Basil!感谢您的解决方案,这确实是一个不错的方法(+1)。在我的其他练习中,二分搜索肯定对我有用。但是,就我而言,现在我想仅使用数组来解决问题。
    【解决方案5】:

    好吧,我设法解决了我想在我的问题中解决的问题,但每个人都非常乐于助人,所以我不知道我应该接受哪个答案:)

    Random random = new Random();
    
    int[] array = new int[50];
    int[] newArray;
    int evenNumber;
    
    for (int i = 0; i < array.length; i++) {
        array[i] = random.nextInt(200);
        System.out.println(array[i] + " ");
    }
    newArray = new int[array.length];
    for (int i = 0; i < array.length; i++) {
        if (array[i] % 2 == 0) {
            evenNumber = array[i];
            for (int j = 0; j < array.length; j++) {
                if (array[j] * 2 == evenNumber) {
                    evenNumber = i;
                    System.out.println("The searched numbers: " + array[evenNumber]);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 2014-05-18
      • 2012-03-17
      • 1970-01-01
      相关资源
      最近更新 更多