C++ Basic Program Runtime Error - c++

I am writing a very easy program for the open.kattis programming website. This is one of the easiest problems on their website so its quite a hit to my ego. When I test the code myself it works fine, but their results indicate that I get a runtime error on an unknown test case. The link to the problem description is: https://open.kattis.com/problems/everywhere but the general basis of the problem is I'm trying to determine the number of unique instances in a list of strings
My code is:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
short t; // test cases
short trips;
char city[21];
char cities[50][21];
bool found;
short count;
// read in the number of test cases
cin >> t;
// loop through each test case
for(int i=0; i<t; i++)
{
// read in the number of trips taken
cin >> trips;
// reset the count to 0
count = 0;
// loop through each trip
for(int j=0; j<trips; j++)
{
// read in the city
cin >> city;
// Linear search to determine if city has been visited
found = false;
for(int k=0; k<count; k++)
{
if(strcmp(city, cities[k]) == 0)
found = true;
}
// If city hasn't been visted, increment count and add to list
if(!found)
{
strcpy(cities[count], city);
count++;
}
}
// Output results for test case
cout << count << endl;
}
return 0;
}

You misread the description. char cities[50][21] isn't enough for this exercise:
The number of trips is at most 100 and no city name contains more than 20 characters.
Calling the number of possible cities "trips" is a little bit misleading here, but it's not the number of tests (T ≤ 50). That being said, you could improve your program a lot if you separate the concerns and actually use the C++ standard library:
#include <iostream>
#include <set> // <- Hint: those both will help you tremendously!
#include <string> // <-
int single_test_case(){
// ...
}
int main(){
int tests;
std::cin >> tests;
for(int i = 0; i < tests; ++i){
std::cout << single_test_case();
}
return 0;
}

Related

C++ How to add numbers in an array within a given range?

I'm working on an assignment for class and am having a bit of a hard time putting it together. I had just started learning arrays and am not sure exactly how to get user input in the array.
Here is the assignment prompt: Create a program that inputs up to 100 integers (space separated!) and outputs their sum. For example:
1 2 3 4 5 6 7 8 9 10
55
This is what I have so far (edit because I forgot to change comments):
#include <iostream>
using namespace std;
int addNum(int n);
int main() {
int n;
// prompt user to input numbers
cout << "Please enter in values to add together: ";
cin >> n;
cout << addNum(n);
// pause and exit
getchar();
getchar();
return 0;
}
// function
int addNum(int n) {
int arr[99] = {};
int sum = 0;
for (int i = 0; i < n; i++) {
sum = sum + arr[i];
}
return sum;
}
Since this is a learning exercise, I wouldn't correct your code, but explain what you've missed so far:
The assignment asks to read integers until there's no more input; your code prompts the user for the count upfront, which should be removed.
You do not need an array to store the individual numbers, because the assignment asks only for the total. This can be computed on the fly: read a number, add it to sum, and forget the number.
You can read numbers until the end of input with a simple loop that uses >> operator below.
Here is an example that limits the input to 100 numbers, or stops when the input stream ends:
int limit = 0;
int nextNumber;
while ((limit++ != 100) && (cin >> nextNumber)) {
... // Process the next number
}
If you are giving your program input from console (as opposed to feeding it a file with numbers) and you need to end your input sequence, press Ctrl+z on Windows or Ctrl+d on UNIX.
In order to provide a diverse range of answers, std::accumulate is pretty cool.
http://en.cppreference.com/w/cpp/algorithm/accumulate
int sum = std::accumulate(v.begin(), v.end(), 0);
or in your case
int sum = std::accumulate(arr, arr + 99, 0);
Another functional approach is to use std::reduce introduced in C++17
http://en.cppreference.com/w/cpp/algorithm/reduce
Was able to get a working code after talking to the professor about it! Here's the working code:
#include <iostream>
using namespace std;
int main() {
// variable declarations
int sum = 0, count = 0;
int c;
// array declaration
int arr[100] = { 0 };
// prompt user to input numbers & add
cout << "Please enter in values to add together: ";
for (int i = 0; i < 100; i++) {
cin >> arr[i];
c = cin.peek();
sum = sum + arr[i];
// if user presses enter, skip to outputting sum without waiting for 100 values
if (c == '\n'){
break;
}
}
// output the sum of input
cout << sum;
// pause and exit
getchar();
getchar();
return 0;
}

Why does my code doesn't print the correct minimum difference?

