I am trying to make a C++ program of the FourSum problem i.e. Does there exist a sum of four different numbers that sum to zero.
"i + j + k + l = 0" "-2 + -1 + 3 + 0 = 0"
I can get it to work, but the running time is around 10-15 times slower than the java implementation (both are naive approaches, so basically just four for loops). I know it is possible to use BinarySearch for the last loop, provided you sort the array. But it was my understanding that generally C++ should perform better and run faster than Java and certainly also Python. So how do I do that?
Any or all suggestions are welcome. Thanks.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main () {
string line;
int N;
ifstream myfile ("ints/ints-400-1.txt");
getline(myfile,line);
stringstream into(line);
into >> N;
std::vector<long long> vals (N);
if (myfile.is_open())
{
int i = 0;
while ( getline(myfile,line) ) {
vals[i] = stoll( line );
++i;
}
myfile.close();
}
else cout << "Unable to open file";
for (int i = 0; i != vals.size(); i++) {
for (int j = i + 1; j != vals.size(); j++) {
for (int k = j + 1; k != vals.size(); k++) {
for (int l = k + 1; l != vals.size(); l++) {
if (vals[i] + vals[j] + vals[k] +vals[l] == 0) {
cout << "true";
}
}
}
}
}
return 0;
}
Related
As you can see from the title I need to decrypt the strings in a text file. I have major problems with this so if you can help me I would really appreciate it.
First of all, here is the input file:
saoreecessinntfi
pmrrj ie2
borj
I want to decrypt these words like this:
sesnaestocifreni
primjer 2
broj
I have used the matrix 4x4 to do this, and here is the code so far:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream test;
test.open("test.txt");
char word[5][5];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
test >> word[i][j];
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
cout << word[j][i];
}
}
return 0;
}
Here is the output:
sesnaestocifreni
It only outputs the first word in text file. I think the problem with this is that I do not know how "long" is "i" and "j" in those other words beacuse the first word has 16 charachters so the counter "i" and "j" are set on 4. How to count each words charachters and if they are the same then decrpyt the word. Also if the word is right spelled I need to cout in the program "ERROR". For example
apple
I do not need to decrypt this word, beacuse it is right word, and "i" and "j" would not be the same or I do not know what I am talking about.
I think this should work just the fine for your case:
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
int matrixSize(std::string &str) {
auto x = sqrt(str.length());
return x - floor(x) == 0 ? x : 0;
}
int main() {
std::fstream file("test.txt");
std::string str;
while (std::getline(file, str)) {
if (int n = matrixSize(str)) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
std::cout << str.at(j * n + i);
std::cout << std::endl;
} else
std::cout << "ERROR" << std::endl;
}
return 0;
}
Sample test.txt file:
saoreecessinntfi
pmrrj ie2
borj
apple
Output on test run:
sesnaestocifreni
primjer 2
broj
ERROR
If I understand your problem correctly, you are given a line of n*n characters and need to unscramble it as given.
while (true) {
std::string line;
std::getline(cin, line);
if (line.empty())
break;
int n = 1;
while (n*n < line.size()) {
n++;
}
if (n*n != line.size()) {
std::cout << "ERROR" << std::endl;
continue;
}
std::string unscrambled;
for (int col = 0; col < n; col++)
for (int row = 0; row < n; row++)
unscrambled.append(1, line[row * n + col]);
std::cout << unscrambled << std::endl;
}
I took a look online and none of the answers solves the problem I have comparing the elements from a vector.
I tried implementing a bool function but the problem is the same.
I am pretty new in c++ so please be patient!
PART2: First of all thank you.
So I changed my programm and created a bool function, the problem is now that it doesn get recognised before 5-6 tries.
#include <iostream>
#include <vector>
#include <time.h>
#include <stdlib.h>
#include <string>
using namespace std;
vector<int> input, compareMe, randomNumbers;
const unsigned int MAX_VEKTORSTELLEN = 5;
const unsigned int UPPER_GRENZE = 49;
const unsigned int LOWER_GRENZE = 1;
unsigned int i, j;
string output;
int random, anzahlRichtige, eingabe;
bool isEqual = false;
string lotto(vector<int>)
{
if (input[i] < LOWER_GRENZE || input[i] > UPPER_GRENZE)
{
output = "Die Zahlen muessen zwischen 1 und 49 liegen! \n";
input.pop_back();
}
else if (input.size() != MAX_VEKTORSTELLEN)
output = "Es muessen 6 Zahlen uebergeben werde! \n";
else if (isEqual == true)
output = "Es duerfen keine doppelten Zahlen vorkommen! \n";
else
for (i = 0; i <= MAX_VEKTORSTELLEN; i++)
srand((unsigned)time(NULL) <= UPPER_GRENZE && (unsigned)time(NULL) > 0);
random = rand();
randomNumbers.push_back(random);
return output;
}
bool compare()
{
compareMe = input;
for (i = 0; i < input.size(); i++)
for (j = 0; j < compareMe.size(); j++)
if (compareMe[j] == input[i])
isEqual = true;
return isEqual;
}
int main()
{
cout << "insert 6 numbers: ";
while (cin >> eingabe)
{
input.push_back(eingabe);
lotto(input);
compare();
cout << output;
for (i = 0; i < input.size(); i++) //Debug
cout << input[i] << ", ";
continue;
}
for (i = 0; i < input.size(); i++)
cout << input[i];
system("pause");
return 0;
}
From line 34 to line I didn´t finish to code but doesn´t really matter because I got stuck before.
All your loops in lotto are wrong. You go one past the end of your containers.
for (i = 0; i <= input.size(); i++)
// ^ !!!
It should be <.
You got this right in main.
I have a task that by given line of weights of cages and I have to split them into 2 trucks. The split should be done like this that |a - b| to have least value where 'a' is the common weight of the cages in the first truck and 'b' is the common weight of the cages of second truck. My program seems to work but when I upload it to hackerrank abort function is called. So where is my fault? Here is the code:
#include <iostream>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string input;
int k;
while (getline(cin, input))
{
/* splitting the input into integers */
vector<int> v;
istringstream iss(input);
while (iss >> k) v.push_back(k);
/* --- II --- */
unsigned long sum = 0;
unsigned i, j;
for (i = 0; i < v.size(); i++)
sum += v[i];
vector<char> can;
can.push_back(1);
for (i = 1; i <= sum; i++)
can[i] = 0;
for (i = 0; i < v.size(); i++)
{
for (j = sum; j+1 > 0; j--)
{
if (can[j])
{
can[j + v[i]] = 1;
}
}
}
for (i = sum / 2; i > 1; i--)
{
if (can[i])
{
if (i <= sum - i)
{
cout << i << " " << sum - i << endl;
break;
}
else
{
cout << "a should be <= b";
break;
}
}
}
}
return 0;
}
How can this work?
You create an empty vector of char, push one single value into it and that try to assign value passed the first:
...
vector<char> can;
can.push_back(1); // can contains one single value
for (i = 1; i <= sum; i++)
can[i] = 0; // Error "vector subscript out of range" in debug mode
If you do not ask the control of vector subscript you will just invoke undefined behaviour.
But if you just want to expand the vector, you can repeatedly can push_back:
for (i = 1; i <= sum; i++)
can.push_back(0);
I am trying to compile the following problem (downloads.cpp) in C++ using Cygwin:
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <climits>
using namespace std;
int main() {
int N, ft = 0, bw = 0;
ifstream input;
input.open("downloads.in");
input >> N;
pair <int, int> S_T[N+1];
S_T[N+1].first = INT_MAX;
S_T[N+1].second = INT_MAX;
int FT[N];
fill(FT, FT + sizeof(FT), 0);
for (int i = 0; i < N; ++i) {
input >> S_T[i].first >> S_T[i].second;
}
input.close();
sort(S_T, S_T + N);
for (int i = 0; i < N; ++i)
{
if (S_T[i+1].second != 0) {
for (int j = i+1; j < N; ++j) {
S_T[j].second -= S_T[i].second;
}
S_T[i+1].first += S_T[i].first;
S_T[i+1].second *= S_T[i-1].second / S_T[i].second;
} else if (S_T[i+1].first != INT_MAX && S_T[i+1].second != INT_MAX) {
S_T[i+1].first += S_T[i].first;
S_T[i+1].second *= S_T[i-1].second / S_T[i].second;
}
FT[i] = S_T[i].second;
}
for (int i = 0; i < N; ++i)
ft += FT[i];
ofstream output;
output.open("downloads.out");
output << ft << endl;
output.close();
return 0;
}
And I get the following error (with varying 5-digit numbers after "downloads"):
0 [main] downloads 76188 cygwin_exception::open_stackdumpfile: Dumping stack trace to downloads.exe.stackdump
[Finished in 6.5s]
Additionally, the program takes significantly longer than the usual one second to compile, and Cygwin seems to create a .exe.stackdump file with the same name as my program in the same file.
I have already checked for Cygwin opening background processes, and have found none. Anyone know why this could be happening?
EDIT: solved! I was treating negative numbers test case as 0, instead of having the output be negative as well. thanks for the help!
Here is the challenge description: https://www.codeeval.com/open_challenges/17/
I keep getting a partially solved score. I want to know why. As in my eyes, this code works. And I believe that it is O(N) time. Thanks for looking!
Here is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
int value = 0; //for holding the value of stock change
while (std::getline(file, line))
{
int pos = 0;
if(line.length() == 0)
continue;
else
{
std::istringstream iss(line);
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while (iss >> value)
{
list.push_back(value);
}
Values.push_back(list);
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
/*
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
*/
return 0;
}
so I swapped out some code now. I get better score but I it's still a partial.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
if (curr_max < 0)
{
curr_max = 0;
max_so_far = 0;
}
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
std::string token; //for the subtring that will be converted from char to int
int value = 0; //for holding the value of stock change
int count = 0;// for holding how many total cases
while (!file.eof())
{
int pos = 0;
getline(file, line);
if(line.length() == 0)
continue;
else
{
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while ((pos = line.find(",")) != std::string::npos )
{
token = line.substr(0,pos);
value = atoi(token.c_str());
line.erase(0, pos + 1);
list.push_back(value);
}
value = atoi(line.c_str());
list.push_back(value);
Values.push_back(list);
++count;
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
return 0;
}
Why are you passing the vector by value here?
int maxSubArray(vector<int> values)
That looks like a significant optimization opportunity.
I think you don't read the problem exactly right. When they say 'all contiguous sub ararys', they mean you have to take the max over all i andj of for(idx = i; i < j; ++i) { total += vec[idx]; }. Right now your code basically assumes i = 0 which isn't what you are supposed to do.
Just from looking at the output examples they provide, I can see that your code isn't going to give the answer that they expect.
it seems right, the only thing I can think of is that when the list gets long, your result can overflow, so change int to long long.
Besides technical optimizations suggested in other answers, concerning the algorithm, i think a little fix can make your algorithm work. When curr_max drops to a negative value, due to encountering a negative integer that exceeds curr_max, you can simply drop all the previous integers including the current value and start over. This fix is simple, you can add one line to your loop like this:
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0); // <---------------- add this line
max_so_far = max(max_so_far, curr_max);
}