Error in program for modified bubble sort - c++

Codeforces problem 339A-http://codeforces.com/problemset/problem/339/A
I have tried to sort the values stored at even places of the array(starting from 0).I get an error while running the program or program returns a junk value.What is wrong with my solution?
My solution:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char s[101],temp;
int i,j;
cin>>s;
for(i=0;i<strlen(s);i+=2) //Bubble sorting values at even values of i.'+' is stored at odd values of i.
{
for(j=0;j<(strlen(s)-i-2);j+=2)
{
if(s[j]>s[j+2])
{
temp=s[j];
s[j]=s[j+2];
s[j+2]=temp;
}
}
}
cout<<s;
}

Your compiler should have warned you about the problem (you did switch on all warnings, yes? always do that!): Once i==strlen(s)-1, the loop for j is essentially unbounded, by the magic of arithmetic rules for signed/unsigned values.
for(unsigned j=0; j+2+i < strlen(s); j+=2)
does not have this problem. (i should be unsigned as well.)
Or stop the loop for i earlier. The problem in your code is still there then, but you won’t run into it. But I believe that is the worse route to take – fix the bug, and then optimize by observing i doesn’t need to go as far up, because the last character already forms a sorted sequence.

For odd lengths len of s, the outer loop runs until i==len-1. The inner loop then terminates at len - len - 1 - 2. Since strlen returns an unsigned type, this evaluates to a very large unsigned number, causing the inner loop to read way beyond the end of s. Eventually you'll reach memory you don't have access to read or write, causing the crash.
You can fix this by ending the outer loop sooner
int len = strlen(s);
for(i=0;i<len-2;i+=2) {
for(j=0;j<(len-i-2);j+=2)

Change this:
for(i=0;i<strlen(s);i+=2)
Into this:
for(i=0;i<strlen(s) - 2;i+=2)
Otherwise the s value be handled beyond its end-point

here is my code
void bubble(int a[], int n){
for(int i=0; i<n; i++){
int swaps=0;
for(int j=0; j<n-i-1; j++){
if(a[j]>a[j+1]){
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
swaps++;
}
}
if(swaps==0)
break;
}
}

Related

How to end program in a do-while (C++)

Here is my code. I am trying to get the entire program to end if it goes into the second if statement inside the do-while loop. But every time I run it, it crashes. I am not sure what I am doing wrong.
#include <iostream>
using namespace std;
int main() {
int myData[10];
for(int i=0;i<10;i++){
myData[i] = 1;
cout<<myData[i];
}
do{
int i;
cout<<endl<<"Input index: ";
cin>> i;
int v;
cout<<endl<<"Input value: ";
cin>>v;
if(i>=0||i<10){
myData[i]=v;
for(int i=0;i<10;i++){
cout<<myData[i]<<" ";
}
}
if (i<0||i>=10){
cout<<"Index out of range. Exit.";
return 0;
}
}while(1);
}
if(i>=0||i<10){
Think about which numbers are either greater than zero or less than ten. I'm sure you realise that is true of all numbers. What you meant to write is
if(i>=0&&i<10){
This explains your crash, you are accessing the myData array with an index that is outside the array bounds.
It's very common for beginners to get && and || confused especially where there is negation involved as well.
Other people have told you the problem:
if(i>=0||i<10){
I'm going to explain why you hit this. You hit it because you didn't use any whitespace.
if (i >= 0 && i < 10) {
Please, please, please, for all that is good in the world, use whitespace liberally. You absolutely will have fewer bugs, because my version is far easier to read. Furthermore if you work with older developers (like me) we can actually read your code far more easily.

Getting Segmentation Fault error in C++ code

#include<bits/stdc++.h>
using namespace std;
//FIRST REPEATING ELEMENT (APPROACH 2)
int main()
{
cout<<"running";
int n;
cin>>n;
int arr[n];
for(int i=1; i<=n; i++)
cin>>arr[i];
const int N = 1e5+2;
int idx[N];
for(int i=0;i<N;i++)
idx[i] = -1;
int minidx = INT_MAX;
for(int i=0;i<n;i++)
{
if(idx[arr[i]] != -1)
minidx = min(minidx, idx[arr[i]]);
else
idx[arr[i]] = i;
}
if(minidx == INT_MAX)
cout<<"-1"<<endl;
else
cout<<minidx + 1<<endl;
return 0;
}
I am writing this code for "First Repeating Element" question and trying to get the index of the first element that repeats.
On debugging, I am getting segmentation fault.
int main()
{ (in this line)
What does it mean and what can I do to remove this.
const int N = 1e5+2;
int idx[N];
That sounds like a big array to be allocated on the stack (400kb!). Try using malloc() to allocate an array of that size. Change that to something like
const int N = 1e5+2;
int* idx = (int*)malloc(N * sizeof(int));
You should also do the same for arr, particularly if you use large values for n.
The program has undefined behavior because you're going out of bound of the array. This is because in your for loop condition, you're using i<=n instead of i<n.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.
So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash.
So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.
Additionally, in Standard C++ the size of an array must be a compile time constant. This means that the following is incorrect in your program.
int n;
cin >> n;
int arr[n]; //not standard C++ since n is not a constant expression
1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.
Segmentation fault is due to usage of memory that you don't own, or in other words stack over flow. Most likely because you're creating an array of size 1e5+2 and looping over it, initializing every element. That's not the best way to find the recurrence of an element. Instead use a map with key value pairs.

why is the sort() changing my input array?

i am stuck on a problem where, after taking input of an array and sorting it and not doing any operation on it at all, the output shows a different array?
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
int t;
cin>>t;
while(t--){
int n;
cin>>n;
long long int c[n],h[n],a[n];
for(int i=0;i<n;i++){
cin>>c[i];
}
for(int i=0;i<n;i++){
cin>>h[i];
}
sort(h,h+n);
for(int i=0;i<n;i++){
a[i]=0;
}
int i=0;
int begin=(i+1)-c[i];
int end = (i+1)+c[i];
int j=begin;
while(i<n){
a[j-1]++;
j++;
if(j>end){
i++;
begin=(i+1)-c[i];
end= (i+1)+c[i];
j=begin;
}
}
sort(a,a+n);
for(int i=0;i<n;i++){
cout<<h[i]<<" ";
}
}
return 0;
}
input for h[]={8,8,8,8,8}..n=5
output h[]={10,10,9,9,8}
Here is a version of your code written in reasonably decent C++. I didn't touch the loop in the middle because I have no clue what it's doing. You're using obscure variable names and no comments and doing all kinds of bizarre things with indexes and mixing them up with user input.
Now, reading indexes from user input and using them isn't bad, though in a real program you'd want to be doing lots of bounds checking on that input to make sure people weren't feeding you bad data. But doing all that stuff with such poorly named variables with no explanation is going to leave anybody looking at it scratching their head. Don't do that.
Also, avoid the use of begin and end as variable names, especially if they hold indexes. In most cases it will confuse things terribly as begin and end are important identifiers in the standard library and always refer to iterators, which are sort of like indexes, but most definitely not indexes, adding greatly to the confusion. beginidx and endidx could be acceptable substitutes in this case.
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using ::std::vector;
using ::std::sort;
using ::std::copy_n;
using ::std::copy;
using ::std::fill;
using ::std::istream_iterator;
using ::std::ostream_iterator;
using ::std::cin;
using ::std::cout;
int main() {
// your code goes here
using vec_el_t = long long int;
int t;
cin >> t;
while (t--) {
int const n = []() { int n; cin >> n; return n; }();
vector<vec_el_t> c{n}, h{n}, a{n};
copy_n(istream_iterator<vec_el_t>{cin}, n, c.begin());
copy_n(istream_iterator<vec_el_t>{cin}, n, h.begin());
// Suggested debugging code:
// cout << "h before sort: "
// copy(h.begin(), h.end(), ostream_iterator<vec_el_t>{cout, " "});
// cout << '\n';
sort(h.begin(), h.end());
// Suggested debugging code:
// cout << "h after sort: "
// copy(h.begin(), h.end(), ostream_iterator<vec_el_t>{cout, " "});
// cout << '\n';
fill(a.begin(), a.end(), 0);
// Weird, unexplained algorithm begins here
int i = 0;
int begin = (i + 1) - c[i];
int end = (i + 1) + c[i];
int j = begin;
while (i < n) {
a[j - 1]++;
j++;
if (j > end){
i++;
begin = (i + 1) - c[i];
end = (i + 1) + c[i];
j = begin;
}
}
// Weird unexplained algorithm ends here
sort(a.begin(), a.end());
copy(h.begin(), h.end(), ostream_iterator<vec_el_t>{cout, " "});
}
return 0;
}
Changes made... Use vector not a variable length array, which isn't valid C++ anyway and will only work in g++ and clang. Don't use explicit loops if there is an algorithm that will do the job. Try to make as many things const as you can so you can make sure that the compiler catches it if you try to change things you didn't mean to change. Avoid using std; and if you want to import names from ::std import exactly the ones you need. Don't use compiler or library implementation specific header files and use the ones from the standard instead (i.e. no bits/stdc++.h).
As for your problem, I have no idea. I suspect that the index manipulation combined with looping isn't doing what you expect. If you print out the arrays before and after sorting, you will discover that sort only alters order, and not content.
As a general rule, always suspect your own code first and make absolutely sure it's correct. And if you really think it's the library code, prove it beyond a shadow of a doubt before coming here to ask why the library isn't doing what it says it does.
The complicated code I didn't touch looks rife with opportunities for out-of-bounds access, and that results in undefined behavior, which means your program might do absolutely anything in that case. You might change uses of operator [] with calls to the at function (one of the many perks of using vector) instead. That way, attempts at out-of-bounds access will throw an exception.
Within these lines you are accessing a outside its limits:
int i=0;
int begin=(i+1)-c[i]; // begin = 1 - c[0]; <<-- this could be arbitrarily small!
int end = (i+1)+c[i]; // unrelated
int j=begin; // also equal to 1-c[0]
while(i<n){
a[j-1]++; // increment a[-c[0]] which is UB unless c[0]==0
This means undefined behavior (UB), i.e., it could do nothing, it could segfault, or (what apparently happened in your case) access elements of an adjacent data structure.

SIGABRT error for - https://www.codechef.com/problems/PRIME1

I am using sieve of eratosthenes to solve this problem but it is giving me SIGABRT error although my code is working fine on codeblocks....
Please help me modify this code to remove error....
My code is...
#include<vector>
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int main()
{
unsigned long int t, n, m,i,j;
vector<int> prime;
cin>>t;
while(t--)
{
cin>>m;
cin>>n;
while(!(1<=m&&m<=n&&n<=1000000000&&n-m<=100000))
cin>>m>>n;
prime.resize(n);
for(i=0;i<n;i++)
prime[i]=1;
prime[0]=0;
prime[1]=0;
for(i=2;i<sqrt(n);i++)
{
if(prime[i]==1)
{
for(j=i;i*j<=n;j++)
prime[i*j]=0;
}
}
for(i=m;i<=n;i++)
{
if(prime[i]==1)
cout<<i<<endl;
}
cout<<endl;
prime.resize(0);
}
return 0;
}
Your j loop allows i*j to equal n, but the vector of size n must be indexed from 0 to n-1. The existing code permits referencing an element out of bounds.
The same problem can occur in the last loop, too.
The SIGABRT is issued by library routines.
You have two library routines in your program: std::vector and sqrt.
Either assign sqrt(n) to a const variable or replace the condition with:
(i * i) < n;
You need to verify that:
prime[i*j]
is a valid location. In other words, (i * j) < n.
Some information about primes (that can help you code your program):
Prime numbers are odd except the value 2.
Your test value can start at 3 and add 2 to get to the next value.
You may be able to save some time by looking values in an array of
known values.
Multiplication is usually faster than division. Try rewriting your
test to use multiplication and not division.
Use a data type that can contain the maximum value.

3n+1 on UVa (C++)

The link to the 3n+1 problem on UVa is:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
My code is :
#include<iostream>
using namespace std;
long long l(long long n)
{
if(n==1)
{
return 1;
}
if(n%2)
{
return 1+l(3*n+1);
}
else
{
return 1+l(n/2);
}
}
int main()
{
long long i,j,k,max=0,f,g;
while(!cin.eof())
{
cin>>i>>j;
f=i;
g=j;
if(i>j)
{
long long temp;
temp=i;
i=j;
j=temp;
}
max=0;
for(long long a=i;a<=j;a++)
{
k=l(a);
if(k>max)
{
max=k;
}
}
cout<<f<<' '<<g<<' '<<max<<'\n';
}
return 0;
}
To explain my code, I'm using simple recursion.
The input is taken as i, j and is preserved as it is using f, g respectively.
i and j are swapped explicitly using temp. max is set 0 in every test case. k is used to hold the result sent by length function l() and is tested with max which stores maximum length till now.
My solution passes all the given trivial test cases in the problem.
It even passes all the tricky test cases which involve i greater than j and i==j
The problem hides integer overflow by giving incomplete information about requirement of long. I even handled that. The output rquires i, j in same order. The input gives no explicit end. I handled all of them. But still am getting wrong answer.
Your code is okay.
The only problem is your input handling untill End of File.
Just change while(!cin.eof()) to while(cin>>i>>j). You will get AC :)
May be problem with '\n'? Try to use cout<<f<<' '<<g<<' '<<max<<endl;