Looping

Pages: 12
Is looping constantly this complex? I couldn't design something like this if my life depended on it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <iomanip>

using namespace std;

int main() 
{
	int i, j;
	for(i = 1; i <= 9; i++)
	{
		for(j = 1; j <= (9 - i); j++)
			cout<<" ";
		for(j = 1; j <= i; j++)
			cout<<setw(1)<<j;
		for(j = (i - 1); j >= 1; j--)
			cout<<setw(1)<<j;
		cout<<endl;
	}
	return 0;
}
Rarely. Probably the most common loop in C++ is
for (size_t a=0;a<some_vector.size();a++)
But sometimes it's necessary to code some fairly complex control structures.
your program could use some additional bracketing, i copied the program and put some brackets where I thought they should go and ran it. the loops executed a finite number of times then the program terminated succesfully(a pyramid?), so check your bracketing
Last edited on
<rhet>Did his post imply at any point the presence of an infinite loop?</rhet>
Last edited on
lol nevermind i feel like a doof
Last edited on
I was starting to worry, even if I was a seasoned programmer; if people are able to spit stuff like that out right off the top of their head, I am in the wrong business.
Is looping constantly this complex? I couldn't design something like this if my life depended on it.


not always this complex, in fact some times it is a lot harder :P

but you get used it it's not that hard to understand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
if (condition is true)
   then execute command

else if (a different condition is true)
   then execute another set of commands

else 
   do something else.


//---------------------------------------

while (condition is true)
   keep looping commands

//---------------------------------------

do{

   some
      commands

} while (some condition is true);

// the difference between do and while is a do will always execute at least once, even if the condition is false.
//--------------------------------------

for ( initializer ; range ; increment )
   do some commands.

//--------------------------------------

switch ( value )
{
   case 1:
      do some commands
      break;
   case 2:
      do something else
      break;
   
   default:
      do default commands
      break;
}

//-------------------------------

/*

The for loop is commonly used for traversing n number of times, counting, and formulas.
For example an array:

*/

char myArray[] = { 'H','e','l','l','o',' ','W','o','r','l','d' };

// for (int i =0;  we can create a variable called i, and initialize it to 0. I is most commonly used in
// for loops as it stands for index. In fact it is one of the only variables commonly used that has
// such a poor but valid naming convention, the reason being is it is tempory. (char c;  is another acceptable "tempory variable")

// i < 11  ;   our array size is 11, so we need to count from 0 to 1 less than 11 (10).
// the reason being is arrays start at index 0, which is the zeroth element (first element), 
// the second element is the oneth element, then twoeth element and so on.
// this seems a bit confusing at first but you get used to it. basically just start counting from 0.

// then i++; is same as saying i+=1; or i=i+1; And also the same as ++i in this instance.
// for traversing loops using for post or pre increment doesn't matter. personal preference.

for ( int i=0 ; i<11 ; i++ )
{
    std::cout << myArray [ i ];
}


when a for loop first starts the initializer is set this happens only once and only at the start, then the range is computed, if the range is TRUE then it will loop, for every subsequent pass the initializer is never read again, the loop reads the increment value, increments as required, and then checks that range is TRUE, if true then the for loops again, third pass it increments, then checks range again so on and so forth.

you can have as many values in a for loop as you like so long as you always have the 2 ' ;; ' eg this is valid:
1
2
3
4
5
6
7
for ( ;; )
   do something

// and so is this

for ( ; index < myString.size() ; ++ index )
   do some commands;


just remember the initializer executes only once at the start, and the increment only increments on the second and above passes.

as you don't have to have all fields complete another way to look at it would be:
for ( only-executes-once ; if condition is true ; executes-all-other-passes )
Last edited on
This is my first week in programming and I have my hello world assignment complete, I was reading ahead (FAR ahead now) and am just getting to functions. Some of the extra exercises were getting too tough for me and I got worried. Here is my first program implementing functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

double larger(double, double);
double compareThree(double, double, double);

int main()
{
	double num1, num2;
	cout<<"Larger of 34 and 23: "<<larger(34, 23)<<endl;
	cout<<"Enter two numbers (less than 100) to be compared: "<<endl;
	cin>>num1>>num2;
	cout<<num1<<" and "<<num2<<" = "<<larger(num1, num2)<<endl;
	double special = (rand() + time(0)) % 100;
	double guess = compareThree(special, num1, num2);
	cout<<"Guess = "<<guess<<endl;
	cout<<"Random number: "<<special<<endl;
	return 0;
}
double larger(double x, double y)
{
	if(x > y)
		return x;
	return y;
}

double compareThree(double x, double y, double z)
{
	return larger(x, larger(y, z));
}
thanks gcampton i like that breakdown
1
2
3
4
5
6
double larger(double x, double y)
{
	if(x > y)
		return x;
	return y;
}

I like that, whether it was intentional or not, most newbies would put:

1
2
3
4
5
6
7
double larger(double x, double y)
{
   if(x > y)
      return x;
   else
      return y;
}


the else is redundant.
I was starting to worry, even if I was a seasoned programmer; if people are able to spit stuff like that out right off the top of their head, I am in the wrong business.
Not necessarily so instinctively. It really all depends on how clear it is you what you're trying to accomplish. If you can precisely describe the procedure in your head, writing something 5-10 times more complex than that is almost monotonous. If I was given the assignment that spawned your snippet, I could finish it in, say, five minutes. Not because I keep a super-brain inside my skull, but because I've already seen things like that hundreds if not thousands of times, and even things much more complicated. Programming is "practice makes perfect" to its highest degree. When you've been juggling several hundred eggs in non-euclidean 5D space with variable gravity for years, juggling 3 balls on Earth is child's play.

