Tournament Structure Sorting C++ - c++

Here I have this code that sorts a tournament structure like array in descending order. It sorts all but one number and always returns a -1 as the lowest integer it sorts, I have read through this code multiple times and I can't seem to figure out why it's not sorting properly, I'm not sure if it's just missing my eyes or if there is a small typo somewhere.
#include <iostream>
#include <cmath>
using namespace std;
int maxi(int i, int j)
{
if (i > j) return(i);
else return(j);
}
int mini(int i, int j)
{
if (i < j) return(i);
else return (j);
}
int buildtourn(int tourn[], int n)
{
int min1=0, a;
//Compute tournament structure
for (int i=2*n-2; i>1; i=i-2)
{
tourn[i/2] = maxi(tourn[i], tourn[i+1]);
a=mini(tourn[i], tourn[i+1]);
if (min1>a) min1=a;
}
return min1;
}
int getnext(int tourn[], int n, int low)
{
int i = 2;
//Part 1 - downward traversal
while (i <= 2*n-1)
{
if (tourn[i]>tourn[i+1])
{
tourn[i]=low;
i=2*i;
}
else
{
tourn[i+1]=low;
i=2*(i+1);
}
}
//Part 2 - upward traversal
for (i = i/2; i>1; i=i/2)
{
if (i%2==0) tourn[i/2]=maxi(tourn[i],tourn[i+1]); // go to the right of i
else tourn[i/2]=maxi(tourn[i], tourn[i-1]); // to the left of i
}
return 0;
}
int main()
{
int tourn[100], n, i, low;
//Read
cout << "Give n :" ;
cin >> n;
cout<< "Enter the integers to be sorted : " << endl;
for (i=n; i<=2*n-1; i++)
cin >> tourn[i];
//build tournament
low=buildtourn(tourn,n)-1;
//Sorting
cout << " Sorted items are : " << endl;
for(i=1; i<=n; i++)
{
cout << tourn[i] << '\t';
getnext(tourn,n,low);
}
cout << '\n';
return 0;
}
I believe the error lies solely in my function that builds the tournament structure but, i'm not quite sure if i'm looking in the wrong place.
int buildtourn(int tourn[], int n)
{
int min1=0, a;
//Compute tournament structure
for (int i=2*n-2; i>1; i=i-2)
{
tourn[i/2] = maxi(tourn[i], tourn[i+1]);
a=mini(tourn[i], tourn[i+1]);
if (min1>a) min1=a;
}
return min1;
}
Thank you in advance for any help and If I need to add anymore details to this problem please let me know in the comments.
EDIT: This is a link to view the output i am receiving.
http://imgur.com/a/KNDO8
EDIT 2: If i were to use the numbers 20 14 1 3 8 to be sorted, it would sort them as 20 8 1 3 -1

In mini maxi functions, replace < and > by <= and >=

Related

Unable to find the error in the code I wrote for a question on loops in C++. Could anyone point it out?

a beginner at coding here.
I was practising loops(c++) when I stumbled upon this problem:-
Write a program in C++ to find the perfect numbers between 1 and 500. (6,28 and 496)
Perfect number: It is a positive integer that is equal to the sum of its proper divisors. The smallest perfect number is 6, which is the sum of 1, 2, and 3.
I wrote the following code:-
#include <iostream>
using namespace std;
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
}
return 0;
}
The code is supposed to print that 6, 28 and 496 are perfect numbers.
But instead, it's not printing anything. Haven't been able to find the error yet after checking for 30+ minutes.
Could anyone point out the error?
You forget to re-initialize some variables in your loop.
for seems more appropriate than while here.
Create sub function also help to "identify" scope.
#include <iostream>
bool isPerfectNumber(int n)
{
int sum = 0;
for (int div = 1; div != n; ++div) {
if (n % div == 0) {
sum += div;
}
}
return sum == n && n > 0;
}
int main()
{
for (int i = 2; i != 501; ++i) {
if (isPerfectNumber(i)) {
std::cout << n << " is a perfect number." << std::endl;
}
}
return 0;
}
#include<iostream>
using namespace std;
bool perfect_num(int x);
int main() {
int m, n, x;
cout << "input the range m, n: " << "\n";
cin >> m >> n;
for (x = m; x <= n; ++x) {
if (perfect_num(x)) {
cout << x << " ";
}
}
return 0;
}
bool perfect_num(int x) {
bool flag = false;
//initialize
int sum = 0, i;
//loop 1 to x
for (i = 1; i < x; ++i) {
//judge whether is the factor
if (x % i == 0) {
sum += i;
}
}
//update flag
flag = (sum == x);
return flag;
}
#include<iostream>
using namespace std;
//judge function
bool isPerfectNum(int num){
int tmp = 0;
for (int i = 1; i < num; ++i) {
if (num % i == 0) {
tmp += i;
}
}
return tmp == num;
}
int main(){
cout << "Perfect Number contains: ";
for (int i = 1; i <= 500; ++i){
if (isPerfectNum(i)) {
cout << i << " ";
}
}
cout << "\n";
return 0;
}
at the end of your first loop, you should bring back div and sum to their default value.
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
div = 1; // you should bring them back here.
sum = 0;
}
return 0;
}

