Ошибки проверки типов в Swift

Я наткнулся на это раньше сегодня и подумал, что могу поделиться решением, которое я в итоге придумал. Я не уверен, что такое политика в отношении ответов на старые сообщения. Я просто переживаю тот факт, что сегодня утром я столкнулся с этим вопросом, и это было бы полезно для меня.

Для эффективности я избегал рекурсии. Кроме того, он не использует какие-либо конкретные материалы c ++ - он отлично работает и на C.

Мы пытаемся создать N вложенных циклов for for. Вместо использования

for(int i = 0; i<max; i++)
  for (int j = 0; j<max; j++)
    ...

я буду заменять i, j, ... массивом: i [0], i [1], ..., i [n-1].

Вот мое решение:

const int n = /*Insert N here: how many loops do you need?*/;
int i[n+1]; // if "n" is not known before hand, then this array will need to be created dynamically.
//Note: there is an extra element at the end of the array, in order to keep track of whether to exit the array.

for (int a=0; a<n+1; a++) {
  i[a]=0;
}

int MAX = 79; //That's just an example, if all of the loops are identical: e.g. "for(int i=0; i<79; i++)". If the value of MAX changes for each loop, then make MAX an array instead: (new) int MAX [n]; MAX[0]=10; MAX[1]=20;...;MAX[n-1]=whatever.

int p = 0; //Used to increment all of the indicies correctly, at the end of each loop.
while (i[n]==0) {//Remember, you're only using indicies i[0], ..., i[n-1]. The (n+1)th index, i[n], is just to check whether to the nested loop stuff has finished.

  //DO STUFF HERE. Pretend you're inside your nested for loops. The more usual i,j,k,... have been replaced here with i[0], i[1], ..., i[n-1].


  //Now, after you've done your stuff, we need to increment all of the indicies correctly.
  i[0]++;
  // p = 0;//Commented out, because it's replaced by a more efficient alternative below.
  while(i[p]==MAX) {//(or "MAX[p]" if each "for" loop is different. Note that from an English point of view, this is more like "if(i[p]==MAX". (Initially i[0]) If this is true, then i[p] is reset to 0, and i[p+1] is incremented.
    i[p]=0;
    i[++p]++; //increase p by 1, and increase the next (p+1)th index
    if(i[p]!=MAX)
      p=0;//Alternatively, "p=0" can be inserted above (currently commented-out). This one's more efficient though, since it only resets p when it actually needs to be reset!
  }
}

Вот и все. Надеемся, что в комментариях дается понять, что он должен делать. Я думаю, что это должно быть довольно эффективно - почти столько же, сколько реальных вложенных циклов. Большая часть накладных расходов является одноразовой в начале, поэтому это должно быть более эффективным с использованием рекурсивных функций и т. Д. (Пожалуйста, поправьте меня, если я ошибаюсь в этой точке).

Надеюсь, это полезно кому-то один день.

Мир и любовь.

-4
задан rmaddy 18 March 2019 в 16:34
поделиться

1 ответ

Я не могу воспроизвести эту проблему, но вы написали, что это довольно неловкий способ, IMO. Вы хотите, чтобы все было Double, поэтому просто сделайте это Double, и тогда код станет намного проще, и вам не понадобится все приведение. pow(x,2) также является очень дорогим способом вычисления x*x, поэтому я бы избавился от этого, и я думаю, что код становится намного проще и определенно не имеет проблем с компиляцией.

func cal(xs: [Int], ys: [Int64]) -> Double {
    let xs = xs.lazy.map(Double.init)
    let ys = ys.lazy.map(Double.init)

    let total = ys.reduce(0, +)
    return zip(xs, ys).map { [110]*[110] * $1 }.reduce(0, +) / total
}

Если вы делаете много такого рода кода, вы можете найти расширение sum() полезным, чтобы сделать код немного понятнее.

extension Sequence where Element: Numeric {
    func sum() -> Element {
        return reduce(0, +)
    }
}

func cal(xs: [Int], ys: [Int64]) -> Double {
    let xs = xs.lazy.map(Double.init)
    let ys = ys.lazy.map(Double.init)

    let total = ys.sum()
    return zip(xs, ys).map { [111]*[111] * $1 }.sum() / total
}
0
ответ дан Rob Napier 18 March 2019 в 16:34
поделиться
Другие вопросы по тегам:

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