[java] Массив пользовательского типа или вопрос от нуба

MoyaStrujka

Ява мне в новинку. Есть класс
public static class Square
{
int xL,yL;
int xR,yR;
Square
{
xL = 0; yL = 0;
xR = 1; yR = 1;
}
Square(int X1,int Y1,int X2,int Y2)
{
xL = X1;
yL = Y1;
xR = X2;
yR = Y2;
}
void Organize
{
int tempxL = this.xL;
int tempyL = this.yL;
this.xL = Math.min(this.xL, this.xR);
this.yL = Math.min(this.yL, this.yR);
this.xR = Math.max(tempxL, this.xR);
this.yR = Math.max(tempyL, this.yR);


}


}

Но код ниже работать не будет. Насколько я понимаю, приведения типа Square к Square[] не происходит. Вопрос простой: как мне создать массив типа Square и инициализировать его.

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt;
Square s[] = new Square[n];
for (int i = 0; i < n;i++)
{
s[i].xL = sc.nextInt;
s[i].yL = sc.nextInt;
s[i].xR = sc.nextInt;
s[i].yR = sc.nextInt;
s[i].Organize;
}
}

MoyaStrujka

вроде допер, так работает
    public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt;
Square s[] = new Square[n];
for (int i = 0; i < n;i++)
{
s[i] = new Square;

s[i].xL = sc.nextInt;
s[i].yL = sc.nextInt;
s[i].xR = sc.nextInt;
s[i].yR = sc.nextInt;
s[i].Organize;
}
}

zorin29

Ты уже все сделал(а) правильно, но, возможно, еще не понял(а что было неправильно. Это опасно, поэтому я попробую дополнительно пояснить.
Насколько я понимаю, приведения типа Square к Square[] не происходит.
Это и невозможно. Как ты приведешь тип "квадрат" к типа "массив квадратов"?
Кроме того, ты в своем коде это и не пытаешься сделать.
Просто массив у тебя создаются (new Square[n] а элементы его не инициализируются. В твоем втором листинге ты инициализируешь его элементы (s[i] = new Square ) и только потом обращаешься к ним, поэтому ошибки нет.

apl13

Просто массив у тебя создаются (new Square[n] а элементы его не инициализируются.
Ы. А есть способ создать, чтоб проинициализировались?

schipuchka1

{new A(1 new A(2)}

apl13

{new A(1 new A(2)}
... new A(19283)? :o

MoyaStrujka

спасибо. Да, я не совсем правильно выразился.
вопрос про http://acm.timus.ru/
кто-нибудь решал там задания? Я уже штуки 4 решил, но у меня ни одна не прошла все тесты.

MoyaStrujka

похоже опять придется просить помощи. На этот раз с алгоритмом.
Дан массив double[] l, нужно вывести индексы элементов от наименьшего к наибольшему.
Есть такой код
 

int idx[] = new int[l.length];
for (int i = 0;i<idx.length;i++)
{
idx[i]=i;
}
int temp;

for (int i=0; i<n; i++)
{
for (int j=i+1; j<n; j++)
{
if (l[idx[i]] > l[idx[j]])
{
temp = idx[i];
idx[i] = idx[j];
idx[j] = temp;

}
}
}

но он является неустойчивым, т.е. для массива {100,10,10,1}
он выведет 3210 а, не 3120

Dimon89

А может просто отсортировать выданный массив каким-нибудь устойчивым алгоритмом с параллельной сортировкой массива индексов? Вообще, вариантов много...

Ivan8209

> нужно вывести индексы элементов от наименьшего к наибольшему
Построй массив пар "индекс --- значение", заведи отношение
порядка на этих парах, которое сравнивает значения,
отсортируй этот массив, выведи значения индексов по порядку.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

MoyaStrujka

кажется написал, упорядочил массив idx. Метод Sort - обычная сортировка пузырьком. Код мне не нравится, но вроде работает.
 
public static int[] Sort2(int[]idx, double[]l)
{
int index0, indexl;
int i;
for (i = 0;i<idx.length;i++)
{
index0 = i;
indexl = i;

while(indexl + 1 <idx.length&&l[idx[indexl]] == l[idx[indexl+1]])
{
indexl++;
}
if(index0 == indexl) continue;
int temp[] = new int[indexl-index0 + 1];
for (int j = 0; j < temp.length; j++)
{
temp[j] = idx[j+index0];
}
temp = Sort(temp);
for (int j = 0; j < temp.length; j++)
{
idx[j+index0] = temp[j];
}
i = i + indexl - index0;

}
return idx;
}

andra1980

Зачем писать сортировку пузырьком, если всё уже написано для нас?

public static int[] sortIdx(final double[] values) {
List<Integer> idx = new ArrayList<Integer>(values.length);
for (int i=0; i<values.length; i++) {
idx.add(i);
}

Comparator<Integer> comp = new Comparator<Integer> {
@Override
public int compare(Integer i1, Integer i2) {
return Double.compare(values[i1], values[i2]);
}
};

Collections.sort(idx, comp);
return toArray(idx);
}

private static int[] toArray(List<Integer> list) {
int[] res = new int[list.size];
for (int i=0; i<res.length; i++) {
res[i] = list.get(i);
}
return res;
}

MoyaStrujka

О, вот оно! Спасибо большое.

zorin29

Зачем писать сортировку пузырьком, если всё уже написано для нас?
Это же timus.ru, задачка про модифицированную сортировку, а ты ее превращаешь в задачу правильно инициализировать аргументы Collections.Sort.
Мне кажется, в интересах человечества запретить пользоваться библиотечной сортировкой людям, которые еще не могут написать сортировку пузырьком сами.
На C# тоже можно написать

var answer = array
.Selectx,i)=>new{i, x})
.OrderBy(t=>t.x)
.Select(t=>i)
.ToArray;

Но обучающего значения это решение не имеет.

zorin29

кажется написал, упорядочил массив idx. Метод Sort - обычная сортировка пузырьком. Код мне не нравится, но вроде работает.
Мне код тоже не нравится. Давай я тебе расскажу, почему.
1. То, что мы делаем, называется сортировка данных по ключу, или нагруженная сортировка. Элемент данных в нашем случае - это пара (значение, хранящееся в массиве; индекс этого значения в массиве).
2. Нагруженная сортировка называется устойчивой, если она не меняет порядок элементов, у которых совпадают ключи.
3. Устойчивая сортировка или нет - это свойство алгоритма сортировки. В частности, алгоритм, который ты написал в первом посте (модификация сортировки прямым выбором) не является устойчивой сортировкой, как ты правильно заметил.
4. Правильное решение - заменить сортировку на устойчивую. Их множество: тот же пузырек, сортировка вставками. Надеюсь, ты знаешь и о сортировках за O(NlogN они тоже могут быть устойчивыми.
5. Но ты вместо этого написал пост-обработку полученного тобой неустойчиво отсортированного массива, которая пересортировывает индексы элементов с одинаковым ключом.
- Во-первых, это уродливо выглядит, как ты и сам заметил.
- Во-вторых, это не обобщается на случай нагруженной сортировки, если данные не являются индексами в исходном массиве.
- В-третьих, ты мог добиться того же эффекта (сортировка сперва по ключу, а затем, при равенстве ключей, по индексу заменив в исходном коде условие

if (l[idx[i]] > l[idx[j]])

на

if (l[idx[i]] > l[idx[j]] || l[idx[i]] == l[idx[j]] && idx[i]>idx[j])
// либо левый элемент больше, либо они равны, но индекс левого больше
Оставить комментарий
Имя или ник:
Комментарий: