Finding repeated strings in a list - c++

I have a list:
Class Name Surname
Math John Johnson
Programming Tom Tomson
Physics John Johnson
I'd like to find out which teacher teaches the most classes and return it as a string. I have written a simple class to save, take, add information.
template <typename tip>
string FindTeacher(List <tip> & A)
{
string module, surname, name, TeacherX;
for (int i = 0; i < A.Length(); i++)
{
tip kk = A.Take(i);
kk.Take(module, surname, name);
//stuck on this part, what to do next?
//how do i find that John Johnson teaches 2 classes, and Tom teaches only 1
}
return TeacherX;
}
I am terribly sorry if it's hard to understand me, english is not my native language.

You can use std::unodered_map, or std::map
with std::pair<std::string, std::string> > as key,
and size_t as data, and every time you get:
kk.Take(module, surname, name);
find by key(surname,name), if no insert with 1 as data, else increase data by one.

Related

Getting rid of duplicates

Can someone help?
I have a file like this:
file = """he is a good man
she is a beautiful woman
this is a clever student
he is a bad neighbour"""
And I want to mark the adjectives in the file, so I extracted them in a list and I want to replace them in the original file in another format, like between brackets. So the list adjectives looks like this
ad = "good, bad, clever, beautiful,"
I tried this
for line in file.splitlines():
for a in ad.split(','):
if a in line:
newline = line.replace(s, '[' + s + ']')
result = file.replace(line, newline)
print result
this gives me this result with duplicates:
he is a [good] man
she is a beatiful woman
this is a clever student
he is a bad neighbor
he is a good man
she is a[ beatiful] woman
this is a clever student
he is a bad neighbor
he is a good man
she is a beatiful woman
this is a[ clever] student
he is a bad neighbor
he is a good man
she is a beatiful woman
this is a clever student
he is a[ bad] neighbor
while I expect result like this
he is a [good] man
she is a [beautiful] woman
this is a [clever] student
he is a [bad] neighbour
The problem is your loop. You aren't splitting your adjectives well and the splitline is unnecessary if you are going to use replace. So, your code should be as follows:
adj = [word.strip() for word in ad.split(",") if word != ""]
for a in adj:
if a in file:
file = file.replace(a, '[' + a + ']')
print file

How to show regex output in pair in c++?

I dont know if it makes any sense or not but here it is
Is there a way that i can get two words from a regex result each time?
supose i have a text file which contains an string such as the following :
Alex Fenix is an Engineer who works for Ford Automotive Company. His
Personal ID is <123456>;etc....
basically if i use \w i would get a list of :
Alex
Fenix
is
an
Engineer
and etc
They are all separated by white space and punctuation marks
what i am asking is , whether there is a way to have a list such as :
Alex Fenix
is an
Engineer who
works for
Ford Automotive
Company His
Personal ID
is 123456
How can i achieve such a format?
Is it even possible or should i store those first results in an array and then iterate through them and create the second list?
By the way please note that the item Alex Fenix is actually an abstraction of a map or any container like that.
The reason i am asking is that i am trying to see if there is any way that i can directly read a file and apply a regex on it and get this second list without any further processing overhead
(I mean reading into a map or string , then iterating through them and creating pairs of the tokens and then carry on what ever is needed )
Try this regex
\w \w
It will match any word followed by a space and another word.
Although you can achieve such a format relatively easy without using a regex. Take a look at this for instance:
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
int main() {
std::string s("Alex Fenix is an Engineer who works for Ford Automotive Company. His Personal ID is <123456>");
// Remove any occurences of '.', '<' or '>'.
s.assign(begin(s), std::remove_if(begin(s), end(s), [] (const char c) {
return (c == '.' || c == '<' || c == '>');
}));
// Tokenize.
std::istringstream iss(s);
std::string t1, t2;
while (iss >> t1 >> t2) {
std::cout << t1 << " " << t2 << std::endl;
}
}
Output:
Alex Fenix
is an
Engineer who
works for
Ford Automotive
Company His
Personal ID
is 123456

Replace last comma with or using ColdFusion

What is the best way to convert an array of values in ColdFusion
[ Fed Jones, John Smith, George King, Wilma Abby]
and to a list where the last comma is an or
Fed Jones, John Smith, George King or Wilma Abby
I thought REReplace might work but haven't found the right expression yet.
If you've got an array, combining the last element with an ArrayToList is the simplest way (as per Henry's answer).
If you've got it as a string, using rereplace is a valid method, and would work like so:
<cfset Names = rereplace( Names , ',(?=[^,]+$)' , ' or ' ) />
Which says match a comma, then check (without matching) that there are no more commas until the end of the string (which of course will only apply for the last comma, and it will thus be replaced).
It'd be easier to manipulate in the array level first, before converting into a list.
names = ["Fed Jones", "John Smith", "George King", "Wilma Abby"];
lastIndex = arrayLen(names);
last = names[lastIndex];
arrayDeleteAt(names, lastIndex);
result = arrayToList(names, ", ") & " or " & last;
// result == "Fed Jones, John Smith, George King or Wilma Abby"
Another option is to work with a list / string using listLast and the JAVA lastIndexOf() method of the result string.
<cfscript>
names = ["Fed Jones", "John Smith", "George King", "Wilma Abby"];
result = arraytoList(names,', ');
last = listLast(result);
result = listLen(result) gt 1 ? mid(result, 1, result.lastIndexOf(',')) & ' or' & last : result;
</cfscript>
<cfoutput>#result#</cfoutput>
Result:
Fed Jones, John Smith, George King or Wilma Abby

