Results 1 to 19 of 19

Thread: Tri-Nested for loop

  1. #1

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037

    Tri-Nested for loop

    I can't get this to work right. I have been workiing on it for a long time now but to no avail. It is a 3 section nested loop (if there is such a thing). It is supposed to print out a graph for each score but when it runs it just prints out
    *
    *
    *
    *
    *
    and I don't know what it prints out before that because it moves so fast and then it ends.

    Am I doing something wrong?
    Code:
    cout << "SCORE" << setw(13) << "FREQUENCY" << setw(13)<< "GRAPH"<< endl;
    // Score output loop
         for (int score=1; score < 10001; score++){
         for (;(frequency[score]>1) && (frequency[score]< 10001);)
         cout<< setw(5) << score << setw(5) << frequency[score] << setw(5);
    // Print bar
                for (int i=1; i <= frequency[i]; i++)
                cout <<"*";
                cout << endl;
         }
    I did have

    if (!(frequency[i]==0)) cout << "*";
    cout << endl;

    after

    cout<< setw(5) << score << setw(5) << frequency[score] << setw(5);

    instead of the 2nd for loop.
    But the problem was that if reads any other statements as else. But I wanted it to go back up to for to increment the number again.

    One of my biggest goals is to stop it from printing 0's.
    Last edited by aewarnick; Jan 7th, 2003 at 09:56 PM.

  2. #2

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    This one does the same thing. I used break and continue before instead of goto but they didn't work either.

    Code:
    cout << "SCORE" << setw(13) << "FREQUENCY" << setw(13)<< "GRAPH"<< endl;
    // Score output loop
         for (int score=1; score < 10001; score++){
         if (frequency[score]>0)
         cout<< setw(5) << score << setw(5) << frequency[score] << setw(5);
         else goto graph;
    // Print graph
    graph:
                for (int i=1; i <= frequency[i]; i++){
                if (frequency[i]==0) goto graph;
                else cout <<"*"; goto graph;
                }
         cout << endl;
         }

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    for (;(frequency[score]>1) && (frequency[score]< 10001)

    This is an endless loop.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Here is what I came up with. It has one minor problem. It does not put the space between the numbers and the graph.

    This line: cout<< setw(5) << i << setw(10) << frequency[i] << setw(9);
    All of it works except the last setw.
    And I could not figure out a way to not use goto.
    Code:
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    using namespace std;
    int d; // Score entering finish letter
    int main(int argc, char *argv[])
    {
    int score[1000001] ={0}; // initialize all memory locations to 0.
    int frequency[1000001] ={0};
    
    cout << "\nEnter scores (Limit: 1000000):\n" << endl;
    // Score entering loop
         for (int i=0; i< 1000001; i++){
         cout << "Enter d when finished. Next score: "; cin >> score[i];
             if (score[i]==d || !(score[i]<1000001)) break;
         }
    // Score counting loop
         for (int i=0; i< 1000001; i++)
         ++frequency [score[i]]; // This is the key to it all!!!
    
    cout << "SCORE" << setw(13) << "FREQUENCY" << setw(14)<< "GRAPH"<< endl;
    // Score output loop
         for (int i=1; i < 1000001; i++){
         if (frequency[i]>0)
         cout<< setw(5) << i << setw(10) << frequency[i] << setw(9);
         else goto graph;
    // Print graph
    graph:
            for(int j=0; j< frequency[i];j++){
            if (!(frequency[i]==0)) cout << '*';
            else continue;
            }
         if (frequency[i]==0) continue;
         cout << endl;
         }
    
    system("PAUSE");
    return 0;
    }

  5. #5
    Frenzied Member Jop's Avatar
    Join Date
    Mar 2000
    Location
    Amsterdam, the Netherlands
    Posts
    1,986
    You can always avoid using Goto.
    In this case you can just put a break in the loop, put the code from the graph flag just outside the loop and you're done?
    Jop - validweb.nl

    Alcohol doesn't solve any problems, but then again, neither does milk.

  6. #6

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Ok. I will try it. Here is what I changed to space out the graph. It does not make sence to me why I had to do this but I am hoping you guys know a way out of it.

    cout<< setw(5) << i << setw(10) << frequency[i]<< setw(6)<< "-";

  7. #7

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    It always breaks out of the big loop and not the small one.

    Code:
    for (int i=1; i < 1000001; i++){{
         if (frequency[i]>0)
         cout<< setw(5) << i << setw(10) << frequency[i]<< setw(6)<< "-";
         else break;
    // Print graph
         }
            for(int j=0; j< frequency[i];j++){
            if (!(frequency[i]==0)) cout << '*';
            else continue;
            }
         if (frequency[i]==0) continue;
         else {cout << endl; continue;
         }}

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I think you're confusing yourself. Insert newlines after EVERY statement.
    You can make if-conditions execute more than one statements by defining a block:
    Code:
    if(condition)
    {
      statement;
      statement;
    }
    else
    {
      statement;
      statement;
    }
    And the indentation is still inconsistent. It would be easier for you if the code was properly formatted.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Shouldn't else break break out of the first loop and the continues at the bottom go back to the top of the first for loop?

    Code:
    // Score output loop
    
         for (int i=1; i < 1000001; i++){
         {
         if (frequency[i]>0)
         cout<< setw(5) << i << setw(10) << frequency[i]<< setw(6)<< "-";
         else break;
    // Print graph
         }
            for(int j=0; j< frequency[i];j++)
            {
            if (!(frequency[i]==0)) cout << '*';
            else continue;
            }
         if (frequency[i]==0) continue;
         else {cout << endl; continue;}
         }
    This never prints anything but the single digit lines for some reason.

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    You have one redundant and irritating pair of braces.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11
    Frenzied Member Jop's Avatar
    Join Date
    Mar 2000
    Location
    Amsterdam, the Netherlands
    Posts
    1,986
    Hmm some of the else's aren't necessary here:

    PHP Code:
    // Score output loop

         
    for (int i=11000001i++){
         {
         if (
    frequency[i]>0)
         
    cout<< setw(5) << << setw(10) << frequency[i]<< setw(6)<< "-";
         else break;
    // Print graph
         
    }
            for(
    int j=0jfrequency[i];j++)
            {
            if (!(
    frequency[i]==0)) cout << '*';

           
    // else continue;  --- Not needed, it will continue by itself
            
    }
    /*
         if (frequency[i]==0) continue; 
         else {cout << endl; continue;}

    This block above can be replaced by:
    */
         
    if (frequency[i]) cout << endl;
         } 
    Jop - validweb.nl

    Alcohol doesn't solve any problems, but then again, neither does milk.

  12. #12

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    I don't think you are seeing the whole picture. Run this program:

    Code:
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    using namespace std;
    char d; // Score entering finish letter
    int main(int argc, char *argv[])
    {
    int score[1000001] ={0}; // initialize all memory locations to 0.
    int frequency[1000001] ={0};
    
    cout << "\nEnter scores (Limit: 1000000):\n" << endl;
    // Score entering loop
         for (int i=0; i< 1000001; i++){
         cout << "Enter d when finished. Next score: "; cin >> score[i];
             if (score[i]==d ||!(score[i]<1000001)) break;
         }
    // Score counting loop
         for (int i=0; i< 1000001; i++)
         ++frequency [score[i]]; // This is the key to it all!!!
    
    cout << "SCORE" << setw(13) << "FREQUENCY" << setw(8)<< "GRAPH"<< endl;
    // Score output loop
         for (int i=1; i < 1000001; i++){{
            if (frequency[i]>0)
            cout<< setw(7) << i << setw(8) << frequency[i]<< setw(6)<< " ";
            else break;
    // Print graph
            }
            for(int j=0; j< frequency[i];j++){
            if (!(frequency[i]==0)) cout << '*';
            }
         if (frequency[i]==0) continue;
         cout << endl;
         }
    
    system("PAUSE");
    return 0;
    }
    Now run this one:
    The 1st one breaks when it encounters a 0 and breaks out of the entire nested loop. Is there any way to make it break out of only the loop it is in and work just like the bottom one here?

    Code:
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    using namespace std;
    char d; // Score entering finish letter
    int main(int argc, char *argv[])
    {
    int score[1000001] ={0}; // initialize all memory locations to 0.
    int frequency[1000001] ={0};
    
    cout << "\nEnter scores (Limit: 1000000):\n" << endl;
    // Score entering loop
         for (int i=0; i< 1000001; i++){
         cout << "Enter d when finished. Next score: "; cin >> score[i];
             if (score[i]==d ||!(score[i]<1000001)) break;
         }
    // Score counting loop
         for (int i=0; i< 1000001; i++)
         ++frequency [score[i]]; // This is the key to it all!!!
    
    cout << "SCORE" << setw(13) << "FREQUENCY" << setw(8)<< "GRAPH"<< endl;
    // Score output loop
         for (int i=1; i < 1000001; i++){
            if (frequency[i]>0)
            cout<< setw(7) << i << setw(8) << frequency[i]<< setw(6)<< " ";
            else goto graph;
    // Print graph
    graph:
            for(int j=0; j< frequency[i];j++){
            if (!(frequency[i]==0)) cout << '*';
            }
         if (frequency[i]==0) continue;
         cout << endl;
         }
    
    system("PAUSE");
    return 0;
    }
    Last edited by aewarnick; Jan 8th, 2003 at 04:46 PM.

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Both source codes crash when compiled with VC++ in debug mode.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    I missed the end brace on the second one. I will fix it. Ok, now try.

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I fixed that myself. I'm not that dumb.
    No, they compile ok but crash when running. I even know why. I'll tell you in a second.

    But first, where is the difference between the two?
    The only difference I see is
    Code:
    else goto graph;
    // Print graph
    graph:
    which does exactly NOTHING.

    Ok, now for the crash. Your arrays are each ~1 million elements large, each consisting of 4 bytes. This means you're allocating 8 MB on the stack. Windows imposes a limit of 1 MB on the stack, applications that do not heed this crash.

    Here's working and properly formatted code that does what you want. You can compare it to yours and figure out what you've done wrong.
    Oh, btw, I cleaned up both of your codes, removing redundant code and such. The outcome is the same, letter by letter.

    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    // Those may not be inside main as the two arrays together need 8MB of stack space!
    // But windows systems don't allow apps to allocate more than 1MB on the stack.
    int score[1000000] ={0}; // initialize all memory locations to 0.
    int frequency[1000001] ={0};
    
    int main(int argc, char *argv[])
    {
    	int temp, entered=0;
    	cout << "Enter scores (Limit: 1000000):" << endl;
    	// Score entering loop
    	for (int i=0; i < 1000000; i++) {
    		cout << "Enter -1 when finished. Next score: ";
    		cin >> temp;
    		while(temp > 1000000) {
    			cout << "Score out of range. Enter again: ";
    			cin >> temp;
    		}
    		if (temp < 0)
    			break;
    		score[i] = temp;
    		entered++;
    	}
    	// Score counting loop
    	for (int i=0; i < entered; i++)
    		++frequency[score[i]]; // This is the key to it all!!!
    
    	cout << "SCORE" << setw(13) << "FREQUENCY" << setw(8)<< "GRAPH"<< endl;
    	// Score output loop
    	for (int i=0; i < 1000001; i++) {
    		if (frequency[i]>0) {
    			cout<< setw(7) << i << setw(8) << frequency[i]<< setw(6)<< " ";
    			// Print graph
    			for(int j=0; j < frequency[i]; j++) {
    				cout << '*';
    			}
    			cout << endl;
    		}
    	}
    
    	system("PAUSE");
    	return 0;
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Putting those outside main makes the program a lot slower but that is ok if it is the right way to do it.

    Why does it slow down like that?

    (and just to let you know, with the dev c++ compiler I needed #include <cstdlib> to compile. The error was with the system("PAUSE")

    I just noticed the the program is now 7 megabites instead of 70 kilobites. That is a problem!!! Can it be fixed?
    Last edited by aewarnick; Jan 8th, 2003 at 05:24 PM.

  17. #17
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I had none of those problems. The app is just as fast and only 470 k in debug compile. gcc doesn't seem to be very efficient there.

    Right, forgot about the system call. It seems that somewhere deep inside the iostream header of VC++ includes cstdlib.

    The problem is that the large arrays are now written to disk and therefore have to be loaded from there. It's probably faster if you do:
    Code:
    int score[1000000];
    int frequency[1000001];
    int main(int, char**)
    {
      memset(score, 0, 1000000*sizeof(int));
      memset(frequency, 0, 1000001*sizeof(int));
      //...
    }
    I think memset is declared in cstdlib.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  18. #18

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Must not be in cstdlib because it gives erros about memset.

  19. #19

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    It is in cstring.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width