'i' meaning and why is it there? - c++

I'm new here as well to coding. Recently I've been going through Principles and Practice Using C++ and inside his code there is always an i inserted into his examples. Some are inside "vector's subscript" function, or inside "for statements" such as int i. But he didn't even make an int called i, it's just there. Maybe I missed something while reading, I don't know, but I hope someone wouldn't mind giving me a meaning as to why it's inserted in the places it's placed in, or just the meaning of i.
Below I took one of his examples from page 148 to show you
int main()
{
vector<double> temps; //temperatures
double temp = 0;
double sum = 0;
double high_temp = 0;
double low_temp = 0;
while (cin>>temp) // read and put into temps
temps.push_back(temp) ;
for (int i = 0; i<temps.size(); ++i) // these 'i's
{
if(temps[i] > high_temp) high_temp = temps[i]; // and these
if(temps[i] < low_temp) low_temp = temps[i];
sum += temps[i]; // compute sum
}
cout << " High temperature: " << high_temp<< endl; // find high
cout << " Low temperature: " << low_temp << endl; // find low
cout << "Average temperature: " << sum/temps.size() << endl;
}

When you write a software program, each variable that you declare must have a meaning, must represent something.
This is also the case in the book fragment you just read, only that we are talking about arrays. As you know, arrays are a collection of values of the same value type. Because it's a collection, it means there are 1 or more values into that array.
This raises the question: if there are 1 ore more values, how can I acces one specific value of that array? Here is where the i you read comes in.
The variable i has the meaning of the position of the array I am working on right now, where "working on" can mean reading, writing, etc. Because i is a variable, it must have a data type, hence the int i notation.
Using i as a variable in this context is not mandatory, but it's a very common practice. If you have a matrix, for example, you will need two such variables (one for rows and one for columns) which most likely will be i and j.
This also explains why we use i inside a for loop. In English, this means that the loop works with the elements that have the coefficient number from 0 to the array size.
i was declared as an int type in the for loop, but it could also be declared before that loop. Something like:
int i=0;
...
for (i=0; i<...)

i is declared as a variable of type int, here:
for (int i = 0; .......)
{
// 'i' used here
}
// 'i' cannot be used here
That i has a scope only inside that for loop. After the loop terminates, so does the lifetime of that variable i.