Checking Duplicates Numbers In Array c++

I wrote a simple C++ program that finds how many duplicates are in the array.
This works perfectly for me but this is very long code. And I would like to know if there is any short code which may perform this task successfully:
#include<iostream>
using namespace std;
int main()
{
int a[10];
int reper=0,word=0,flage=0,number[10]={
0
};
//Getting Input From User
for (int i = 0; i <=9; i++)
{
cout<<"Enter The Value For "<<i<<" Index"<<endl;
cin>>a[i];
}
//Checking The Duplicates Numbers
for (int i = 0; i <= 9; i++)
{
reper=0;
flage=0;
for (int j = 0; j <=9; j++)
{
if (a[i]==a[j])
{
if (i!=j)
{
reper++;
}
}
}
number[i]=a[i];
for (int k = 0; k <=9; k++)
{
if (i!=k)
{
if(number[i]==number[k])
{
flage=1;
break;
}
}
}
//If There Are Duplicates Then Prints That Numebr, How Many Times It Repeated And Total Occurance Of That Number In The Array
if (reper!=0&&flage==0)
{
cout<<"Repeated Number Of The Array Is : "<<a[i]<<" ";
cout<<"And This Number Repeated "<<reper<<" Times "<<"And Total Occurance Of This Number is : "<<reper+1<<endl;
word=a[i];
}
}
//If There Is Nothing Any Duplicate In The Array Then Simply Prints This Message On Console
if (reper==0&&word==0)
{
cout<<"There Is Nothing Any Repeated Number Of This Array: "<<endl;
}
system("Pause");
return 0;
}
IMHO the easiest way to implement this - using http://en.cppreference.com/w/cpp/container/multiset. It has logarithmic complexity and inner methods to count repeated items.
Refer an example below:
#include <iostream>
#include <set>
int main(int argc, char *argv[])
{
std::multiset<int> ms;
//Getting Input From User
for (int i = 0; i <=9; i++)
{
std::cout<<"Enter The Value For "<<i<<" Index"<<std::endl;
int val;
std::cin>>val;
ms.insert(val);
}
bool repeated_number_found=false;
std::multiset<int>::const_iterator it = ms.begin();
while (it != ms.end()) {
int reper=ms.count(*it);
if (reper > 1){
std::cout << "Number " << *it << " repeated for " << reper << " times" << std::endl;
repeated_number_found=true;
}
it = ms.upper_bound(*it);
}
if (!repeated_number_found){
std::cout<<"There Is Nothing Any Repeated Number Of This Array"<<std::endl;
}
return 0;
}
But using this container you will loose first entrance of repeated number, if it matters to you, I will recommend using struct or std::pair to hold entrance number with entered number. In this case you will need to provide custom comparator also (refer to doc.)
I think the better way to achieve this would be to sort the array and do something like this :-
(include the header file algorithm before doing this.)
vector <int> a (10,0);
for (int i = 0; i <=9; i++)
{
cout<<"Enter The Value For "<<i<<" Index"<<endl;
cin>>a[i];
}
int count = 0;
sort(a.begin(), a.end());
for(int i = 0; i < a.size() - 1; i++) {
if (a[i] == a[i + 1]) {
count++;
}
}
cout << count << endl;

combinatorial function c++ using Recursion

