Как работает for (;;) на Java? [Дубликат]

Моя попытка:

def merge(lsts):
  sets = [set(lst) for lst in lsts if lst]
  merged = 1
  while merged:
    merged = 0
    results = []
    while sets:
      common, rest = sets[0], sets[1:]
      sets = []
      for x in rest:
        if x.isdisjoint(common):
          sets.append(x)
        else:
          merged = 1
          common |= x
      results.append(common)
    sets = results
  return sets

lst = [[65, 17, 5, 30, 79, 56, 48, 62],
       [6, 97, 32, 93, 55, 14, 70, 32],
       [75, 37, 83, 34, 9, 19, 14, 64],
       [43, 71],
       [],
       [89, 49, 1, 30, 28, 3, 63],
       [35, 21, 68, 94, 57, 94, 9, 3],
       [16],
       [29, 9, 97, 43],
       [17, 63, 24]]
print merge(lst)

Benchmark:

import random

# adapt parameters to your own usage scenario   
class_count = 50
class_size = 1000
list_count_per_class = 100
large_list_sizes = list(range(100, 1000))
small_list_sizes = list(range(0, 100))
large_list_probability = 0.5

if False:  # change to true to generate the test data file (takes a while)
  with open("/tmp/test.txt", "w") as f:
    lists = []
    classes = [range(class_size*i, class_size*(i+1)) for i in range(class_count)]
    for c in classes:
      # distribute each class across ~300 lists
      for i in xrange(list_count_per_class):
        lst = []
        if random.random() < large_list_probability:
          size = random.choice(large_list_sizes)
        else:
          size = random.choice(small_list_sizes)
        nums = set(c)
        for j in xrange(size):
          x = random.choice(list(nums))
          lst.append(x)
          nums.remove(x)
        random.shuffle(lst)
        lists.append(lst)
    random.shuffle(lists)
    for lst in lists:
      f.write(" ".join(str(x) for x in lst) + "\n")

setup = """
# Niklas'
def merge_niklas(lsts):
  sets = [set(lst) for lst in lsts if lst]
  merged = 1
  while merged:
    merged = 0
    results = []
    while sets:
      common, rest = sets[0], sets[1:]
      sets = []
      for x in rest:
        if x.isdisjoint(common):
          sets.append(x)
        else:
          merged = 1
          common |= x
      results.append(common)
    sets = results
  return sets

# Rik's
def merge_rik(data):
  sets = (set(e) for e in data if e)
  results = [next(sets)]
  for e_set in sets:
    to_update = []
    for i,res in enumerate(results):
      if not e_set.isdisjoint(res):
        to_update.insert(0,i)

    if not to_update:
      results.append(e_set)
    else:
      last = results[to_update.pop(-1)]
      for i in to_update:
        last |= results[i]
        del results[i]
      last |= e_set
  return results

# katrielalex's
def pairs(lst):
  i = iter(lst)
  first = prev = item = i.next()
  for item in i:
    yield prev, item
    prev = item
  yield item, first

import networkx
def merge_katrielalex(lsts):
  g = networkx.Graph()
  for lst in lsts:
    for edge in pairs(lst):
      g.add_edge(*edge)
  return networkx.connected_components(g)

# agf's (optimized)
from collections import deque
def merge_agf_optimized(lists):
  sets = deque(set(lst) for lst in lists if lst)
  results = []
  disjoint = 0
  current = sets.pop()
  while True:
    merged = False
    newsets = deque()
    for _ in xrange(disjoint, len(sets)):
      this = sets.pop()
      if not current.isdisjoint(this):
        current.update(this)
        merged = True
        disjoint = 0
      else:
        newsets.append(this)
        disjoint += 1
    if sets:
      newsets.extendleft(sets)
    if not merged:
      results.append(current)
      try:
        current = newsets.pop()
      except IndexError:
        break
      disjoint = 0
    sets = newsets
  return results

# agf's (simple)
def merge_agf_simple(lists):
  newsets, sets = [set(lst) for lst in lists if lst], []
  while len(sets) != len(newsets):
    sets, newsets = newsets, []
    for aset in sets:
      for eachset in newsets:
        if not aset.isdisjoint(eachset):
          eachset.update(aset)
          break
      else:
        newsets.append(aset)
  return newsets

# alexis'
def merge_alexis(data):
  bins = range(len(data))  # Initialize each bin[n] == n
  nums = dict()

  data = [set(m) for m in data ]  # Convert to sets
  for r, row in enumerate(data):
    for num in row:
      if num not in nums:
        # New number: tag it with a pointer to this row's bin
        nums[num] = r
        continue
      else:
        dest = locatebin(bins, nums[num])
        if dest == r:
          continue # already in the same bin

        if dest > r:
          dest, r = r, dest   # always merge into the smallest bin

        data[dest].update(data[r])
        data[r] = None
        # Update our indices to reflect the move
        bins[r] = dest
        r = dest

  # Filter out the empty bins
  have = [ m for m in data if m ]
  return have


def locatebin(bins, n):
  while bins[n] != n:
    n = bins[n]
  return n

lsts = []
size = 0
num = 0
max = 0
for line in open("/tmp/test.txt", "r"):
  lst = [int(x) for x in line.split()]
  size += len(lst)
  if len(lst) > max: max = len(lst)
  num += 1
  lsts.append(lst)
"""

