Bubble Sort program does not output result - c++

I am in a discrete mathematics class and one of the hw problems is to implement a bubble sort. Here's my futile attempt because it does not output the solution. Please advice. Thank you.
#include <iostream>
#include <cstdlib>
using namespace std;
void BubbleSort();
int array1[100] = {0};
int k;
int main()
{
cout << "Enter your numbers and when you are done, enter 0000:\n";
int x = 0;
int i;
while (i != 0000)
{
cin >> i;
array1[x] = i;
x++;
k = x;
}
BubbleSort();
system("pause");
return 0;
}
void BubbleSort(){
int temp;
for( int i = 0; i < k; i++ ){
if ( array1[i] > array1[i+1]){
temp = array1[i+1];
array1[i+1] = array1[i];
array1[i] = temp;
}
}
int x = 0;
while (x <= k)
{
cout << array1[x] << "\n";
x++;
}
}
Please only use basic programming techniques because this is my first programming class. Thank you.
Edit: fixed the relational operator. But now I get incorrect results.

while (x >! k)
This doesn't do what you think it does. If you want something that says "while x is not greater than k", you want <=. Since array1[k] isn't one of the elements you sorted, though, you probably want <.
while (x < k)
Note that for exists for loops like these:
for (int x = 0; x < k; x++) {
cout << array1[x] << "\n";
}
As for the new bug, you're only doing one round of bubbling in your bubble sort. You need another for loop. Also, i is never initialized in main, and i != 0000 isn't going to check whether the user literally entered 4 zeros. It'll only check whether the user's input was equal to the number 0.

The primary problem is here:
while (x >! k)
On the first iteration, the condition checks whether (0 > !k), and k is not 0, so !k is 0, so the condition is false and the loop never executes. Try using:
for (int x = 0; x < k; x++)
cout << array1[x] << "\n";
You also have a problem in the sort phase of your bubble sort; you only iterate through the data once, which is not enough to sort it, in general.
Finally, some design issues.
You should have one function to sort the data and a separate function to print it. Don't combine the two functions as you have done here.
Avoid global variables. Pass the array and its operational length to the sort function, and to the print function if you have one.

Related

My array is gettting an error because it's being defined as a singular integer