How to Reverse a given sentence (string) in C++?

Example: if the input was DOGS LIKE CATS
output- CATS LIKE DOGS
consider that I have to use only : If-else conditions, while & for loops, Arrays, strings and Functions. NOT strings functions, Pointers & Dynamic memory allocation & structures.
Spaces need to be the same as the example as well.
I tried to do the following but it doesnt work can you help please?
void revSent(char str[]){
char temp[100];
int k;
for (i=sentenceSize ; i>0 ; i--)
for (k=0 ; k<sentenceSize ; k++)
temp[k]=str[i];
for (k=0 ; k<sentenceSize ; k++)
if (temp[k]!=' ')
for (i=k ; i>0 ; i--)
printf("%c", temp[i]);
}
It's easy to do this in-place, without any additional data structures:
reverse the whole string: DOGS LIKE CATS -> STAC EKIL SGOD
reverse each word in the string: STAC EKIL SGOD -> CATS LIKE
DOGS
Hint: you can use the same function for both (1) and (2).
You could implement the following to arrive at a solution:
Separate the sentence into a list of words.
Reverse this list.
Concat this list together to form the sentence.
If you define a word as a whitespace-delimited token then the following will do:
std::vector<std::string> sentence;
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::back_inserter(sentence));
std::reverse(sentence.begin(), sentence.end());
In essence you want to start with the definition of a word, then place in a container your words, and finally use std::reverse() to reverse them.
For an algorithms homework your instructor probably won't be satisfied with this. You want to create a function that splits a sentence into words. You can, of course, work with pointers within the same string -- and that may well be the intent of your instructor, but if that isn't what you must then I personally find working with a container easier.
I'll give a hint: since you can't use data structures you can't directly use Paul or OJ's method. BUT, recursive function calling would form a stack.
Break the sentence into words
In order, push each word onto a stack
Pop each item off the stack and print out/add to list/write to file/whatever.
Voila!
who says the STL isn't useful?
Depending on how you do this, there are different ways to attack this.
my way is just:
while (original_string isn't empty){
take first word
prepend to reversed string
}
Here's the C++ solution (using find and substr, two very useful string functions)
using namespace std;
string word_reverse(string original){
string reverse_string;
if (original.find(' ')!=string::npos){
do{
int pos=original.find(' ');
//prepend word
reverse_string=original.substr(0,pos)+' '+reverse_string;
//remove word from original,considering the found whitespace
original=original.substr(pos+1,original.length()-(pos+1));
}while(original.find(' ')!=string::npos);
//don't forget the last word!
return original+' '+reverse_string;
}
else{//no whitespace: return original text
return original;
}
}

Parse 'family' names into people + last name with regex

Given the following string, I'd like to parse into a list of first names + a last name:
Peter-Paul, Mary & Joël Van der Winkel
(and the simpler versions)
I'm trying to work out if I can do this with a regex. I've got this far
(?:([^, &]+))[, &]*(?:([^, &]+))
But the problem here is that I'd like the last name to be captured in a different capture.
I suspect I'm beyond what's possible, but just in case...
UPDATE
Extracting captures from the group was new for me, so here's the (C#) code I used:
string familyName = "Peter-Paul, Mary & Joël Van der Winkel";
string firstperson = #"^(?<First>[-\w]+)"; //.Net syntax for named capture
string lastname = #"\s+(?<Last>.*)";
string others = #"(?:(?:\s*[,|&]\s*)(?<Others>[-\w]+))*";
var reg = new Regex(firstperson + others + lastname);
var groups = reg.Match(familyName).Groups;
Console.WriteLine("LastName=" + groups["Last"].Value);
Console.WriteLine("First person=" + groups["First"].Value);
foreach(Capture firstname in groups["Others"].Captures)
Console.WriteLine("Other person=" + firstname.Value);
I had to tweak the accepted answer slightly to get it to cover cases such as:
Peter-Paul&Joseph Van der Winkel
Peter-Paul & Joseph Van der Winkel
Assuming a first name can not be two words with a space (otherwise Peter Paul Van der Winkel is not automatically parsable), then the following set of rules applies:
(first name), then any number of (, first name) or (& first name)
Everything left is the last name.
^([-\w]+)(?:(?:\s?[,|&]\s)([-\w]+)\s?)*(.*)
Seems that this might do the trick:
((?:[^, &]+\s*[,&]+\s*)*[^, &]+)\s+([^,&]+)