setup += """
print "%i lists, {class_count} equally distributed classes, average size %i, max size %i" % (num, size/num, max)
""".format(class_count=class_count)

import timeit
print "niklas"
print timeit.timeit("merge_niklas(lsts)", setup=setup, number=3)
print "rik"
print timeit.timeit("merge_rik(lsts)", setup=setup, number=3)
print "katrielalex"
print timeit.timeit("merge_katrielalex(lsts)", setup=setup, number=3)
print "agf (1)"
print timeit.timeit("merge_agf_optimized(lsts)", setup=setup, number=3)
print "agf (2)"
print timeit.timeit("merge_agf_simple(lsts)", setup=setup, number=3)
print "alexis"
print timeit.timeit("merge_alexis(lsts)", setup=setup, number=3)

Эти тайминги, очевидно, зависят от конкретных параметров к эталону, например, от количества классов, количества списков, размер списка и т. д. Адаптируйте эти параметры к необходимости получения более полезных результатов.

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

=====================
# many disjoint classes, large lists
class_count = 50
class_size = 1000
list_count_per_class = 100
large_list_sizes = list(range(100, 1000))
small_list_sizes = list(range(0, 100))
large_list_probability = 0.5
=====================

niklas
5000 lists, 50 equally distributed classes, average size 298, max size 999
4.80084705353
rik
5000 lists, 50 equally distributed classes, average size 298, max size 999
9.49251699448
katrielalex
5000 lists, 50 equally distributed classes, average size 298, max size 999
21.5317108631
agf (1)
5000 lists, 50 equally distributed classes, average size 298, max size 999
8.61671280861
agf (2)
5000 lists, 50 equally distributed classes, average size 298, max size 999
5.18117713928
=> alexis
=> 5000 lists, 50 equally distributed classes, average size 298, max size 999
=> 3.73504281044

===================
# less number of classes, large lists
class_count = 15
class_size = 1000
list_count_per_class = 300
large_list_sizes = list(range(100, 1000))
small_list_sizes = list(range(0, 100))
large_list_probability = 0.5
===================

niklas
4500 lists, 15 equally distributed classes, average size 296, max size 999
1.79993700981
rik
4500 lists, 15 equally distributed classes, average size 296, max size 999
2.58237695694
katrielalex
4500 lists, 15 equally distributed classes, average size 296, max size 999
19.5465381145
agf (1)
4500 lists, 15 equally distributed classes, average size 296, max size 999
2.75445604324
=> agf (2)
=> 4500 lists, 15 equally distributed classes, average size 296, max size 999
=> 1.77850699425
alexis
4500 lists, 15 equally distributed classes, average size 296, max size 999
3.23530197144

===================
# less number of classes, smaller lists
class_count = 15
class_size = 1000
list_count_per_class = 300
large_list_sizes = list(range(100, 1000))
small_list_sizes = list(range(0, 100))
large_list_probability = 0.1
===================

niklas
4500 lists, 15 equally distributed classes, average size 95, max size 997
0.773697137833
rik
4500 lists, 15 equally distributed classes, average size 95, max size 997
1.0523750782
katrielalex
4500 lists, 15 equally distributed classes, average size 95, max size 997
6.04466891289
agf (1)
4500 lists, 15 equally distributed classes, average size 95, max size 997
1.20285701752
=> agf (2)
=> 4500 lists, 15 equally distributed classes, average size 95, max size 997
=> 0.714507102966
alexis
4500 lists, 15 equally distributed classes, average size 95, max size 997
1.1286110878
54
задан Sotirios Delimanolis 23 July 2016 в 17:41
поделиться

7 ответов

Цикл for в java имеет следующую структуру -

for (initialization statement; condition check; update)
    loop body;

Как вы можете видеть, здесь есть четыре оператора -

  1. Инструкция инициализации: это оператор выполняется только один раз, когда цикл вводится в первый раз. Это необязательный оператор, то есть вы можете оставить это поле пустым. Обычно используется для некоторой цели инициализации.
  2. Условная проверка: это утверждение, вероятно, самое важное. Он проверяет, соответствует ли определенное выражение истинному. Если это так, выполнение цикла продолжается. Вы можете оставить это поле пустым, которое будет оценено в true.
  3. Update: этот список операторов выполняется слева направо, обычно используется для увеличения / уменьшения некоторой переменной.
  4. тело цикла: тело цикла, которое будет выполняться снова и снова, основываясь на значении истинности условной проверки.