The point of this program is to output whether a series of digits (the number of digits undefined) is sorted or not (largest to smallest or smallest to largest).
I have defined my array in my function parameter, and I am trying to use a for loop to store the user's input, as long as it is above 0, in said array.
However, I am getting the error argument of type int is incompatible with parameter of type int*.
The exact error is the argument of type int is incompatible with parameter of type int*.
It is referring to line 22 and 23, these two;
isSorted(list[2000]); and
bool is = isSorted(list[2000]);.
I know this means my for loop is assigning a single value to my variable repeatedly from reading similar questions however I can not figure out how to fix this.
#include <iostream>
using namespace std;
bool isSorted(int list[]);
int main()
{
int i;
int list[2000];
int k = 0;
for (i = 0; i < 2000; i++)
{
int j;
while (j > 0)
{
cin >> j;
list[i] = j;
}
}
isSorted(list[2000]);
bool is = isSorted(list[2000]);
if (is == true)
cout << "sorted";
else
cout << "unsorted";
return 0;
}
bool isSorted(int list[])
{
int i = 0;
for (i = 0; i < 2000; i++)
{
if (list[i] > list[i + 1] || list[i] < list[i - 1])
{
return false;
}
else
return true;
}
}
I removed unused variable k.
Made 2000 parameterized (and set to 5 for testing).
In isSorted you are not allowed to return
true in the else as if your first element test would end in else you would return true immediately not testing other elements. But those later elements can be unsorted as well.
In isSorted you are not allowed to run the loop as for(i = 0; i < 2000; i++), because you add inside the for loop 1 to i and end up querying for i == 1999 list[2000], which is element number 2001 and not inside your array. This is correct instead: for (i = 0; i < 1999; i++). You also do not need to check into both directions.
You cannot call isSorted(list[2000]) as this would call is sorted with an int and not an int array as parameter.
You write int j without initializing it and then query while j > 0 before you cin << j. This is undefined behaviour, while most likely j will be zero, there is no guarantee. But most likely you never enter the while loop and never do cin
I renamed the isSorted as you just check in your example for ascending order. If you want to check for descending order you are welcome to train your programming skills and implementing this yourself.
Here is the code with the fixes:
#include <iostream>
using namespace std;
bool isSortedInAscendingOrder(int list[]);
const int size = 5; // Set this to 2000 again if you want
int main()
{
int i;
int list[size];
for (i = 0; i < size; i++)
{
int j = 0;
while(j <= 0)
{
cin >> j;
if(j <= 0)
cout << "rejected as equal or smaller zero" << endl;
}
list[i] = j;
}
if (isSortedInAscendingOrder(list))
cout << "sorted" << endl;
else
cout << "unsorted" << endl;
return 0;
}
bool isSortedInAscendingOrder(int list[])
{
for (int i = 0; i < size -1; i++)
{
if (list[i] > list[i + 1])
{
return false;
}
}
return true;
}
This is a definition of an array of 2000 integers.
int list[2000];
This is reading the 2000th entry in that array and undefined, because the highest legal index to access is 1999. Remember that the first legal index is 0.
list[2000]
So yes, from point of view of the compiler, the following only gives a single integer on top of being undefined behaviour (i.e. "evil").
isSorted(list[2000]);
You probably should change to this, in order to fix the immediate problem - and get quite close to what you probably want. It names the whole array as parameter. It will decay to a pointer to int (among other things loosing the information of size, but you hardcoded that inside the function; better change that by the way).
isSorted(list);
Delete the ignored first occurence (the one alone on a line), keep the second (the one assigning to a bool variable).
On the other hand, the logic of a your sorting check is flawed, it will often access outside the array, for indexes 0 and 1999. I.e. at the start and end of your loop. You need to loop over slightly less than the whole array and only use one of the two conditions.
I.e. do
for (i = 1; i < 2000; i++)
{
if (list[i] < list[i - 1])
/* ... */
The logic for checking ascending or descending sorting would have to be more complex. The question is not asking to fix that logic, so I stick with fixing the issues according to the original version (which did not mention two-way-sorting).
You actually did not ask about fixing the logic for that. But here is a hint:
Either use two loops, which you can break from as soon as you find a conflict, but do not return from the fuction immediatly.
Or use one loop and keep a flag of whether ascending or descending order has been broken. Then return true if either flag is still clear (or both, in case of all identical values) or return false if both are set.

While loop task in c++

I am a beginner in c++ and I am having problems with making this code work the way I want it to. The task is to write a program that multiplies all the natural numbers up to the loaded number n.
To make it print the correct result, I divided x by n (see code below). How can I make it print x and not have to divide it by n to get the correct answer?
#include<iostream>
using namespace std;
int main(){
int n,x=1;
int i=0;
cout<<"Enter a number bigger than 0:"<<endl;
cin>>n;
while(i<n){
i++;
x=i*x;
};
cout<<"The result is: "<<x/n<<endl;
return 0;
}
At very first a principle you best get used to as quickly as possible: Always check user input for correctness!
cin >> n;
if(cin && n > 0)
{
// valid
}
else
{
// appropriate error handling
}
Not sure, why do you need a while loop? A for loop sure is nicer in this case:
int x = 1;
for(int i = 2; i < n; ++i)
x *= i;
If you still want the while loop: Start with i == 2 (1 is neutral anyway) and increment afterwards:
i = 2;
while(i < n)
{
x *= i;
++i;
}
In case of n == 1, the loop (either variant) simply won't be entered and you are fine...
You already have two very good options, but here is an other one you might want to take a look at when you are at ease enough in programming :
unsigned factorial(unsigned value)
{
if (value <= 1)
{
return 1;
}
else
{
return value * factorial(value - 1);
}
}
It's a recursive function, which is kind of neat when used in proper moments (which could not be the case here unfortunately because the execution stack might get so big you fill your memory before you're done. But you can check it out to learn more about recursive functions)
When your memory is full, you then crash your app with what is called actually a stack overflow.
How can I make it so that in the last cout I can only put x and not have to divide x by n to get the correct answer?
It will be better to use a for loop.
// This stops when i reaches n.
// That means, n is not multiplied to the result when the loop breaks.
for (int i = 1; i < n; ++i )
{
x *= i;
}
cout << "The result is: " << x <<endl;

Cyclical vector - Finding the least possible 'cost' (From CodeChef)

