loop through an array in c++ - c++

I want to loop through an array that I have that has a max value of 1000. I am filling the array with values from a text file. I am trying to loop through that array but in my for loop, I do not know the length of the array, so I do not know what to put in the second part of the for loop statement. For example: I have an array called: int scores[1000]; and I am trying to iterate through this array and putting scores in a grade category. So A = 90-100, B = 80-89, C = 70-79, D = 60-69, F = 0-59.
So I dont know what my for loop would look like:
for(int i = 0; i < ...; i++){
if(scores[i] > = 90 || scores[i] <= 100){
//Do stuff...
}
I guess I am also confused as to how to get the total counts of each category at the end too. But for the most part its how to iterate through this array. I know sizeof(scores[]) wont work because that will give me the int size and not the length of the array itself. Thanks though in advance!

Actually the sizeof() should be done like this:
sizeof(scores) / sizeof(scores[0])
And this will give you the total element numbers of the array.

If you use an std::vector (link) instead, you can add elements and have the vector dynamically change size. That size can be queried easily using the size() method. If you use arrays like this, you have to keep track of the number of elements in it yourself.
If you have a vector filles with elements your loop could look like this:
std::vector<int> scores;
// fill vector
for (unsigned int i=0; i<scores.size(); i++) {
// use value
}
If you have to use arrays and actually have a scoreCount variable with the number of real values put in there, simply use that in your loop:
for (int i=0; i<scoreCount; i++) {
// use value
}
A third option, as I mentioned in the comments, would be initializing the whole array with a value that you're never using (typically -1) and then use that as a marker for filled vs empty array positions like so:
for (int i=0; i<1000; i++) {
scores[i] = -1;
}
// add real values to scores
int i=0;
while (scores[i] != -1 && i < 1000) {
// use value
i++;
}

When you populate the scores array, you need to actually count how many items you put in it. Then you remember that number and use it for iteration later. For example, you may have read your scores like this:
// Read some scores: Stop when -1 is entered, an error occurs, or 1000 values are read.
int num_scores = 0;
for( ; num_scores < 1000; num_scores++ )
{
if( !(cin >> scores[num_scores]) || scores[num_scores] == -1 ) break;
}
// Do stuff with scores...
for(int i = 0; i < num_scores; i++) {
...
}
There are some other options to consider:
use a sentinel value to represent the end of data, such as a score of -1.
use a std::vector instead.
By the way, the logical statement inside your loop will always be true. Are you sure you didn't mean to use && instead of ||?

If you really want to use a container with a fixed size, use std::array for modern C++ instead of a C-array:
#include <array>
std::array<std::int32_t, 1000> scores;
for (std::size_t i{0}; i < scores.size(); ++i) {
// Do stuff...
}
Otherwise use a std::vector:
#include <vector>
std::vector<std::int32_t> scores;
for (std::size_t i{0}; i < scores.size(); ++i) {
// Do stuff...
}
If you are able to use C++11 I also recommend to use the fixed width integer types.

Related

Determine duplicates/pairs in an array in C++

I have been doing this problem for 2 days now, and I still can't figure out how to do this properly.
In this program, I have to input the number of sticks available (let's say 5). Then, the user will be asked to input the lengths of each stick (space-separated integer). Let's say the lengths of each stick respectively are [4, 4, 3, 3, 4]. Now, I have to determine if there are pairs (2 sticks of same length). In this case, we have 2 (4,4 and 3,3). Since there are 2 pairs, we can create a canvas (a canvas has a total of 2 pairs of sticks as the frame). Now, I don't know exactly how to determine how many "pairs" there are in an array. I would like to ask for your help and guidance. Just note that I am a beginner. I might not understand complex processes. So, if there is a simple (or something that a beginner can understand) way to do it, it would be great. It's just that I don't want to put something in my code that I don't fully comprehend. Thank you!
Attached here is the link to the problem itself.
https://codeforces.com/problemset/problem/127/B
Here is my code (without the process that determines the number of pairs)
#include<iostream>
#include<cmath>
#define MAX 100
int lookForPairs(int numberOfSticks);
int main(void){
int numberOfSticks = 0, maxNumOfFrames = 0;
std::cin >> numberOfSticks;
maxNumOfFrames = lookForPairs(numberOfSticks);
std::cout << maxNumOfFrames << std::endl;
return 0;
}
int lookForPairs(int numberOfSticks){
int lengths[MAX], pairs = 0, count = 0, canvas = 0;
for(int i=0; i<numberOfSticks; i++){
std::cin >> lengths[i];
}
pairs = floor(count/2);
canvas = floor(pairs/2);
return count;
}
I tried doing it like this, but it was flawed. It wouldn't work when there were 3 or more integers of the same number (for ex. [4, 4, 3, 4, 2] or [5. 5. 5. 5. 6]). On the first array, the count would be 6 when it should only be 3 since there are only three 4s.
for(int i=0; i<numberOfSticks; i++){
for (int j=0; j<numberOfSticks; j++){
if (lengths[i] == lengths[j] && i!=j)
count++;
}
}
Instead of storing all the lengths and then comparing them, count how many there are of each length directly.
These values are known to be positive and at most 100, so you can use an int[100] array for this as well:
int counts[MAX] = {}; // Initialize array to all zeros.
for(int i = 0; i < numberOfSticks; i++) {
int length = 0;
std::cin >> length;
counts[length-1] += 1; // Adjust for zero-based indexing.
}
Then count them:
int pairs = 0;
for(int i = 0; i < MAX; i++) {
pairs += counts[i] / 2;
}
and then you have the answer:
return pairs;
Just an extension to molbdnilo's answer: You can even count all pairs in one single iteration:
for(int i = 0; i < numberOfSticks; ++i)
{
if(std::cin >> length) // catch invalid input!
{
pairs += flags[length] == 1; // add a pair if there is already a stick
flags[length] ^= 1; // toggle between 0 and 1...
}
else
{
// some appropriate error handling
}
}
Note that I skipped subtracting 1 from the length – which requires the array being one larger in length (but now it can be of smallest type available, i.e. char), while index 0 just serves as an unused sentinel. This variant would even allow to use bitmaps for storing the flags, though questionable if, with a maximum length that small, all this bit fiddling would be worth it…
You can count the number of occurrences using a map. It seems that you are not allowed to use a standard map. Since the size of a stick is limited to 100, according to the link you provided, you can use an array, m of 101 items (stick's minimum size is 1, maximum size is 100). The element index is the size of the stick. The element value is the number of sticks. That is, m[a[i]] is the number of sticks of size a[i]. Demo.
#define MAX 100
int n = 7;
int a[MAX] = { 1,2,3,4,1,2,3 };
int m[MAX + 1]; // maps stick len to number of sticks
void count()
{
for (int i = 0; i < n; ++i)
m[a[i]]++;
}
int main()
{
count();
for (int i = 1; i < MAX + 1; ++i)
if (m[i])
std::cout << i << "->" << m[i] << std::endl;
}
Your inner loop is counting forward from the very beginning each time, making you overcount the items in your array. Count forward from i , not zero.
for(int i=0; i<numberOfSticks; i++)
{
for (int j=i; j<numberOfSticks; j++) { // count forward from i (not zero)
if (lengths[i] == lengths[j] && i!=j)
{ // enclosing your blocks in curly braces , even if only one line, is easier to read
count++; // you'll want to store this value somewhere along with the 'length'. perhaps a map?
}
}
}

Can you change a pointer in loop?

Let's say I have a vector of integers:
vector<int> v(n);
Which I fill up in a for loop with valid values. What I want to do is to find a index of a given value in this vector. For example if I have a vector of 1, 2, 3, 4 and a value of 2, i'd get a index = 1. The algorithm would assume that the vector is sorted in ascending order, it would check a middle number and then depending of it's value (if its bigger or smaller than the one we're asking for) it would check one of halves of the vector. I was asked to do this recursive and using pointer. So I wrote a void function like:
void findGiven(vector<int> &v){
int i = 0;
int *wsk = &v[i];
}
and I can easily access 0th element of the vector. However I seem to have some basic knowledge lacks, because I can't really put this in a for loop to print all the values. I wanted to do something like this:
for (int j = 0; j<v.size(); j++){
cout << *wsk[j];
}
Is there a way of doing such a thing? Also I know it's recurisve, I'm just trying to figure out how to use pointers properly and how to prepare the algorithm so that later I can build it recursively. Thanks in advance!
The correct way is:
for (int wsk : v) {
cout << wsk;
}
If you insist on pointers:
int* first = v.data();
for (size_t j = 0; j < v.size(); ++j) {
cout << first[j];
}

If statement - C++

I have this array that I have created full of values and basically I want to go thru an if statement to check for every value that is input into the array is of a certain condition. The condition is fine and I have all the values that I need but this if statement is taking all the values from the redsigma array rather than each one from the array. How do I put each value into the if statement rather than the whole array. Relatively new to c++. Any help is appreciated.
for (int i = 0; i < 7990272; i++)
{
float redsigma[] = { img1->pixels[i].r + img2->pixels[i].r + img3->pixels[i].r + img4->pixels[i].r}
if (redsigma[0] > lbounds && redsigma[0] < upbounds)
{
do work blah blah blah
}
}
You need to use a for-loop to iterate over the elements:
for(int i = 0; i < the length of redsigma; ++i) {
if(redsigma[i] meets conditions) {
}
}
I recommend that you use std::vector instead of an array.

C++ check if element exists in array

I've found a lot of topics like this, but it was kinda too complicated for me.
How to check if element exists in an array?
first I declare an array and put values in it
for(int l=0;l<=21;l++){
skirt[l]=l;
}
and then with another for I'd like to check if any element which exist in other array is in array skirt[];
Is there a way to write it something like this?
for(int k=0;k<=n;k++){
if(skaiciai[k]!=skirt[k]){
counter++;
}
}
The best way to do this would be to use standard algorithm, rather than a handwritten loop:
if (std::find_first_of(
skirt, skirt + skirt_size,
skaiciai, skaiciai + skaiciai_size)
!= skirt + skirt_size)
{
//skirt contained an element from skaiciai
}
The loop:
for(int k=0;k<=n;k++){
if(skaiciai[k]!=skirt[k]){
counter++;
}
}
would only compare elements at the same index in the arrays. Nested for loops are required with the outer for loop iterating over the elements in one array and the inner for loop iterating over elements in the other array:
for (int k_skirt = 0; k_skirt <= n; k_skirt++)
{
for (int k_skaiciai = 0; k_skaiciai <= n; k_skaiciai++)
{
if(skaiciai[k_skaicia] == skirt[k_skirt]){
counter++;
}
}
}
You could simply use the std::count algorithm.
auto counter = std::count( skirt, skirt+skirt_size );

C++ Checking for identical values in 2 arrays

I have 2 arrays called xVal, and yVal.
I'm using these arrays as coords. What I want to do is to make sure that the array doesn't contain 2 identical sets of coords.
Lets say my arrays looks like this:
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
Here I want to find the match between xVal[0] yVal[0] and xVal[1] yVal[1] as 2 identical sets of coords called 1,1.
I have tried some different things with a forLoop, but I cant make it work as intended.
You can write an explicit loop using an O(n^2) approach (see answer from x77aBs) or you can trade in some memory for performance. For example using std::set
bool unique(std::vector<int>& x, std::vector<int>& y)
{
std::set< std::pair<int, int> > seen;
for (int i=0,n=x.size(); i<n; i++)
{
if (seen.insert(std::make_pair(x[i], y[i])).second == false)
return false;
}
return true;
}
You can do it with two for loops:
int MAX=4; //number of elements in array
for (int i=0; i<MAX; i++)
{
for (int j=i+1; j<MAX; j++)
{
if (xVal[i]==xVal[j] && yVal[i]==yVal[j])
{
//DUPLICATE ELEMENT at xVal[j], yVal[j]. Here you implement what
//you want (maybe just set them to -1, or delete them and move everything
//one position back)
}
}
}
Small explanation: first variable i get value 0. Than you loop j over all possible numbers. That way you compare xVal[0] and yVal[0] with all other values. j starts at i+1 because you don't need to compare values before i (they have already been compared).
Edit - you should consider writing small class that will represent a point, or at least structure, and using std::vector instead of arrays (it's easier to delete an element in the middle). That should make your life easier :)
int identicalValueNum = 0;
int identicalIndices[4]; // 4 is the max. possible number of identical values
for (int i = 0; i < 4; i++)
{
if (xVal[i] == yVal[i])
{
identicalIndices[identicalValueNum++] = i;
}
}
for (int i = 0; i < identicalValueNum; i++)
{
printf(
"The %ith value in both arrays is the same and is: %i.\n",
identicalIndices[i], xVal[i]);
}
For
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
the output of printf would be:
The 0th value in both arrays is the same and is: 1.
The 1th value in both arrays is the same and is: 1.
The 3th value in both arrays is the same and is: 4.