Program Times Out When Only Blank Newline Is Entered - c++

The assignment was to write a program that receives numbers as an inputs (each one on a new line) and then sorts them from smallest to largest. The way to end the input is to enter a blank newline after the numbers are entered. My program works fine except for when I enter only a blank line. Then the program times out.
Here is my code:
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
void sort(vector<int>& v)
{
for(int i = 0; i < v.size() - 1; ++i)
{
int min = i;
for(int j = i; j < v.size(); ++j)
{
if(v[j] < v[min])
{
min = j;
}
}
if(min != i){
int temp = v[min];
v[min] = v[i];
v[i] = temp;
}
}
}
void print(vector<int> v)
{
for(int i = 0; i < v.size(); ++i)
{
cout << v[i];
if(i != v.size() - 1)
{
cout << ", ";
}
}
cout << endl;
}
int main()
{
cout << "Enter integers (one on each line, entering an empty line quits):" << endl;
vector<int> v;
string str;
while(getline(cin, str))
{
if(str == "")
{
cout << "Sorted: ";
break;
}
else
{
v.push_back(atoi(str.c_str()));
}
}
sort(v);
print(v);
return 0;
}
Any help is appreciated.

You don't check for empty vector in sort() and v.size() - 1 causes integer underflow. Add check for empty vector:
void sort(vector<int>& v)
{
if (!v.empty()) {
for(int i = 0; i < v.size() - 1; ++i)
{
int min = i;
for(int j = i; j < v.size(); ++j)
{
if(v[j] < v[min])
{
min = j;
}
}
if(min != i){
int temp = v[min];
v[min] = v[i];
v[i] = temp;
}
}
}
}

Related

How to compare elements of a vector with elements of a vector of vectors?

My intention is after pushing pair to vector temp_pairs, compare it's 2 elements with the elements of the vector of vectors jumpers, and if one element of temp_pairs is equal to any element of jumpers .clear() the temp_pairs.
The following code works, except for the 2 first pairs.
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
typedef std::vector<int> vector_i;
typedef std::vector<char> vector_c;
vector_c control {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','w','y','z',' ','.'};
std::vector<vector_c> jump_input();
int main()
{
jump_input();
return 0;
}
std::vector<vector_c> jump_input()
{
std::vector<vector_c> jumpers;
vector_c temp_pairs(2);
int jump_count = 0;
char in;
vector_c pair;
do
{
for (int i = 0; i < jumpers.size(); i++)
{
for (int j = 0; j < jumpers[i].size(); j++)
{
std::cout << jumpers[i][j];
}
std::cout << " ";
}
for (int i = 0; i < 2; i++)
{
std::cout << "\n" << "Enter the " << i+1 << " of the pair number "<< jumpers.size()+1 << "\n";
std::cin >> in;
for (int j = 0; j < control.size(); j++)
{
if (in == control[j])
{
pair.push_back(in);
}
}
}
if (pair.size()>1)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < control.size(); j++)
{
if (pair[i] == control[j])
{
temp_pairs.push_back(pair[i]);
}
}
}
}
// where the comparation happens
for (int i = 0; i < jumpers.size(); i++)
{
for (int j = 0; j < 2; j++)
{
if (jumpers[i][j] == temp_pairs[j])
{
temp_pairs.clear();
}
}
}
if (!temp_pairs.empty())
{
jumpers.push_back(temp_pairs);
jump_count += 1;
}
temp_pairs.clear();
pair.clear();
in='\0';
} while (jump_count<21);
return jumpers;
}
Terminal image
enter image description here
I tried series of if statements and for loops, and this is the best result i code reach.

How do I output all numbers with a given amount of divisors? (C++)