This is a question from Codechef but please bear with me.
https://www.codechef.com/ZCOPRAC/problems/ZCO12004
The contest is for the preparation of the Zonal Computing Olympiad held in India, so its not a competitive contest from which I'd earn something as such. Just need a little help to see what is wrong with my code, because I have a feeling I've overlooked something big and stupid. :P
The problem basically states:
Imagine there is a vector or array such that the last element is
linked to the first one. Find the lowest possible sum from adding at
least one of each adjacent pairs of elements. (refer to link please)
So answer for {1,2,1,2,2} output would be 4 by adding 1+1+2.
Here is my solution:
Basically what it does is that it iterates backwards, from the end of the vector to the beginning, and stores the lowest possible sum that can be achieved from that vector onwards, in vector M. Done using dynamic programming, basically.
The first two elements of M are the possible answers. Then I do some checks to see which is possible. If M[1] is less than M[0] then the last element of the array/vector should have been included in the sum calculated in M[1].
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
if (M[0] <= M[1]) cout << M[0] << endl;
else if (M[1] < M[0]) {
if (M[N-1] <= (M[N-2])) cout << M[1] << endl;
else cout << M[0] << endl;
}
}
However, I could not pass 2 of the test cases in subtask 2. I think the last part of my code is incorrect. Any idea what I could be doing wrong? Either that, or I have misunderstood the question. The term "adjacent pairs" is sort of ambiguous. So if there are 4 numbers 3,4,5,6 does adjacent pairs mean adjacent pairs to be {(3,4) (4,5) (5,6) (6,3)} or {either (3,4) and (5,6) or (4,5) and (6,3)}? My code considers the former.
EDIT:
Thanks a lot #User_Targaryen cleared some doubts about this question! Basically my implementation was the same as yours as my idea behind using dynamic programming was the same. Only that in this case my M (your dp) was the reverse of yours. Anyway I got AC! :) (I had left some silly debugging statements and was wondering for 15 mins what went wrong xD) Updated solution:
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x, sum = 0;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
//print(M);
reverse(A.begin(), A.end());
vector <ll> M2(N+2);
fill(M2.begin(),M2.end(),0);
for (int i = N-1; i >= 0; i--) {
M2[i] = A[i]+*min_element(M2.begin()+i+1, M2.begin()+i+3);
}
//print(M2);
cout << min(M[0], M2[0]) << endl;
}
I am attaching my accepted solution here:
#include<iostream>
using namespace std;
int main()
{
int i,j,k,n;
cin>>n;
int a[n],dp1[n],dp2[n];
int ans;
for(i=0;i<n;i++)
{
cin>>a[i];
dp1[i]=0;
dp2[i]=0;
}
if(n <= 2)
cout<< min(a[0],a[1]);
else{
i = 2;
dp1[0] = a[0];
dp1[1] = a[1];
while (i < n){
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
i = i + 1;
}
dp2[0] = a[n-1];
dp2[1] = a[n-2];
i = n-3;
j = 2;
while(i >= 0){
dp2[j] = a[i] + min(dp2[j-1],dp2[j-2]);
i = i - 1;
j = j + 1;
}
ans = min(dp1[n-1], dp2[n-1]);
cout<<ans;
}
return 0;
}
dp1[i] means the most optimal solution till now by including the i-th element in the solution
dp2[i] means the most optimal solution till now by including the i-th element in the solution
dp1[] is calculated from left to right, while dp2[] is calculated from right to left
The minimum of dp1[n-1] and dp2[n-1] is the final answer.
I did your homework!
Edit: #Alex: Dynamic Programming is something that is very difficult to teach. It is something that comes naturally with some practice. Let us consider my solution (forget about your solution for some time):
dp1[n-1] means that I included the last element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied because it always follows:
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
dp2[n-1] means that I included the first element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied also.
So, the minimum of the above two, will give me the final result.
The idea in your M[i] array is "the minimum cost for a solution, assuming the index i is included in it".
The condition if (M[0] <= M[1]) means "if including index 0 is better than not including it, done".
If this condition doesn't hold, then, first of all, the check if (M[1] < M[0]) is superfluous - remove it. It won't fix any bugs, but will at least reduce confusion.
If the condition is false, you should output M[1], but only if it corresponds to a valid solution. That is, since index 0 is not chosen, the last index should be chosen. However, with your data structure it's impossible to know whether M[1] corresponds to a solution that chose last index - this information is lost.
To fix this, consider building two arrays - add e.g. an array L whose meaning is "the minimum cost for a solution, assuming the index i is included in it, and also index N-1 is included in it".
Then, at the end of your program, output the minimum of M[0] and L[1].

How to make tri angle with blank inside using c++?

