I try to make a list of digit of consequence number from 1 to 100; for example, 123456789101112..... However, when I print out the result from the list_result; there is some strange number in my list_result vector. Here the following code:
int main()
{
vector<int> list_num;
vector<int> list_result;
int count =0;
for(int index = 1; index<=100; index++)
{
count = index;
if(index<10)
{
list_result.push_back(index);
}
else
{
while(count!=0)
{
list_num.push_back(count%10);
count=count/10;
}
for(int i=0; i<=list_num.size();i++)
{
list_result.push_back(list_num[list_num.size()-i]);
}
list_num.clear();
}
for(int i = 0; i<=list_result.size(); i++)
{
cout<<list_result[i];
}
}
return 0;
}
Anyone has any ideas? Thank,
Your program exhibits undefined behavior.
for(int i=0; i<=list_num.size();i++)
{
list_result.push_back(list_num[list_num.size()-i]);
}
Valid indexes into list_num are 0 through list_num.size()-1. Yet on the first iteration of this loop, when i == 0, you attempt to access list_num[list_num.size()]. There is no such element.
Igor Tandetnik described an issue in the for loop inside the else block, but I've identified another issue, this time in the output stage of the program.
Remember that indices are zero-based, which means they run from zero to the number of elements minus one. vector::size() returns the total number of elements, in this case 100. Because you're comparing this value with the index using a less-than-or-equal inequality, you end up trying to access element 100 on the final iteration of the loop, and element 100 does not exist since the range of valid indices is 0 to 99. When writing a loop that iterates through an array or vector, you should always compare indices with array/vector sizes using strict inequalities.
In the final for loop, replace the <= with a strict < comparison so that it stops at the actual last element and not afterwards:
for(int i = 0; i<list_result.size(); i++)
{
cout<<list_result[i];
}
Wikipedia has an easy-to-understand explanation of this common programming mistake, known as an off-by-one error.
Related
I have the following code written in c++ and the algorithm works when in this scenario. I am knew to c++ and don't understand what I did wrong in my 2nd test.
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {7,5,6,4};
bubbleSort(numbers,4);
for (int print = 0; print < 4; print++) {
cout << numbers[print] << endl;
}
return 0;
}
But, fails when I try to put in numbers that are already sorted:
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {1,2,3};
bubbleSort(numbers,3);
for (int print = 0; print < 3; print++) {
cout << numbers[print] << endl;
}
return 0;
}
for (int j=0; j<size;j++) {
If size is 3, if the array has three values, for example, this loop iterates with values of j of 0, 1, and 2.
if (numbers[j] > numbers[j+1]) {
When j is 2 this compares numbers[2] with numbers[3].
There is no numbers[3]. This is undefined behavior. The loop is off by 1 value.
Additionally, the overall bubble sort implementation is flawed. In the shown code the inner loop iterates over the entire array (ignoring the off-by-1 bug), every time. In a classical bubble sort the first pass (the first iteration of the outer loop) results in the inner loop iterating over the entire array and "bubbling" the smallest/largest value to the end of the array. On the next pass the inner loop does not need to iterate over the entire array, but only up until the 2nd smallest/largest position of the array. And so on, each pass (the outer loop) results in the inner loop iterating over a smaller, and smaller subset of the array, "bubbling" the corresponding value to the appropriate stop.
In addition to fixing the off-by-1 bug you'll also need to adjust the overall logic of this bubble sort, if you wish to get a perfect grade for your homework assignment.
Implementing bubble sort in its entirety is problematic. In the example code, the inner loop repeatedly iterates over the full array while disregarding the shift by 1. The inner loop iterates over the whole array in a traditional bubble sort's first iteration of the outer loop, "bubbling" the smallest/largest value to the array's end. On the subsequent iteration, the inner loop only has to iterate up to the array's second-smallest/largest point rather than the full array. The inner loop then iterates through a smaller and smaller subset of the array, making bubbles of the associated the associated value to the proper stop with each successive run in the outside loop.
I'm trying to create a program which allows for a dynamically allocated array to store some integers, increase the maximum size if need be, and then display both the unsorted and sorted array in that order.
Link to my full code is at the bottom.
The first issue I have is the dynamically allocated array going haywire after the size needs to be increase the first time. The relevant code is below.
while (counter <= arraySize)
{
cout <<"Please enter an integer number. Use 999999 (six 9's) to stop\n";
if (counter == arraySize) //If the counter is equal to the size of the array
{ //the array must be resized
arraySize +=2;
int *temp = new int[arraySize];
for (counter = 0; counter < arraySize; counter++)
{
temp[counter] = arrayPtr[counter];
}
delete [] arrayPtr;
arrayPtr = temp;
counter ++; //the counter has to be reset to it's original position
} //which should be +1 of the end of the old array
cin >> arrayPtr[counter];
if (arrayPtr[counter] == sentinel)
{
cout << "Sentinel Value given, data entry ending.\n";
break;
}
counter ++;
}
This produces the unintended operation where instead of waiting for the sentinel value, it just begins to list the integers in memory past that point (because no bounds checking).
The next issue is that my sorting function refuses to run. I tried testing this on 5 values and the program just crashes upon reaching that particular part of code.
The function is called using
sorting (arrayPtr);
but the function itself looks like this:
void sorting (int *arr)
{
int count = 0, countTwo = 0, tempVal;
for (count = 0; arr[count] != 999999; count++) //I figured arr[count] != 999999 is easier and looks better
{ //A bunch of if statements
for (countTwo = 0; arr[countTwo] != 99999; countTwo++)
{
if (arr[countTwo] > arr[countTwo+1])
{
tempVal = arr[countTwo];
arr[countTwo] = arr[countTwo+1];
arr[countTwo+1] = tempVal;
}
}
}
}
Any help on this issue is appreciated.
Link to my source code:
http://www.mediafire.com/file/w08su2hap57fkwo/Lab1_2336.cpp
Due to community feedback, this link will remain active as long as possible.
The link below is to my corrected source code. It is annotated in order to better highlight the mistakes I made and the answers to fixing them.
http://www.mediafire.com/file/1z7hd4w8smnwn29/Lab1_2336_corrected.cpp
The first problem I can spot in your code is in the for loop where counter goes from 0 to arraySize-1, the last two iteration of the loop will access arrrayPtr out of bounds.
Next, at the end of the if (counter == arraySize) there is a counter++; This is not required since at this moment counter is already indexing the array out of bound.
Finally in your sorting function the inner loop looks for the wrong value (99999 instead of 999999), so it never stop and goes out of bounds. To prevent this kind of error, you should define your sentinel as a const in an unnamed namespace and use it through the code instead of typing 999999 (which is error prone...).
So, I tried to make an array using input first, then sorting it out from smallest to biggest, then display the array to monitor.
So I come up with this code :
#include <iostream>
using namespace std;
void pancakeSort(int sortArray[], int sortSize);
int main()
{
// Input The Array Element Value
int pancake[10];
for(int i=0; i<10; i++)
{
cout << "Person " << i+1 << " eat pancakes = ";
cin >> pancake[i];
}
// call pancake sorting function
pancakeSort(pancake, 10);
}
void pancakeSort(int sortArray[], int sortSize)
{
int length = 10;
int temp;
int stop = 10;
// this is where the array get sorting out from smallest to biggest number
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
// after that, the array get display here
for(int x=0; x<sortSize; x++)
{
cout << sortArray[x] << " ";
}
}
but the output is weird :
enter image description here
the function is successfully sorting the array from smallest to biggest,
but there is 2 weird things :
1. The biggest value element (which is 96 from what I input and it's the 10th element after got sorted out), disappear from the display.
2. For some reason, there is value 10 , which I didn't input on the array.
So, what happened?
In the loop
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop is the length of the array, and you are iterating through values of j = 0 to stop - 1. When j reaches stop - 1, the next element that is j+1 becomes stop (10 in this case). But since your array has a length of 10, sortArray[10] is not part of the array, but is referring to some other object in memory which is usually a garbage value. The garbage value is 10 in this case. When you swap sortArray[10] and sortArray[9], the garbage value becomes part of the array and the value at index 9 leaves the array. This keeps on happening till the outer loop ends.
The end result is that unless the garbage value < largest element in the array, the garbage value is pushed in the array and the greatest value of the array is put at sortArray[10] which is not part of the array. If the garbage value is greater than all the values of the array, it'll be found at sortArray[10] which is again not part of the array and your code will return the desired result.
Essentially, what you are doing is giving the function an array of 10 (or stop) elements, but the function is actually working with an array of 11 (or stop + 1) elements, with the last element being a garbage value. The simple fix is to change the conditional of the loop to j < stop - 1.
Note that if you had written this code in a managed (or a comparatively higher level) language like Java or C#, it would have raised an IndexOutOfBoundsException.
At index 9, j+1 is out of bounds. So to fix this, you only need to check till index 8
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop-1; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
Look carefully at the inner loop condition j<stop-1
My code: (i expect it sort passed array into ascending order).
void sort( int arr[], int n) {
int c=0;
for(int i = 0; i<n-1; ++i) {
if (arr[i]>arr[i+1]) {
c=arr[i];
arr[i]=arr[i+1];
arr[i]=c;
i=0;
}
}
}
example array: int arr[4]={3,1,2,4};
sort(arr,4);
Error: Infinite loop???
Your code for swapping two consecutive elements in the array is wrong. Replace the first three lines inside the if statement with:
c = arr[i];
arr[i] = arr[i+1];
arr[i+1] = c;
The last line is the one I fixed.
This algorithm is called a bubble sort.
EDIT: Another thing you need to do to ensure correct sorting is to set i to -1 instead of 0 at the end of the if statement. If you just set it to 0, then on the next iteration of the loop it will get incremented and become 1, which means that your code will not consider swapping the first two elements of the loop. (Thanks to the comment from Anton Savin.)
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.