Для каждой позиции мы хотели бы знать, какие ячейки указывают на нее.
1 2 4 5 4 1
5: 3
4: 2, 4 (leader)
3: None
2: 1
1: 0, 5
0: None
Теперь следуйте назад от лидера:
Who's looking at 4?
-> 2
[x, x, 1, x, 0, x]
Who's looking at 2?
-> 1
[x, 2, 1, x, 0, x]
Who's looking at 1?
-> 0 and 5
[3, 2, 1, x, 0, 3]
Who's looking at 0 or 5?
-> 3
[3, 2, 1, 4, 0, 3]
Псевдокод:
// For each position, we'd like to know
// which cells are pointing to it
A = input array
leader = None
map = {}
for i=0 to length(A)-1:
if i = A[i]:
leader = i
if i != leader:
if A[i] in map:
map[A[i]].append(i)
else:
map[A[i]] = [i]
//Now follow backwards from the leader
output = Array(length(A))
next = leader
output[leader] = 0
rank = 0
// Assumes the data provides
// for a straightforward solution.
// There may be edge cases to work
// out if that's not the case.
while next:
for i in map[next]:
next = None
if i in map:
next = i
rank = rank + 1
for j in map[next]:
output[j] = rank
break
Нет, нет.
Java "финал" не является точным эквивалентом C++ "константа". Следующее (задержанная инициализация последней переменной) работает в Java:
final double x;
int w = 1;
if (w > 2)
{
x = 0.5;
}
else
{
x = - 0.5;
}
но это не работает в C++ с "финалом", замененным "константой".
Используя "финал" на переменной в объявлении метода может быть полезным в Java, потому что позволяет Вам использовать эту переменную в любом анонимном классе, созданном в Вашем методе.
PS. Я был сначала разочарован отсутствием "константы" в Java, но позже учился жить с "финалом".
PS2. Глоссарий Java (http://mindprod.com/jgloss/immutable.html), связанный с в этом потоке, имеет одну вещь неправильно: нет, Вам не дают 100%-ю гарантию, что последняя переменная не изменяет свое значение:
1) это изменяется от "неопределенного" до "определенного", но компилятор скажет Вам при ссылке на него перед инициализацией
2) на Linux двойное имеет 80-разрядную точность при хранении в регистре, но 64-разрядный при хранении в памяти. Когда финал удваивается, переменная продвинута из регистра, это будет усеченным и изменит свое значение. Как Joel Spolsky говорит, "абстракция дала течь".
BTW: Java действительно имеет константу как ключевое слово, но Вы не можете использовать его нигде.
Java не имеет ничего как понятие C++ константы. Это - предмет некоторого спора, хотя интересно отметить, что.NET не делает также. Я полагаю, что причины:
Как выше, нет в Java нет никакой константы. Но когда мы хотим достигнуть 'близкий' к тому же результату в Java, мы используем
public static final Object x = somedata;
Это устанавливает данные в той точке и раскрытии утечек абстракции и т.д, Вы имеете как близко к эквиваленту, поскольку можно добраться.
Самый близкий Java, эквивалентный для const
final
.
void func(final SomeClass x) {
// The following causes a compiler error
x = ...;
// The following works. If you don't want it to, then you have to make
// somevar final or write a getter (but not a setter) for it in SomeClass.
x.somevar = ...;
}
Посмотрите это для достижения этого в Java: Неизменные объекты в Java