I'm currently trying to solve the horse-racing game on Codingame. The problem statement is as follows:
Input
Line 1: Number N of horses
The N following lines: the strength Pi of each horse. Pi is an integer.
Output
The difference D between the two closest strengths. D is an integer greater than or equal to 0.
I'm using a std::set, and my algorithm is quite easy but for some reason it fails 2/8 of the submission validators. I don't have access to the actual test data, but according to the test names, the code below fails for
all horses same strength
horses in disorder
Why does my code fail on that input?
#include <iostream>
#include <set>
using namespace std;
int main()
{
int N;
cin >> N; cin.ignore();
set<int> power;
for (int i = 0; i < N; i++)
{
int Pi;
cin >> Pi; cin.ignore();
power.insert(Pi);
}
int minDiff = 10000000;
auto i = power.begin();
while (i != power.end())
{
minDiff = min(minDiff, abs(*i - *(++i)));
}
cout << minDiff << endl;
}
Your solution fails if any two horses have the same strength:
std::set<int> horses;
horses.insert(1);
horses.insert(2);
horses.insert(1);
// your algorithm returns 1, but it should be 0
Also, you have undefined behaviour. What happens if ++i is power.end() here?
minDiff = std::min(minDiff, abs(*i - *(++i)));
Use two iterators instead, and check for the special case where you have only one kind of horse if you want to use std::set.

How to make a while loop till there is something to be readen c++

I know that you probably gona again vote me down, I really don't understand this but im really stuck at something and cant figure it out , there is no such information anywhere in the web , neither in my book for the course, so I have this assignment where I need make 2 sums of containers where the difference between 2 sums is the lowest , so the program is done is working perfectly calculated everything however , in my assignment:
The user enter on one row unkwonw length numbers so after that I do all kind of sums between them and find the one with lowest difference between.
Ok but the way I wrote the code I use one while(true) so that to work with infinity testcases(as from assignment) and in this while(true) I have another while(cin>>(SOMEINT)) loop and push it back in a vector , and after it reads new line it just break the wile and continue with the calculation.
However in our test software this one give runtime error since after finding some cases then it start print infinity 0 0 since there is nothing to enter but the while(true) just continues.
I mean I just want to make it that way that the while is till user enters something , for instance you enter 30 50 90 it will return 80 90 , then wiat for another entry and so on.
CODE:
#include <iostream>
#include <string>
#include<vector>
#include <sstream>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <climits>
using namespace std;
const int length = 17000;
int power(int x){
int sum =2;
for(int i = 0;i<x;i++) {
sum *= 2;
}
return sum;
}
bool ison(int i,int x)
{
if((i>>x) & 1)return true;
return false;
}
int main()
{
while(true){
vector<int> Vec;
int cur = 0;
while (cin >> cur) {
Vec.push_back(cur);
if (cin.get() == '\n') {
break;
}
}
int * sumOfarr1 = new int[length];
int * sumOfarr2 = new int[length];
for(int i = 0; i<length;i++){
sumOfarr1[i] = 0;
}
for(int i = 0; i<length;i++){
sumOfarr2[i] = 0;
}
int index=0;
for(int i=1;i<length;i++)
{
for(int j=0;j<Vec.size();j++)
{
if(ison(i,j))
{
sumOfarr1[index]+=Vec[j];
}
else
{
sumOfarr2[index]+=Vec[j];
}
}index++;
}
int ans=INT_MAX;
int ii;
for(int i=0;i<index;i++)
{
if(abs(sumOfarr1[i]-sumOfarr2[i])<ans)
{
ii=i;
ans=abs(sumOfarr1[i]-sumOfarr2[i]);
}
}
if(sumOfarr1[ii]<sumOfarr2[ii]){
cout << sumOfarr1[ii] << " " << sumOfarr2[ii];
}
else{
cout << sumOfarr2[ii] << " " << sumOfarr1[ii];
}
cout << endl;
delete[] sumOfarr1;
delete[] sumOfarr2;
Vec.clear();
}
return 0;
}
Yes I found the solution just using getline and stringstream.
aka this
vector<int> Vec;
string line;
while(getline( cin, line ))
{
istringstream iss( line );
int number;
while( iss >> number )
Vec.push_back(number);
}

C++ program ( print out n words in alphabetical order ) runtime error