I did try many modifications to my code to make like this, but i not get what i want :
example if i put 7 in variable N the result will show
*
**
* *
* *
* *
* *
*******
this my code
#include <iostream>
using namespace std;
int main() {
for (int x=1; x<=N; x++){
cout<<"*";
for (int y=1; y<x; y++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
what i must add to my code have to the result like above?
Since others have suggested that this might be homework, here are some tips:
Always make sure you have a valid main signature. int main() is sufficient and main() without a return type is invalid.
Enable warnings. -Wall -pedantic should be sufficient for most cases (i.e, it catches the above mistake) but -Wextra can be useful as well.
using namespace std; is considered bad practice because you may define functions or variable names that clash with imported names. Get into the habit of typing std::. (For example, an assignment may require you to have a distance function, which may conflict with std::distance.
Use descriptive variable names. For a trivial program, x, y and N are fine, but decrease readability. It also helps you visualize the problem you are trying to solve.
We know that y is always going to be at most x because the number of characters per line should equal the current line. For example, line 7 should contain 7 asterisks. We only print a space if y is not equal to zero or x - 1, because that should be our "border". Lastly, the final line should contain all asterisks.
// The amount of asterisks per line is [1, N]
for (int x = 1; x <= N; x++)
{
// x is the amount of characters we want to print per line
for (int y = 0; y < x; y++)
{
// If we at the beginning or end of a line, this is our "border".
// Print an asterisk.
if (y == 0 || (y + 1 == x))
std::cout << "*";
else
{
// Otherwise we are "inside" the triangle.
// If this is the last line, print all asterisks
if (x == N)
std::cout << "*";
else
std::cout << " ";
}
}
std::cout << "\n";
}
Also, as another answer suggested, you can eliminate the need for confusing if structures by putting your condition into a single variable.
bool space_or_asterisk = (y == 0 || (y + 1 == x) || x == N);
std::cout << (space_or_asterisk ? '*' : ' ');
While you've gotten a couple of answers that work, the logic can be quite a bit simpler if you eliminate the confusing if/then/else statements:
#include <iostream>
int main() {
static const char chars[] = "* ";
static const int size = 7;
for (int i=0; i<size; i++) {
for (int j=0; j<size; j++)
std::cout << chars[j!=0 && i!=j && bool(i+1-size)];
std::cout << "\n";
}
}
Although the logic is clearly simpler, you still want to be sure to study it enough to answer any questions about it if you turn this in as homework.
main() {
for (int x=1; x<=N; x++){
for (int y=1; y<=x; y++){
if(y==1||y==x||x==N){
cout<<"*";
}else{
cout<<"*";
}
}
cout<<"\n";
}
return 0;
}

Why is my program not printing perfect integers?

I am new to C++ programming and have a problem with one of my programs
#include <iostream>
using namespace std;
bool IsPerfect(int n);
int main ()
{
for(int i=1; i<100; i++){
IsPerfect(i);
}
return 0;
}
bool IsPerfect(int n){
int sum;
for(int x=1; x<n; x++){
if(n%x==0){
sum+=x;
return true;
cout <<n;
}
else{
return false;
}
}
}
I am trying to create a program that will list perfect numbers but I can't find the bug as to why it would not print.
I see 3 issues:
Your algorithm is wrong. Your loop terminates on the first time a number is evenly divisible by any factor (including 1). See Wikipedia for an explanation of the algorithm.
You have an uninitialized variable with int sum; Also, you only ever write to it, you don't read it in a useful manner ever.
You have unreachable code. Your cout << n; in the loop will never be hit.
Try the following corrected code:
#include <iostream>
#include <cassert>
using namespace std;
bool IsPerfect(int n)
{
int sum = 1;
for(int x = 2; x < n; ++x)
{
if(n % x == 0)
sum += x;
}
return sum == n;
}
int main ()
{
for(int i=1; i<100; i++){
if (IsPerfect(i))
cout << i << endl;
}
assert(IsPerfect(6));
assert(IsPerfect(28));
assert(IsPerfect(496));
return 0;
}
You have a return statement before you output statement here:
return true;
cout <<n;
you need to swap the order of these statements, you also probably want to add a comma or some other separator:
std::cout << n << ", " ;
return true;
I am not sure that is where you want to return from since you will exit the first time you enter that if statement, which will happen when x is 1.
If you want to capture perfect numbers - numbers which are equal to the sum of their divisors, correct? - you need to allow the loop to proceed (and the sum to actually, well, sum) without returning. Take your print statement and your return statements and place them after the end of your loop; you should be checking then if the sum you have calculated is equal to n.
All these answers are telling you to write the number before returning. But that's ignoring the poor design here: you have a function that decides whether a number is perfect; it should not be that function that also decides what to do with this information (print it, store it, send it over the network, ...).
This will also make your code more readable, because the name IsPerfect is misleading - it tells the reader that this function just returns whether the number is perfect. Thus, the loop in the main function reads as, "for the integers 1 to 100, ask whether it is perfect and ignore the answer". This is not a useful program.
Remove the cout line from IsPerfect completely and put it in main instead:
for (int x = 1; x < 100; ++x) {
if (IsPerfect(x)) {
std::cout << x << '\n';
}
}
Try this
if(n%x==0){
sum+=x;
cout <<n;
return true;
}
The issue is in here:
if(n%x==0){
sum+=x;
return true;
cout <<n;
}
the keyword return immediately ends the function and returns the appropriate value (true). This means that all statements following it won't be executed. Try the following:
if(n%x==0){
sum+=x;
cout <<n;
return true;
}
In addition to the problems others have pointed out, you will never compute the right answer because you didn't initialize your sum variable.
Change
int sum;
to
int sum=0;