C/C++ code for rearranging .txt file [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Hi i have to make a function in C++ that gets one file as an input and as an output it has another file, that is rearranged in a specific way. In the file there are names of people,names of subject they are teaching, commented lines starting with '#' and also duplicated white spaces. The input file looks like this (before ':' are the names, after it are the subjects):
john : PA1 , PA2,OSY
#this is commented line
peter: PA1, PA2
And the output in the second file should look like this:
OSY: john
PA1: john, peter
PA2: john, peter
As you can see, the function should put one subject on each line (in alphabetical order) and then there should be ':' and after that the names of the people teaching it (also in aplhabetical order). Also all commented lines should be deleted and the same with duplicated white spaces.
I know how to delete duplicated white spaces and commented lines, but I have problem with rearranding the people and subjects. Is there any possible way to do this function without using classes?
I would be very thankful for any help or advices.
bool transform ( const char * inFile,
const char * outFile )
{
// todo
}

There are various different problems to solve. You must first identify those individual problems, then solve them one by one, and then put the pieces together. Many years ago, when I was a student at university, this approach was taught to me as "divide & conquer".
Here are the individual problems I can identify in your question:
Read a text file's contents into memory, so that you deal with strings and each line is a string.
Parse a string. Split it into substrings, so that you deal with a collection of strings (tokens). Know when a string starts with a particular character.
Create a data structure in which a sorted, unique string key relates to a list of (likewise ordered and unique) strings.
Write a series of strings to a text file.
Each of the sub-problems may well be individual separate questions on Stack Overflow. I'll give you hints for every one of them, so that you can google them or browse the archive for related questions:
Reading a text file line by line in order to end up with a series of std::string objects is best done with std::ifstream and std::getline.
Getting the first character of a std::string is easy: my_string[0], first checking if !my_string.empty(). Splitting it is more difficult. I would personally use the occasion and get started with the Boost libraries. See the Boost Tokenizer example.
The data structure you need is already there - C++ itself provides it as part of the language. The first thing which comes to mind is std::map<std::string, std::set<std::string> >.
Writing is simpler: use std::ofstream and write line by line with operator<<.

std::map and std::set are your best friends here.

Related

Best way to find if string contains any one element of a vector of string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have a target string and a vector of strings. I want to check if any of the string in the vector is contained in my target string and do something. Otherwise, do others.
What would be the best way of doing this. I know I can use for loop and string::find. But if there is any other function in stl can do this? Or using lambda function?
I tried for loop and it surely will work
std::string target = "United States";
std::vector<std::string> stringVec = {"United","America","Kindom"};
For (auto it = stringVec.cbegin(); it!=stringVec.cend(); ++it)
{
if (target.find(*it)!=std::string::npos)
cout << "Contains";
else
cout << "Not existed";
}
Abstracting away a bit from the specifics of C++ code, the problem you're describing is called the multi-string search problem. In that problem, you're given a list of pattern strings P1, P2, ..., Pk and a text string T, and the goal is to determine which substrings appear within the pattern string. This is a well-studied problem and there are some great algorithms for it.
If you have a fixed set of patterns and will be searching over lots of different strings to find those patterns, then the Aho-Corasick algorithm is a great solution. It does a small (linear) amount of preprocessing on the pattern strings to build a matcher that can then find all matches of those strings in variable texts quickly (in time linear in the length of the string to search plus the number of matches). There are a number of C++ implementations of this algorithm available; check Google for some examples.
On the other hand, if you have a fixed string and a variable set of patterns, you might want to look into suffix arrays or suffix trees, which, after linear preprocessing work on the string to search inside of, support efficient (linear, or close-to-linear) searches of that string for any pattern you'd like.
These algorithms have the downside that they're a bit complex not something you'd code up unless you really needed the efficiency. For example, if you're working on strings that are millions of characters long, then these approaches are probably what you're looking for. So in that sense, if you're searching short strings, you can probably get away with just using the code that you have, since it's unlikely to be a bottleneck and is fairly easy to understand.
std::any_of will do the job.
std::string target = "United States";
std::vector<std::string> stringVec = {"United","America","Kindom"};
bool found = std::any_of(stringVec.begin(), stringVec.end(),
[&target](const auto& s){ return target.find(s) != std::string::npos; });
if(found)
std::cout << "Contains";
else
cout << "Not existed";
Your code will do something for every string if it meets the condition, not only once if the string is found (which is what you wanted I believe, judging by the description).

Designing Game of Life using classes C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
for my final project in my intro C++ class we have to design a version of Game of Life using classes and file I/O. I have been given some beginning functions/instructions but can't even begin to understand where to start or if I am missing other functions to get started. I've included the instructions given and what I have so far. I don't necessarily need the whole thing laid out for me, but if I could just have a little help on how to get started, that would be great.
Instructions:Since the project is in chapter 7, the book’s version doesn’t work with classes and it doesn’t have any file IO. Let’s
address the file IO first. On the project download page in addition to the usual items there will be two data files
containing very simple life community specifications. The files have the following format: first item in the file is the
number of rows the community requires, second item in the file is the number of columns the community requires, third
item is the LIFE community which is stored as ‘.’ (dead) or ‘O’ (alive) characters in the array shape specified by the
preceding two values.
In order for your project to work with these inputs you will need to specify a two dimensional array. The book specifies a
22 by 80 array. The GTA project uses a 50 by 100 (row by col) array. So long as your array is larger than the size specified
by the input, your code will work with the input. After creating the array, the code reads in the data from the input and
fills out your LIFE community array with a small twist. The book suggests filling in the grid directly with asterisks for live
cells and blanks for dead cells. We will use class objects instead.
The normal implementation of LIFE uses two identical arrays. One stores the now generation and one is used to store
the next generation. (see the book pgs 446 & 447) We will be using one array which contains LIFE cell objects made from
the simplest useful class we could think of. Our class objects will contain two Boolean data items that store the cell’s life
condition and one function which will age the cell.
Your LIFE community’s size should be square and an edge length is define globally as const int edge=#. Your class is
named cell and contains the public boolean variables aod_d0, aod_d1 and the void function age(). Create a general
function that counts the number of living neighbors of a cell and declare its type with the following declaration: int
nbors_sum(cell[edge][edge], int, int, int, int);. Your LIFE community ages a day at a time so create a general function that
reads cells at d0 and determines whether that cell is alive or dead (aod) at d1. It’s declaration is: void oneday(cell[edge]
[edge], int, int);. The oneday function will call the nbors_sum function. The GTA version has a fair amount of code in
main() including file input and the while(true) display loop.
Code:
#include <iostream>
#include <fstream>
using namespace std;
const int edge=20;
class cell{
public:
bool aod_d0, aod_d1;
int nbors_sum(cell[edge][edge],int,int,int,int);
void oneday(cell[edge][edge],int,int);
int main()
{
ifstream in;
in.open("glidergun.txt");
if(in.fail())
{
cout <<"Input file failed to open.\n";
return 1;
}
oneday()
in.close();
return 0;
}
void age();
int nbors_sum(cell[edge][edge],int,int,int,int);
void oneday(cell[edge][edge],int,int){
}
It's not so hard - that's a pretty common excercise, so there's a lot of material on the Web. Just check Wikipedia, for example, to get an idea and see some animations of this "Game" in motion:
https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
As a starting point, I would suggest that you do the following:
Make your program read in a file and store the data within a 2D
array, as suggested by the excercise
Make your program print the
resulting 2D array to the console (standard output)
If you manage to get those two steps done, by the point you proceed you will already have a better understanding of what this is all about.
My general suggestion would be that you, if you face a problem like that where you don't know what to do, just start by doing the very obvious things that need to be done anyway (such as the reading the file, in this case). By doing that, you will get familiar with the rest on the way.

C++ send objects in named pipe [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
i am trying to send an object throught a named pipe but, i don't understand how to serialize my object :
class Order {
public:
void addFile(std::string const &file);
void setType(Parser::Information const &type);
std::list<std::string> getFileList() const;
Parser::Information getType() const;
void clear();
private:
std::vector<std::string> fileList;
Parser::Information type;
};
i already managed to make my named pipe work with basic data types but, i don't understand how to send and receive a full object (without using boost serialization)
I tried to put the object's datas in a struct, but I didn't manage to send it through named pipes... probably because of the vector
Could someone share his knowledge with me please
You need to convert the structure into something that can fit into a single array of bytes that can be written to the pipe as a block of memory. A string is the simplest example.
A trivial (but inflexible) way to format your data as a string would be to use C++ string streams to write type, followed by a newline, then write the first entry in fileList, followed by a newline, then the second entry, a newline, etc. When the far end of the pipe receives this data, it would have to read the first line from the string, parse it into type, then read each of the next lines and add them to file list. (If your named pipe is across the network, you may want to encode the data as utf-8 to avoid character set problems.)
In practice, you want a more flexible file format that tags the values. A common solution is JSON, which can encode multiple structures, vectors, boolean, int, double and other values. JSON is always utf-8 and can handle nested structures. C++ isn't the easiest language from which to use JSON, but it's better than rolling your own solution. One library that can read and write JSON data is https://github.com/open-source-parsers/jsoncpp.
At the high end of serialization formats is binary encoding, which is much faster to parse than string-based data. However, binary data is not human readable, so it can be more difficult to debug. One example of a library that does binary encoding/decoding is Cap'n Proto at https://capnproto.org/.

Search a string for any occurence of a word in a list of strings [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
The community reviewed whether to reopen this question 3 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I want to know how, in C++, to search a string for the first instance of ANY of a list of strings. A kind of full-word version of std::string::find_first_of(): "Searches the string for the first character that matches any of the characters specified in its arguments".
I want something that will search the string for the first WORD that matches any of the words in a provided list/array. To be clear, I don't want to search an array for an instance of a string. I want to search a string, for an instance of something in an array.
My goal is to be able to take a sentence, and remove all words that I have in a list. For example, if I give it the list {"the" "brown", "over"};
and the sentence, "the quick brown fox jumped over the lazy dog",
I want it to output, " quick fox jumped lazy dog".
And I want to be able to give it a list of even 100 words if I want; I need this to be expandable.
The only solution I can think of is to use std::find(stringArray[0]) in a while loop on my block of text, and save the indexes that that word is found at, then put all that in another for loop and do that on every single word in my array, saving the indexes of each word into one huge list. Optionally then numerically sorting that list, and finally then going through and removing each word that is at a position in that list.
I'm really hoping there's a function or an easier way to do it, because my solution seems difficult and VERY slow, especially since I need to use it many times, on many different strings, to go through all the sentences of a 50,000 character block of text. Anything better optimized would be preferred.
If you look for standard functions, there are somme possiblities if you dare to store your sentences as a container of strings:
string input="Hello, world ! I whish you all \na happy new year 2016 !";
vector<string> sentence;
stringstream sst(input); // split the string into its pieces
string tmp;
while (sst>>tmp)
sentence.push_back(tmp);
Of course, in the real world you would do the split not just on whitespaces, but also on punctuations. This is just a proof of concept.
Once you have it in this form, it's easy to use the <algorithm> form of find_first_of():
vector<string> search{"We", "You", "I"};
auto it = find_first_of(sentence.begin(), sentence.end(),
search.begin(), search.end());
// display remaining of the sentence
copy(it , sentence.end(), ostream_iterator<string>(cout,"/"));
cout<<endl;
And deleting words from a vector shouldn't then be anymore an issue. I let it to you as an exercise.
Once you have your cleaned vector you can rebuild a string:
stringstream so;
copy(it , sentence.end(), ostream_iterator<string>(so," "));
string result = so.str();
Here an online demo.
This solution won't address all your performance issues however. For this you need to analyse further where your performance bottleneck comes from: do you make a lot of unnecessary copies of objects ? Is it that your own algorithm triggers a lot of inefficient memory allocations ? Or is it really the sheer volume of text ?
Some ideas for further work:
build an alphabetical index to the words in the sentence (map> where the unsigned
consider a trie data structure (trie and not tree !!)
Use regular expressions in <regex>
Some people's fast is other people's slow, so it is hard to say which fast you mean and 50000 characters doesn't sound so large, that one must do something extraordinary.
The only thing, that should be avoided is manipulating the input string in-place (would result in O(n^2) running time) - just return a new resulting string. It's probably wise to reserve enough memory for the resulting string, because it would save a constant factor for some inputs.
There is my proposal:
std::string remove_words(const std::string &sentence, const std::set<std::string> &words2remove, const std::string &delimiters){
std::string result;
result.reserve(sentence.size());//ensure there is enough place
std::string lastDelimiter;//no delimiter so far...
size_t cur_position=0;
while(true){
size_t next=sentence.find_first_of(delimiters, cur_position);
std::string token=sentence.substr(cur_position, next-cur_position);
result+=lastDelimiter;
if(words2remove.find(token)==words2remove.end())
result+=token;//not forbidden
if(next==std::string::npos)
break;
//prepare for the next iteration:
lastDelimiter=sentence[next];
cur_position=next+1;
}
return result;
}
This method uses a set rather than a list of forbidden words because of the faster look-up. As delimiters any set of chars can be used e.g. " " or " ,.;".
It runs in O(n*log(k)) where n is the number of characters in the sentence and k the number of words in the forbidden set.
You may want to look into boost::tokonizer if you need a more flexible tokonizer and don't want to reinvent the wheel.
In case the number of forbidden words is large, you may consider to use std::unordered_set (c++11) or boost::unordered_set instead of std::set to reduce the expected running time of the algorithm to O(n).

Copy Certain Portion of One Array to Another

I'm still quite new to programming -- about two months in -- so if this is a really basic question, then I apologize. Going along with that, my terminology might be completely off. If it is, I'd greatly appreciate any help you might be able to offer with telling me the proper terms. I searched around the forums here for a bit, but couldn't find anything that answered my question. If you're aware of a topic that does, then please just link it below.
Onto the question.
Let's say that I have an external text file with a bunch of information in it. The information is divided into items, each item delineated from the next by '::'. Each item is divided into four fields, each field delineated from the next by '\'.
What I want to do is take one item's information out of the text file and place it into an array called info. I want to then take info and pass it to another function. This function will create four new arrays and then portion out field 1 to array 1, field 2 to array 2, etc.
Basically, how do I take an array, take a portion of that array and give it to another variable, then copy another portion of that array and give it to another array.
Example:
The External Text File looks like the following:
26::Female::Kentucky::Trauma\\34::Male::Michigan::Elective\\85::Male::Unknown::Trauma\\18:Female::Washington::Emergent
Using fstream, I then take "26::Female:Kentucky::Trauma" and put it into an array called 'info', which is then passed to a function called Sort(char info[]).
How do I get Sort(char info[]) to take an array with "26::Female::Kentucky::Trauma" and turn it into four arrays such as:
Age: 26
Sex: Female
Location: Kentucky
Reason for Admission: Trauma
EDIT
Array 1 looks like:
26::Female::Kentucky::Trauma
I then create four char arrays called, Age, Sex, Location, Reason. How do I get 26 into the Age array, Female into the Sex array, Kentucky into the Location array, and Trauma, into the Reason array?
I know that I could do this at the stage where I'm reading in from an external file, but it seems easier to do it this way for my purposes.
Thank you for your time.
Look at the documentation for the string class. The functions find_first_of and substr will be useful. Split the string when it finds :: or //. For example, 26::Female::Kentucky::Trauma would be split into 26 and Female::Kentucky::Trauma. This sounds like it may be an assignment, so I will not give a complete solution, but this should be enough to get you going.