Insertion sort task - c++

I was trying to solve a problem in which I should sort increasingly array of numbers, than take first k numbers from sorted array and eliminate those numbers that are repeating and write them on the output.
This is my code:
#include <iostream>
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
int tab[n];
for (int i = 0; i < n; i++) //taking n numbers from input
{
cin >> tab[i];
}
int j, element;
for (int i = 1; i < n; i++) //i am using insertion sort
{
j = 0;
while (tab[j] < tab[i])
j++;
element = tab[i];
for(int k = i - 1; k >= j; k--)
tab[k + 1] = tab[k];
tab[j] = element;
}
for (int i = 0; i < k; i++) //writing k smallest numbers without repetitions
{
if (tab[i] == tab[i + 1])
continue;
cout << tab[i] <<"\n";
}
cin >> n;
return 0;
}
generally it works and it gives expected output, however when I am uploading this problem to check its correctness (i found this problem on polish site), it says "wrong anwser".
I cannot see any errors here, maybe you will see something which I wrote bad.

I think you misunderstood the problem. 'eliminate those numbers that are repeating' means you have to print the number once and eliminate subsequent occurrence(s) of that number. For ex.
n = 5;
k = 3;
tab[n] = 5 1 1 1 1
Here, sorted tab[] becomes '1 1 1 1 5', then expected output is '1', but your program gives nothing!
I hope this helps :)

Related

program that reads an integer, and prints all the perfect numbers

int n;
int sum;
cout << "write a number";
cin >> n;
for (int i = 1; i < n; i++)
{
sum = 0;
for (int j = 1; j <= i; j++)
{
if (i % j == 0)
sum = sum + j;
}
if (sum == i)
cout << i<< endl;
}
Why do I always get 1 as a result? I couldn't understand the logic of it. When I change the second for loop and make it i/2, I get the correct result, but I couldn't understand how it worked.
input 1000
expected result = 6 28 496
Remind about mathematics. Refer to wiki
In number theory, a perfect number is a positive integer that is equal
to the sum of its positive divisors, excluding the number itself.
So, in your code, you are making sum of ALL divisors of i include itself. That's why you only get result 1.
You should change it simply.
for (int j = 1; j < i; j++)

Range max sum query using sparse table

I Implemented range max sum query using sparse Table ,I Know more efficient approach would be using segment trees.
What I have tried:
I am calculating the max sum in the range (i,2^j-1) for all possible value of i and j and storing them in a table
where i is the index and j denotes the power of 2 (2^j denotes the length of segment from i for which we are calculating max sum)
Now using the above table we can answer the queries
Input:
3
-1 2 3
1
1 2
expected output:
2
actual output:
"wrong answer(garbage value)"
we actually have to tell the max contiguous sum in a given query
Link to the ques spoj gss1
Please help:
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
const int k = 16;
const int N = 1e5;
const int ZERO = 0; // ZERO + x = x + ZERO = x (for any x)
long long table[N][k + 1]; // k + 1 because we need to access table[r][k]
long long Arr[N];
int main()
{
int n, L, R, q;
cin >> n; // array size
for(int i = 0; i < n; i++)
cin >> Arr[i];
// build Sparse Table
for(int i = 0; i < n; i++)
table[i][0] = Arr[i];
for(int j = 1; j <= k; j++) {
for(int i = 0; i <= n - (1 << j); i++)
//table[i][j] = table[i][j - 1] + table[i + (1 << (j - 1))][j - 1];
table[i][j] = max(table[i][j-1],max(table[i+(1<<(j-1))][j-1],table[i+(1<<(j-1))][j-1]+table[i][j-1]));
}
cin >> q; // number of queries
for(int i = 0; i < q; i++) {
cin >> L >> R; // boundaries of next query, 0-indexed
long long int answer = LLONG_MIN;
for(int j = k; j >= 0; j--) {
if(L + (1 << j) - 1 <= R) {
answer = max(answer,answer + table[L][j]);
L += 1 << j; // instead of having L', we increment L directly
}
}
cout << answer << endl;
}
return 0;
}
link to the question Spoj Gss1

Why doesn't this C++ insertion sort work?