i is a part of convention, where it stands for iteration number.
It has been defined in the for loop:
for (int i = 0 ....
Which basically states that you start from iteration number zero. Once you gain some experience, you will see that iterations don't always start from zero, so i may be initialized with a different value (or a different variable name may be used instead of i altogether).
Mathematically, i is often used in context of a list/array: the ith element or summation from i=0 to i=n etc.

i is an integer, used as an indexing variable. You often see it in loops.
First, let's think about a vector and what it looks like. A vector is a variable-length array.
So if we have a vector named myVector with 5 elements, then we have something that looks like
myVector: item1 item2 item3 item4 item5
Now how do we specify individual items? We'll need to index each item. Traditionally (from mathematics), indexing begins at 0. So to index the first element, we do myVector[0]. To index the second element, we do myVector[1], and so on. (The [] is known as the subscript operator. You can also use myVector.at(0), myVector.at(1), but this is less used.)
Now what if we wanted to find the minimum or maximum value in a vector? We'd need to check each item and compare them. So we'll need to iterate (loop) through the entire array.
How do we do this? How do we iterate through each and every item? To loop through each item, we'd need something to specify the items. To loop through every item, we'd need a loop.
The loop in your code does this, iterating from 0 up to the length of the array/vector.
for (int i = 0; i < temps.size(); ++i) // iterate through EVERY element of the vector
{
// access EACH element of using temps[i]
}

Related

getting infinte amount of inputs from the user than printing the biggest 3 , without using arrays

First time around, first time learning to code anything. Sorry for my ignorance.
So I've been asked to code a program that gets infinite amount of number from the users until he submits the number I manage to do so very well, but I also need to print the biggest sum of a following three inputs, for example, the user inputs 4,20,2,4,11,9,8,1 the program should print 11,9,8 because the sum of those 3 is greater than all other 3.
I must tell you I cannot use arrays, I know its a bummber but I know it is possible to do so without.
I was trying to build a function that tries to act like an array but I can't really call her back since its a two-variable function and one of them is the input, which I obviously don't know. was working on this question for 5 hours now and thought ill ask for your wisdom
cout << " enter numbers as long as you wish" << endl;
cout << "when you wish to stop enter the number 1" << endl;
int n;
int sum;
int i = 1;
while (n != 1) {
cin >> n;
remember(i, n);
if (n == 1) {
cout << "you choosed to stop " << endl;
break;
}
i++;
}
And the function I was trying to build is really simple but I can't call any specific value for example remember(1, n) when I want to sum them up and see who is bigger.
int remember(int i, int n){
return n;
}
*** Please note that the sums that are being tested are the sums of the numbers in the exact order that the user-submitted therefor 11,9,8 is the output and NOT 20,11,9
You need seven variables: Three which is the "window" you're currently reading, and which you check your sum with; Three which is the "biggest sum" triple; And one which is the current input.
For each input you read into the "current input" variable, you shift the window down one value and set the top variable to the just read input.
Then you take the sum of all three values in the window, and check if it's bigger than the sum of the current "biggest sum" triple. If it is, then you make the "biggest sum" triple equal to the current window values.
Iterate until there is no more input, and then print the "biggest" values.
Regarding the shifting of the three window values, lets say you have three variables named window1, window2 and window3 then you could shift like this:
window1 = window2;
window2 = window3;
window3 = current;
Checking the sum is as easy as
if ((window1 + window2 + window3) > (biggest1 + biggest2 + biggest3))
All window and biggest variables need to be initialized to the lowest possibly value for the type (for int that would be std::numeric_limits<int>::min()).
Since you initialize all values, there's no need to have special cases for the first and second input.
Iterating while there's input could be done by doing
while (std::cin >> current)
First of all, n is uninitialized, so it's undefined behavior when you do while (n != 1){. So technically, there's no guarantee that anything works past that. You should initialize it, for example by setting it to 0 (or any other value that's not 1, in this case):
int n = 0;
But the issue that you observe is because you have another int n; in your loop, which shadows the outer n (the one that is checked in the while condition). So the cin >> n; only ever modifies that inner n. The outer one will stay at the same uninitialized value. So if that value made it enter the loop, it will never exit the loop, because n != 1 is always true.
Remove the int n; inside the loop to solve the problem.
Basically, what you need is 4 variables to account the actual list and its sums (3 for the list and 1 for the sum of it)
You need 3 more variables to account the actual list.
At each interaction, you have two things to do:
Compare the sum of actual list with the stored one. If the sum the actual list is greater than that stored, actualize it
For each new number, rotate you variables that account for the actual list.
In pseudo code:
v3 = v2;
v2 = v1;
v1 = new_number;

How to find the index of second largest element in an array collection?

I have a function which calculates sum of money spent on each checkout on a counter, After calculation, i want to find the best two checkout counter, I am able to find the index of the largest checkout, but I have a small confusion regarding finding the second largest checkout counter.
Here's the code.
for (int j = 0; j < Bq[i]; j++)
{
sumM += p.GetValue(i, j).GetSum();
sumT += p.GetValue(i, j).GetTime();
}
indexofmax = i;
if(sumM > maxmoney)
{
Secondbestcheckout=firstbestcheckout;
firstbestcheckout = indexofmax+1;
maxmoney = sumM;
secondindex = Secondbestcheckout;
indexofmax =firstbestcheckout;
}
fr << i+1 << fixed << setw(9) << setprecision(2) << sumM
<< " " << setw(6) << sumT << endl;
}
fr << "The first best checkout interms of money collected is "
<< firstbestcheckout << "And the second best checkout is "
<< secondindex << endl;
This code is successful in printing the index of largest checkout counter, but not successful in printing the index of second largest.
The second best is not sent only when you outperform the best.
Example with 40, 60, 50, 30
With your code, the fist time you set a best, is with 40. Then 60 replaces it an 40 becomes the second best. THen 50 arrives but it doesn't outperform the best so gets ignored as second best.
You have to add an clause, to handle this case:
...
if (sumM > maxmoney) // as you already did
{
Secondbestcheckout=firstbestcheckout;
firstbestcheckout = indexofmax+1;
secondmaxmoney = maxmoney; // <<NEW INSTRUCTION - of course, you'll need to create and init secondmaxmoney somewhere ;-)
maxmoney = sumM;
secondindex = Secondbestcheckout;
indexofmax =firstbestcheckout;
}
else if (sumM > secondmaxmoney) // NEW STATEMENT
{
Secondbestcheckout= ...; // as above, but unclear for me what the difference with secondinex is
secondmaxmoney = maxmoney; // update amount onf second best
secondindex = i; // or i+1 ? Not clear if you start from 0 or from 1
}
... // rest or your code
If you can keep all the values in memory (i.e. if you have fewer than billions of checkouts), you can either use std::partial_sort to sort the two largest elements (but leave the rest unsorted), or you can use std::nth_element twice, once with 1 and once with 2. (In both cases, your predicate should be std::greater, I suppose.)
If you need to process the values in a streaming fashion (i.e. with constant space), then you'll need to keep track of each order index separately, essentially similar to what you're attempting already. Boost.Accumulators may have some tools to simplify that task.
Don't make it complicated, it is simple:
INDX = (-ARRAY).argsort()[:N]
where N is the number of elements you are searching for, e.g. N=2 (two largest numbers)
ARRAY is your numpy array which you are searching in, e.g. ARRAY=np.array[10.1,9,10,5,1,3]
and, INDX is a list of the indices of the elements within the ARRAY. Obviously the length of INDX is equal to N.

Using a hash to find one duplicated and one missing number in an array

I had this question during an interview and am curious to see how it would be implemented.
Given an unsorted array of integers from 0 to x. One number is missing and one is duplicated. Find those numbers.
Here is what I came up with:
int counts[x+1];
for(int i =0;i<=x; i++){
counts[a[i]]++;
if(counts[a[i]] == 2)
cout<<”Duplicate element: “<<a[i]; //I realized I could find this here
}
for(int j=0; j<=x; j++){
if(counts[j] == 0)
cout<<”Missing element: “<<j;
//if(counts[j] == 2)
// cout<<”Duplicate element: “<<j; //No longer needed here.
}
My initial solution was to create another array of size x+1, loop through the given array and index into my array at the values of the given array and increment. If after the increment any value in my array is two, that is the duplicate. However, I then had to loop through my array again to find any value that was 0 for the missing number.
I pointed out that this might not be the most time efficient solution, but wasn't sure how to speed it up when I was asked. I realized I could move finding the duplicate into the first loop, but that didn't help with the missing number. After waffling for a bit, the interviewer finally gave me the idea that a hash would be a better/faster solution. I have not worked with hashes much, so I wasn't sure how to implement that. Can someone enlighten me? Also, feel free to point out any other glaring errors in my code... Thanks in advance!
If the range of values is the about the same or smaller than the number of values in an array, then using a hash table will not help. In this case, there are x+1 possible values in an array of size x+1 (one missing, one duplicate), so a hash table isn't needed, just a histogram which you've already coded.
If the assignment were changed to be looking for duplicate 32 bit values in an array of size 1 million, then the second array (a histogram) could need to be 2^32 = 4 billion counts long. This is when a hash table would help, since the hash table size is a function of the array size, not the range of values. A hash table of size 1.5 to 2 million would be large enough. In this case, you would have 2^32 - 2^20 = 4293918720 "missing" values, so that part of the assignment would go away.
Wiki article on hash tables:
Hash Table
If x were small enough (such that the sum of 0..x can be represented), you could compute the sum of the unique values in a, and subtract that from the sum of 0..x, to get the missing value, without needing the second loop.
Here is a stab at a solution that uses an index (a true key-value hash doesn't make sense when the array is guaranteed to include only integers). Sorry OP, it's in Ruby:
values = mystery_array.sort.map.with_index { |n,i| n if n != i }.compact
missing_value,duplicate_value = mystery_array.include?(values[0] - 1) ? \
[values[-1] + 1, values[0]] : [values[0] - 1, values[-1]]
The functions used likely employ a non-trivial amount of looping behind the scenes, and this will create a (possibly very large) variable values which contains a range between the missing and/or duplicate value, as well as a second lookup loop, but it works.
Perhaps the interviewer meant to say Set instead of hash?
Sorting allowed?
auto first = std::begin(a);
auto last = std::end(a);
// sort it
std::sort( first, last );
// find duplicates
auto first_duplicate = *std::adjacent_find( first, last );
// find missing value
auto missing = std::adjacent_find(first, last, [](int x, int y) {return x+2 == y;});
int missing_number = 0;
if (missing != last)
{
missing_number = 1+ *missing;
}
else
{
if (counts[0] != 0)
{
missing_number = 0;
}
else
{
missing_number = 9;
}
}
Both could be done in a single hand-written loop, but I wanted to use only stl algorithms. Any better idea for handling the corner cases?
for (i=0 to length) { // first loop
for( j=0 to length ){ // second loop
if (t[i]==j+1) {
if (counter==0){//make sure duplicated number has not been found already
for( k=i+1 to length ) { //search for duplicated number
if(t[k]==j+1){
j+1 is the duplicated number ;
if(missingIsFound)
exit // exit program, missing and dup are found
counter=1 ;
}//end if t[k]..
}//end loop for duplicated number
} // end condition to search
continue ; // continue to first loop
}
else{
j+1 is the missing number ;
if(duplicatedIsFound)
exit // exit program, missing and dup are found
continue ; //continue to first loop
}//end second loop
} //end first loop

For statement find unique values

I am trying to find the unique values in the array num[], without functions, C++
Unique values in that an array with (3,5,3,4) would only find 3 unique values, the array comparing against itself. Size is the elements in the array(size 4 for the above array)
for ( k=0; k<size; k++){
for (i=k+1;num[k]!=num[i]&&i<size; i++) { // i = 1 don't want it to compare itself
if ( i+1 == size) {
unique++;
}
}
}
The problem I keep getting 1 or 0 unique values depending on what I do, any suggestions in the right direction would be helpful. Edit: added i=k+1 to second FOR (still getting 1 short though, maybe it is skipping the last iteration or first)
You're trying it without functions, but are you willing to use data structures? You could use a hash table. The keys are the values, and the values are the number of appearances, then you can count the number of hashes to find the number of unique items.
If you're using the brute force method, you'll need to compare each of element with every other element. Carefully check your code to see if it's doing that.
Alternatively, for a much faster method, use a std::set - keep adding elements into the set and find out the size of the set in the end. Duplicate elements are automatically discarded.
Thanks for everyone's answers, i = k+1 (previous loop was needed) and since the last iteration had nothing to compare to you had to check for that and add one.
for ( k=0; k<size; k++){
for (i=k+1;num[k]!=num[i]; i++) { // i = 1 don't want it to compare itself
if ( i+1 == size)
number++;
}
if(k+1==size)
number++
}

Getting a memory address in my array?

I'm writing a C++ application that has a user enter a 0 (zero) or a one (1) as input, then stores the numbers as an array and sorts them so that the zeros come first and the ones come last.
However, I think I'm getting a memory address in my array that's messing up the sorting operation.
The function that accepts input looks like this:
cout << "Please enter number " << i+1 << ":\n";
cin >> ar[i];
Then there's a function that's called that sorts the input and displays the sorted list:
sort_elements(ar, number);
... and that function looks like this:
void sort_elements(int ar[], long int num_elements) {
int temp_num;
num_elements -= 1; //since the array starts at 0
cout << "num_elements is " << num_elements << "\n";
for (int i=0; i < (num_elements/2); i++ ) {
if (ar[i] > ar[num_elements-i]) {
temp_num = ar[i];
ar[i] = ar[num_elements-i];
ar[num_elements-i] = temp_num;
}
}
cout << "Here's your neatly sorted list of numbers: \n";
for (int j=0; j <= num_elements; j++) {
cout << ar[j] << ", ";
}
cout << "\n";
}
For a five number input, starting with three "1"s, and ending with two "0"s, this results in an output that looks like this:
1, 0, 1, 1, 1892218304,
I'm assuming the 1892218304 is a memory address, that's messing up the input. Though I don't really know.
Can anyone figure out why my sort operation is getting messed up?
Thanks in advance.
Suggestion
Use vector and sort in standard library
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
int main()
{
std::vector<int> v;
for(int i=0; i < 10; i++)
{
v.push_back(i);
}
std::sort(v.begin(), v.end());
return 0;
}
The number you are seeing is not a memory address, but the value of the 4 bytes either immediately before or immediately after your array, interpreted as an int. Your code has an off-by-one error that causes an access to just outside the array. That much I suspect even though I don't have proof.
However, I can't find anything wrong with the code you posted that would cause it to access outside the array bounds.
Are you sure that num_elements has the correct value when this function is called?
Update to address the pastebin code
Things are going wrong already from the start:
int number;
int ar[number]
This is called a variable-length array and it's not legal in C90 or any flavor of C++. That your program compiles is probably "thanks to" a compiler extension... which helpfully raises a bug: the value of number is not initialized before the array is allocated.
You need to do one of the following:
declare ar as an array of constant size (a hard limit on the number of inputs you can accept)
dynamically allocate ar with new[] after number is entered from the user
(by far preferable) use an std::vector instead of an array
It looks to me like you're just getting an uninitialized value in your output.
Under the circumstances, the simplest "sorting" method is probably a counting sort -- i.e., count the number of 0's and the number of 1's the user enters, and then print out the appropriate number of 0's followed by the appropriate number of 1's.
As Tony said, your sorting algorithm is incorrect.
If we assume the following values:
ar[0] = 0
ar[1] = 1
ar[2] = 0
ar[3] = 1
ar[4] = 0
that gives us num_elements equal to 5.
Running this through your function as written, we get the following sorting behavior:
First pass, i = 0
ar[0] > ar[4] -> not true, so no switch
Secon pass, i = 1
ar[1] > ar[3] -> not true, so no switch
There is no third pass, as your for loop condition is met
i = 2
num_elements/2 = 2
2 is not less than 2
So based on your code, you didn't sort anything. This is the first issue.
Your print problem is interesting, based on what you have shown num_elements has been decremented by 1 at the top of your code snippet in your function - therefore the <= condition is correct and you should not be outside the bounds of your 'ar' array. Are you sure this is the exact code, or perhaps you did not copy it properly here and you are actually having a scoping issue?
(EDIT: Although the other answers suggesting using a built in sorting method via vectors, I'd suggest you still work your current implementation out to figure out WHY this is wrong, and what you need to do to fix it. You will not always have an available type that has built in sorting, so understanding the fundamentals is important for any young programmer.)
EDIT2: Based on the link you provided, you aren't properly defining your integer array. You are defining the array based on an uninitialized integer (int ar[number]) when number has not yet been initialized. You then read a value from the standard input to set number, and assume your array has been dynamically adjusted to be of the size read from cin. It does not work this way. Your entire loop is reading/writing outside the bounds of your array which is a big no-no. You want to read the number first, and then define your array based on the size read. - Looks like Jon beat me again.. BAH! :P
The last element being read and printed to the screen has never been written to. I think it's likely your function which accepts input has a fault, like maybe you have a line like you have here
num_elements -= 1; //since the array starts at 0
at the input function so that the first element you write to is at address 1. Then when you're reading them you read from address zero.
I kind of agree with Jim's point: Use the facilities in the C++ standard library to finish your task as much as possible.
Besides, I suggest you go through the algorithm all by yourself, manually, instead of letting the computer run it for you. Ever heard of the "Rubber Duck Debugging Method"? :-) Have a try.