I recently started to learn C++ programing, and watched many of your posts and answers with interest when my mind would lack the creativity. I have a few issues with this code right here. Basically it should show "n" words in alphabetical order. "n" being introduce by the user and the words as well. I get a weird error, could someone give me a few hints on what should i do?
#include <iostream>
#include <vector>
#include <string>
int main () {
int n=0;
std::string cuvant;
std::vector<std::string> lista_cuvinte;
std::cout<<" Cate cuvinte doriti sa comparati = "<< std::endl;
std::cin>> n;
for (int i=0; i<n; i++)
{
std::cout<<"cubantul al " << i + 1 <<" -lea = ";
std::cin>> cuvant;
lista_cuvinte.push_back(cuvant);
for (int i=0; i < n; i++)
{
for (int j=i + 1; j < n; j++)
{
if (lista_cuvinte.at(i) > lista_cuvinte.at(j))
{
std::string temp=lista_cuvinte.at(i);
lista_cuvinte[i]=lista_cuvinte.at(j);
lista_cuvinte[j]=temp;
i=i-1;
break;
std::cout<< temp << std::endl;
}
}
}
}
return 0;
}
You are doing a lot things wrong. Simply sorting starts before all data was read in in your code. Code after a break will never executed. And there is no output.
But you can achieve the same result much simpler by using sort from algorithm. I believe your code is only for learning, so it maybe makes sense to do it by hand. Normally it does not :-)
#include <iostream>
#include <vector>
#include <string>
int main () {
int n=0;
std::string cuvant;
std::vector<std::string> lista_cuvinte;
std::cout<<" Cate cuvinte doriti sa comparati = "<< std::endl;
std::cin>> n;
// read data
for (int i=0; i<n; i++)
{
std::cout<<"cubantul al " << i + 1 <<" -lea = ";
std::cin>> cuvant;
lista_cuvinte.push_back(cuvant);
}
// sort data
for (int i=0; i < n; i++)
{
for (int j=i + 1; j < n; j++)
{
if (lista_cuvinte.at(i) > lista_cuvinte.at(j))
{
std::string temp=lista_cuvinte.at(i);
lista_cuvinte[i]=lista_cuvinte.at(j);
lista_cuvinte[j]=temp;
i=i-1;
break;
}
}
}
// output data
for (int i=0; i<n; i++)
{
std::cout << lista_cuvinte[i] << std::endl;
}
return 0;
}
And with std::sort your code in the section sorting reduces to:
// sort data
std::sort( lista_cuvinte.begin(), lista_cuvinte.end());
Thats all!
As a hint to you for writing and finding errors in general: Please use a debugger. Your code simply throws an exception. Your debugger will catch it for you and you go in the backtrace to the point where the error occurs. In your code it was an access out of range from the array, because the data was not read in at this point of execution.
You are starting sorting before completing the input of the words. Your second for (int i=0... loop is inside your first one.

Error-correcting loop in C++, find specific chars in a string and flag as bad input

Here is v1.0 of the binary_to_decimal converter I wrote. I want to make several changes as I keep improving the spec. Classes and pointers will be added as well in the future. Just to keep me fresh and well practiced.
Well, I now want to implement an error-correcting loop that will flag any character that is not a 0 or a 1 and ask for input again.
I have been trying something along the line of this code block that worked with an array.
It might be way off but I think I can tweak it. I am still learning 0_0
I want to add something like this:
while ((cin >> strint).get())
{
cin.clear(); //reset the input
while (cin.get() != '\n') //clear all the way to the newline char
continue; //
cout << "Enter zeroes and/or ones only! \n";
}
Here is the final code without the error-correcting loop:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
const int MAX = 100;
int conv(int z[MAX], int l[MAX], int a);
int main()
{
int zelda[MAX];
int link[MAX];
string strint;
int am;
cout << "Enter a binary number: \n";
(cin >> strint).get(); //add error-correction to only read 0s and 1s.
am = strint.size();
cout << am << " digits entered." << endl;
int i = 0;
int p = 0;
while (i < am)
{
zelda[i] = strint[p] - '0'; //copies the string array elements into the int array; essentially STRING TO INT (the minus FORCES a conversion because it is arithmetic) <---- EXTREMELY CLEVER!
++i;
++p;
}
cout << conv(zelda, link, am);
cin.get();
return 0;
}
int conv(int zelda[MAX], int link[MAX], int length)
{
int sum = 0;
for (int t = 0; t < length; t++)
{
long int h, i;
for (int h = length - 1, i = 0; h >= 0; --h, ++i)
if (zelda[t] == 1)
link[h] = pow(2.0, i);
else
link[h] = 0;
sum += link[t];
}
return sum;
}
thanks guys.
I'm not completely sure of what you're trying to do, but I think what you're wanting is string::find_first_not_of. There's an example included in that link. You could have something like: myString.find_first_not_of("01");
If the return value is string::npos, then there are no characters in the string other than 1 or 0, therefore it's valid. If the return value is anything else, then prompt again for valid input and continue looping until the input's valid.