I have a problem running my small piece of code.
I have a vector who reads in temperature from User Input. I want to process the data a bit. Giving out which kind of day it was (hot day, summer day, etc...) and which day was the hottest.
But everytime I want to get the maximum temperature with the function maxNumber I get 2 errors which I dont understand:
non-standard syntax; use '&' to create a pointer to member
"! =": Function overload cannot be resolved
Please help! Thx very much
Code:
#include <iostream>
#include <vector>
std::string klimaTag(float a) {
if (a >= 25 and a < 30) {
return "Sommertag";
}
else if (a >= 30 and a < 35) {
return "Heißer Tag";
}
else if (a >= 35) {
return "Wüstentag";
}
else {
return "Normaltag";
}
}
float maxNumber(std::vector<float> &a) {
float current_max = 0;
for (int i = a.begin; i != a.end; i++) {
if (a.at(i) > current_max) {
current_max = a.at(i);
}
return current_max;
}
}
int main()
{
std::vector<float> temperatures;
float current_temp;
for (int i = 0; i < 5; i++) {
std::cout << "Hoechsttemp für Tag " << i << " eingeben: ";
std::cin >> current_temp;
temperatures.push_back(current_temp);
}
for (int i = 0; i < 5; i++) {
std::cout << "Tag " << i + 1 << " ist ein " << klimaTag(temperatures.at(i)) << std::endl;
}
std::cout << maxNumber(temperatures);
}
First of all begin() and end() are method, so you're getting that error because you're trying to reference a function so it should require an address operator.
Second is begin() and end() return an iterator and not an index, and you're clearing trying to access like index.
Third thing is you're always returning after the first cycle as your return is inside it and should be outside.
To loop correctly your array is enough to use the for range loop
float maxNumber(std::vector<float> &a) {
float current_max = 0;
for(const auto& element : a) {
if(element > current_max){
current_max = element;
}
}
return current_max;
}
if you want to use the old way you can always do
float maxNumber(std::vector<float> &a) {
float current_max = 0;
for(int i=0; i<a.size(); ++a) {
if(a.at(i) > current_max){
current_max = a.at(i);
}
}
return current_max;
}
a.end refers to the function address, you need to invoke the function itself with a.end() hence the complaint about the non standard syntax, as if you meant to take the function address you could call &a.end. Same with a.begin.
To use the for loop as you described, you need int i = 0; i < a.size(). Moreover the return statement is inside the for loop in maxNumber. That's not what you want (it exits at the first loop cycle), put it outside.
Begin and end are actually methods for working with iterators. To use them you should change a bit the loop.
begin and end are functions which need to be called like functions: begin() and end().
However, you can use range-based for loop like:
float maxNumber(std::vector<float> &a) {
float current_max = 0;
for (auto const i : a) {
if (i > current_max) {
current_max = i;
}
}
return current_max;
}
Please, note where I put your return statement. It is outside of the for loop.
Related
Solution is probably pretty easy but I can't figure it out. How do I make a permanent change to the vector and not only a change that takes effect inside the function? I debugged it and I can see that "numbers" is updated with the value I want it to have but it disappears as soon as it is executed.
using namespace std;
bool checkVal();
vector<int> getNumbers();
void setPowerball(vector<int> numbers);
int main()
{
srand(time(0));
vector<int> numbers = getNumbers();
setPowerball(numbers);
for (int i = 0; i < 5; i++)
{
cout << numbers[i];
cout << " ";
}
}
bool checkVal(vector<int> numbers, int size, int value)
{
for (int i = 0; i < size; ++i)
{
if (numbers[i] == value)
{
return true;
}
}
return false;
}
void setPowerball(vector<int> numbers)
{
for (int i = 4; i < 5; i++)
{
int last = rand() % 26 + 1;
if (checkVal(numbers, i, last))
{
i--;
}
else
{
numbers.push_back(last);
}
}
}
vector<int> getNumbers()
{
vector<int> numbers;
for (int i = 0; i < 4; i++)
{
int num = rand() % 69 + 1;
if (checkVal(numbers, i, num))
{
i--;
}
else
{
numbers.push_back(num);
}
}
sort(numbers.begin(), numbers.end());
return numbers;
}
You are passing arguments to setPowerBall function by value. So whenever it's called, it gets its private copy of the vector, which gets destructed at the end of function scope.
Instead you should be passing the arguments by reference in this case.
void setPowerball(vector<int>& numbers)
{
// do stuff
}
MAIN POINTS :-
Notice the & in function declaration. It implies taking a lvalue reference.
References allow you to modify the original variable without making a copy.
References are also cheaper to pass in case of objects like std::string or std::vector. But for primitive types like int or float, pass by value is faster.
Note : You could also have used pointers to do the same but using References is recommended and safer way. Rule of the thumb is Use references when you can, and pointers when you must
During compiling, it shows this warning - control reaches end of non-void function [-Wreturn-type]. I googled and found that this warning shows when you don't return anything in the function. But I couldn't figure out where's the error in my code.
Here's my code:
#include <iostream>
#include <algorithm>
using namespace std;
int findUnique(int *a, int n){
sort(a, a+n);
int i=0;
while(i<n){
if(a[i]==a[i+1]){
i += 2;
}
else{
return a[i];
}
}
}
int main(){
int t;
cin >> t;
while (t--){
int size;
cin >> size;
int *input = new int[size];
for (int i = 0; i < size; ++i)
{
cin >> input[i];
}
cout << findUnique(input, size) << endl;
}
return 0;
}
You have to know why this warning is shown to understand what to do about it, this warning is shown when your function has a return type but you haven't returned value from one or more exit points of a function. Now see in your function, you return a[i] but consider a situation where your code doesn't go in the else block at all. So after coming out of the while block. There is no return statement therefore compiler is throwing control reaches the end of non-void function [-Wreturn-type].
The function returns nothing in case when the array does not contain a unique number or when the parameter n is equal to 0.
So the compiler issues the warning message.
Moreover the while loop can invoke undefined behavior when i is equal to n-1 due to using a non-existent element with the index n in this if statement
if(a[i]==a[i+1]){
Also there is a logical error. The if statement
if(a[i]==a[i+1]){
i += 2;
}
else{
return a[i];
}
does not guarantee that indeed a unique number will be returned.
Using your approach when it is allowed to change the original array by calling the algorithm std::sort the function can be defined for example the following way
size_t findUnique( int *a, size_t n )
{
std::sort( a, a + n );
size_t i = 0;
bool unique = false;
while ( !unique && i != n )
{
size_t j = i++;
while ( i != n && a[i] == a[j] ) i++;
unique = i - j == 1;
}
return unique ? i - 1 : i;
}
And in main the function can be called like
size_t pos = findUnique(input, size);
if ( pos != size )
{
cout << input[pos] << endl;
}
else
{
// output a message that there is no unique number
}
Pay attention to that your program produces multiple memory leaks. You need to free the allocated memory in each iteration of the while loop.
The problem is in the function findUnique This function is supposed to return int no matter what although in your code you are returning an integer only under certain conditions
Here is a possible fix:
// return true if unique number found
// return false otherwise
bool findUnique(int *a, int n, int *unique){
sort(a, a+n);
int i=0;
while(i<n){
if(a[i]==a[i+1]){
i += 2;
}
else{
*unique = a[i];
return true;
}
}
return false;
}
Then in the main something like that:
int unique;
bool uniqueFound = findUnique(input, size &unique);
if (uniqueFound == true)
cout << unique << endl;
else
cout << "No unique number found" << endl;
I am trying to improve my programming skills by solving couple of Code Jam questions. I have been stuck for a while on the "Trouble Sort" question from the Qualifier Rounds in 2018. My code produces the expected output with the example input in my console, but the online judge return "Wrong Answer".
Apparently Trouble sort is just like bubble sort, except instead of comparing the ith and i+1th elements, it compares the ith and i+2th elements and if the former is greater than the latter then the elements are swapped. The question says that this algorithm is flawed as arrays like 897 after trouble sort will return 798, which isn't sorted either. The task is to check if for a given list of integers, trouble sort is able to successfully sort the array or if it isn't then which is the index value of the first element that is out of place.
My code inputs the number of tests t and the size of integer list. Then I make a copy of it and put one copy through bubble sort and the other through trouble sort. Then I compare them element wise and if an index which has the two elements as different integers is found, it is outputted. I'm not sure what I am doing wrong here.
#include<iostream>
#include<vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
void swapVal(int& a, int& b)
{
int t = a;
a = b;
b = t;
}
int main()
{
int t;
cin >> t;
for (int i = 1; i <= t; i++)
{
int n;
cin >> n;
vector<int> bs(n);
vector<int> ts(n);
for (int i = 0; i < n; i++)
{
cin >> bs[i];
ts[i] = bs[i];
}
//bubbleSort(bs, n);
{
bool bsSorted = false;
while (!bsSorted)
{
bsSorted = true;
for (int i = 0; i < n - 1; i++)
{
if (bs[i] > bs[i + 1])
{
swapVal(bs[i], bs[i + 1]);
bsSorted = false;
}
}
}
}
//troubleSort(ts, n);
{
bool tsSorted = false;
while (!tsSorted)
{
tsSorted = true;
for (int i = 0; i < n - 2; i++)
{
if (ts[i] > ts[i + 2])
{
swapVal(ts[i], ts[i + 2]);
tsSorted = false;
}
}
}
}
bool same = true;
int minidx = 0;
for (int i = 0; i < n; i++)
{
if (bs[i] != ts[i])
{
same = false;
minidx = i;
break;
}
}
if (same == true)
{
cout << "Case #" << i << ": OK" << endl;
}
else if (same == false)
{
cout << "Case #" << i << ": " << minidx;
}
}
}
I am expecting the judge to give me a tick of approval, but instead it is repeatedly returning "Wrong Answer". What am I doing wrong here?
The algorithm looks correct to me. I noticed that in the false case you seem to be missing the newline. So two consecutive false statements will be on the same line.
cout << "Case #" << i << ": " << minidx<<'\n';
Might solve your problem.
Few remarks:
if (same == true) is equivalent to if(same) and if (same == false) to if(!same).
There's already std::swap.
Some people might not like nested for loops having equally named variables - the nested variable will hide the outer one.
I am creating a program that rewrites an array with values from a file. I have linked the code below. When running the file I get the error "Run-time check failure, stack around 'arr' variable was corrupted.
Also, the output of the program returns all the array locations with the same number,
arr[0] = -858993460
The numbers in the file, separated by a line are:
12
13
15
#include<iostream>;
#include<fstream>;
using namespace std;
template <class T>
void init(T * a, int size, T v)//done
{
for (int i = 0; i < size; i++)
{
a[size] = v;
}
}
bool getNumbers(char * file, int * a, int & size)//not done
{
int count = 0;
ifstream f(file);
while (f.good() == true && count < 1)
{
f >> a[count];
count++;
}
if (size > count)
{
return true;
}
else if (size < count)
{
return false;
}
}
void testGetNumbers()
{
int arr[5];
int size = 5;
cout << "Testing init and getNumbers." << endl;
init(arr, 5, -1);
cout << "Before getNumbers: " << endl;
for (int i = 0; i < size; i++)
{
cout << "arr[" << i << "] = " << arr[i] << endl;
}
if (getNumbers("nums.txt", arr, size))
{
cout << size << " numbers read from file" << endl;
}
else
{
cout << "Array not large enough" << endl;
}
cout << "After getNumbers: " << endl;
for (int i = 0; i < size; i++)
{
cout << "arr[" << i << "] = " << arr[i] << endl;
}
cout << endl;
}
int main()
{
testGetNumbers();
return 0;
}
This line in the first loop looks like having error.
a[size] = v;
It causes out of array bound access and memory/stack corruption. It should be
a[i] = v;
Starting with the main function, the line
return 0;
... is not necessary because that's the default return value for main. I would remove it, some people insist on having it, I think most people don't care. But it's always a good idea to be fully aware of what the code expresses, implicitly or explicitly, so: returning 0 expresses that the program succeeded.
For an explicit main return value I recommend using the names EXIT_SUCCESS and EXIT_FAILURE from the <stdlib.h> header.
Then it's much more clear.
main calls testGetNumbers, which, except for an output statement, starts like this:
int arr[5];
int size = 5;
init(arr, 5, -1);
As it happens the init function is has Undefined Behavior and doesn't fill the array with -1 values as intended, but disregard. For now, look only at the verbosity above. Consider writing this instead:
vector<int> arr( 5, -1 );
Using std::vector from the <vector> header.
Following the call chain down into init, one finds
a[size] = v;
That attempts to assign value v to the item just beyond the end of the array.
That has Undefined Behavior.
Should probably be
a[i] = v;
But as noted, this whole function is redundant when you use std::vector, as you should unless strictly forbidden by your teacher.
Back up in testGetNumbers it proceeds to call getNumbers, in that function we find
ifstream f(file);
while (f.good() == true && count < 1)
{
f >> a[count];
count++;
}
Generally one should never use f.good() or f.eof() in a loop condition: use f.fail(). Also, ~never compare a boolean to true or false, just use it directly. Then the loop can look like this:
ifstream f(file);
while (!f.fail() && count < 1)
{
f >> a[count];
count++;
}
Tip: in standard C++ you can write ! as not and && as and. With the Visual C++ compiler you have to include the <iso646.h> header to do that.
Disclaimer: the fixes noted here do not guarantee that the loop is correct for your intended purpose. Indeed the increment of count also when the input operation fails, looks probably unintended. Ditto for the loop limit.
The function continues (or rather, ends) with
if (size > count)
{
return true;
}
else if (size < count)
{
return false;
}
This has a big problem: what if size == count? Then the execution continues to fall off the end of the function without returning a value. This is again Undefined Behavior.
I leave it to you to decide what you want the function to return in that case, and ensure that it does that.
In your init function...
template <class T>
void init(T * a, int size, T v)//done
{
for (int i = 0; i < size; i++)
{
a[size] = v;
}
}
Nope:
a[size] = v;
Yup:
a[i] = v;
whats the smartest way to do something only once per iteration in a nested loop? i can't pull out the invariant part because the outer loop is very complex.
Here is my C++ example:
void foo::bar() {
if(oldCycle == tree.cycle) {
doSomething();
oldCycle++;
}
}
this method is called very often until tree.cycle is incremented. oldCycle is a private member variable of foo
claas foo {
public: ...
private:
int oldCycle;
};
Does the compiler optimize this code or will the if check run every iteration?
Edit: Here like requested the code with the loops:
the first loop is in the mexFunction() method, the algorithm is started in matlab and calls the mexFunction.
void mexFunction(...) {
for( tree.cycle = 0; tree.cycle<maxIt; tree.cycle++ ) {
foo->startfoo();
}
}
and here is the other loop:
void foo::startfoo() {
for(tree.cur_it = 0; tree.cur_it <=39; tree.cur_it++ ) {
bar();
}
}
For a general condition, you can't really optimize this out, since you would need to remove the special case from the collection one way or another.
However, for the special case of treating the first element specially (e.g. when printing a range with delimiters as "1, 2, 3"), you can use Knuth's "loop-and-a-half":
Naive loop:
for (unsigned int i = 0; i != values.size(); ++i)
{
if (i != 0) { std::cout << ", "; }
std::cout << values[i];
}
Loop-and-a-half:
if (!values.empty())
{
for (unsigned int i = 0; ; )
{
std::cout << values[i];
++i;
if (i == values.size()) { break; }
std::cout << ", ";
}
}
The latter construction is more involved, but saves you the mostly false check i != 0.
That said, it's quite plausible that a good compiler will do the partial unrolling even if you write the code the naive way.
For simple cases I prefer this method.
if ( ! values.empty())
{
std::cout << values[0];
for (size_t z = 1; z < values.size(); z++)
{
std::cout << ", " << values[z];
}
}