Более эффективный способ кодирования этой программы - PullRequest
2 голосов
/ 18 мая 2011

Эта программа была домашним заданием. Мы уже закончили и готовы идти. Мне было интересно, если есть более обтекаемый способ написания этой программы? Программа называется Interleave, и она берет два ArrayLists и объединяет их так, что каждый второй элемент в первом происходит из второго ArrayList. Звучит просто, и мы использовали Итератор, чтобы пройти и добавить необходимые элементы. Но код БЛОК. Мне кажется, что должен быть лучший способ написать это, верно? Заранее спасибо.

import java.util.*;

public class Interleave
{

public static void main(String[] args)
{

    ArrayList<Integer> a1 = new ArrayList<Integer>();
    Collections.addAll(a1, 10, 20, 30);

    ArrayList<Integer> a2 = new ArrayList<Integer>();
    Collections.addAll(a2, 4, 5, 6, 7, 8, 9);

    System.out.println(a1);
    System.out.println(a2);

    System.out.println(interleave(a1, a2));

    ArrayList<String> list = new ArrayList<String>();
    String[] words =
    { "how", "are", "you?" };

    for (String s : words)
    {
        list.add(s);
    }

}

public static ArrayList<Integer> interleave(ArrayList<Integer> a1,
        ArrayList<Integer> a2)
{
    Iterator<Integer> it = a2.iterator();
    int i = 1;
    while (it.hasNext())
    {
        int val = it.next();
        if (a1.size() >= i)
        {
            a1.add(i, val);
        } else
        {
            a1.add(val);
        }
        i += 2;
    }
    return a1;

}

}

Ответы [ 4 ]

2 голосов
/ 18 мая 2011
public static ArrayList<Integer> interleave(ArrayList<Integer> a1, ArrayList<Integer> a2)
{
    Iterator<Integer> it1 = a1.iterator();
    Iterator<Integer> it2 = a2.iterator();
    ArrayList<Integer> output = new ArrayList<Integer>();

    while (it1.hasNext() || it2.hasNext())
    {
        if (it1.hasNext()) { output.add( it1.next() ); }
        if (it2.hasNext()) { output.add( it2.next() ); }
    }

    return output;    
}
1 голос
/ 18 мая 2011

Эффективность важнее, чем то, как выглядит код. Каждый раз, когда вы добавляете элемент с индексом i, каждый элемент после этого индекса должен перемещаться на один индекс с помощью ArrayList, поскольку он использует массив в качестве своей базовой структуры данных. Этот код был бы намного эффективнее, если бы он использовал LinkedList, который позволяет избежать этой проблемы, или если вы создали третий массив размера (первый массив + второй массив) и просто добавили к нему элементы. Опять же, вы также должны учитывать пространство, поэтому создание другого массива увеличивает требования к пространству.

Даже если вы придерживаетесь своего текущего подхода, вы должны увеличить емкость массива ПЕРЕД добавлением всех элементов. Таким образом, емкость массива уже будет достаточно большой, чтобы добавить все элементы из другого массива, и ее (потенциально) не нужно будет увеличивать многократно.

Надеюсь, это поможет.

редактирование:

Вы также можете перенастроить свой массив заранее, чтобы каждое второе пятно уже было пустым, что избавило бы вас от проблемы смещения массива, которую я описал ранее.

0 голосов
/ 18 мая 2011

Не думаю, что вы можете значительно сократить объем кода.Вероятно, это нельзя сделать слишком быстрым.Однако я бы предложил некоторые другие улучшения:

  1. Не рекомендуется изменять объект, который вы передаете, если возвращаете другой объект.
  2. Вы можете просто использовать List вместо ArrayList, чтобы можно было передавать любой тип List.
  3. Вы можете использовать дженерики, чтобы не привязывать их к списку Integer.

Все это в совокупности даст что-то вроде этого:

public static <T> List<T> interleave(List<T> a1, List<T> a2) {
    List<T> list = new ArrayList<T>(a1.size() + a2.size());
    Iterator<T> it1 = a1.iterator();
    Iterator<T> it2 = a2.iterator();

    while (it1.hasNext() || it2.hasNext()) {
        if (it1.hasNext()) {
            list.add(it1.next());
        }
        if (it2.hasNext()) {
            list.add(it2.next());
        }
    }

    return list;
}
0 голосов
/ 18 мая 2011

В данный момент ваша функция interleave предполагает реализацию списка * (ArrayList) и , которые должны содержать (* 1009)*).Вы можете обобщить эту функцию с помощью обобщений:

public static <T> List<T> interleave(List<T> first, List<T> second)
{
    Iterator<T> it = second.iterator();
    int i = 1;
    while (it.hasNext()) {
        T val = it.next();
        if (first.size() >= i)
            first.add(i, val);
        else
            first.add(val);
        i += 2;
    }

    return first;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...