I need to enter 2 integers, n and k, n is the range and k is the amount of divisors for those numbers, and only display the numbers with k divisors.
#include <iostream>
using namespace std;
int main()
{
int n, k,cnt=0;
cin>>n;
cin>>k;
for(int i=1; i<=n; i++)
{
if(n%i==0)
{
cnt++;
}
if(k==cnt)
cout<<i<<" ";
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k;
cin>>n>>k;
for(int i = 1; i <= n; i++){
int num_divisors_i = 0;
for (int j = 1, len = sqrt(i); j <= len; j++) {
if (i % j == 0) {
if (i / j == j) {
num_divisors_i++;
}
else {
num_divisors_i = num_divisors_i + 2;
}
}
}
if(num_divisors_i == k) cout<<i<<" has "<<k<<" divisors"<<endl;
}
}
This was my solution:
#include<iostream>
int main(int argc, char* argv[]) {
int n = 0, k = 0;
std::cout << "Enter the range: ";
std::cin >> n; if (!std::cin) throw std::runtime_error("range read failed");
std::cout << std::endl << "Enter the number divisors: ";
std::cin >> k; if (!std::cin) throw std::runtime_error("number of divisors read failed");
std::cout << "numbers with " << k << " divisor:: ";
for (int i = 1; i != n+1/*if k is inclusive else n*/; ++i) {
int cnt = 0;
for (int j = 1; j != i+1; ++j) {
if (i % j == 0)
cnt += 1;
}
if(cnt == k)
std::cout << i << ' ';
}
return 0;
}

MAX value of matrix and saving indexes in the same loop

I get a NxM sized matrix and I have to find the max value, the number of max values and the lines that contain it.
I tired using three for{for{}} loops, but it took too long. This method seems to work for small inputs, but when I try it with a 1000x1000 matrix, it finishes before it even takes all the input.
I realise this may be too much of a noob question, but I couldn't find anything else.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
for(int i=0; i<n; i++)
{
for(int p=0; p<m; p++)
{
cin >> vekt[p];
}
for(int j=0; j<m; j++)
{
if(vekt[j] == crnt)
{
lines[cnt] = i + 1;
cnt += 1;
}
if(vekt[j] > crnt)
{
crnt = vekt[j];
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
EDIT : not using vector or [n] was just easier... I simply saved it to a variable and used a bool:
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
bool inLine;
inLine = false;
for(int i=0; i<n; i++)
{
inLine = false;
for(int j=0; j<m; j++)
{
cin >> inp;
if(inp == crnt && inLine == false)
{
lines[cnt] = i + 1;
cnt += 1;
inLine = true;
}
if(inp > crnt)
{
crnt = inp;
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
This cut the time by enough so that I went under the limit.
int vekt[m]; is not standard C++, it is a variable length array (which some compilers allow as extension). Use std::vector instead.
That would also fix the bug you currently have: If cnt >= n (i.e. if you find more maxima than the matrix has lines), you will go out of bounds of lines and your program will most likely crash (although anything could happen), which is more likely to happen with larger matrices.
You can do this instead:
Declaration and initialization:
std::vector<int> linesWithMaxima;
When you find another value equal to the current maximum:
linesWithMaxima.push_back(i+1);
When you find a new maximum (larger than current):
linesWithMaxima.clear();
linesWithMaxima.push_back(i+1);
Note that this will list a line with multiple (identical) maxima multiple times. If you want to avoid duplicates, you can either check that you have not already added the current line (linesWithMaxima.back() != i+1) or use std::sort, std::unique and std::vector::erase.
Other than that your code looks fine. I would recommend naming the loop indices better (line instead of i etc.) and possibly merging the p and j loop because separating them seems to have no purpose. And if you want the most negative integer, use std::numeric_limits<int>::lowest().
Check this realization, without STL and vectors:
void input_matrix(int **&matrix, int &lines, int &columns)
{
int m = 0, n = 0;
cout << "input lines count:";
cin >> m;
cout << "input rows count:";
cin >> n;
matrix = new int *[m];
for(int i = 0;i < m;i++)
matrix[i] = new int[n];
cout << endl << "input matrix:" << endl;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> matrix[i][j];
lines = m;
columns = n;
}
void print_matrix(int **&matrix, int &lines, int &columns)
{
for(int i = 0; i < lines; i++)
{
for(int j = 0; j < columns; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
}
int find_max(int **matrix, int lines, int columns, int &max_count)
{
int max = INT_MIN;
max_count = 0;
for(int i = 0; i < lines; i++)
for(int j = 0; j < columns; j++)
{
if(matrix[i][j] > max)
{
max = matrix[i][j];
max_count = 1;
}
else
if(matrix[i][j] == max)
++max_count;
}
return max;
}
int main()
{
int **matrix = nullptr;
int m=0, n=0, count=0;
input_matrix(matrix, n, m);
cout << endl;
print_matrix(matrix, n, m);
cout << endl;
int max = find_max(matrix, n, m, count);
cout << "max=" << max << " count=" << count << endl;
for(int i = 0; i < n; i++)
delete[]matrix[i];
delete []matrix;
}
As requested by mister Max Langhof I would also like to propose a more modern solution, based on the std::vector container, which does not need pointers and manual memory management. It's a simple class matrix:
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdint>
using namespace std;
class matrix
{
private:
vector<vector<int>> m_data;
public:
matrix(int cols, int rows)
{
m_data.resize(cols);
for(auto &r : m_data)
r.resize(rows);
}
int max_element()
{
int max = INT_MIN;
for(auto &row: m_data)
{
auto maxinrow = *std::max_element(row.begin(), row.end());
if(maxinrow > max)
max = maxinrow;
}
return max;
}
int element_count(int elem)
{
int count = 0;
for(auto &row : m_data)
count += std::count_if(row.begin(), row.end(), [elem](int a){return a == elem;});
return count;
}
friend istream& operator>>(istream &os, matrix &matr);
friend ostream& operator<<(ostream &os, matrix &matr);
};
Input and output operators could be realized like this:
istream& operator>>(istream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cin >> matr.m_data[i][j];
cout << endl;
}
return os;
}
ostream& operator<<(ostream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cout << matr.m_data[i][j] << " ";
cout << endl;
}
return os;
}
And a sample of using of this matrix:
int main()
{
int m = 5, n = 4;
matrix matr(m, n);
cout << "input matrix:" << endl;
cin >> matr;
cout << endl << matr;
int max = matr.max_element();
cout << "max: " << max << " count:" << matr.element_count(max) << endl;
}
Checkout something like this
#include <iostream>
#include <set>
#include <vector>
int main() {
int rowsNo, columnsNo;
std::cin >> rowsNo >> columnsNo;
std::vector<int> matrix(rowsNo*columnsNo);
//Creating matrix
for(auto row = 0; row < rowsNo; ++row) {
for (auto column = 0; column < columnsNo; ++column)
std::cin >> matrix[row*columnsNo + column];
}
auto maxValue = -51;
//Finding positions of maximums
std::set<int> linesWithMaxValue;
for (auto position = 0; position < matrix.size(); ++position) {
if(matrix[position] == maxValue)
linesWithMaxValue.insert(position / columnsNo);
else if(matrix[position] > maxValue) {
linesWithMaxValue.clear();
maxValue = matrix[position];
linesWithMaxValue.insert(position / columnsNo);
}
}
//Print info
const auto numberOfMaxValues = linesWithMaxValue.size();
std::cout << "Number of maxiums: " << numberOfMaxValues << std::endl;
std::cout << "Lines that contains maximum:";
for (const auto& lineId : linesWithMaxValue)
std::cout << " " << lineId;
return 0;
}

Bubble sort logical error?

I am trying to do a bubble sort, but I don't know what's happening in my code. I am a noob so sorry if the code I wrote seems obvious ^.^
main() {
int a[5], i, j, smallest, temp;
cout << "Enter 5 numbers: " << endl;
for ( i = 0; i <= 4; i++ ) {
cin >> a[i];
}
for ( i = 0; i <=4; i++ ) {
smallest = a[i];
for ( j = 1; j <= 4; j++ ) {
if ( smallest > a[j] ) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
cout << endl << endl;
for ( i = 0; i <= 4; i++ ) {
cout << a[i] << endl;
}
system("pause");
}
Any answer will be highly appreciated. Thanks!
Your bubblesort almost appears to be a selection sort. Bubblesort looks at pairs of items and swaps them if necessary. Selection sort looks for the lowest item in the rest of the array, and then swaps.
#include <iostream>
#include <utility>
using std::cin;
using std::cout;
using std::endl;
using std::swap;
void bubblesort(int a[5])
{
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i = 0; i < 4; i++)
{
if (a[i] > a[i + 1])
{
swap(a[i], a[i + 1]);
swapped = true;
}
}
}
}
void selectionSort(int a[5])
{
for (int i = 0; i < 4; i++)
{
int smallest = i;
for (int j = smallest; j < 5; j++)
{
if (a[smallest] > a[j])
{
smallest = j;
}
}
if (smallest != i)
{
swap(a[i], a[smallest]);
}
}
}
int main(int argc, char* argv[])
{
int a[5];
cout << "Enter 5 numbers: " << endl;
for (int i = 0; i < 5; i++ )
{
cin >> a[i];
}
//selectionSort(a);
bubblesort(a);
cout << endl << endl;
for (int i = 0; i <= 4; i++ ) {
cout << a[i] << endl;
}
}

Using a function to remove duplicates from an array in C++

I'm writing a program that has a user input integers into an array, calls a function that removes duplicates from that array, and then prints out the modified array. When I run it, it lets me input values into the array, but then gives me a "Segmentation fault" error message when I'm done inputing values. What am I doing wrong?
Here is my code:
#include <iostream>
using namespace std;
void rmDup(int array[], int& size)
{
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (array[i] == array[j])
{
array[i - 1 ] = array[i];
size--;
}
}
}
}
int main()
{
const int CAPACITY = 100;
int values[CAPACITY], currentSize = 0, input;
cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";
while (cin >> input)
{
if (currentSize < CAPACITY)
{
values[currentSize] = input;
currentSize++;
}
}
rmDup(values, currentSize);
for (int k = 0; k < currentSize; k++)
{
cout << values[k];
}
return 0;
}
Thank you.
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (array[i] == array[j])
{
array[i - 1 ] = array[i]; /* WRONG! array[-1] = something */
size--;
}
}
}
If array[0] and array[1] are equal, array[0-1] = array[0], meaning that array[-1] = array[0]. You are not supposed to access array[-1].
I wouldn't make it even possible to create duplicates:
int main()
{
const int CAPACITY = 100;
cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";
std::set<int> myInts;
int input;
while (std::cin >> input && input != 'q' && myInts.size() <= CAPACITY) //note: 113 stops the loop, too!
myInts.insert(input);
std::cout << "Count: " << myInts.size();
}
And do yourself a favour and don't use raw arrays. Check out the STL.
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
vector<int> vec = {1,1,2,3,3,4,4,5,6,6};
auto it = vec.begin();
while(it != vec.end())
{
it = adjacent_find(vec.begin(),vec.end());
if(it != vec.end())
vec.erase(it);
continue;
}
for_each(vec.begin(),vec.end(),[](const int elem){cout << elem;});
return 0;
}
This code compiles with C++11.
#include<iostream>
#include<stdio.h>
using namespace std;
int arr[10];
int n;
void RemoveDuplicates(int arr[]);
void Print(int arr[]);
int main()
{
cout<<"enter size of an array"<<endl;
cin>>n;
cout<<"enter array elements:-"<<endl;
for(int i=0;i<n ;i++)
{
cin>>arr[i];
}
RemoveDuplicates(arr);
Print(arr);
}
void RemoveDuplicates(int arr[])
{
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;)
{
if(arr[i]==arr[j])
{
for(int k=j;k<n;k++)
{
arr[k]=arr[k+1];
}
n--;
}
else
j++;
}
}
}
void Print(int arr[])
{
for(int i=0;i<n;i++)
{
cout<<arr[i]<<" ";
}
}