I'm learning C++ and this is one of my first programs that is going to sort a list of numbers, I found the algorithm in Kenneth H. Rosen book and wrote it in C++. when I check it on the paper it seems to be correct, but in practice it has some error. For example I enter 3(enter)2(enter)1(enter)4(enter)5(enter) and it returns 3 1 1 4 5 as the answer. I don't know what is the problem, please help.
int main()
{
int i, j, s, n, k, a[50];
cout << "Enter number of numbers:\n";
cin >> n;
cout << "Enter the numbers:\n";
for (i = 0; i < n; i++) {
cin >> a[i];
}
for (j = 2; j < n; j++) {
i = 1;
while (a[j] > a[i]) {
i = i + 1; // Here we find the proper place to(if needed) directly insert our number into the sorted part.
}
s = a[j];
for (k = 0; k < j - i - 1; k++) {
a[j - k] = a[j - k - 1];
}
a[i] = s;
}
for (i = 0; i < n; i++) {
cout << a[i] << " ";
}
_getch();
return 0;
}
I've also included the header files and namespace, not written here though. And in the case you think I have used so many variables, sorry about that, I needed them :)
Your index i should start from the first element which is 0 instead of 1.
Fixing line 11 should do the job:
for (j = 2; j < n; j++) {
i = 0;
while (a[j] > a[i]) {
Edit:
Oh, and also, your variable j should start from the second element which is index 1 instead of 2:
for (j = 1; j < n; j++) {

My C++ code goes into infinite loop when array size increases

I am trying to solve the problem at: Cut the Sticks.
My code works fine when the array size <=3 but goes bonkers then the size increases to >=6
#include<iostream>
using namespace std;
int minElement(int a[]){
int min = a[0];
int k;
for (k=1; k < 6; k++){
if (a[k] < min and a[k] > 0)
min = a[k];
}
return min;
}
int main(){
int a[6];
for (int i=0; i<6; i++){
cin >> a[i];
}
int minElem, flag;
while (true){
flag = 0;
minElem = minElement(a);
for (int i = 0; i < 6; i++){
a[i] = a[i] - minElem;
}
for (int j = 0; j < 6; j++){
if (a[j] > 0){
cout<<a[j]<<endl;
flag++;
}
}
if (flag == 0)
break;
};
return 0;
}
The problem is arising in the minElement function, it seems. On print min after assignment, it shows min as empty. Similarly, inside the loop in the function, I am getting blanks for all mins. What could be the issue?
EDIT
Please try the code here: http://cpp.sh/2ti6 with the input as [5,4,4,2,2,8]. It doesn't reach zero, the code starts failing before the first iteration, when the minimum element is called as Nothing is returned from the minElement functionn
Problem is there because of this line in the code
int min = a[0];
you need to check that array element is non-zero
int minElement(int a[]){
int min = 0;
int i=0;
while(i<6) // check the array element is non -zero
{
if(a[i]>0){
min = a[i];
break;
}
i++;
}
//int min = a[0];
int k;
for (k=1; k < 6; k++){
if (a[k] < min && a[k] > 0)
min = a[k];
}
return min;
}
The problem lies in your minElement function.
In the case that a[0] happens to be zero, you'll never assign another value to min and will return zero. Out of the function you will subtract zero to the values and enter the infinite loop.
In the case that a[0] is a negative number, you'll end up subtracting a negative value (and so increase the values instead). Then a[0] will become zero and your program loops.
Initializing min with a[0] is not enough, you have to look for a valid minimum value. You could, for example, initialize it with a very large value (not a very good solution) or search the array for the first valid min value.
EDIT:
I added some prints to your code:
...
while (true){
flag = 0;
minElem = minElement(a);
std::cout << "Min: " << minElem << std::endl;
for (int i = 0; i < 6; i++){
a[i] = a[i] - minElem;
}
std::cout << "Values:";
for (int j = 0; j < 6; j++){
std::cout << " " << a[j];
if (a[j] > 0){
//cout << " " << a[j];
flag++;
}
}
std::cout << std::endl;
if (flag == 0)
break;
getchar();
}
...
Here's the output:
5 4 4 2 2 8
Min: 2
Values: 3 2 2 0 0 6
Min: 2
Values: 1 0 0 -2 -2 4
Min: 1
Values: 0 -1 -1 -3 -3 3
Min: 0
Values: 0 -1 -1 -3 -3 3
(...) Loop forever
I hope that helps you understand now what the problem is.
int minElement(int a[]); change this to int minElement(int a[], int size)
2.
int a[6];
for (int i=0; i<6; i++){
cin >> a[i];
}
change this to
int arr_size=0;
cout << "Enter the array size ";
cin >> arr_size;
int a[arr_size];
for (int i=0; i<arr_size; i++){
cin >> a[i];
}
for (int i = 0; i < 6; i++){
a[i] = a[i] - minElem;
}
You are subtracting the min of the array from each element, so at this point there is only one 0 in the array and rest are positive numbers.
for (int j = 0; j < 6; j++){
if (a[j] > 0){
cout<<a[j]<<endl;
flag++;
}
So at this point flag has to be some positive number, and in this case 5.
if (flag == 0)
break;
This condition will never hit and hence the infinite loop.
it has nothing to do with the dimension.
What happens is that if a[0] is the smallest value => it will run in an infinte loop. Why because a[0] eventually becomes 0.
Why does a[0]=0 run in an infinte loop?
What value does minElement return when a[0] is 0?
try replace int min = a[0]; qith min = (a[0]>0) ? a[0]: 1;
or adding `minElem= (minElem>0) ? minElem: 1;' after 'minElem = minElement(a);'
PS:
Looking at all the answers this seems the simplest minElement that does what you want:
int minElement(int a[]){
int min = a[0];
int k;
for (k=1; k < 6; k++){
if(min==0 && a[k]>0 )
min=a[k];
else
if (a[k] < min and a[k] > 0)
min = a[k];
}
return min;
}
the min will only be zero at iteration N if a[j]==0 for all j+1
I solve this base on the link you provide. I use vector for me to easy remove those minimum length stick.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int noOfInput;
int input;
vector<int> myVec;
cin>>noOfInput;
for (int i=0; i<noOfInput; i++){
cin >> input;
myVec.push_back(input);
}
sort(myVec.begin(),myVec.end(),greater<int>());
while(myVec.size()>0){
int minimum = myVec[myVec.size()-1];
int lengthOfVector = myVec.size();
cout<<myVec.size()<<" ";
for(int i = lengthOfVector-1 ; i >=0 ; i--){
myVec[i]=myVec[i]-minimum;
if(myVec[i]==0){
myVec.pop_back();
}
}
}
return 0;
}

Selection sort ascending

That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.