If you can't (precisely describe the procedure in your head), you have to take other avenues. In programming, it's very easy to create monstrously complex systems by starting with simple ones and piling complexity after complexity. It's so easy, in fact, that it's a problem.
Thanks. Less characters = less execution time has been drilled into my head from software engineering. Although I'm pretty sure an extra else wouldn't hurt anything, if you have a few hundred extra ones it would have an impact. Speaking of execution time, The big o notation is confusing, is the best time n^2 or 2^n, or is it something completely different?
If f(n) = n, f(n) = log2n, and f(n) = nlog2n.
Multi-dimentional arrays referred to arrays of arrays, they can be represented much like a table.

as your example used nested for loops, they are used frequently when dealing with these.

eg.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int myArray[5][5] = { { 1, 2, 3, 4, 5 }, {2, 3, 4, 5, 1}, {3, 4, 5, 1, 2},
      {4,5,1,2,3},{5,1,2,3,4}};

/*
If we show this in a tabular format it looks like this:

1  2  3  4  5
2  3  4  5  1
3  4  5  1  2
4  5  1  2  3
5  1  2  3  4

and the loop:
*/

for ( int i=0; i<5 ; i++ )
{
   for ( int j=0; j<5 ; j++ )
   {
      cout << myArray[i][j];
      cout << endl;
   }
}

first pass is i is 0, so the first row (1,2,3,4,5) j is 0, and points to the zeroth element (1),
and the inner for loop processes 'j', 'i' will remain 0.
so it prints out like myArray[0][0], myArray[0][1], myArray[0][2], myArray[0][3] and so on up to [4] then the inner for loop exits and the outer for loop increments by 1, and now 'i' becomes 1, and it prints like
myArray[1][0], myArray[1][1], myArray[1][2] and so on...
@helios Actually, I have been taught to come up with psuedo before coding, but I would rather declare variables as I need tham and start off of something small. It's not an actual asignment, at least not yet, but I was trying to get ahead of my class; it is an exercise at the end of one of the chapters and we were supposed to try and decipher what the output was without compiling and executing the code, which inevitably I found impossible. Something I am still stuck on is: "Write a program that prompts the user to input an integer and then outputs the number with the digits reversed. For example, if the input is 12345, the output should be 54321. Your program must also output 5000 as 0005 and 980 as 089."
ok so I just described this in my last post, the outer loop executes, initializes to 0, then the inner loops complete their process, then the outer loops increment and if true loop again, in which case the inner loops start again.


so for every loop in outer for;
run the inner for's n number of times.


and your other post
http://cplusplus.com/forum/beginner/17880/

the example I listed at the bottom is a good example using modulus and breaking up numbers into individual digits. if you take that example and say for instance, you want to store a number that is backwards in a variable. then you can take, dig1, dig2 etc and multiply them by the number they need and add them together.

eg: 28471
dig1=2, dig2=8, dig3=4, dig4=7, dig5=1

now to print backwards we would simply say dig5-dig1 but what if we want this as a variable.
then one way we could do it is, multiply dig5 by 10,000, dig4 * 1000, dig3*100, dig2*10 and add them all together.
theis would give us the number

17482
Last edited on
Although I'm pretty sure an extra else wouldn't hurt anything
Actually, in this case, both versions generate the same code.
In any case, the best one is return (x>y)?x:y;

is the best time n^2 or 2^n, or is it something completely different?
From best to worst,
O(1), O(log n), O(n), O(n log n), O(nk), O(kn), O(n!). There are also some in between, but these are the most common.
Their names are constant, logarithmic, linear, linearithmic, polynomial, exponential, and factorial.

Multi-dimentional arrays referred to arrays of arrays
No, they're not. Particularly not in the case of myArray, which is just a regular array with syntactical sugar.

we were supposed to try and decipher what the output was without compiling and executing the code
Ah... tracing. A very important skill. A master can debug by "just" staring at the code hard enough.
in that case what is a multi-dimensional array 3 or more ?
should I call it 2 dimensional array?
//------------------------

looking at the example I would say the output would be:
1
2
3
4
5
6
7
8
        11
       11
      11
     11
    11
   11
  11
 11

but I could be terribly wrong.
Last edited on
gcampton - I am still trying to find the correct (exact) semantics for my print in reverse exercise. I like what you have but is there a way to declare extra variables from within a loop during execution time? I'm not a fan of asking the user how many digits they want to enter. This was something I coded for a preveious similar exercise:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

using namespace std;

int main()
{
	int i;
	int a, b, c, d;
	cout<<"Enter a four digit number sperated by spaces: "<<endl;
	cin>>a>>b>>c>>d;
	cout<<endl<<a<<endl<<b<<endl<<c<<endl<<d<<endl;
	cin>>i;
	return 0;
}


helios - So if (theoretically) a computer executes 1 billion instructions per second then O(1) = 100, O(n) = .10ms, and O(k^n) = 4(10^13) years. That's crazy. What kind of scenario causes O(n!)? Maybe I'm just too inexperienced atm.
yea that works, to print the number backwards you can just say:
int temp = (d*1000) + (c*100) + (b*10) + a;
cout << temp;
Big O notation doesn't describe the time it takes to complete an operation. It describes the order of magnitude of the rate of growth of the number of operations it takes a given algorithm to finish as its input size increases.
For example, if an O(2^n) algorithm takes 2 operations to finish for an input size of 1, it'll take 1024 units for an input size of 10. An O(n^2) would take 100 operations; O(n), 10 operations; O(log n), ~3 operations; and O(1) would take 2 operations, no matter the input size.
We call it "time complexity", but it doesn't measure actual time. It measures number of operations. Space complexity is a little more literal, since information already has a universal measure (the bit).
Last edited on
Pages: 12