Now this is the combinatorial function if you don't know it:
C(n,k)= { 1 if k=0 or k = n
C(n−1,k−1)+C(n−1,k) otherwise
Now, What I really need is to use recursion to print a Pascal's triangle.
Ok,so what I've done so far is this simple recursion function:
#include <iostream>
using namespace std;
int Pas(int r, int c) {
if (c == 0 || c == r) {
return 1;
} else {
return Pas(r - 1, c - 1) + Pas(r - 1, c);
}
}
int main(){
cout << Pas(4,2) << endl;
return 0;
}
Now this function computes perfectly for example:
Pas(4,2) = 6
But I'm having problem using it to print the whole Pascal's triangle, because I'm new into C++ and especially recursion ..
I'd appreciate any feedback, and I hope that someone would help figure out this problem. But I'd appreciate it more if you guys don't just give me the whole answer (code) just like that; I want to learn.
Thanks!
Something similar to this might to the job
void printTriangle(int printRows, int a = 1, int b = 0)
{
if (a > printRows) return;
int val = Pas(a, b);
cout << val << " ";
if (a == b) {
cout << endl;
printTriangle(printRows, a + 1, 0);
} else {
printTriangle(printRows, a, b + 1);
}
}
Running printTriangle(7) should print the first 7 rows.
Tail recursion is the recursive equivalent to iterative loops. The following function when called with sum(0, 5)
int sum(int start, int end, int resultSoFar = 0) {
if (start == end) return resultSoFar;
return sum(start + 1, end, resultSoFar + start);
}
is equivalent to the iterative function called with sum(0, 5).
int sum(int start, int end) {
int resultSoFar = 0;
for (int i = start; i < end; i++) {
resultSoFar += i;
}
return resultSoFar;
}
If you are allowed to use your recursive function in a loop, the easiest way would be something like:
int n=4;
for (int i=0; i<=n; i++) {
for (int j=0; j<=i; j++) {
cout << Pas(i,j)<<" ";
}
cout <<endl;
}
If you want to reinforce the layout, you coud also #include <iomanip> and <limits> to use a fixed size number output, using the number of digits required to display an integer: just replace the output statement with:
cout << setw(numeric_limits<int>::digits10+1)<<Pas(i,j);
Edit:
You could easily build a recursive function to print lines of the triangle:
void PrintPas(int r) {
if (r==1)
cout << Pas(1,0);
else {
PrintPas(r-1);
for (int c=0; c<=r; c++)
cout << Pas(r,c)<< " ";
}
cout <<endl;
}
Edit 2
If you want a fully recursive version:
void PrintPas(int r, int c) {
if (r==1)
cout << Pas(1,0)<<" ";
else if (c==-1) {
PrintPas(r-1,r-1);
}
else {
PrintPas(r,c-1);
cout << Pas(r,c)<< " ";
}
if (r==c)
cout <<endl;
}
Online demo

How to optimize the N-Queen backtracking

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
ifstream f("damesah.in");
ofstream g("damesah.out");
int st[20], n,nrSol=0;
void afisare() {
for (int i = 1; i <= n; ++i) {
g << st[i] << " ";
}
g << "\n";
}
int valid(int k) {
for (int i = 1; i < k; ++i) {
if (st[k] == st[i] || abs(st[k]-st[i]) == abs(k-i))
return 0;
}
return 1;
}
void BK(int k) {
for (int i = 1; i <= n; ++i) {
st[k] = i;
if (valid(k)) {
if (k == n) {
++nrSol;
if(nrSol == 1)
afisare();
}
else
BK(k + 1);
}
}
}
int main()
{
f >> n;
BK(1);
g << nrSol << "\n";
return 0;
}
This is the code I have made to solve the N-Queen problem using backtracking , if you do not know the problem , here it is : The N Queen is the problem of placing N chess queens on an N×N chessboard so that no two queens attack each other. A queen is attacking another one if they are on the same column, row or on the same diagonal.
If we insert 4, the output will show only the first solution, then the number of solutions on the second row :
2 4 1 3
2
I want to optimise this algorithm using one more array which will store the row the diagonal and the column used by the queen so the complexity of the validation will be O(1), but I do not know how to implement it.

C++ Vector Subscript out of Range Error 1221

I am trying to make a program that recieves numbers from the user, and then rearranges the from least to greatest. I am using vectors (which I just learned about), and it gives me a subscript out of range error. I am not able to find what part of the code gives me this error, so hopefully someone more knowledgeable on vector and c++ can find it:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void order(int a, int b);
void orderRev(int a, int b);
int main() {
vector<int> num;
bool going = true;
do {
cout << "\nEnter a number or type 'x' to order:" << endl;
string reply;
getline(cin, reply);
if (reply != "x") {
int a = atoi(reply.c_str());
num.push_back(a);
cout << "\nYou currently have " << num.size() << " numbers added." << endl;
}
else {
going = false;
}
} while (going);
for (int i = 0; i < num.size(); i++) {
order(num[i], num[i + 1]);
}
for (int i = num.size() - 1; i >= 0; i--) {
orderRev(num[i + 1], num[i]);
}
cout << "\nThe number you entered in order from least to greatest are: " << endl;
for (int i = 0; i < num.size(); i++) {
cout << num[i] << " ";
}
void order(int a, int b) {
if (a > b) {
int c = b;
b = a;
a = c;
}
}
void orderRev(int a, int b) {
if (a < b) {
int c = b;
b = a;
a = c;
}
}
Fix these lines to this:
// added the -1 as this will now go up to the 2nd to last element
// for `n`, and the last element for `n+1`
for (int i = 0; i < num.size() - 1; i++) {
order(num[i], num[i + 1]);
}
// changed the starting number to size -2 (for the same reasoning)
for (int i = num.size() - 2; i >= 0; i--) {
orderRev(num[i + 1], num[i]);
}
Why does this need to be this way? Think about how indices in C++ work. They are zero-indexed! That means that if you want both the element and the one in front of it, you must go up to the size of the vector minus 1. Hence, for a vector of 10 items (size 10), at i == 9 your code will work like this:
for (int i = 0; i < num.size(); i++) {
// i = 9
order(num[9], num[9+1]);// index 10 does not exist! Hence, you really need to go up to num.size() - 1!
}
Vectors index start with 0. index will be 0 to n-1 , if you use num[i + 1] it will exceed the vector size, if you don't check in loop condition.
Your code has more than one flaw. The output will be same as the input , hint: know the difference between pass by reference and pass by value and after that check some sorting algorithms.