I have three functions below, I'm not sure why the second and the third one have a warning at *arr but the first one doesn't. What does the warning mean and how to fix this?
IDE: Clion 2017.3 MinGW64 5.0, CMake 3.9.4
Thank you.
int getFirstEven(int n, int *arr) {
for (int i = 0; i < n; ++i) {
if (arr[i] % 2 == 0)
return arr[i];
}
return -1;
}
int getLastOdd(int n, int *arr) {
int lastOdd = -1;
for (int i = 0; i < n; ++i) {
if (arr[i] % 2 != 0)
lastOdd = arr[i];
}
return lastOdd;
}
int countElement(int n, int *arr, int e) {
int cnt = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == e)
cnt++;
}
return cnt;
}
It makes sense to favor immutability where possible and to indicate immutable things with const.
The warning means that your function does not modify the data pointed at by arr and so the function could be better declared with pointer to const parameter. About like that:
int getFirstEven(int n, int const* arr) {
for (int i = 0; i < n; ++i) {
if (arr[i] % 2 == 0)
return arr[i];
}
return -1;
}
Related
This question already has answers here:
C++ code showing Line 25: Char 5: error: non-void function does not return a value in all control paths [-Werror,-Wreturn-type]
(3 answers)
Closed 1 year ago.
This may be a simple mistake but I can't get my head around why this doesn't work.
When I try to return index or -1 as in the code, it doesn't work. I get the error:
error: non-void function does not return a value in all control paths [-Werror,-Wreturn-type]
}
^
Why does it do this yet I'm returning an integer? Someone, please explain
int firstUniqChar(string s) {
map<char, int> data;
int index;
int arrayLength = s.size();
for(int i = 0; i< arrayLength; i++)
data[s[i]] = -1;
for(int i = 0; i< arrayLength; i++)
{
if(data[s[i]] == -1)
data[s[i]] = 1;
else
data[s[i]] += 1;
}
for(int i = 0; i< arrayLength; i++)
{
if(data[s[i]] == 1){
index = i;
return index;
}
return -1;
}
}
};
However, when I assign the result to a variable and return it as below in the code, it works fine. Why is that?
public:
int firstUniqChar(string s) {
map < char, int > data;
int index;
int arrayLength = s.size();
for (int i = 0; i < arrayLength; i++)
data[s[i]] = -1;
for (int i = 0; i < arrayLength; i++) {
if (data[s[i]] == -1)
data[s[i]] = 1;
else
data[s[i]] += 1;
}
for (int i = 0; i < arrayLength; i++) {
if (data[s[i]] == 1) {
index = i;
return index;
}
index = -1;
}
return index;
}
};
The return -1; is inside for so the routine potentially ends with no return.
You might have noticed it yourself after normalizing the indentation. :)
I would like to modify the N-Queens backtracking algorithm by getting the size of the board (N) from the standard input instead of defining N as a constant.
However, I can't match the types at the functions. Should I define some kind of global maximum constant and then work with n?
Here's the code:
#include <iostream>
using namespace std;
bool safe(int N, char mat[][N], int v, int k)
{
int i, j;
for (i = 0; i < v; i++)
if (mat[i][k] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j >= 0; i--, j--)
if (mat[i][j] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j < N; i--, j++)
if (mat[i][j] == 'Q')
return false;
return true;
}
void backtrack(int N, char mat[][N], int v)
{
if (v == N)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << mat[i][j] << " ";
cout << endl;
}
cout << endl;
return;
}
for (int i = 0; i < N; i++)
{
if (safe(N, mat, v, i))
{
mat[v][i] = 'Q';
backtrack(N, mat, v + 1);
mat[v][i] = '-';
}
}
}
int main()
{
int N;
cin >> N;
char mat[N][N];
memset(mat, '-', sizeof mat);
backtrack(N,mat, 0);
return 0;
}
char mat[N][N]; is a Variable Length Array (VLA) which is a non standard extension of some c++ compilers that you should avoid using. If you need run-time allocated memory, consider using a std::vector:
int N{};
std::cin >> N;
std::vector<std::vector<char>> mat(N, std::vector<char>(N, '-'));
will do what you want. You can then pass this to any function using:
void foo(const std::vector<std::vector<char>>& mat); // for read-only
void foo(std::vector<std::vector<char>>& mat); // for read-write
Note: this is potentially less effeccient depending on how memory is allocated. If you need your memory to line up all together, use a 1D vector and access function to get index for you.
I want to compare a 2D array with my custom compare function. I also reference some similar problem, but it doesn't work.
Following is what I did (compare 2D array with row and I need to use array instead of vector):
int n, dim;
int box[33][33];
bool cmp(const int a[], const int b[]){
for(int i = 0; i < dim; i++){
if(a[i] != b[i])
return a[i] < b[i];
}
return a[dim] < b[dim];
}
int main()
{
while(cin>>n>>dim){
for(int i = 0; i < n; i++){
for(int j = 0; j < dim; j++){
cin>>box[i][j];
}
box[i][dim] = i+1; // store index of box
sort(box[i], box[i]+dim);
}
sort(box, box + n, cmp); // This line is where I want to modify
for(int i = 0; i < n; i++){
for(int j = 0; j < dim; j++){
cout<<box[i][j]<<" ";
}
cout<<"\n";
}
}
return 0;
}
You could use std::qsort in this case, by providing the appropriate comparator:
int cmp(const void *l, const void *r)
{
const int *a = (const int*)l;
const int *b = (const int*)r;
for(int i = 0; i < dim; i++)
{
if(a[i] != b[i])
return (a[i] > b[i]) - (a[i] < b[i]);
}
return (a[dim] > b[dim]) - (a[dim] < b[dim]);
}
and then calling it like this:
std::qsort(box, n, sizeof(int) * (dim + 1), cmp);
You could also simplify the comparator like this:
int comp(const void *l, const void *r)
{
const int *a = (const int*)l;
const int *b = (const int*)r;
return std::lexicographical_compare(b, b + dim + 1, a, a + dim +1);
}
Note that the arguments are in opposite order to get ascending order.
I'm working on a program that will display all possible permutations for an array, and then store the unique permutations in another array, however I am having issues with storing the unique permutations. I was going through my code and was getting a few errors because I had created the uniquePermutations variable and hadn't initialized. After trying to access the variable the program would crash so then I tried setting it equal to nullptr which helped.
So now when I use my copyUniquePermutations function (which is called in the permute function, it checks to see if the array is empty with nullptr and then if it is, we declare 3 new arrays, and set each spot equal to NULL so that we won't get any undefined behavior. Then next, I check to see if any spots are NULL so that we won't get to the equalArrays function which may cause issues and then we get to the assignment part which causes issues. Since we assigned newArray[i] to be NULL why does the computer say that it is having issues writing to this spot?
#include <iostream>
using namespace std;
int permutations[] = { 2, 1, 2 };
void swap(int &x, int &y)
{
int temp;
temp = x;
x = y;
y = temp;
}
bool equalArrays(int array1[], int array2[], int size)
{
for (int i = 0; i < size; i++)
if (array1[i] != array2[i]) return false;
return true;
}
void copyUniquePermutations(int oldArray[], int *newArray[])//This is the function that is causing issues
{
for (int i = 0; i < 3; i++)
{
if (newArray == nullptr)
{
newArray = new int*[3];
for (int j = 0; j<3; j++)
newArray[i] == NULL;
}
if (newArray[i] == NULL || !equalArrays(oldArray, newArray[i], 3))
{
for (int j = 0; j < 3; j++)
newArray[i][j] == oldArray[j];
}
}
}
void permute(int permutations[], int *uniquePermutations[], int l, int r)
{
int i;
if (l == r)
copyUniquePermutations(permutations, uniquePermutations);
else
{
for (i = l; i <= r; i++)
{
swap((permutations[l]), (permutations[i]));
permute(permutations, uniquePermutations, l + 1, r);
swap((permutations[l]), (permutations[i]));
}
}
}
int main()
{
int **uniquePermutations = nullptr;
permute(permutations, uniquePermutations, 0, 2);
for (int i = 0; i < 3 ; i++)
delete[] uniquePermutations[i];
delete[] uniquePermutations;
return 0;
}
I think here you need to have j in newArray[j]
for (int j = 0; j<3; j++)
newArray[i] == NULL;
I'm writing a program that is made of a function that takes in a 2d array, c0unts the evens in the array and returns the amount of evens in that array. The function isn't returning the value that i intend it to, which is 6. Sometimes I get 0, sometimes I get a number like 2147483646.
#include <iostream>
#include <array>
using namespace std;
const int MaxNumOfRows = 3;
const int MaxNumOfColumns = 2;
int Even(int A[MaxNumOfRows][MaxNumOfColumns], int length, int width)
{
int NumnberOfEvens = 0;
int i;
int j;
for (i = 0; i < length; length++)
{
for (j = 0; j < width; width++)
{
if (A[i][j] % 2 == 0)
{
NumnberOfEvens++;
}
}
}
return NumnberOfEvens;
}
int main()
{
//int output = 0;
int A[MaxNumOfRows][MaxNumOfColumns] =
{
{2,2},{2,4},{2,2}
};
Even(A, MaxNumOfRows, MaxNumOfColumns);
//output = Even(A, MaxNumOfRows, MaxNumOfColumns);
cout << Even(A, MaxNumOfRows, MaxNumOfColumns) << endl;
system("pause");
return 0;
}
Check those for loops, I imagine you want to be incrementing the variables ++i and ++j rather than width++ and length++.
With an example this trivial, I imagine stepping through the executing code and finding the problem in a debugger would be pretty straightforward...are you writing this using an IDE with a debugger?
You are not applying increment on loop variables ('i' and 'j') here. 'length' and 'width' are increasing (due to length++, width++) whereas 'i' and 'j' are not. So, loop won't stop and thus the garbage values.
for (i = 0; i < length; length++)
{
for (j = 0; j < width; width++)
{
if (A[i][j] % 2 == 0)
{
NumnberOfEvens++;
}
}
}
This must work.
for (i = 0; i < length; i++)
{
for (j = 0; j < width; j++)
{
if (A[i][j] % 2 == 0)
{
NumnberOfEvens++;
}
}
}