How would I add an element to an array, assuming that I have enough space? My code looks something like this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
ofstream out("hi.out");
ifstream in("hi.in");
string currentLine;
string values[135];/*Enough for worst case scenario*/
if (out.is_open && in.isopen()){
while (in >> currentLine){
/*Add currentLine to values*/
}
/*Do stuff with values and write to hi.out*/
}
out.close()
in.close()
return 0;
}
No need to write the loop yourself. With your array:
auto l = std::copy(std::istream_iterator<std::string>(in), {}, values);
l - values is the number of strings read.
Or even better, use a vector, so that you don't have to worry about the possibility of your "worst case scenario" not being the actual worst case scenario.
std::vector<std::string> values(std::istream_iterator<std::string>(in), {});
You could use an index counter variable:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
ofstream out("hi.out");
ifstream in("hi.in");
string currentLine;
string values[135];/*Enough for worst case scenario*/
int index = 0;
if (out.is_open && in.isopen()){
while (in >> currentLine){
/*Add currentLine to values*/
values[index++] = currentLine;
}
/*Do stuff with values and write to hi.out*/
}
out.close()
in.close()
return 0;
}
The variable index, once the loop is complete, will contain the number of strings in your array.
Related
I am solving a twoSum problem.
Steps:
Read an input file with a following template:
7
1 7 3 4 7 9
First line is the target number, second line is a number sequence.
Numbers can be in range 0 < N < 999999999
If the sum of two numbers from the number sequence equals the target number, I write "1" to the output file.
If there are no numbers the sum of which equals the target number then I write "0" to the output file.
I need to optimize memory usage in my code. How can I do that?
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;
int main() {
ifstream f1;
vector<int> nums;
string line;
string source;
//Open input file and read it to a string
f1.open("input.txt");
while (getline(f1, line, '\n')) {
source+=line + " ";
} f1.close();
//Parse the string into an int vector
stringstream parser(source);
int num;
while (parser >> num) { nums.push_back(num); }
//Clear used strings
line = "";
source = "";
//Get target number
int target = nums.at(0);
//Get number sequence
nums.erase(nums.begin());
bool flag = false;
//Check number sequence for two numbers sum of which equals the target number
unordered_map<int, int> mp;
for(int i=0;i<nums.size();i++){
if(mp.count(nums[i])==1){
flag = true;
break;}
mp[target-nums[i]]=i;
}
//Write the result into the output file
ofstream f2;
f2.open("output.txt");
f2 << flag;
f2.close();
}
There are a couple of things you can do to minimise memory usage here. First up, you don't need to read entire contents of the file into std::string. You can read directly into std::vector, or better still read the file contents into a single int variable and process the numbers as you go. Another thing: you do not need to use a std::unordered_map, because presence of the key is the only thing you are really interested in, so std::unordered_set is sufficient. Below a simple solution making use of that suggestions:
#include <fstream>
#include <unordered_set>
int main() {
std::ifstream input {"input.txt"};
int target;
input >> target;
int current_number;
bool found = false;
std::unordered_set<int> observed_numbers;
while (input >> current_number) {
if (observed_numbers.count(target - current_number) > 0) {
found = true;
break;
}
observed_numbers.insert(current_number);
}
std::ofstream output {"output.txt"};
output << found;
}
How to write a program that reads 5 strings from user input and prints only those strings that end with the letter ‘ed’ in C++. Need help!
The solution is rather straightforward.
First we define a container that can contain 5 std::string. For that we use a std::vector together with a constructor to reserve space for the 5 elements.
Then we copy 5 strings from the console (from user input) into the vector.
And, last, we copy elements out of the std::vector to std::cout, if the strings end with "ed".
Because of the simplicity of the program, I cannot explain much more . . .
Please see.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <iterator>
constexpr size_t NumberOfTexts = 5U;
int main()
{
// Define a container that can hold 5 strings
std::vector<std::string> text(NumberOfTexts);
// Read 5 strings from user
std::copy_n(std::istream_iterator<std::string>(std::cin), NumberOfTexts, text.begin());
// Print the strings with ending "ed" to display
std::copy_if(text.begin(), text.end(), std::ostream_iterator<std::string>(std::cout,"\n"), [](const std::string& s){
return s.size()>=2 && s.substr(s.size()-2) == "ed";
});
return 0;
}
Simple solution,
#include<iostream>
using namespace std;
bool endsWith(const std::string &mainStr, const std::string &toMatch)
{
if(mainStr.size() >= toMatch.size() &&
mainStr.compare(mainStr.size() - toMatch.size(), toMatch.size(), toMatch) == 0)
return true;
else
return false;
}
int main()
{
string s[5];
for(int i=0;i<5;i++)
{
cin>>s[i];
}
for(int i=0;i<5;i++)
{
if(endsWith(s[i],"ed"))
cout<<s[i]<<endl;
}
}
Hope This might Helps:)
I am having what seems to be a common issue however reading through the replies to the similar questions I can't find the solution to my issue at all as I have already done what they are suggesting such as making the variable an array. I have the following code:
#include "stdafx.h"
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <future>
using namespace std;
string eng2Str[4] = { "money", "politics", "RT", "#"};
int resArr[4];
int main()
{
engine2(eng2Str[4], resArr[4]);
system("Pause");
system("cls");
return 0;
}
void engine2(string &eng2Str, int &resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++) {
while (getline(fin, line)) {
if (line.find(eng2Str[i]) != string::npos) {
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
Before you mark as duplicate I have made sure of the following:
The array and variable I am trying to assign are both int
Its an array
The error is:
expression must have pointer-to-object type
The error is occurring at the "resArr[i] = fcount;" line and am not sure why as resArr is an int array and I am trying to assign it a value from another int variable. I am quite new to C++ so any help would be great as I am really stuck!
Thanks!
The problem is that you've declared your function to take a reference to a single string and int, not arrays. It should be:
void engine2(string *eng2Str, int *resArr)
or:
void engine2(string eng2Str[], int resArr[])
Then when you call it, you can give the array names as arguments:
engine2(eng2Str, resArr);
Another problem is the while loop in the function. This will read the entire file during the first iteration of the for() loop. Other iterations will not have anything to read, since it will be at the end of the file already. You could seek back to the beginning of the file, but a better way would be to rearrange the two loops so you just need to read the file once.
while (getline(fin, line)) {
for (int i = 0; i < 4; i++) {
if (line.find(eng2Str[i]) != string::npos) {
resArr[i]++;
}
}
}
I would suggest to use std::vector instead of pure C array.
In your code, there are more issues.
You are passing the fourth element of both arrays to the engine2 function.
From your definition of void engine2(string &eng2Str, int &resArr) you expect reference to a string (not array / vector) and an address / reference of int - you need to pass an pointer to the first element of resArr.
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <future>
using namespace std;
vector<string> eng2Str = { "money", "politics", "RT", "#" };
int resArr[4] = {};
void engine2(const vector<string>& eng2Str, int* resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++)
{
while (getline(fin, line))
{
if (line.find(eng2Str[i]) != string::npos)
{
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
int main()
{
engine2(eng2Str, resArr);
system("Pause");
system("cls");
return 0;
}
I notice that amending (or replacing) an element in a large vector is consuming a lot of time when the vector is getting bigger, even when the element's place in the vector is known.
Is there an explanaition for this?
I use an unsorted set as an index. The code first tries to find the element in the set with set.find(). If the element not present in the set the code insert it at the end of the set and at the same time pushes it at the end of the vector.
If the element is found on position "x" of the set the data in the vector is replaced by using:
vector.at(x)=vector[x]+element.
When I skip the vector part and only insert the element in the set the code easily processes 95 million elements in less then 2 minutes. But when I add the vector part to it the code keeps on running for hours.
The file I'm importing is a semicolumn separated text, with below structure
2161182;Jutfaseweg;footway;no;7740068,13877901
2953564;Timorkade;cycleway;no;7785429,368846814,582743212,582743202,582743213,582743203,582743214,582743206,582743210,45200603
Each line represents a way. The ID's in the last element are waypoints of that particular way. Each element has a righthand neighbour, unless it is the last element of the way and based on the 4th element ("yes" or "no", meaning oneway or not), also a lefthand neighbour, unless it is the first element of the way.
Below is the code as requested
#include <windows.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <set>
#include <vector>
using namespace std;
set<string>PresentStreet;
set<int>PresentNode;
vector<string>NeighBours;
string line1;
void split(const string& s, char c,
vector<string>& v) {
string::size_type i = 0;
string::size_type j = s.find(c);
while (j != string::npos) {
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
v.push_back(s.substr(i, s.length()));
}
}
int main(int argc, char *argv[]) {
ifstream myfile ("filename.txt");
int CounterLine=1;
while ( getline (myfile,line1) ) {
string s1=line1;
vector<string> v1;
split(line1, ';', v1);
PresentStreet.insert(v1[2]);
vector<string> v2;
split(v1[4], ',', v2);
for (int t=0;t<v2.size();t++) {
auto search = PresentNode.find(atoi(v2[t].c_str()));
if(search == PresentNode.end()) {
string Neighbours="";
if(v1[3].find("no")!=std::string::npos&&t>0) {
Neighbours=Neighbours+v2[t-1]+",";
}
if(t<v2.size()-1) {
Neighbours=Neighbours+v2[t+1]+",";
}
stringstream ss;
ss<<CounterLine;
stringstream ss2;
ss2<<v2[t];
PresentNode.insert(atoi(v2[t].c_str()));
NeighBours.push_back(Neighbours);
}else{
int nPosition = distance (PresentNode.begin (), search);
string Neighbours=NeighBours[nPosition];
if(v1[3].find("no")!=std::string::npos&&t>0) {
Neighbours=Neighbours+v2[t-1]+",";
}
if(t<v2.size()-1) {
Neighbours=Neighbours+v2[t+1]+",";
}
NeighBours.at(nPosition)=Neighbours;
}
}CounterLine++;
}
}
So I am supposed to take all ints in source3.txt and check which of them occur in source.txt. If any of them don't occur, I'm supposed to print a corresponding line from source2.txt to output.txt (source2.txt contains descriptions of the numbers in source 3, in the same order, each description is 1 line). I wrote this code, but it only prints the last line from source2.txt, furthermore it is a wrong line.
I have no idea what might be wrong. Can you help me?
#include <bits/stdc++.h>
using namespace std;
int main()
{
ifstream source ("source.txt");
ifstream source2 ("source2.txt");
ifstream source3 ("source3.txt");
vector<int> tab(1051,0);
vector<string> tab2(857,*new string);
vector<int> tab3(857,0);
ofstream output("output.txt");
for(int i=0;i<1050;++i)
{
source>>tab[i];
}
for(int i=0;i<856;++i)
{
string a;
getline(source2,a);
tab2[i]=a;
source3>>tab3[i];
}
for(int i=0;i<856;++i)
{
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
{
continue;
}
else
{
output<<tab2[i]<<endl;
}
}
}
I think below modifications to code should work for you . Replace value of SOURCE_COUNT with 1051 and SOURCE2_COUNT with 857
#include <iostream>
#include <fstream>
#include <vector>
#include <vector>
const int SOURCE_COUNT = 4;
const int SOURCE2_COUNT = 3;
//const int SOURCE2_COUNT = 3;
using namespace std;
int main()
{
ifstream source ("source.txt");
ifstream source2 ("source2.txt");
ifstream source3 ("source3.txt");
vector<int> tab(SOURCE_COUNT,0);
vector<string> tab2(SOURCE2_COUNT,"");
vector<int> tab3(SOURCE2_COUNT,0);
ofstream output("output.txt");
for(int i=0;i<SOURCE_COUNT;++i)
{
source>>tab[i];
}
for(int i=0;i<SOURCE2_COUNT;++i)
{
string a;
getline(source2,a);
tab2[i]=a;
source3>>tab3[i];
}
for(int i=0;i<SOURCE2_COUNT;++i)
{
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
{
continue;
}
else
{
output<<tab2[i]<<endl;
}
}
}
It looks to me like you are printing only in those cases where you have not found the number. In other words, the cases in your if-statement are reversed. It should read:
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
output<<tab2[i]<<endl;
[EDIT] Oops, I read the question not carefully enough. It should print the line, if the number is NOT contained in source3. So the loop should read:
if(std::find(tab.begin(), tab.end(), tab3[i]) == tab.end())
output<<tab2[i]<<endl;
Also: I would strongly suggest to do away with all those constants like 856 and 1050. Why don't you simply read the file until you reach the end?