C ++ - сила цикла for - это возможно? [Дубликат]

Я обнаружил, что параметры должны быть установлены следующим образом:

.set("spark.hive.mapred.supports.subdirectories","true")
.set("spark.hadoop.mapreduce.input.fileinputformat.input.dir.recursive","true")
3
задан Lightness Races in Orbit 4 March 2012 в 17:17
поделиться

6 ответов

Вот пример в простом старом C ++. Сначала я создаю вектор диапазонов для каждого измерения под названием maxes. если сумма всех индексов равна 2, то я печатаю что-то. В примере I цикл z от 0 до 1, y от 0 до 2, x от 0 до 3

Вы можете точно сделать это более аккуратным.

Здесь идет:

#include <iostream>
#include <vector>
using namespace std;

int f(){ 
    return 2 ;
}

void inner(int depth,vector<int> & numbers,vector<int> & maxes){
  if (depth>0){
     for(int i=0;i<maxes[depth-1];i++){
        numbers[depth-1]=i;
        inner(depth-1, numbers,maxes) ;
     }
  }else{
     // calculate sum of x,y,z:
     cout << "values are ";
     for(int i=0;i<numbers.size();i++){
        cout <<numbers[i]<<" ";
     }
     int thesum(0);
     for(int i=0;i<numbers.size();i++){
        thesum+=numbers[i];
     }
     if (thesum==f()){
        cout << "did something! ";
     }
     cout<<endl;
   }
}

void donest(){
   vector<int>  numbers;
   numbers.resize(3);
   vector<int>  maxes;
   maxes.push_back(4);
   maxes.push_back(3);
   maxes.push_back(2);
   inner(numbers.size(),numbers,maxes);
}

int main(){
   donest();
}

результат:

values are 0 0 0 
values are 1 0 0 
values are 2 0 0  did something! 
values are 3 0 0 
values are 0 1 0 
values are 1 1 0  did something! 
values are 2 1 0 
values are 3 1 0 
values are 0 2 0  did something! 
values are 1 2 0 
values are 2 2 0 
values are 3 2 0 
values are 0 0 1 
values are 1 0 1  did something! 
values are 2 0 1 
values are 3 0 1 
values are 0 1 1  did something! 
values are 1 1 1 
values are 2 1 1 
values are 3 1 1 
values are 0 2 1 
values are 1 2 1 
values are 2 2 1 
values are 3 2 1 
2
ответ дан Danny 21 August 2018 в 04:18
поделиться

Основная структура рекурсивного алгоритма с несколькими циклами выглядит следующим образом:

void recursiveLoops(vector<int>& indexes, const vector<int>& endPerIndex, int currentIndex) {
    if (currentIndex == indexes.size()) {
        // This is where the real logic goes.
        // indexes[i] contain the value of the i-th index.
    } else {
        for (indexes[pos] = 0 ; indexes[pos] != endPerIndex[pos] ; indexes[pos]++) {
            // Recurse for the next level
            recursiveLoops(indexes, endPerIndex, pos+1);
        }
    }
}

Для вызова вызова recursiveLoops с верхнего уровня требуется два вектора - один для индексов, а один для количество итераций на каждом уровне. Пример ниже устанавливает три вложенных цикла, повторяя 5, 6 и 9 раз на каждом уровне:

vector<int> indexes(3, 0);
vector<int> endPerIndex;
endPerIndex.push_back(5);
endPerIndex.push_back(6);
endPerIndex.push_back(9);
recursiveLoops(indexes, endPerIndex, 0);
8
ответ дан dasblinkenlight 21 August 2018 в 04:18
поделиться
  • 1
    Одна типичная проблема для рекурсивных функций - переполнение стека. Для переменной-вложенного цикла for это очень вероятно. Я знаю, что наш поставщик жестко закодировал свои петли до максимального уровня гнезд 5, и они сказали, что повысят ограничение до 9. Три года назад они все еще не сделали этого, lol. – fchen 7 October 2016 в 16:11

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

Для эффективности я избегал рекурсии. Кроме того, он не использует какие-либо конкретные материалы 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!
  }
}

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

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

Мир и любовь.

8
ответ дан Kevin Tindall 21 August 2018 в 04:18
поделиться
  • 1
    Код в порядке, но было бы лучше, если бы большинство комментариев было удалено. – Valentas 14 October 2015 в 19:12
  • 2
    Хорошая идея избежать переполнения стека – fchen 7 October 2016 в 16:11
  • 3
    Я нашел только один специальный случай MAX = 1, где он, кажется, работает вечно. – Valentas 25 August 2017 в 15:20

Вы могли бы написать это так, но ... я бы этого не сделал. Это запутанный код и не дает вам никаких преимуществ. Если вы этого хотите, потому что ваш истинный вариант использования имеет большое количество вложенных циклов, подумайте, что просто не делайте этого; это серьезный запах дизайна.

void nested_loop(const int levels, const int comparator, const int level = 0, const int accumulator = 0)
{
   if (level < levels) {
      for (int i = 0; i < 6; i++) {
         nested_loop(levels, comparator, level + 1, accumulator + i);
      }
   }
   else {
      if (accumulator == comparator) {   // your if (z+y+x==f)
         //do something
      }
   }
}

int main() {
   const int levels = 3;
   const int f = 42;

   nested_loop(levels, f);
}

Live demo .

0
ответ дан Lightness Races in Orbit 21 August 2018 в 04:18
поделиться

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

void recursiveX(int zVal, int yVal, int xVal)
{
    if(zVal+yVal+xVal == f)...
    if(xVal != 0)
        recursiveX(zVal, yVal, xVal -1);
}

void recursiveY(int zVal, int yVal)
{
    recursiveX(zVal, yVal, 6);
    if(yVal != 0)
        recursiveY(zVal, yVal-1);
}

void recursiveZ(int val)
{
    recursiveY(val, 6);
    if(val != 0)
        recursiveZ(val-1);
}
...
recursiveZ(6);

И в итоге вы можете объединить все это в одну функцию. Тем не менее использование рекурсии просто потому, что это возможно, никогда не является хорошей идеей.

0
ответ дан mkaes 21 August 2018 в 04:18
поделиться

просто подсчитывает глубину для каждой функции рекурсии и рассчитывает на f ..

void myRecursiveFunc(int depth){
   if(depth == f)
      //do something
      return;
   else{
      myRecursiveFunc(depth + 1);
   }
}

, если вы действительно хотите, вы можете использовать три разные функции для x, y и z.

0
ответ дан WeaselFox 21 August 2018 в 04:18
поделиться
  • 1
    Ну, @ Светлость. Моя проблема заключается в следующем. – cortex 4 March 2012 в 17:12
Другие вопросы по тегам:

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