В основном, так выглядит выполнение: во-первых, когда цикл вводится в первый раз, оператор инициализации выполняется один раз. Затем выполняется условная проверка, чтобы проверить, соответствует ли она истинному. Если это так, то тело цикла выполняется, в противном случае выполнение цикла завершено. После этого выполняются () операторы обновления. Затем выполняется условная проверка, и если она оценивает значение true, то снова выполняется тело цикла, затем выполняется инструкция обновления, затем снова условная проверка .... вы получаете изображение.

Теперь о синтаксисе for( ; ; ). У него нет инструкции инициализации, поэтому ничего не будет выполнено. Это условная инструкция проверки также пуста, поэтому означает, что она оценивает значение true. После этого выполняется тело цикла. Затем, поскольку оператор обновления пуст, ничего не выполняется. Затем выполняется условная проверка, которая снова будет оцениваться как истина, а затем весь этот процесс снова повторится.

Итак, вы видите, что это в основном бесконечный цикл, который не имеет инструкции инициализации, чья условная проверка всегда будет оценивает значение true и не имеет инструкции обновления. Это эквивалентно -

while(true)
{
    .....
}

, который является еще одной популярной конструкцией цикла в java.

Когда вы используете бесконечный цикл, подобный этому, важно обратить внимание на условие нарушения, как в в большинстве случаев вы не можете позволить циклу запускать бесконечно. Чтобы вырваться из этих типов циклов, вы можете использовать инструкцию break. Структура следующая:

if(some_condition_is_true)
    break;        // This will cause execution to break out of its nearest loop

или

if(some_condition_is_false)
    break;
72
ответ дан Sotirios Delimanolis 17 August 2018 в 12:17
поделиться

Этот цикл не имеет защиты и действует как цикл while (true). Он будет вращаться бесконечно до перерыва.

6
ответ дан Aram Kocharyan 17 August 2018 в 12:17
поделиться

Это бесконечный цикл. Операторы инициализации, условия и приращения являются необязательными, поэтому без каких-либо из них это всегда будет повторяться снова (если только разрыв не ударит или какая-либо другая конструкция не взаимодействует с ним).

Хотя я не уверен о Java, этот вопрос объясняет, как в .Net ваши пустые for и while (true) будут скомпилированы точно так же. Я не удивлюсь, если Java тоже.

2
ответ дан Community 17 August 2018 в 12:17
поделиться

Это то же самое, что:

while(true) {
  //Some Stuff
}

В принципе, альтернативный синтаксис для бесконечного цикла.

34
ответ дан Marcelo 17 August 2018 в 12:17
поделиться
  • 1
    Хотя нас учат избегать использования бесконечных циклов, я несколько раз виноват (правда). – Aram Kocharyan 16 August 2011 в 17:15
  • 2
    Я чувствую, что у них есть моменты, когда они полезны – user489041 16 August 2011 в 18:02
  • 3
    По крайней мере, если вы используете while (true), человек, читающий код, скорее всего его поймет ... – PeterT 31 October 2012 в 02:25
  • 4
    Просто потратил 5 минут на чтение принятого ответа, когда вы объяснили это через 5 секунд. – Andy Guibert 10 December 2015 в 02:22

Это бесконечный цикл. Не совсем правильное кодирование, потому что оно не является интуитивным, которое фактически скомпилирует или не выдаст ошибку времени выполнения. Переписывание как while(true) { /* code */ } было бы более читаемым, чтобы указать бесконечный цикл.

3
ответ дан Paŭlo Ebermann 17 August 2018 в 12:17
поделиться
  • 1
    Вы забыли закрывающую скобку в вашем примере кода; D – Martijn Courteaux 16 August 2011 в 18:26
  • 2
    вы правы, что мой код не будет записывать закрывающую скобку, как написано из-за встроенного комментария, но я просто хотел, чтобы все это было на одной строке. – Travis Nelson 16 August 2011 в 18:32

Это все бесконечные петли

for(;;) {
   // endlessly
}

while(true) {
   // endlessly
}

do {
   // endlessly
} while(true);
8
ответ дан Peter Lawrey 17 August 2018 в 12:17
поделиться

/ * while loop

5 баксов

1 шоколад = 1 бакс

while my money is greater than 1 bucks 
  select chocolate
  pay 1 bucks to the shopkeeper
  money = money - 1
end

приходят домой и не могут идти во время магазина, потому что мои деньги = 0 баксов * /

#include<stdio.h>
int main(){
  int money = 5;

  while( money >= 1){   
    printf("inside the shopk and selecting chocolate\n");
    printf("after selecting chocolate paying 1 bucks\n");
    money = money - 1 ;  
    printf("my remaining moeny = %d\n", money);
    printf("\n\n");
  }

  printf("dont have money cant go inside the shop, money = %d",  money);

  return 0;
} 

бесконечные деньги

while( codition ){ // condition will always true ....infinite loop
  statement(s)
}

, пожалуйста, посетите это видео для лучшего понимания https://www.youtube.com/watch?v = eqDv2wxDMJ8 & Amp; T = 25s

0
ответ дан sandeep bairwa 17 August 2018 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: