really new to C++, trying to instantiate some basic algorithms with it. Having trouble returning the correct result for selection sort. Here is my code
#include <iostream>
#include <array>
#include <vector>
using namespace std;
// Selection Sort :
int findMin(vector<int> &arr, int a)
{
int m = a;
for (int i = a + 1; i < arr.size(); i++)
{
if (arr[i] < arr[m])
{
m = i;
}
return m;
}
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void selectionSort(vector<int> &arr)
{
if (!arr.empty())
{
for (int i = 0; i < arr.size(); ++i)
{
int min = findMin(arr, i);
swap(arr[i], arr[min]); // Assume a correct swap function
}
}
}
void print(vector<int> &arr)
{
if (!arr.empty())
{
for (int i = 0; i < arr.size(); i++)
{
cout << arr[i] << "";
cout << endl;
}
}
}
int main()
{
vector<int> sort;
sort.push_back(2);
sort.push_back(1);
sort.push_back(7);
sort.push_back(4);
sort.push_back(5);
sort.push_back(3);
print(sort);
cout << "this was unsorted array";
cout << endl;
cout << findMin(sort, 0);
cout << "this was minimum";
cout << endl;
selectionSort(sort);
print(sort);
}
I am getting the following results:
comparison_sort.cpp:20:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
1 warning generated.
2
1
7
4
5
3
this was unsorted array
1
this was minimum
1
2
4
5
3
0
My question is: What is causing this control path error? Why is the "7" here being replaced with a "0"?
Thanks in advance! Sorry for the noob question.
I have reviewed all my current functions and nothing seems to explain why the 7 is replaced with a 0. I have tried multiple integers and it looks like the maximum number is always replaced.
The warning is very real, and it alludes to the problem that's breaking your sort as well.
You are currently returning m inside your loop body. What that means is that if the loop is entered, then the function will return m on the very first time around the loop. It only has a chance to check the first element.
And of course, if a is the last index of the array, then the loop will never execute, and you will never explicitly return a value. This is the "control path" which does not return a value.
It's quite clear that you've accidentally put return m; in the wrong place, and even though you have good code indentation, some inexplicable force is preventing you from seeing this. To fix both the warning and the sorting issue, move return m; outside the loop:
int findMin(vector<int> &arr, int a)
{
int m = a;
for (int i = a + 1; i < arr.size(); i++)
{
if (arr[i] < arr[m])
{
m = i;
}
}
return m;
}
Related
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;
I'm trying to delete all elements of an array that match a particular case.
for example..
if(ar[i]==0)
delete all elements which are 0 in the array
print out the number of elements of the remaining array after deletion
what i tried:
if (ar[i]==0)
{
x++;
}
b=N-x;
cout<<b<<endl;
this works only if i want to delete a single element every time and i can't figure out how to delete in my required case.
Im assuming that i need to traverse the array and select All instances of the element found and delete All instances of occurrences.
Instead of incrementing the 'x' variable only once for one occurence, is it possible to increment it a certain number of times for a certain number of occurrences?
edit(someone requested that i paste all of my code):
int N;
cin>>N;
int ar[N];
int i=0;
while (i<N) {
cin>>ar[i];
i++;
}//array was created and we looped through the array, inputting each element.
int a=0;
int b=N;
cout<<b; //this is for the first case (no element is deleted)
int x=0;
i=0; //now we need to subtract every other element from the array from this selected element.
while (i<N) {
if (a>ar[i]) { //we selected the smallest element.
a=ar[i];
}
i=0;
while (i<N) {
ar[i]=ar[i]-a;
i++;
//this is applied to every single element.
}
if (ar[i]==0) //in this particular case, we need to delete the ith element. fix this step.
{
x++;
}
b=N-x;
cout<<b<<endl;
i++;
}
return 0; }
the entire question is found here:
Cut-the-sticks
You could use the std::remove function.
I was going to write out an example to go with the link, but the example form the link is pretty much verbatim what I was going to post, so here's the example from the link:
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ' ' << *p;
std::cout << '\n';
return 0;
}
Strictly speaking, the posted example code could be optimized to not need the pointers (especially if you're using any standard container types like a std::vector), and there's also the std::remove_if function which allows for additional parameters to be passed for more complex predicate logic.
To that however, you made mention of the Cut the sticks challenge, which I don't believe you actually need to make use of any remove functions (beyond normal container/array remove functionality). Instead, you could use something like the following code to 'cut' and 'remove' according to the conditions set in the challenge (i.e. cut X from stick, then remove if < 0 and print how many cuts made on each pass):
#include <iostream>
#include <vector>
int main () {
// this is just here to push some numbers on the vector (non-C++11)
int arr[] = {10,20,30,30,20,10,10,20}; // 8 entries
int arsz = sizeof(arr) / sizeof(int);
std::vector<int> vals;
for (int i = 0; i < arsz; ++i) { vals.push_back(arr[i]); }
std::vector<int>::iterator beg = vals.begin();
unsigned int cut_len = 2;
unsigned int cut = 0;
std::cout << cut_len << std::endl;
while (vals.size() > 0) {
cut = 0;
beg = vals.begin();
while (beg != vals.end()) {
*beg -= cut_len;
if (*beg <= 0) {
vals.erase(beg--);
++cut;
}
++beg;
}
std::cout << cut << std::endl;
}
return 0;
}
Hope that can help.
If you have no space bound try something like that,
lets array is A and number is number.
create a new array B
traverse full A and add element A[i] to B[j] only if A[i] != number
assign B to A
Now A have no number element and valid size is j.
Check this:
#define N 5
int main()
{
int ar[N] = {0,1,2,1,0};
int tar[N];
int keyEle = 0;
int newN = 0;
for(int i=0;i<N;i++){
if (ar[i] != keyEle) {
tar[newN] = ar[i];
newN++;
}
}
cout<<"Elements after deleteing key element 0: ";
for(int i=0;i<newN;i++){
ar[i] = tar[i];
cout << ar[i]<<"\t" ;
}
}
Unless there is a need to use ordinary int arrays, I'd suggest using either a std::vector or std::array, then using std::remove_if. See similar.
untested example (with c++11 lambda):
#include <algorithm>
#include <vector>
// ...
std::vector<int> arr;
// populate array somehow
arr.erase(
std::remove_if(arr.begin(), arr.end()
,[](int x){ return (x == 0); } )
, arr.end());
Solution to Cut the sticks problem:
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
// Cuts the sticks by size of stick with minimum length.
void cut(vector<int> &arr) {
// Calculate length of smallest stick.
int min_length = INT_MAX;
for (size_t i = 0; i < arr.size(); i++)
{
if (min_length > arr[i])
min_length = arr[i];
}
// source_i: Index of stick in existing vector.
// target_i: Index of same stick in new vector.
size_t target_i = 0;
for (size_t source_i = 0; source_i < arr.size(); source_i++)
{
arr[source_i] -= min_length;
if (arr[source_i] > 0)
arr[target_i++] = arr[source_i];
}
// Remove superfluous elements from the vector.
arr.resize(target_i);
}
int main() {
// Read the input.
int n;
cin >> n;
vector<int> arr(n);
for (int arr_i = 0; arr_i < n; arr_i++) {
cin >> arr[arr_i];
}
// Loop until vector is non-empty.
do {
cout << arr.size() << endl;
cut(arr);
} while (!arr.empty());
return 0;
}
With a single loop:
if(condition)
{
for(loop through array)
{
if(array[i] == 0)
{
array[i] = array[i+1]; // Check if array[i+1] is not 0
print (array[i]);
}
else
{
print (array[i]);
}
}
}
This is my first time here. I really hope anyone can help me out there. So this is my problem. I keep getting run time error #2 something about a corrupt "arr". But the program runs fine until the end. I can't figure it out.
This is my code:
#include <iostream>
using namespace std;
void main(){
int arr1[3];
int temp;
//INPUT NUMBERS
for (int i=0; i<5;i++)
{
cin>>arr1[i];
}
cout<<endl;
//SORT
for(int c=0;c<5;c++)
{
for (int k=0;k<5;k++)
{
if(arr1[c]<arr1[k])
{
temp=arr1[k];
arr1[k]=arr1[c];
arr1[c]=temp;
}
}
}
for (int m=0; m<5; m++)
{
cout<<arr1[m]<<endl;
}
}
Try this out:
#include <iostream>
using namespace std;
int main()
{
int arr1[5];
int temp;
//INPUT NUMBERS
for (int i = 0; i < 5; i++) {
cin >> arr1[i];
}
cout << endl;
//SORT
for (int c = 0; c < 5; c++) {
for (int k = 0; k < 5; k++) {
if (arr1[c] < arr1[k]) {
temp = arr1[k];
arr1[k] = arr1[c];
arr1[c] = temp;
}
}
}
for (int m = 0; m < 5; m++) {
cout << arr1[m] << endl;
}
}
It compiles properly without any errors. The mistake you had made is in declaring the size of the array. If you want to store 5 in puts, you need to declare an array of size 5. Your code might work, but a good compiler will always give out an error.
The reason being that when you declare an array, you actually create a pointer to the first element of the array. And then, some memory regions are kept for this array, depending on the size. If you try to access an element that is outside these memory regions, you may encounter a garbage value.
Here's your code in ideone.
#include <iostream>
#include <vector>
using namespace std;
class PerformSort
{
public:
const vector<int> * p;
vector<int>& getElements(int);
vector<int>& sortArray(vector<int>&);
void printer(vector<int>&);
}firstSort;
vector<int>& PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
p = &elements;
return p;
}
vector<int>& PerformSort::sortArray (vector<int>& vector)
{
int holder, min;
for (int i = 0; i < (sizeof(vector) - 1); i++)
{
min = i;
for (int j = (i + 1); j < sizeof(vector); j++)
{
if (vector[j] < vector[min])
{
min = j;
}
}
if (min != i)
{
holder = vector[i];
vector[i] = vector[min];
vector[min] = holder;
}
}
return vector;
}
void PerformSort::printer(vector<int>& vector2)
{
for (int i = 0; i < sizeof(vector2); i++)
{
cout << vector2[i] << " ";
}
}
int main ()
{
int numberOfTimes;
cin >> numberOfTimes;
firstSort.printer(firstSort.sortArray(firstSort.getElements(numberOfTimes)));
return 0;
}
This returns the error: "invalid initialization of reference of type from expression of type". My first approach to create a SelectionSort algorithm was to try passing the vector by value (stupidly). After this I started to use pointers instead, after some research. However, this resulted in the aforementioned error. Declaring everything as constant does not seem to resolve the underlying error, despite how, if I understand things correctly, the error lies with temporary references being passed where constant ones are required. Any thoughts on how I might achieve this passing and returning of vectors? (I come from a Java background and am just beginning C++, so forgive me if I have made any obvious errors with regards to the pointers).
Return it by value:
vector<int> PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
return elements;
}
This will also let you get rid of p, which is a huge can of worms in its own right.
Finally, I notice that you use sizeof(vector) in quite a few places. This won't give you the number of elements in the vector; use vector.size() instead.
Rename the variable vector to something else:
vector<int>& PerformSort::sortArray (vector<int>& wayBetterName)
&
return wayBetterName;
What urged you to name a variable the same as a type?
There's many more other issues with the code.
You don't need pointers, you don't need the references, plus you're better off just using std::sort.